00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00027 #include <stdlib.h>
00028 
00029 #include "libavutil/intreadwrite.h"
00030 #include "avcodec.h"
00031 #include "bytestream.h"
00032 #include "get_bits.h"
00033 #include "dsputil.h"
00034 
00035 enum {
00036     PRED_NONE = 0,
00037     PRED_LEFT,
00038     PRED_GRADIENT,
00039     PRED_MEDIAN,
00040 };
00041 
00042 typedef struct UtvideoContext {
00043     AVCodecContext *avctx;
00044     AVFrame pic;
00045     DSPContext dsp;
00046 
00047     uint32_t frame_info_size, flags, frame_info;
00048     int planes;
00049     int slices;
00050     int compression;
00051     int interlaced;
00052     int frame_pred;
00053 
00054     uint8_t *slice_bits;
00055     int slice_bits_size;
00056 } UtvideoContext;
00057 
00058 typedef struct HuffEntry {
00059     uint8_t sym;
00060     uint8_t len;
00061 } HuffEntry;
00062 
00063 static int huff_cmp(const void *a, const void *b)
00064 {
00065     const HuffEntry *aa = a, *bb = b;
00066     return (aa->len - bb->len)*256 + aa->sym - bb->sym;
00067 }
00068 
00069 static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
00070 {
00071     int i;
00072     HuffEntry he[256];
00073     int last;
00074     uint32_t codes[256];
00075     uint8_t bits[256];
00076     uint8_t syms[256];
00077     uint32_t code;
00078 
00079     *fsym = -1;
00080     for (i = 0; i < 256; i++) {
00081         he[i].sym = i;
00082         he[i].len = *src++;
00083     }
00084     qsort(he, 256, sizeof(*he), huff_cmp);
00085 
00086     if (!he[0].len) {
00087         *fsym = he[0].sym;
00088         return 0;
00089     }
00090     if (he[0].len > 32)
00091         return -1;
00092 
00093     last = 255;
00094     while (he[last].len == 255 && last)
00095         last--;
00096 
00097     code = 1;
00098     for (i = last; i >= 0; i--) {
00099         codes[i] = code >> (32 - he[i].len);
00100         bits[i]  = he[i].len;
00101         syms[i]  = he[i].sym;
00102         code += 0x80000000u >> (he[i].len - 1);
00103     }
00104 
00105     return init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1,
00106                            bits,  sizeof(*bits),  sizeof(*bits),
00107                            codes, sizeof(*codes), sizeof(*codes),
00108                            syms,  sizeof(*syms),  sizeof(*syms), 0);
00109 }
00110 
00111 static int decode_plane(UtvideoContext *c, int plane_no,
00112                         uint8_t *dst, int step, int stride,
00113                         int width, int height,
00114                         const uint8_t *src, int src_size, int use_pred)
00115 {
00116     int i, j, slice, pix;
00117     int sstart, send;
00118     VLC vlc;
00119     GetBitContext gb;
00120     int prev, fsym;
00121     const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P);
00122 
00123     if (build_huff(src, &vlc, &fsym)) {
00124         av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
00125         return AVERROR_INVALIDDATA;
00126     }
00127     if (fsym >= 0) { 
00128         send = 0;
00129         for (slice = 0; slice < c->slices; slice++) {
00130             uint8_t *dest;
00131 
00132             sstart = send;
00133             send   = (height * (slice + 1) / c->slices) & cmask;
00134             dest   = dst + sstart * stride;
00135 
00136             prev = 0x80;
00137             for (j = sstart; j < send; j++) {
00138                 for (i = 0; i < width * step; i += step) {
00139                     pix = fsym;
00140                     if (use_pred) {
00141                         prev += pix;
00142                         pix   = prev;
00143                     }
00144                     dest[i] = pix;
00145                 }
00146                 dest += stride;
00147             }
00148         }
00149         return 0;
00150     }
00151 
00152     src      += 256;
00153     src_size -= 256;
00154 
00155     send = 0;
00156     for (slice = 0; slice < c->slices; slice++) {
00157         uint8_t *dest;
00158         int slice_data_start, slice_data_end, slice_size;
00159 
00160         sstart = send;
00161         send   = (height * (slice + 1) / c->slices) & cmask;
00162         dest   = dst + sstart * stride;
00163 
00164         
00165         slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
00166         slice_data_end   = AV_RL32(src + slice * 4);
00167         slice_size       = slice_data_end - slice_data_start;
00168 
00169         if (!slice_size) {
00170             for (j = sstart; j < send; j++) {
00171                 for (i = 0; i < width * step; i += step)
00172                     dest[i] = 0x80;
00173                 dest += stride;
00174             }
00175             continue;
00176         }
00177 
00178         memcpy(c->slice_bits, src + slice_data_start + c->slices * 4, slice_size);
00179         memset(c->slice_bits + slice_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00180         c->dsp.bswap_buf((uint32_t*)c->slice_bits, (uint32_t*)c->slice_bits,
00181                          (slice_data_end - slice_data_start + 3) >> 2);
00182         init_get_bits(&gb, c->slice_bits, slice_size * 8);
00183 
00184         prev = 0x80;
00185         for (j = sstart; j < send; j++) {
00186             for (i = 0; i < width * step; i += step) {
00187                 if (get_bits_left(&gb) <= 0) {
00188                     av_log(c->avctx, AV_LOG_ERROR, "Slice decoding ran out of bits\n");
00189                     goto fail;
00190                 }
00191                 pix = get_vlc2(&gb, vlc.table, vlc.bits, 4);
00192                 if (pix < 0) {
00193                     av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
00194                     goto fail;
00195                 }
00196                 if (use_pred) {
00197                     prev += pix;
00198                     pix   = prev;
00199                 }
00200                 dest[i] = pix;
00201             }
00202             dest += stride;
00203         }
00204         if (get_bits_left(&gb) > 32)
00205             av_log(c->avctx, AV_LOG_WARNING, "%d bits left after decoding slice\n",
00206                    get_bits_left(&gb));
00207     }
00208 
00209     free_vlc(&vlc);
00210 
00211     return 0;
00212 fail:
00213     free_vlc(&vlc);
00214     return AVERROR_INVALIDDATA;
00215 }
00216 
00217 static const int rgb_order[4] = { 1, 2, 0, 3 };
00218 
00219 static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, int height)
00220 {
00221     int i, j;
00222     uint8_t r, g, b;
00223 
00224     for (j = 0; j < height; j++) {
00225         for (i = 0; i < width * step; i += step) {
00226             r = src[i];
00227             g = src[i + 1];
00228             b = src[i + 2];
00229             src[i]     = r + g - 0x80;
00230             src[i + 2] = b + g - 0x80;
00231         }
00232         src += stride;
00233     }
00234 }
00235 
00236 static void restore_median(uint8_t *src, int step, int stride,
00237                            int width, int height, int slices, int rmode)
00238 {
00239     int i, j, slice;
00240     int A, B, C;
00241     uint8_t *bsrc;
00242     int slice_start, slice_height;
00243     const int cmask = ~rmode;
00244 
00245     for (slice = 0; slice < slices; slice++) {
00246         slice_start = ((slice * height) / slices) & cmask;
00247         slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start;
00248 
00249         bsrc = src + slice_start * stride;
00250 
00251         
00252         bsrc[0] += 0x80;
00253         A = bsrc[0];
00254         for (i = step; i < width * step; i += step) {
00255             bsrc[i] += A;
00256             A = bsrc[i];
00257         }
00258         bsrc += stride;
00259         if (slice_height == 1)
00260             continue;
00261         
00262         C = bsrc[-stride];
00263         bsrc[0] += C;
00264         A = bsrc[0];
00265         for (i = step; i < width * step; i += step) {
00266             B = bsrc[i - stride];
00267             bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
00268             C = B;
00269             A = bsrc[i];
00270         }
00271         bsrc += stride;
00272         
00273         for (j = 2; j < slice_height; j++) {
00274             for (i = 0; i < width * step; i += step) {
00275                 B = bsrc[i - stride];
00276                 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
00277                 C = B;
00278                 A = bsrc[i];
00279             }
00280             bsrc += stride;
00281         }
00282     }
00283 }
00284 
00285 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
00286 {
00287     const uint8_t *buf = avpkt->data;
00288     int buf_size = avpkt->size;
00289     const uint8_t *buf_end = buf + buf_size;
00290     UtvideoContext *c = avctx->priv_data;
00291     const uint8_t *ptr;
00292     int i, j;
00293     const uint8_t *plane_start[5];
00294     int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
00295     int ret;
00296 
00297     if (c->pic.data[0])
00298         avctx->release_buffer(avctx, &c->pic);
00299 
00300     c->pic.reference = 3;
00301     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00302     if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) {
00303         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00304         return ret;
00305     }
00306 
00307     
00308     ptr = buf;
00309     for (i = 0; i < c->planes; i++) {
00310         plane_start[i] = ptr;
00311         if (buf_end - ptr < 256 + 4 * c->slices) {
00312             av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
00313             return AVERROR_INVALIDDATA;
00314         }
00315         ptr += 256;
00316         slice_start = 0;
00317         slice_end   = 0;
00318         for (j = 0; j < c->slices; j++) {
00319             slice_end   = bytestream_get_le32(&ptr);
00320             slice_size  = slice_end - slice_start;
00321             if (slice_size < 0) {
00322                 av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
00323                 return AVERROR_INVALIDDATA;
00324             }
00325             slice_start = slice_end;
00326             max_slice_size = FFMAX(max_slice_size, slice_size);
00327         }
00328         plane_size = slice_end;
00329         if (buf_end - ptr < plane_size) {
00330             av_log(avctx, AV_LOG_ERROR, "Plane size is bigger than available data\n");
00331             return AVERROR_INVALIDDATA;
00332         }
00333         ptr += plane_size;
00334     }
00335     plane_start[c->planes] = ptr;
00336     if (buf_end - ptr < c->frame_info_size) {
00337         av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
00338         return AVERROR_INVALIDDATA;
00339     }
00340     c->frame_info = AV_RL32(ptr);
00341     av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info);
00342 
00343     c->frame_pred = (c->frame_info >> 8) & 3;
00344 
00345     if (c->frame_pred == PRED_GRADIENT) {
00346         av_log_ask_for_sample(avctx, "Frame uses gradient prediction\n");
00347         return AVERROR_PATCHWELCOME;
00348     }
00349 
00350     av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
00351                    max_slice_size + FF_INPUT_BUFFER_PADDING_SIZE);
00352 
00353     if (!c->slice_bits) {
00354         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
00355         return AVERROR(ENOMEM);
00356     }
00357 
00358     switch (c->avctx->pix_fmt) {
00359     case PIX_FMT_RGB24:
00360     case PIX_FMT_RGBA:
00361         for (i = 0; i < c->planes; i++) {
00362             ret = decode_plane(c, i, c->pic.data[0] + rgb_order[i], c->planes,
00363                                c->pic.linesize[0], avctx->width, avctx->height,
00364                                plane_start[i], plane_start[i + 1] - plane_start[i],
00365                                c->frame_pred == PRED_LEFT);
00366             if (ret)
00367                 return ret;
00368             if (c->frame_pred == PRED_MEDIAN)
00369                 restore_median(c->pic.data[0] + rgb_order[i], c->planes,
00370                                c->pic.linesize[0], avctx->width, avctx->height,
00371                                c->slices, 0);
00372         }
00373         restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
00374                            avctx->width, avctx->height);
00375         break;
00376     case PIX_FMT_YUV420P:
00377         for (i = 0; i < 3; i++) {
00378             ret = decode_plane(c, i, c->pic.data[i], 1,
00379                                c->pic.linesize[i], avctx->width >> !!i, avctx->height >> !!i,
00380                                plane_start[i], plane_start[i + 1] - plane_start[i],
00381                                c->frame_pred == PRED_LEFT);
00382             if (ret)
00383                 return ret;
00384             if (c->frame_pred == PRED_MEDIAN)
00385                 restore_median(c->pic.data[i], 1, c->pic.linesize[i],
00386                                avctx->width >> !!i, avctx->height >> !!i,
00387                                c->slices, !i);
00388         }
00389         break;
00390     case PIX_FMT_YUV422P:
00391         for (i = 0; i < 3; i++) {
00392             ret = decode_plane(c, i, c->pic.data[i], 1,
00393                                c->pic.linesize[i], avctx->width >> !!i, avctx->height,
00394                                plane_start[i], plane_start[i + 1] - plane_start[i],
00395                                c->frame_pred == PRED_LEFT);
00396             if (ret)
00397                 return ret;
00398             if (c->frame_pred == PRED_MEDIAN)
00399                 restore_median(c->pic.data[i], 1, c->pic.linesize[i],
00400                                avctx->width >> !!i, avctx->height, c->slices, 0);
00401         }
00402         break;
00403     }
00404 
00405     *data_size = sizeof(AVFrame);
00406     *(AVFrame*)data = c->pic;
00407 
00408     
00409     return buf_size;
00410 }
00411 
00412 static av_cold int decode_init(AVCodecContext *avctx)
00413 {
00414     UtvideoContext * const c = avctx->priv_data;
00415 
00416     c->avctx = avctx;
00417 
00418     dsputil_init(&c->dsp, avctx);
00419 
00420     if (avctx->extradata_size < 16) {
00421         av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d, should be at least 16\n",
00422                avctx->extradata_size);
00423         return AVERROR_INVALIDDATA;
00424     }
00425 
00426     av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
00427            avctx->extradata[3], avctx->extradata[2],
00428            avctx->extradata[1], avctx->extradata[0]);
00429     av_log(avctx, AV_LOG_DEBUG, "Original format %X\n", AV_RB32(avctx->extradata + 4));
00430     c->frame_info_size = AV_RL32(avctx->extradata + 8);
00431     c->flags           = AV_RL32(avctx->extradata + 12);
00432 
00433     if (c->frame_info_size != 4)
00434         av_log_ask_for_sample(avctx, "Frame info is not 4 bytes\n");
00435     av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08X\n", c->flags);
00436     c->slices      = (c->flags >> 24) + 1;
00437     c->compression = c->flags & 1;
00438     c->interlaced  = c->flags & 0x800;
00439 
00440     c->slice_bits_size = 0;
00441 
00442     switch (avctx->codec_tag) {
00443     case MKTAG('U', 'L', 'R', 'G'):
00444         c->planes      = 3;
00445         avctx->pix_fmt = PIX_FMT_RGB24;
00446         break;
00447     case MKTAG('U', 'L', 'R', 'A'):
00448         c->planes      = 4;
00449         avctx->pix_fmt = PIX_FMT_RGBA;
00450         break;
00451     case MKTAG('U', 'L', 'Y', '0'):
00452         c->planes      = 3;
00453         avctx->pix_fmt = PIX_FMT_YUV420P;
00454         break;
00455     case MKTAG('U', 'L', 'Y', '2'):
00456         c->planes      = 3;
00457         avctx->pix_fmt = PIX_FMT_YUV422P;
00458         break;
00459     default:
00460         av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
00461                avctx->codec_tag);
00462         return AVERROR_INVALIDDATA;
00463     }
00464 
00465     return 0;
00466 }
00467 
00468 static av_cold int decode_end(AVCodecContext *avctx)
00469 {
00470     UtvideoContext * const c = avctx->priv_data;
00471 
00472     if (c->pic.data[0])
00473         avctx->release_buffer(avctx, &c->pic);
00474 
00475     av_freep(&c->slice_bits);
00476 
00477     return 0;
00478 }
00479 
00480 AVCodec ff_utvideo_decoder = {
00481     .name           = "utvideo",
00482     .type           = AVMEDIA_TYPE_VIDEO,
00483     .id             = CODEC_ID_UTVIDEO,
00484     .priv_data_size = sizeof(UtvideoContext),
00485     .init           = decode_init,
00486     .close          = decode_end,
00487     .decode         = decode_frame,
00488     .capabilities   = CODEC_CAP_DR1,
00489     .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
00490 };
00491