Libav
|
00001 /* 00002 * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com> 00003 * Copyright (C) 2008 Ramiro Polla <ramiro@lisha.ufsc.br> 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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) /* end-of-block code */ 00177 return 1; 00178 if(vlc == -1) 00179 return 0; 00180 00181 /* pos_add and num_bits are coded in the vlc code */ 00182 pos += vlc&15; // pos_add 00183 num_bits = vlc>>4; // num_bits 00184 00185 if(pos >= 64) 00186 return 0; 00187 00188 value = get_bits(&ctx->gb, num_bits); 00189 00190 /* FFmpeg's IDCT behaves somewhat different from the original code, so 00191 * a factor of 4 was added to the input */ 00192 00193 coeff = vlcdec_lookup[num_bits][value]; 00194 if(pos<3) 00195 coeff <<= 4; 00196 else /* TODO Use >> 10 instead of / 1001 */ 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 /* Check for a change condition in the current block. 00221 * - iframes always change. 00222 * - Luma plane changes on get_bits1 == 0 00223 * - Chroma planes change on get_bits1 == 1 */ 00224 if(is_iframe || get_bits1(&ctx->gb) == is_chroma) { 00225 00226 /* Luma planes may use a backreference from the 15 last 00227 * frames preceding the previous. (get_bits1 == 1) 00228 * Chroma planes don't use backreferences. */ 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; /* some constant (always 256) */ 00293 quality = bytestream_get_le16(&buf); 00294 width = bytestream_get_le16(&buf); 00295 height = bytestream_get_le16(&buf); 00296 buf += 4; /* some constant */ 00297 is_pframe = bytestream_get_le32(&buf); 00298 num_coeffs = bytestream_get_byte(&buf); 00299 buf += 3; /* some constant */ 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 /* Only release frames that aren't used for backreferences anymore */ 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 };