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 {
49 ScanTable intra_scantable;
50 DECLARE_ALIGNED(32, int16_t, block)[6][64];
54 static const uint8_t intra_cb[] = {
58 static const uint8_t inter_cb[] = {
62 static const uint8_t cbplo_symbols[] = {
63 3, 4, 19, 20, 35, 36, 51, 52
66 static const uint8_t cbplo_bits[] = {
67 1, 4, 3, 6, 3, 6, 3, 6
70 static const uint8_t cbplo_codes[] = {
71 1, 1, 1, 1, 2, 2, 3, 3
74 static const uint8_t cbphi_bits[] = {
75 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
78 static const uint8_t cbphi_codes[] = {
79 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
82 static const uint8_t blktype_symbols[] = {
83 0, 1, 2, 3, 4, 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 50, 51, 52
86 static const uint8_t blktype_bits[] = {
87 1, 3, 3, 5, 6, 4, 7, 7, 8, 9, 4, 7, 7, 8, 6, 8, 7, 9
90 static const uint8_t blktype_codes[] = {
91 1, 3, 2, 3, 4, 3, 7, 5, 4, 4, 2, 6, 4, 3, 5, 5, 3, 2
94 static const uint16_t block_symbols[] = {
95 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x81, 0x82, 0x83,
96 0x84, 0x85, 0x86, 0x101, 0x102, 0x103, 0x104, 0x181, 0x182, 0x183, 0x201, 0x202,
97 0x203, 0x281, 0x282, 0x283, 0x301, 0x302, 0x303, 0x381, 0x382, 0x401, 0x402,
98 0x481, 0x482, 0x501, 0x502, 0x581, 0x601, 0x681, 0x701, 0x781, 0x801, 0x881,
99 0x901, 0x981, 0xA01, 0xA81, 0xB01, 0xB81, 0xC01, 0xC81, 0xD01, 0x4001, 0x4002,
100 0x4003, 0x4081, 0x4082, 0x4101, 0x4181, 0x4201, 0x4281, 0x4301, 0x4381, 0x4401,
101 0x4481, 0x4501, 0x4581, 0x4601, 0x4681, 0x4701, 0x4781, 0x4801, 0x4881, 0x4901,
102 0x4981, 0x4A01, 0x4A81, 0x4B01, 0x4B81, 0x4C01, 0x4C81, 0x4D01, 0x4D81, 0x4E01,
103 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x5081, 0x5101, 0x5181, 0x5201, 0x5281, 0x5301,
107 static const uint8_t block_bits[] = {
108 7, 2, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 3, 6, 8, 10, 11, 12, 4, 8,
109 10, 12, 5, 9, 10, 5, 9, 12, 5, 10, 12, 6, 10, 12, 6, 10, 6, 10, 6,
110 10, 7, 12, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 12, 12, 4, 9,
111 11, 6, 11, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
112 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
116 static const uint8_t block_codes[] = {
117 3, 2, 15, 21, 23, 31, 37, 36, 33, 32, 7, 6, 32, 6, 20, 30, 15, 33, 80,
118 14, 29, 14, 81, 13, 35, 13, 12, 34, 82, 11, 12, 83, 19, 11, 84, 18,
119 10, 17, 9, 16, 8, 22, 85, 21, 20, 28, 27, 33, 32, 31, 30, 29, 28,
120 27, 26, 34, 35, 86, 87, 7, 25, 5, 15, 4, 14, 13, 12, 19, 18, 17, 16,
121 26, 25, 24, 23, 22, 21, 20, 19, 24, 23, 22, 21, 20, 19, 18, 17, 7,
122 6, 5, 4, 36, 37, 38, 39, 88, 89, 90, 91, 92, 93, 94, 95
125 static VLC cbplo_tab;
126 static VLC cbphi_tab;
127 static VLC blktype_tab;
128 static VLC block_tab;
130 static int get_cbphi(GetBitContext *gb, int x)
134 value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1);
136 return AVERROR_INVALIDDATA;
138 return x ? value : 15 - value;
141 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
142 int block, int factor, int flag, int offset)
144 IMM4Context *s = avctx->priv_data;
145 const uint8_t *scantable = s->intra_scantable.permutated;
146 int i, last, len, factor2;
148 for (i = !flag; i < 64; i++) {
151 value = get_vlc2(gb, block_tab.table, block_tab.bits, 1);
153 return AVERROR_INVALIDDATA;
155 last = get_bits1(gb);
156 len = get_bits(gb, 6);
157 factor2 = get_sbits(gb, 8);
159 factor2 = value & 0x7F;
160 last = (value >> 14) & 1;
161 len = (value >> 7) & 0x3F;
168 s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
176 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
177 unsigned cbp, int flag, int offset)
179 IMM4Context *s = avctx->priv_data;
180 const uint8_t *scantable = s->intra_scantable.permutated;
183 memset(s->block, 0, sizeof(s->block));
185 for (i = 0; i < 6; i++) {
187 int x = get_bits(gb, 8);
193 s->block[i][scantable[0]] = x;
196 if (cbp & (1 << (5 - i))) {
197 ret = decode_block(avctx, gb, i, s->factor, flag, offset);
206 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
208 IMM4Context *s = avctx->priv_data;
209 int ret, x, y, offset = 0;
213 return AVERROR_INVALIDDATA;
214 s->factor = intra_cb[s->lo];
217 s->factor = s->lo * 2;
219 s->factor = s->lo * 2;
230 for (y = 0; y < avctx->height; y += 16) {
231 for (x = 0; x < avctx->width; x += 16) {
232 unsigned cbphi, cbplo;
234 cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
237 cbphi = get_cbphi(gb, 1);
239 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
243 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
244 frame->linesize[0], s->block[0]);
245 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
246 frame->linesize[0], s->block[1]);
247 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
248 frame->linesize[0], s->block[2]);
249 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
250 frame->linesize[0], s->block[3]);
251 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
252 frame->linesize[1], s->block[4]);
253 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
254 frame->linesize[2], s->block[5]);
261 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
262 AVFrame *frame, AVFrame *prev)
264 IMM4Context *s = avctx->priv_data;
265 int ret, x, y, offset = 0;
269 return AVERROR_INVALIDDATA;
270 s->factor = inter_cb[s->lo];
273 s->factor = s->lo * 2;
275 s->factor = s->lo * 2;
286 for (y = 0; y < avctx->height; y += 16) {
287 for (x = 0; x < avctx->width; x += 16) {
288 int reverse, intra_block, value;
289 unsigned cbphi, cbplo;
292 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
293 prev->data[0] + y * prev->linesize[0] + x,
294 frame->linesize[0], prev->linesize[0], 16);
295 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
296 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
297 frame->linesize[1], prev->linesize[1], 8);
298 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
299 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
300 frame->linesize[2], prev->linesize[2], 8);
304 value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
306 return AVERROR_INVALIDDATA;
308 intra_block = value & 0x07;
309 reverse = intra_block == 3;
314 cbphi = get_cbphi(gb, reverse);
316 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
320 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
321 frame->linesize[0], s->block[0]);
322 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
323 frame->linesize[0], s->block[1]);
324 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
325 frame->linesize[0], s->block[2]);
326 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
327 frame->linesize[0], s->block[3]);
328 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
329 frame->linesize[1], s->block[4]);
330 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
331 frame->linesize[2], s->block[5]);
334 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset);
338 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
339 prev->data[0] + y * prev->linesize[0] + x,
340 frame->linesize[0], prev->linesize[0], 16);
341 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
342 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
343 frame->linesize[1], prev->linesize[1], 8);
344 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
345 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
346 frame->linesize[2], prev->linesize[2], 8);
348 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
349 frame->linesize[0], s->block[0]);
350 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
351 frame->linesize[0], s->block[1]);
352 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
353 frame->linesize[0], s->block[2]);
354 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
355 frame->linesize[0], s->block[3]);
356 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
357 frame->linesize[1], s->block[4]);
358 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
359 frame->linesize[2], s->block[5]);
367 static int decode_frame(AVCodecContext *avctx, void *data,
368 int *got_frame, AVPacket *avpkt)
370 IMM4Context *s = avctx->priv_data;
371 GetBitContext *gb = &s->gb;
372 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 scaled = avpkt->data[8];
397 int mode = avpkt->data[10];
426 if (s->changed_size == 1 &&
427 (avctx->width != width || avctx->height != height)) {
428 av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
429 return AVERROR_INVALIDDATA;
431 ret = ff_set_dimensions(avctx, width, height);
437 skip_bits_long(gb, 24 * 8);
438 type = get_bits_long(gb, 32);
439 s->hi = get_bits(gb, 16);
440 s->lo = get_bits(gb, 16);
444 frame->key_frame = 1;
445 frame->pict_type = AV_PICTURE_TYPE_I;
448 frame->key_frame = 0;
449 frame->pict_type = AV_PICTURE_TYPE_P;
452 avpriv_request_sample(avctx, "type %X", type);
453 return AVERROR_PATCHWELCOME;
456 if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
459 if (frame->key_frame) {
460 ret = decode_intra(avctx, gb, frame);
464 av_frame_unref(s->prev_frame);
465 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
468 if (!s->prev_frame->data[0]) {
469 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
470 return AVERROR_INVALIDDATA;
473 ret = decode_inter(avctx, gb, frame, s->prev_frame);
483 static av_cold void imm4_init_static_data(void)
485 INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
486 cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
488 INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
489 cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
491 INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
492 blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
494 INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
495 block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
498 static av_cold int decode_init(AVCodecContext *avctx)
500 static AVOnce init_static_once = AV_ONCE_INIT;
501 IMM4Context *s = avctx->priv_data;
504 for (int i = 0; i < 64; i++)
507 ff_bswapdsp_init(&s->bdsp);
508 ff_idctdsp_init(&s->idsp, avctx);
509 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
511 s->prev_frame = av_frame_alloc();
513 return AVERROR(ENOMEM);
515 ff_thread_once(&init_static_once, imm4_init_static_data);
520 static av_cold int decode_close(AVCodecContext *avctx)
522 IMM4Context *s = avctx->priv_data;
524 av_frame_free(&s->prev_frame);
525 av_freep(&s->bitstream);
526 s->bitstream_size = 0;
531 AVCodec ff_imm4_decoder = {
533 .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
534 .type = AVMEDIA_TYPE_VIDEO,
535 .id = AV_CODEC_ID_IMM4,
536 .priv_data_size = sizeof(IMM4Context),
538 .close = decode_close,
539 .decode = decode_frame,
540 .capabilities = AV_CODEC_CAP_DR1,
541 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
542 FF_CODEC_CAP_INIT_CLEANUP,