00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <stdint.h>
00025 
00026 #include "avcodec.h"
00027 #include "get_bits.h"
00028 #include "bytestream.h"
00029 #include "dsputil.h"
00030 #include "thread.h"
00031 
00032 #define MIMIC_HEADER_SIZE   20
00033 
00034 typedef struct {
00035     AVCodecContext *avctx;
00036 
00037     int             num_vblocks[3];
00038     int             num_hblocks[3];
00039 
00040     void           *swap_buf;
00041     int             swap_buf_size;
00042 
00043     int             cur_index;
00044     int             prev_index;
00045 
00046     AVFrame         buf_ptrs    [16];
00047     AVPicture       flipped_ptrs[16];
00048 
00049     DECLARE_ALIGNED(16, DCTELEM, dct_block)[64];
00050 
00051     GetBitContext   gb;
00052     ScanTable       scantable;
00053     DSPContext      dsp;
00054     VLC             vlc;
00055 
00056     
00057     int             next_cur_index;
00058     int             next_prev_index;
00059 } MimicContext;
00060 
00061 static const uint32_t huffcodes[] = {
00062     0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
00063     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
00064     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b,
00065     0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9,
00066     0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb,
00067     0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb,
00068     0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9,
00069     0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000,
00070     0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9,
00071     0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb,
00072     0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8,
00073     0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb,
00074     0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9,
00075     0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8,
00076     0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa,
00077     0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000,
00078     0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb,
00079     0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9,
00080     0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9,
00081     0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb,
00082     0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9,
00083     0x3ffffffa,
00084 };
00085 
00086 static const uint8_t huffbits[] = {
00087      4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00088      0,  0,  0,  0,  2,  4,  5,  6,  7,  7,  7,  8,
00089      8, 10, 11, 11, 11, 11, 12, 12,  2,  6,  7,  8,
00090      9,  9, 12, 12, 13, 13, 13, 13, 14, 14, 14,  0,
00091      3,  6,  9, 14, 15, 15, 15, 15, 16, 16, 16, 16,
00092     17, 17, 17,  0,  4,  8,  9, 17, 18, 18, 18, 18,
00093     19, 19, 19, 19, 20, 20, 20,  0,  5, 10, 20, 21,
00094     21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,  0,
00095      6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
00096     26, 26, 27,  0, 10, 27, 27, 27, 28, 28, 28, 28,
00097     29, 29, 29, 29, 30, 30, 30,
00098 };
00099 
00100 static const uint8_t col_zag[64] = {
00101      0,  8,  1,  2,  9, 16, 24, 17,
00102     10,  3,  4, 11, 18, 25, 32, 40,
00103     33, 26, 19, 12,  5,  6, 13, 20,
00104     27, 34, 41, 48, 56, 49, 42, 35,
00105     28, 21, 14,  7, 15, 22, 29, 36,
00106     43, 50, 57, 58, 51, 44, 37, 30,
00107     23, 31, 38, 45, 52, 59, 39, 46,
00108     53, 60, 61, 54, 47, 55, 62, 63,
00109 };
00110 
00111 static av_cold int mimic_decode_init(AVCodecContext *avctx)
00112 {
00113     MimicContext *ctx = avctx->priv_data;
00114 
00115     ctx->prev_index = 0;
00116     ctx->cur_index = 15;
00117 
00118     if(init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
00119                  huffbits, 1, 1, huffcodes, 4, 4, 0)) {
00120         av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
00121         return -1;
00122     }
00123     dsputil_init(&ctx->dsp, avctx);
00124     ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
00125 
00126     return 0;
00127 }
00128 
00129 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
00130 {
00131     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
00132 
00133     if (avctx == avctx_from) return 0;
00134 
00135     dst->cur_index  = src->next_cur_index;
00136     dst->prev_index = src->next_prev_index;
00137 
00138     memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
00139     memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
00140 
00141     memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
00142 
00143     return 0;
00144 }
00145 
00146 static const int8_t vlcdec_lookup[9][64] = {
00147     {    0, },
00148     {   -1,   1, },
00149     {   -3,   3,   -2,   2, },
00150     {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
00151     {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
00152        -11,  11,  -10,  10,   -9,   9,   -8,   8, },
00153     {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
00154        -27,  27,  -26,  26,  -25,  25,  -24,  24,
00155        -23,  23,  -22,  22,  -21,  21,  -20,  20,
00156        -19,  19,  -18,  18,  -17,  17,  -16,  16, },
00157     {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
00158        -59,  59,  -58,  58,  -57,  57,  -56,  56,
00159        -55,  55,  -54,  54,  -53,  53,  -52,  52,
00160        -51,  51,  -50,  50,  -49,  49,  -48,  48,
00161        -47,  47,  -46,  46,  -45,  45,  -44,  44,
00162        -43,  43,  -42,  42,  -41,  41,  -40,  40,
00163        -39,  39,  -38,  38,  -37,  37,  -36,  36,
00164        -35,  35,  -34,  34,  -33,  33,  -32,  32, },
00165     { -127, 127, -126, 126, -125, 125, -124, 124,
00166       -123, 123, -122, 122, -121, 121, -120, 120,
00167       -119, 119, -118, 118, -117, 117, -116, 116,
00168       -115, 115, -114, 114, -113, 113, -112, 112,
00169       -111, 111, -110, 110, -109, 109, -108, 108,
00170       -107, 107, -106, 106, -105, 105, -104, 104,
00171       -103, 103, -102, 102, -101, 101, -100, 100,
00172        -99,  99,  -98,  98,  -97,  97,  -96,  96, },
00173     {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
00174        -91,  91,  -90,  90,  -89,  89,  -88,  88,
00175        -87,  87,  -86,  86,  -85,  85,  -84,  84,
00176        -83,  83,  -82,  82,  -81,  81,  -80,  80,
00177        -79,  79,  -78,  78,  -77,  77,  -76,  76,
00178        -75,  75,  -74,  74,  -73,  73,  -72,  72,
00179        -71,  71,  -70,  70,  -69,  69,  -68,  68,
00180        -67,  67,  -66,  66,  -65,  65,  -64,  64, },
00181 };
00182 
00183 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
00184 {
00185     DCTELEM *block = ctx->dct_block;
00186     unsigned int pos;
00187 
00188     ctx->dsp.clear_block(block);
00189 
00190     block[0] = get_bits(&ctx->gb, 8) << 3;
00191 
00192     for(pos = 1; pos < num_coeffs; pos++) {
00193         uint32_t vlc, num_bits;
00194         int value;
00195         int coeff;
00196 
00197         vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
00198         if(!vlc) 
00199             return 1;
00200         if(vlc == -1)
00201             return 0;
00202 
00203         
00204         pos +=     vlc&15; 
00205         num_bits = vlc>>4; 
00206 
00207         if(pos >= 64)
00208             return 0;
00209 
00210         value = get_bits(&ctx->gb, num_bits);
00211 
00212         
00213 
00214 
00215         coeff = vlcdec_lookup[num_bits][value];
00216         if(pos<3)
00217             coeff <<= 4;
00218         else 
00219             coeff = (coeff * qscale) / 1001;
00220 
00221         block[ctx->scantable.permutated[pos]] = coeff;
00222     }
00223 
00224     return 1;
00225 }
00226 
00227 static int decode(MimicContext *ctx, int quality, int num_coeffs,
00228                   int is_iframe)
00229 {
00230     int y, x, plane, cur_row = 0;
00231 
00232     for(plane = 0; plane < 3; plane++) {
00233         const int is_chroma = !!plane;
00234         const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2;
00235         const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane];
00236         const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
00237         uint8_t       *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
00238 
00239         for(y = 0; y < ctx->num_vblocks[plane]; y++) {
00240             for(x = 0; x < ctx->num_hblocks[plane]; x++) {
00241 
00242                 
00243 
00244 
00245 
00246                 if(is_iframe || get_bits1(&ctx->gb) == is_chroma) {
00247 
00248                     
00249 
00250 
00251                     if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
00252 
00253                         if(!vlc_decode_block(ctx, num_coeffs, qscale))
00254                             return 0;
00255                         ctx->dsp.idct_put(dst, stride, ctx->dct_block);
00256                     } else {
00257                         unsigned int backref = get_bits(&ctx->gb, 4);
00258                         int index = (ctx->cur_index+backref)&15;
00259                         uint8_t *p = ctx->flipped_ptrs[index].data[0];
00260 
00261                         ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0);
00262                         if(p) {
00263                             p += src -
00264                                 ctx->flipped_ptrs[ctx->prev_index].data[plane];
00265                             ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
00266                         } else {
00267                             av_log(ctx->avctx, AV_LOG_ERROR,
00268                                      "No such backreference! Buggy sample.\n");
00269                         }
00270                     }
00271                 } else {
00272                     ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index], cur_row, 0);
00273                     ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
00274                 }
00275                 src += 8;
00276                 dst += 8;
00277             }
00278             src += (stride - ctx->num_hblocks[plane])<<3;
00279             dst += (stride - ctx->num_hblocks[plane])<<3;
00280 
00281             ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], cur_row++, 0);
00282         }
00283     }
00284 
00285     return 1;
00286 }
00287 
00292 static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
00293 {
00294     int i;
00295     dst->data[0] = src->data[0]+( ctx->avctx->height    -1)*src->linesize[0];
00296     dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2];
00297     dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1];
00298     for(i = 0; i < 3; i++)
00299         dst->linesize[i] = -src->linesize[i];
00300 }
00301 
00302 static int mimic_decode_frame(AVCodecContext *avctx, void *data,
00303                               int *data_size, AVPacket *avpkt)
00304 {
00305     const uint8_t *buf = avpkt->data;
00306     int buf_size = avpkt->size;
00307     MimicContext *ctx = avctx->priv_data;
00308     int is_pframe;
00309     int width, height;
00310     int quality, num_coeffs;
00311     int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
00312 
00313     if(buf_size < MIMIC_HEADER_SIZE) {
00314         av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
00315         return -1;
00316     }
00317 
00318     buf       += 2; 
00319     quality    = bytestream_get_le16(&buf);
00320     width      = bytestream_get_le16(&buf);
00321     height     = bytestream_get_le16(&buf);
00322     buf       += 4; 
00323     is_pframe  = bytestream_get_le32(&buf);
00324     num_coeffs = bytestream_get_byte(&buf);
00325     buf       += 3; 
00326 
00327     if(!ctx->avctx) {
00328         int i;
00329 
00330         if(!(width == 160 && height == 120) &&
00331            !(width == 320 && height == 240)) {
00332             av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
00333             return -1;
00334         }
00335 
00336         ctx->avctx     = avctx;
00337         avctx->width   = width;
00338         avctx->height  = height;
00339         avctx->pix_fmt = PIX_FMT_YUV420P;
00340         for(i = 0; i < 3; i++) {
00341             ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
00342             ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
00343         }
00344     } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
00345         av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
00346         return -1;
00347     }
00348 
00349     if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
00350         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
00351         return -1;
00352     }
00353 
00354     ctx->buf_ptrs[ctx->cur_index].reference = 1;
00355     ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P:AV_PICTURE_TYPE_I;
00356     if(ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) {
00357         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00358         return -1;
00359     }
00360 
00361     ctx->next_prev_index = ctx->cur_index;
00362     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
00363 
00364     prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
00365                   (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
00366 
00367     ff_thread_finish_setup(avctx);
00368 
00369     av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size,
00370                                  swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
00371     if(!ctx->swap_buf)
00372         return AVERROR(ENOMEM);
00373 
00374     ctx->dsp.bswap_buf(ctx->swap_buf,
00375                         (const uint32_t*) buf,
00376                         swap_buf_size>>2);
00377     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
00378 
00379     if(!decode(ctx, quality, num_coeffs, !is_pframe)) {
00380         if (avctx->active_thread_type&FF_THREAD_FRAME)
00381             ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
00382         else {
00383             ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
00384             return -1;
00385         }
00386     }
00387 
00388     *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
00389     *data_size = sizeof(AVFrame);
00390 
00391     ctx->prev_index = ctx->next_prev_index;
00392     ctx->cur_index  = ctx->next_cur_index;
00393 
00394     
00395     if(ctx->buf_ptrs[ctx->cur_index].data[0])
00396         ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
00397 
00398     return buf_size;
00399 }
00400 
00401 static av_cold int mimic_decode_end(AVCodecContext *avctx)
00402 {
00403     MimicContext *ctx = avctx->priv_data;
00404     int i;
00405 
00406     av_free(ctx->swap_buf);
00407 
00408     if(avctx->is_copy) return 0;
00409 
00410     for(i = 0; i < 16; i++)
00411         if(ctx->buf_ptrs[i].data[0])
00412             ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
00413     free_vlc(&ctx->vlc);
00414 
00415     return 0;
00416 }
00417 
00418 AVCodec ff_mimic_decoder = {
00419     "mimic",
00420     AVMEDIA_TYPE_VIDEO,
00421     CODEC_ID_MIMIC,
00422     sizeof(MimicContext),
00423     mimic_decode_init,
00424     NULL,
00425     mimic_decode_end,
00426     mimic_decode_frame,
00427     CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
00428     .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
00429     .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
00430 };