Libav 0.7.1
|
00001 /* 00002 * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com> 00003 * Copyright (C) 2008 Ramiro Polla 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav 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 * Libav 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 Libav; 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 #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 /* Kept in the context so multithreading can have a constant to read from */ 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) /* end-of-block code */ 00199 return 1; 00200 if(vlc == -1) 00201 return 0; 00202 00203 /* pos_add and num_bits are coded in the vlc code */ 00204 pos += vlc&15; // pos_add 00205 num_bits = vlc>>4; // num_bits 00206 00207 if(pos >= 64) 00208 return 0; 00209 00210 value = get_bits(&ctx->gb, num_bits); 00211 00212 /* Libav's IDCT behaves somewhat different from the original code, so 00213 * a factor of 4 was added to the input */ 00214 00215 coeff = vlcdec_lookup[num_bits][value]; 00216 if(pos<3) 00217 coeff <<= 4; 00218 else /* TODO Use >> 10 instead of / 1001 */ 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 /* Check for a change condition in the current block. 00243 * - iframes always change. 00244 * - Luma plane changes on get_bits1 == 0 00245 * - Chroma planes change on get_bits1 == 1 */ 00246 if(is_iframe || get_bits1(&ctx->gb) == is_chroma) { 00247 00248 /* Luma planes may use a backreference from the 15 last 00249 * frames preceding the previous. (get_bits1 == 1) 00250 * Chroma planes don't use backreferences. */ 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; /* some constant (always 256) */ 00319 quality = bytestream_get_le16(&buf); 00320 width = bytestream_get_le16(&buf); 00321 height = bytestream_get_le16(&buf); 00322 buf += 4; /* some constant */ 00323 is_pframe = bytestream_get_le32(&buf); 00324 num_coeffs = bytestream_get_byte(&buf); 00325 buf += 3; /* some constant */ 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 /* Only release frames that aren't used for backreferences anymore */ 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 };