2 * Infinity IMM4 decoder
4 * Copyright (c) 2018 Paul B Mahol
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "libavutil/thread.h"
31 #include "copy_block.h"
36 typedef struct IMM4Context {
48 ScanTable intra_scantable;
49 DECLARE_ALIGNED(32, int16_t, block)[6][64];
53 static const uint8_t intra_cb[] = {
57 static const uint8_t inter_cb[] = {
61 static const uint8_t cbplo_symbols[] = {
62 3, 4, 19, 20, 35, 36, 51, 52
65 static const uint8_t cbplo_bits[] = {
66 1, 4, 3, 6, 3, 6, 3, 6
69 static const uint8_t cbplo_codes[] = {
70 1, 1, 1, 1, 2, 2, 3, 3
73 static const uint8_t cbphi_bits[] = {
74 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
77 static const uint8_t cbphi_codes[] = {
78 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
81 static const uint8_t blktype_symbols[] = {
82 0, 1, 2, 3, 4, 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 50, 51, 52
85 static const uint8_t blktype_bits[] = {
86 1, 3, 3, 5, 6, 4, 7, 7, 8, 9, 4, 7, 7, 8, 6, 8, 7, 9
89 static const uint8_t blktype_codes[] = {
90 1, 3, 2, 3, 4, 3, 7, 5, 4, 4, 2, 6, 4, 3, 5, 5, 3, 2
93 static const uint16_t block_symbols[] = {
94 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x81, 0x82, 0x83,
95 0x84, 0x85, 0x86, 0x101, 0x102, 0x103, 0x104, 0x181, 0x182, 0x183, 0x201, 0x202,
96 0x203, 0x281, 0x282, 0x283, 0x301, 0x302, 0x303, 0x381, 0x382, 0x401, 0x402,
97 0x481, 0x482, 0x501, 0x502, 0x581, 0x601, 0x681, 0x701, 0x781, 0x801, 0x881,
98 0x901, 0x981, 0xA01, 0xA81, 0xB01, 0xB81, 0xC01, 0xC81, 0xD01, 0x4001, 0x4002,
99 0x4003, 0x4081, 0x4082, 0x4101, 0x4181, 0x4201, 0x4281, 0x4301, 0x4381, 0x4401,
100 0x4481, 0x4501, 0x4581, 0x4601, 0x4681, 0x4701, 0x4781, 0x4801, 0x4881, 0x4901,
101 0x4981, 0x4A01, 0x4A81, 0x4B01, 0x4B81, 0x4C01, 0x4C81, 0x4D01, 0x4D81, 0x4E01,
102 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x5081, 0x5101, 0x5181, 0x5201, 0x5281, 0x5301,
106 static const uint8_t block_bits[] = {
107 7, 2, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 3, 6, 8, 10, 11, 12, 4, 8,
108 10, 12, 5, 9, 10, 5, 9, 12, 5, 10, 12, 6, 10, 12, 6, 10, 6, 10, 6,
109 10, 7, 12, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 12, 12, 4, 9,
110 11, 6, 11, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
111 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
115 static const uint8_t block_codes[] = {
116 3, 2, 15, 21, 23, 31, 37, 36, 33, 32, 7, 6, 32, 6, 20, 30, 15, 33, 80,
117 14, 29, 14, 81, 13, 35, 13, 12, 34, 82, 11, 12, 83, 19, 11, 84, 18,
118 10, 17, 9, 16, 8, 22, 85, 21, 20, 28, 27, 33, 32, 31, 30, 29, 28,
119 27, 26, 34, 35, 86, 87, 7, 25, 5, 15, 4, 14, 13, 12, 19, 18, 17, 16,
120 26, 25, 24, 23, 22, 21, 20, 19, 24, 23, 22, 21, 20, 19, 18, 17, 7,
121 6, 5, 4, 36, 37, 38, 39, 88, 89, 90, 91, 92, 93, 94, 95
124 static VLC cbplo_tab;
125 static VLC cbphi_tab;
126 static VLC blktype_tab;
127 static VLC block_tab;
129 static int get_cbphi(GetBitContext *gb, int x)
133 value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1);
135 return AVERROR_INVALIDDATA;
137 return x ? value : 15 - value;
140 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
141 int block, int factor, int flag, int offset)
143 IMM4Context *s = avctx->priv_data;
144 const uint8_t *scantable = s->intra_scantable.permutated;
145 int i, last, len, factor2;
147 for (i = !flag; i < 64; i++) {
150 value = get_vlc2(gb, block_tab.table, block_tab.bits, 1);
152 return AVERROR_INVALIDDATA;
154 last = get_bits1(gb);
155 len = get_bits(gb, 6);
156 factor2 = get_sbits(gb, 8);
158 factor2 = value & 0x7F;
159 last = (value >> 14) & 1;
160 len = (value >> 7) & 0x3F;
167 s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
175 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
176 unsigned cbp, int flag, int offset)
178 IMM4Context *s = avctx->priv_data;
179 const uint8_t *scantable = s->intra_scantable.permutated;
182 memset(s->block, 0, sizeof(s->block));
184 for (i = 0; i < 6; i++) {
186 int x = get_bits(gb, 8);
192 s->block[i][scantable[0]] = x;
195 if (cbp & (1 << (5 - i))) {
196 ret = decode_block(avctx, gb, i, s->factor, flag, offset);
205 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
207 IMM4Context *s = avctx->priv_data;
208 int ret, x, y, offset = 0;
212 return AVERROR_INVALIDDATA;
213 s->factor = intra_cb[s->lo];
216 s->factor = s->lo * 2;
218 s->factor = s->lo * 2;
229 for (y = 0; y < avctx->height; y += 16) {
230 for (x = 0; x < avctx->width; x += 16) {
231 unsigned cbphi, cbplo;
233 cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
236 cbphi = get_cbphi(gb, 1);
238 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
242 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
243 frame->linesize[0], s->block[0]);
244 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
245 frame->linesize[0], s->block[1]);
246 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
247 frame->linesize[0], s->block[2]);
248 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
249 frame->linesize[0], s->block[3]);
250 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
251 frame->linesize[1], s->block[4]);
252 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
253 frame->linesize[2], s->block[5]);
260 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
261 AVFrame *frame, AVFrame *prev)
263 IMM4Context *s = avctx->priv_data;
264 int ret, x, y, offset = 0;
268 return AVERROR_INVALIDDATA;
269 s->factor = inter_cb[s->lo];
272 s->factor = s->lo * 2;
274 s->factor = s->lo * 2;
285 for (y = 0; y < avctx->height; y += 16) {
286 for (x = 0; x < avctx->width; x += 16) {
287 int reverse, intra_block, value;
288 unsigned cbphi, cbplo;
291 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
292 prev->data[0] + y * prev->linesize[0] + x,
293 frame->linesize[0], prev->linesize[0], 16);
294 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
295 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
296 frame->linesize[1], prev->linesize[1], 8);
297 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
298 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
299 frame->linesize[2], prev->linesize[2], 8);
303 value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
305 return AVERROR_INVALIDDATA;
307 intra_block = value & 0x07;
308 reverse = intra_block == 3;
313 cbphi = get_cbphi(gb, reverse);
315 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
319 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
320 frame->linesize[0], s->block[0]);
321 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
322 frame->linesize[0], s->block[1]);
323 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
324 frame->linesize[0], s->block[2]);
325 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
326 frame->linesize[0], s->block[3]);
327 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
328 frame->linesize[1], s->block[4]);
329 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
330 frame->linesize[2], s->block[5]);
333 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset);
337 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
338 prev->data[0] + y * prev->linesize[0] + x,
339 frame->linesize[0], prev->linesize[0], 16);
340 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
341 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
342 frame->linesize[1], prev->linesize[1], 8);
343 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
344 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
345 frame->linesize[2], prev->linesize[2], 8);
347 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
348 frame->linesize[0], s->block[0]);
349 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
350 frame->linesize[0], s->block[1]);
351 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
352 frame->linesize[0], s->block[2]);
353 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
354 frame->linesize[0], s->block[3]);
355 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
356 frame->linesize[1], s->block[4]);
357 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
358 frame->linesize[2], s->block[5]);
366 static int decode_frame(AVCodecContext *avctx, void *data,
367 int *got_frame, AVPacket *avpkt)
369 IMM4Context *s = avctx->priv_data;
370 GetBitContext *gb = &s->gb;
371 AVFrame *frame = data;
376 if (avpkt->size <= 32)
377 return AVERROR_INVALIDDATA;
379 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
380 FFALIGN(avpkt->size, 4));
382 return AVERROR(ENOMEM);
384 s->bdsp.bswap_buf((uint32_t *)s->bitstream,
385 (uint32_t *)avpkt->data,
386 (avpkt->size + 3) >> 2);
388 if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
391 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
392 avctx->color_range = AVCOL_RANGE_JPEG;
394 width = avctx->width;
395 height = avctx->height;
397 scaled = avpkt->data[8];
399 int mode = avpkt->data[10];
429 skip_bits_long(gb, 24 * 8);
430 type = get_bits_long(gb, 32);
431 s->hi = get_bits(gb, 16);
432 s->lo = get_bits(gb, 16);
436 frame->key_frame = 1;
437 frame->pict_type = AV_PICTURE_TYPE_I;
440 frame->key_frame = 0;
441 frame->pict_type = AV_PICTURE_TYPE_P;
444 avpriv_request_sample(avctx, "type %X", type);
445 return AVERROR_PATCHWELCOME;
448 if (!frame->key_frame &&
449 (avctx->width != width ||
450 avctx->height != height)) {
451 av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
452 return AVERROR_INVALIDDATA;
455 ret = ff_set_dimensions(avctx, width, height);
459 if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
462 if (frame->key_frame) {
463 ret = decode_intra(avctx, gb, frame);
467 av_frame_unref(s->prev_frame);
468 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
471 if (!s->prev_frame->data[0]) {
472 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
473 return AVERROR_INVALIDDATA;
476 ret = decode_inter(avctx, gb, frame, s->prev_frame);
486 static av_cold void imm4_init_static_data(void)
488 INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
489 cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
491 INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
492 cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
494 INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
495 blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
497 INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
498 block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
501 static av_cold int decode_init(AVCodecContext *avctx)
503 static AVOnce init_static_once = AV_ONCE_INIT;
504 IMM4Context *s = avctx->priv_data;
507 for (int i = 0; i < 64; i++)
510 ff_bswapdsp_init(&s->bdsp);
511 ff_idctdsp_init(&s->idsp, avctx);
512 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
514 s->prev_frame = av_frame_alloc();
516 return AVERROR(ENOMEM);
518 ff_thread_once(&init_static_once, imm4_init_static_data);
523 static av_cold int decode_close(AVCodecContext *avctx)
525 IMM4Context *s = avctx->priv_data;
527 av_frame_free(&s->prev_frame);
528 av_freep(&s->bitstream);
529 s->bitstream_size = 0;
534 AVCodec ff_imm4_decoder = {
536 .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
537 .type = AVMEDIA_TYPE_VIDEO,
538 .id = AV_CODEC_ID_IMM4,
539 .priv_data_size = sizeof(IMM4Context),
541 .close = decode_close,
542 .decode = decode_frame,
543 .capabilities = AV_CODEC_CAP_DR1,
544 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
545 FF_CODEC_CAP_INIT_CLEANUP,