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