1/* 2 * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com> 3 * Copyright (C) 2008 Ramiro Polla 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include <stdlib.h> 23#include <string.h> 24#include <stdint.h> 25 26#include "libavutil/mem_internal.h" 27#include "libavutil/thread.h" 28 29#include "avcodec.h" 30#include "blockdsp.h" 31#include "codec_internal.h" 32#include "internal.h" 33#include "get_bits.h" 34#include "bytestream.h" 35#include "bswapdsp.h" 36#include "hpeldsp.h" 37#include "idctdsp.h" 38#include "thread.h" 39#include "threadframe.h" 40 41#define MIMIC_HEADER_SIZE 20 42#define MIMIC_VLC_BITS 11 43 44typedef struct MimicContext { 45 AVCodecContext *avctx; 46 47 int num_vblocks[3]; 48 int num_hblocks[3]; 49 50 void *swap_buf; 51 int swap_buf_size; 52 53 int cur_index; 54 int prev_index; 55 56 ThreadFrame frames [16]; 57 58 DECLARE_ALIGNED(32, int16_t, dct_block)[64]; 59 60 GetBitContext gb; 61 ScanTable scantable; 62 BlockDSPContext bdsp; 63 BswapDSPContext bbdsp; 64 HpelDSPContext hdsp; 65 IDCTDSPContext idsp; 66 67 /* Kept in the context so multithreading can have a constant to read from */ 68 int next_cur_index; 69 int next_prev_index; 70} MimicContext; 71 72static VLC block_vlc; 73 74static const uint8_t huffsyms[] = { 75 0x10, 0x20, 0x30, 0x00, 0x11, 0x40, 0x50, 0x12, 0x13, 0x21, 0x31, 0x60, 76 0x14, 0x15, 0x16, 0x22, 0x41, 0x17, 0x18, 0x23, 0x24, 0x25, 0x32, 0x42, 77 0x51, 0x61, 0x70, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x26, 0x27, 78 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x33, 0x34, 0x35, 0x36, 0x37, 79 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x43, 0x44, 0x45, 0x46, 0x47, 80 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x52, 0x53, 0x54, 0x55, 0x56, 81 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x62, 0x63, 0x64, 0x65, 82 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73, 83 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 84}; 85 86static const uint8_t huffbits[] = { 87 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 88 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 89 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 90 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 91 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 92 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 93}; 94 95static const uint8_t col_zag[64] = { 96 0, 8, 1, 2, 9, 16, 24, 17, 97 10, 3, 4, 11, 18, 25, 32, 40, 98 33, 26, 19, 12, 5, 6, 13, 20, 99 27, 34, 41, 48, 56, 49, 42, 35, 100 28, 21, 14, 7, 15, 22, 29, 36, 101 43, 50, 57, 58, 51, 44, 37, 30, 102 23, 31, 38, 45, 52, 59, 39, 46, 103 53, 60, 61, 54, 47, 55, 62, 63, 104}; 105 106static av_cold int mimic_decode_end(AVCodecContext *avctx) 107{ 108 MimicContext *ctx = avctx->priv_data; 109 int i; 110 111 av_freep(&ctx->swap_buf); 112 ctx->swap_buf_size = 0; 113 114 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { 115 if (ctx->frames[i].f) 116 ff_thread_release_ext_buffer(avctx, &ctx->frames[i]); 117 av_frame_free(&ctx->frames[i].f); 118 } 119 120 return 0; 121} 122 123static av_cold void mimic_init_static(void) 124{ 125 INIT_VLC_STATIC_FROM_LENGTHS(&block_vlc, MIMIC_VLC_BITS, FF_ARRAY_ELEMS(huffbits), 126 huffbits, 1, huffsyms, 1, 1, 0, 0, 4368); 127} 128 129static av_cold int mimic_decode_init(AVCodecContext *avctx) 130{ 131 static AVOnce init_static_once = AV_ONCE_INIT; 132 MimicContext *ctx = avctx->priv_data; 133 int i; 134 135 ctx->prev_index = 0; 136 ctx->cur_index = 15; 137 138 ff_blockdsp_init(&ctx->bdsp, avctx); 139 ff_bswapdsp_init(&ctx->bbdsp); 140 ff_hpeldsp_init(&ctx->hdsp, avctx->flags); 141 ff_idctdsp_init(&ctx->idsp, avctx); 142 ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag); 143 144 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { 145 ctx->frames[i].f = av_frame_alloc(); 146 if (!ctx->frames[i].f) 147 return AVERROR(ENOMEM); 148 } 149 150 ff_thread_once(&init_static_once, mimic_init_static); 151 152 return 0; 153} 154 155#if HAVE_THREADS 156static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from) 157{ 158 MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data; 159 int i, ret; 160 161 if (avctx == avctx_from) 162 return 0; 163 164 dst->cur_index = src->next_cur_index; 165 dst->prev_index = src->next_prev_index; 166 167 for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) { 168 ff_thread_release_ext_buffer(avctx, &dst->frames[i]); 169 if (i != src->next_cur_index && src->frames[i].f->data[0]) { 170 ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]); 171 if (ret < 0) 172 return ret; 173 } 174 } 175 176 return 0; 177} 178#endif 179 180static const int8_t vlcdec_lookup[9][64] = { 181 { 0, }, 182 { -1, 1, }, 183 { -3, 3, -2, 2, }, 184 { -7, 7, -6, 6, -5, 5, -4, 4, }, 185 { -15, 15, -14, 14, -13, 13, -12, 12, 186 -11, 11, -10, 10, -9, 9, -8, 8, }, 187 { -31, 31, -30, 30, -29, 29, -28, 28, 188 -27, 27, -26, 26, -25, 25, -24, 24, 189 -23, 23, -22, 22, -21, 21, -20, 20, 190 -19, 19, -18, 18, -17, 17, -16, 16, }, 191 { -63, 63, -62, 62, -61, 61, -60, 60, 192 -59, 59, -58, 58, -57, 57, -56, 56, 193 -55, 55, -54, 54, -53, 53, -52, 52, 194 -51, 51, -50, 50, -49, 49, -48, 48, 195 -47, 47, -46, 46, -45, 45, -44, 44, 196 -43, 43, -42, 42, -41, 41, -40, 40, 197 -39, 39, -38, 38, -37, 37, -36, 36, 198 -35, 35, -34, 34, -33, 33, -32, 32, }, 199 { -127, 127, -126, 126, -125, 125, -124, 124, 200 -123, 123, -122, 122, -121, 121, -120, 120, 201 -119, 119, -118, 118, -117, 117, -116, 116, 202 -115, 115, -114, 114, -113, 113, -112, 112, 203 -111, 111, -110, 110, -109, 109, -108, 108, 204 -107, 107, -106, 106, -105, 105, -104, 104, 205 -103, 103, -102, 102, -101, 101, -100, 100, 206 -99, 99, -98, 98, -97, 97, -96, 96, }, 207 { -95, 95, -94, 94, -93, 93, -92, 92, 208 -91, 91, -90, 90, -89, 89, -88, 88, 209 -87, 87, -86, 86, -85, 85, -84, 84, 210 -83, 83, -82, 82, -81, 81, -80, 80, 211 -79, 79, -78, 78, -77, 77, -76, 76, 212 -75, 75, -74, 74, -73, 73, -72, 72, 213 -71, 71, -70, 70, -69, 69, -68, 68, 214 -67, 67, -66, 66, -65, 65, -64, 64, }, 215}; 216 217static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale) 218{ 219 int16_t *block = ctx->dct_block; 220 unsigned int pos; 221 222 ctx->bdsp.clear_block(block); 223 224 block[0] = get_bits(&ctx->gb, 8) << 3; 225 226 for (pos = 1; pos < num_coeffs; pos++) { 227 uint32_t vlc, num_bits; 228 int value; 229 int coeff; 230 231 vlc = get_vlc2(&ctx->gb, block_vlc.table, MIMIC_VLC_BITS, 3); 232 if (!vlc) /* end-of-block code */ 233 return 0; 234 if (vlc == -1) 235 return AVERROR_INVALIDDATA; 236 237 /* pos_add and num_bits are coded in the vlc code */ 238 pos += vlc & 15; // pos_add 239 num_bits = vlc >> 4; // num_bits 240 241 if (pos >= 64) 242 return AVERROR_INVALIDDATA; 243 244 value = get_bits(&ctx->gb, num_bits); 245 246 /* FFmpeg's IDCT behaves somewhat different from the original code, so 247 * a factor of 4 was added to the input */ 248 249 coeff = ((int8_t*)vlcdec_lookup[num_bits])[value]; 250 if (pos < 3) 251 coeff *= 16; 252 else /* TODO Use >> 10 instead of / 1001 */ 253 coeff = (coeff * qscale) / 1001; 254 255 block[ctx->scantable.permutated[pos]] = coeff; 256 } 257 258 return 0; 259} 260 261static int decode(MimicContext *ctx, int quality, int num_coeffs, 262 int is_iframe) 263{ 264 int ret, y, x, plane, cur_row = 0; 265 266 for (plane = 0; plane < 3; plane++) { 267 const int is_chroma = !!plane; 268 const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000, 269 10000) << 2; 270 const int stride = ctx->frames[ctx->cur_index ].f->linesize[plane]; 271 const uint8_t *src = ctx->frames[ctx->prev_index].f->data[plane]; 272 uint8_t *dst = ctx->frames[ctx->cur_index ].f->data[plane]; 273 274 for (y = 0; y < ctx->num_vblocks[plane]; y++) { 275 for (x = 0; x < ctx->num_hblocks[plane]; x++) { 276 /* Check for a change condition in the current block. 277 * - iframes always change. 278 * - Luma plane changes on get_bits1 == 0 279 * - Chroma planes change on get_bits1 == 1 */ 280 if (is_iframe || get_bits1(&ctx->gb) == is_chroma) { 281 /* Luma planes may use a backreference from the 15 last 282 * frames preceding the previous. (get_bits1 == 1) 283 * Chroma planes don't use backreferences. */ 284 if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) { 285 if ((ret = vlc_decode_block(ctx, num_coeffs, 286 qscale)) < 0) { 287 av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding " 288 "block.\n"); 289 return ret; 290 } 291 ctx->idsp.idct_put(dst, stride, ctx->dct_block); 292 } else { 293 unsigned int backref = get_bits(&ctx->gb, 4); 294 int index = (ctx->cur_index + backref) & 15; 295 uint8_t *p = ctx->frames[index].f->data[0]; 296 297 if (index != ctx->cur_index && p) { 298 ff_thread_await_progress(&ctx->frames[index], 299 cur_row, 0); 300 p += src - 301 ctx->frames[ctx->prev_index].f->data[plane]; 302 ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8); 303 } else { 304 av_log(ctx->avctx, AV_LOG_ERROR, 305 "No such backreference! Buggy sample.\n"); 306 } 307 } 308 } else { 309 ff_thread_await_progress(&ctx->frames[ctx->prev_index], 310 cur_row, 0); 311 ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8); 312 } 313 src += 8; 314 dst += 8; 315 } 316 src += (stride - ctx->num_hblocks[plane]) << 3; 317 dst += (stride - ctx->num_hblocks[plane]) << 3; 318 319 ff_thread_report_progress(&ctx->frames[ctx->cur_index], 320 cur_row++, 0); 321 } 322 } 323 324 return 0; 325} 326 327/** 328 * Flip the buffer upside-down and put it in the YVU order to revert the 329 * way Mimic encodes frames. 330 */ 331static void flip_swap_frame(AVFrame *f) 332{ 333 int i; 334 uint8_t *data_1 = f->data[1]; 335 f->data[0] = f->data[0] + ( f->height - 1) * f->linesize[0]; 336 f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2]; 337 f->data[2] = data_1 + ((f->height >> 1) - 1) * f->linesize[1]; 338 for (i = 0; i < 3; i++) 339 f->linesize[i] *= -1; 340} 341 342static int mimic_decode_frame(AVCodecContext *avctx, AVFrame *rframe, 343 int *got_frame, AVPacket *avpkt) 344{ 345 const uint8_t *buf = avpkt->data; 346 int buf_size = avpkt->size; 347 int swap_buf_size = buf_size - MIMIC_HEADER_SIZE; 348 MimicContext *ctx = avctx->priv_data; 349 GetByteContext gb; 350 int is_pframe; 351 int width, height; 352 int quality, num_coeffs; 353 int res; 354 355 if (buf_size <= MIMIC_HEADER_SIZE) { 356 av_log(avctx, AV_LOG_ERROR, "insufficient data\n"); 357 return AVERROR_INVALIDDATA; 358 } 359 360 bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE); 361 bytestream2_skip(&gb, 2); /* some constant (always 256) */ 362 quality = bytestream2_get_le16u(&gb); 363 width = bytestream2_get_le16u(&gb); 364 height = bytestream2_get_le16u(&gb); 365 bytestream2_skip(&gb, 4); /* some constant */ 366 is_pframe = bytestream2_get_le32u(&gb); 367 num_coeffs = bytestream2_get_byteu(&gb); 368 bytestream2_skip(&gb, 3); /* some constant */ 369 370 if (!ctx->avctx) { 371 int i; 372 373 if (!(width == 160 && height == 120) && 374 !(width == 320 && height == 240)) { 375 av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n"); 376 return AVERROR_INVALIDDATA; 377 } 378 379 res = ff_set_dimensions(avctx, width, height); 380 if (res < 0) 381 return res; 382 383 ctx->avctx = avctx; 384 avctx->pix_fmt = AV_PIX_FMT_YUV420P; 385 for (i = 0; i < 3; i++) { 386 ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height, 3 + !!i); 387 ctx->num_hblocks[i] = width >> (3 + !!i); 388 } 389 } else if (width != ctx->avctx->width || height != ctx->avctx->height) { 390 avpriv_request_sample(avctx, "Resolution changing"); 391 return AVERROR_PATCHWELCOME; 392 } 393 394 if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) { 395 av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n"); 396 return AVERROR_INVALIDDATA; 397 } 398 399 ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]); 400 ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P : 401 AV_PICTURE_TYPE_I; 402 if ((res = ff_thread_get_ext_buffer(avctx, &ctx->frames[ctx->cur_index], 403 AV_GET_BUFFER_FLAG_REF)) < 0) 404 return res; 405 406 ctx->next_prev_index = ctx->cur_index; 407 ctx->next_cur_index = (ctx->cur_index - 1) & 15; 408 409 ff_thread_finish_setup(avctx); 410 411 av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size); 412 if (!ctx->swap_buf) 413 return AVERROR(ENOMEM); 414 415 ctx->bbdsp.bswap_buf(ctx->swap_buf, 416 (const uint32_t *) (buf + MIMIC_HEADER_SIZE), 417 swap_buf_size >> 2); 418 init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); 419 420 res = decode(ctx, quality, num_coeffs, !is_pframe); 421 ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0); 422 if (res < 0) { 423 if (!(avctx->active_thread_type & FF_THREAD_FRAME)) 424 ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]); 425 return res; 426 } 427 428 if ((res = av_frame_ref(rframe, ctx->frames[ctx->cur_index].f)) < 0) 429 return res; 430 *got_frame = 1; 431 432 flip_swap_frame(rframe); 433 434 ctx->prev_index = ctx->next_prev_index; 435 ctx->cur_index = ctx->next_cur_index; 436 437 return buf_size; 438} 439 440const FFCodec ff_mimic_decoder = { 441 .p.name = "mimic", 442 .p.long_name = NULL_IF_CONFIG_SMALL("Mimic"), 443 .p.type = AVMEDIA_TYPE_VIDEO, 444 .p.id = AV_CODEC_ID_MIMIC, 445 .priv_data_size = sizeof(MimicContext), 446 .init = mimic_decode_init, 447 .close = mimic_decode_end, 448 FF_CODEC_DECODE_CB(mimic_decode_frame), 449 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, 450 .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context), 451 .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS | 452 FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, 453}; 454