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 #define CBPLO_VLC_BITS 6
38 typedef struct IMM4Context {
50 ScanTable intra_scantable;
51 DECLARE_ALIGNED(32, int16_t, block)[6][64];
55 static const uint8_t intra_cb[] = {
59 static const uint8_t inter_cb[] = {
63 static const uint8_t cbplo_symbols[] = {
64 3, 4, 19, 20, 35, 36, 51, 52
67 static const uint8_t cbplo_bits[] = {
68 1, 4, 3, 6, 3, 6, 3, 6
71 static const uint8_t cbplo_codes[] = {
72 1, 1, 1, 1, 2, 2, 3, 3
75 static const uint8_t cbphi_bits[] = {
76 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
79 static const uint8_t cbphi_codes[] = {
80 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
83 static const uint8_t blktype_symbols[] = {
84 0, 1, 2, 3, 4, 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 50, 51, 52
87 static const uint8_t blktype_bits[] = {
88 1, 3, 3, 5, 6, 4, 7, 7, 8, 9, 4, 7, 7, 8, 6, 8, 7, 9
91 static const uint8_t blktype_codes[] = {
92 1, 3, 2, 3, 4, 3, 7, 5, 4, 4, 2, 6, 4, 3, 5, 5, 3, 2
95 static const uint16_t block_symbols[] = {
96 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x81, 0x82, 0x83,
97 0x84, 0x85, 0x86, 0x101, 0x102, 0x103, 0x104, 0x181, 0x182, 0x183, 0x201, 0x202,
98 0x203, 0x281, 0x282, 0x283, 0x301, 0x302, 0x303, 0x381, 0x382, 0x401, 0x402,
99 0x481, 0x482, 0x501, 0x502, 0x581, 0x601, 0x681, 0x701, 0x781, 0x801, 0x881,
100 0x901, 0x981, 0xA01, 0xA81, 0xB01, 0xB81, 0xC01, 0xC81, 0xD01, 0x4001, 0x4002,
101 0x4003, 0x4081, 0x4082, 0x4101, 0x4181, 0x4201, 0x4281, 0x4301, 0x4381, 0x4401,
102 0x4481, 0x4501, 0x4581, 0x4601, 0x4681, 0x4701, 0x4781, 0x4801, 0x4881, 0x4901,
103 0x4981, 0x4A01, 0x4A81, 0x4B01, 0x4B81, 0x4C01, 0x4C81, 0x4D01, 0x4D81, 0x4E01,
104 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x5081, 0x5101, 0x5181, 0x5201, 0x5281, 0x5301,
108 static const uint8_t block_bits[] = {
109 7, 2, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 3, 6, 8, 10, 11, 12, 4, 8,
110 10, 12, 5, 9, 10, 5, 9, 12, 5, 10, 12, 6, 10, 12, 6, 10, 6, 10, 6,
111 10, 7, 12, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 12, 12, 4, 9,
112 11, 6, 11, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
113 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
117 static const uint8_t block_codes[] = {
118 3, 2, 15, 21, 23, 31, 37, 36, 33, 32, 7, 6, 32, 6, 20, 30, 15, 33, 80,
119 14, 29, 14, 81, 13, 35, 13, 12, 34, 82, 11, 12, 83, 19, 11, 84, 18,
120 10, 17, 9, 16, 8, 22, 85, 21, 20, 28, 27, 33, 32, 31, 30, 29, 28,
121 27, 26, 34, 35, 86, 87, 7, 25, 5, 15, 4, 14, 13, 12, 19, 18, 17, 16,
122 26, 25, 24, 23, 22, 21, 20, 19, 24, 23, 22, 21, 20, 19, 18, 17, 7,
123 6, 5, 4, 36, 37, 38, 39, 88, 89, 90, 91, 92, 93, 94, 95
126 static VLC cbplo_tab;
127 static VLC cbphi_tab;
128 static VLC blktype_tab;
129 static VLC block_tab;
131 static int get_cbphi(GetBitContext *gb, int x)
135 value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1);
137 return AVERROR_INVALIDDATA;
139 return x ? value : 15 - value;
142 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
143 int block, int factor, int flag, int offset, int flag2)
145 IMM4Context *s = avctx->priv_data;
146 const uint8_t *scantable = s->intra_scantable.permutated;
147 int i, last, len, factor2;
149 for (i = !flag; i < 64; i++) {
152 value = get_vlc2(gb, block_tab.table, block_tab.bits, 1);
154 return AVERROR_INVALIDDATA;
156 last = get_bits1(gb);
157 len = get_bits(gb, 6);
158 factor2 = get_sbits(gb, 8);
160 factor2 = value & 0x7F;
161 last = (value >> 14) & 1;
162 len = (value >> 7) & 0x3F;
169 s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
174 if (s->hi == 2 && flag2 && block < 4) {
176 s->block[block][scantable[0]] *= 2;
177 s->block[block][scantable[1]] *= 2;
178 s->block[block][scantable[8]] *= 2;
179 s->block[block][scantable[16]] *= 2;
185 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
186 unsigned cbp, int flag, int offset, unsigned flag2)
188 IMM4Context *s = avctx->priv_data;
189 const uint8_t *scantable = s->intra_scantable.permutated;
192 memset(s->block, 0, sizeof(s->block));
194 for (i = 0; i < 6; i++) {
196 int x = get_bits(gb, 8);
202 s->block[i][scantable[0]] = x;
205 if (cbp & (1 << (5 - i))) {
206 ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
215 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
217 IMM4Context *s = avctx->priv_data;
218 int ret, x, y, offset = 0;
222 return AVERROR_INVALIDDATA;
223 s->factor = intra_cb[s->lo];
225 s->factor = s->lo * 2;
235 for (y = 0; y < avctx->height; y += 16) {
236 for (x = 0; x < avctx->width; x += 16) {
237 unsigned flag, cbphi, cbplo;
239 cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
240 flag = get_bits1(gb);
242 cbphi = get_cbphi(gb, 1);
244 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
248 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
249 frame->linesize[0], s->block[0]);
250 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
251 frame->linesize[0], s->block[1]);
252 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
253 frame->linesize[0], s->block[2]);
254 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
255 frame->linesize[0], s->block[3]);
256 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
257 frame->linesize[1], s->block[4]);
258 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
259 frame->linesize[2], s->block[5]);
266 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
267 AVFrame *frame, AVFrame *prev)
269 IMM4Context *s = avctx->priv_data;
270 int ret, x, y, offset = 0;
274 return AVERROR_INVALIDDATA;
275 s->factor = inter_cb[s->lo];
277 s->factor = s->lo * 2;
287 for (y = 0; y < avctx->height; y += 16) {
288 for (x = 0; x < avctx->width; x += 16) {
289 int reverse, intra_block, value;
290 unsigned cbphi, cbplo, flag2 = 0;
293 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
294 prev->data[0] + y * prev->linesize[0] + x,
295 frame->linesize[0], prev->linesize[0], 16);
296 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
297 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
298 frame->linesize[1], prev->linesize[1], 8);
299 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
300 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
301 frame->linesize[2], prev->linesize[2], 8);
305 value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
307 return AVERROR_INVALIDDATA;
309 intra_block = value & 0x07;
310 reverse = intra_block == 3;
312 flag2 = get_bits1(gb);
315 cbphi = get_cbphi(gb, reverse);
317 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
321 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
322 frame->linesize[0], s->block[0]);
323 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
324 frame->linesize[0], s->block[1]);
325 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
326 frame->linesize[0], s->block[2]);
327 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
328 frame->linesize[0], s->block[3]);
329 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
330 frame->linesize[1], s->block[4]);
331 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
332 frame->linesize[2], s->block[5]);
334 flag2 = get_bits1(gb);
336 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
340 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
341 prev->data[0] + y * prev->linesize[0] + x,
342 frame->linesize[0], prev->linesize[0], 16);
343 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
344 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
345 frame->linesize[1], prev->linesize[1], 8);
346 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
347 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
348 frame->linesize[2], prev->linesize[2], 8);
350 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
351 frame->linesize[0], s->block[0]);
352 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
353 frame->linesize[0], s->block[1]);
354 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
355 frame->linesize[0], s->block[2]);
356 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
357 frame->linesize[0], s->block[3]);
358 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
359 frame->linesize[1], s->block[4]);
360 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
361 frame->linesize[2], s->block[5]);
369 static int decode_frame(AVCodecContext *avctx, void *data,
370 int *got_frame, AVPacket *avpkt)
372 IMM4Context *s = avctx->priv_data;
373 GetBitContext *gb = &s->gb;
374 AVFrame *frame = data;
379 if (avpkt->size <= 32)
380 return AVERROR_INVALIDDATA;
382 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
383 FFALIGN(avpkt->size, 4));
385 return AVERROR(ENOMEM);
387 s->bdsp.bswap_buf((uint32_t *)s->bitstream,
388 (uint32_t *)avpkt->data,
389 (avpkt->size + 3) >> 2);
391 if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
394 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
395 avctx->color_range = AVCOL_RANGE_JPEG;
397 width = avctx->width;
398 height = avctx->height;
400 scaled = avpkt->data[8];
402 int mode = avpkt->data[10];
432 skip_bits_long(gb, 24 * 8);
433 type = get_bits_long(gb, 32);
434 s->hi = get_bits(gb, 16);
435 s->lo = get_bits(gb, 16);
439 frame->key_frame = 1;
440 frame->pict_type = AV_PICTURE_TYPE_I;
443 frame->key_frame = 0;
444 frame->pict_type = AV_PICTURE_TYPE_P;
447 avpriv_request_sample(avctx, "type %X", type);
448 return AVERROR_PATCHWELCOME;
451 if (avctx->width != width ||
452 avctx->height != height) {
453 if (!frame->key_frame) {
454 av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
455 return AVERROR_INVALIDDATA;
457 av_frame_unref(s->prev_frame);
460 ret = ff_set_dimensions(avctx, width, height);
464 if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
467 if (frame->key_frame) {
468 ret = decode_intra(avctx, gb, frame);
472 av_frame_unref(s->prev_frame);
473 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
476 if (!s->prev_frame->data[0]) {
477 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
478 return AVERROR_INVALIDDATA;
481 ret = decode_inter(avctx, gb, frame, s->prev_frame);
491 static av_cold void imm4_init_static_data(void)
493 INIT_VLC_SPARSE_STATIC(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo_bits),
494 cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1,
495 1 << CBPLO_VLC_BITS);
497 INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
498 cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
500 INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
501 blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
503 INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
504 block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
507 static av_cold int decode_init(AVCodecContext *avctx)
509 static AVOnce init_static_once = AV_ONCE_INIT;
510 IMM4Context *s = avctx->priv_data;
513 for (int i = 0; i < 64; i++)
516 ff_bswapdsp_init(&s->bdsp);
517 ff_idctdsp_init(&s->idsp, avctx);
518 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
520 s->prev_frame = av_frame_alloc();
522 return AVERROR(ENOMEM);
524 ff_thread_once(&init_static_once, imm4_init_static_data);
529 static void decode_flush(AVCodecContext *avctx)
531 IMM4Context *s = avctx->priv_data;
533 av_frame_unref(s->prev_frame);
536 static av_cold int decode_close(AVCodecContext *avctx)
538 IMM4Context *s = avctx->priv_data;
540 av_frame_free(&s->prev_frame);
541 av_freep(&s->bitstream);
542 s->bitstream_size = 0;
547 AVCodec ff_imm4_decoder = {
549 .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
550 .type = AVMEDIA_TYPE_VIDEO,
551 .id = AV_CODEC_ID_IMM4,
552 .priv_data_size = sizeof(IMM4Context),
554 .close = decode_close,
555 .decode = decode_frame,
556 .flush = decode_flush,
557 .capabilities = AV_CODEC_CAP_DR1,
558 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
559 FF_CODEC_CAP_INIT_CLEANUP,