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 DECLARE_ALIGNED(32, int16_t, block)[6][64];
52 static const uint8_t intra_cb[] = {
56 static const uint8_t inter_cb[] = {
60 static const uint8_t cbplo_symbols[] = {
61 3, 4, 19, 20, 35, 36, 51, 52
64 static const uint8_t cbplo_bits[] = {
65 1, 4, 3, 6, 3, 6, 3, 6
68 static const uint8_t cbplo_codes[] = {
69 1, 1, 1, 1, 2, 2, 3, 3
72 static const uint8_t cbphi_bits[] = {
73 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
76 static const uint8_t cbphi_codes[] = {
77 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
80 static const uint8_t blktype_symbols[] = {
81 0, 1, 2, 3, 4, 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 50, 51, 52
84 static const uint8_t blktype_bits[] = {
85 1, 3, 3, 5, 6, 4, 7, 7, 8, 9, 4, 7, 7, 8, 6, 8, 7, 9
88 static const uint8_t blktype_codes[] = {
89 1, 3, 2, 3, 4, 3, 7, 5, 4, 4, 2, 6, 4, 3, 5, 5, 3, 2
92 static const uint16_t block_symbols[] = {
93 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x81, 0x82, 0x83,
94 0x84, 0x85, 0x86, 0x101, 0x102, 0x103, 0x104, 0x181, 0x182, 0x183, 0x201, 0x202,
95 0x203, 0x281, 0x282, 0x283, 0x301, 0x302, 0x303, 0x381, 0x382, 0x401, 0x402,
96 0x481, 0x482, 0x501, 0x502, 0x581, 0x601, 0x681, 0x701, 0x781, 0x801, 0x881,
97 0x901, 0x981, 0xA01, 0xA81, 0xB01, 0xB81, 0xC01, 0xC81, 0xD01, 0x4001, 0x4002,
98 0x4003, 0x4081, 0x4082, 0x4101, 0x4181, 0x4201, 0x4281, 0x4301, 0x4381, 0x4401,
99 0x4481, 0x4501, 0x4581, 0x4601, 0x4681, 0x4701, 0x4781, 0x4801, 0x4881, 0x4901,
100 0x4981, 0x4A01, 0x4A81, 0x4B01, 0x4B81, 0x4C01, 0x4C81, 0x4D01, 0x4D81, 0x4E01,
101 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x5081, 0x5101, 0x5181, 0x5201, 0x5281, 0x5301,
105 static const uint8_t block_bits[] = {
106 7, 2, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 3, 6, 8, 10, 11, 12, 4, 8,
107 10, 12, 5, 9, 10, 5, 9, 12, 5, 10, 12, 6, 10, 12, 6, 10, 6, 10, 6,
108 10, 7, 12, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 12, 12, 4, 9,
109 11, 6, 11, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
110 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
114 static const uint8_t block_codes[] = {
115 3, 2, 15, 21, 23, 31, 37, 36, 33, 32, 7, 6, 32, 6, 20, 30, 15, 33, 80,
116 14, 29, 14, 81, 13, 35, 13, 12, 34, 82, 11, 12, 83, 19, 11, 84, 18,
117 10, 17, 9, 16, 8, 22, 85, 21, 20, 28, 27, 33, 32, 31, 30, 29, 28,
118 27, 26, 34, 35, 86, 87, 7, 25, 5, 15, 4, 14, 13, 12, 19, 18, 17, 16,
119 26, 25, 24, 23, 22, 21, 20, 19, 24, 23, 22, 21, 20, 19, 18, 17, 7,
120 6, 5, 4, 36, 37, 38, 39, 88, 89, 90, 91, 92, 93, 94, 95
123 static VLC cbplo_tab;
124 static VLC cbphi_tab;
125 static VLC blktype_tab;
126 static VLC block_tab;
128 static int get_cbphi(GetBitContext *gb, int x)
132 value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1);
134 return AVERROR_INVALIDDATA;
136 return x ? value : 15 - value;
139 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
140 int block, int factor, int flag)
142 IMM4Context *s = avctx->priv_data;
143 int i, last, len, factor2;
145 for (i = !flag; i < 64; i++) {
148 value = get_vlc2(gb, block_tab.table, block_tab.bits, 1);
150 return AVERROR_INVALIDDATA;
152 last = get_bits1(gb);
153 len = get_bits(gb, 6);
154 factor2 = get_sbits(gb, 8);
156 factor2 = value & 0x7F;
157 last = (value >> 14) & 1;
158 len = (value >> 7) & 0x3F;
165 s->block[block][i] = factor * factor2;
173 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
174 unsigned cbp, int flag)
176 IMM4Context *s = avctx->priv_data;
179 memset(s->block, 0, sizeof(s->block));
181 for (i = 0; i < 6; i++) {
183 int x = get_bits(gb, 8);
192 if (cbp & (1 << (5 - i))) {
193 ret = decode_block(avctx, gb, i, s->factor, flag);
202 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
204 IMM4Context *s = avctx->priv_data;
207 s->factor = intra_cb[s->sindex] * 2;
209 for (y = 0; y < avctx->height; y += 16) {
210 for (x = 0; x < avctx->width; x += 16) {
211 unsigned cbphi, cbplo;
213 cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
216 cbphi = get_cbphi(gb, 1);
218 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0);
222 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
223 frame->linesize[0], s->block[0]);
224 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
225 frame->linesize[0], s->block[1]);
226 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
227 frame->linesize[0], s->block[2]);
228 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
229 frame->linesize[0], s->block[3]);
230 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
231 frame->linesize[1], s->block[4]);
232 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
233 frame->linesize[2], s->block[5]);
240 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
241 AVFrame *frame, AVFrame *prev)
243 IMM4Context *s = avctx->priv_data;
246 s->factor = inter_cb[s->sindex];
248 for (y = 0; y < avctx->height; y += 16) {
249 for (x = 0; x < avctx->width; x += 16) {
250 int reverse, intra_block, value;
251 unsigned cbphi, cbplo;
254 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
255 prev->data[0] + y * prev->linesize[0] + x,
256 frame->linesize[0], prev->linesize[0], 16);
257 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
258 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
259 frame->linesize[1], prev->linesize[1], 8);
260 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
261 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
262 frame->linesize[2], prev->linesize[2], 8);
266 value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
268 return AVERROR_INVALIDDATA;
270 intra_block = value & 0x07;
271 reverse = intra_block == 3;
276 cbphi = get_cbphi(gb, reverse);
278 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0);
282 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
283 frame->linesize[0], s->block[0]);
284 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
285 frame->linesize[0], s->block[1]);
286 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
287 frame->linesize[0], s->block[2]);
288 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
289 frame->linesize[0], s->block[3]);
290 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
291 frame->linesize[1], s->block[4]);
292 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
293 frame->linesize[2], s->block[5]);
296 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1);
300 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
301 prev->data[0] + y * prev->linesize[0] + x,
302 frame->linesize[0], prev->linesize[0], 16);
303 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
304 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
305 frame->linesize[1], prev->linesize[1], 8);
306 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
307 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
308 frame->linesize[2], prev->linesize[2], 8);
310 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
311 frame->linesize[0], s->block[0]);
312 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
313 frame->linesize[0], s->block[1]);
314 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
315 frame->linesize[0], s->block[2]);
316 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
317 frame->linesize[0], s->block[3]);
318 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
319 frame->linesize[1], s->block[4]);
320 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
321 frame->linesize[2], s->block[5]);
329 static int decode_frame(AVCodecContext *avctx, void *data,
330 int *got_frame, AVPacket *avpkt)
332 IMM4Context *s = avctx->priv_data;
333 GetBitContext *gb = &s->gb;
334 AVFrame *frame = data;
338 if (avpkt->size <= 32)
339 return AVERROR_INVALIDDATA;
341 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
342 FFALIGN(avpkt->size, 4));
344 return AVERROR(ENOMEM);
346 s->bdsp.bswap_buf((uint32_t *)s->bitstream,
347 (uint32_t *)avpkt->data,
348 (avpkt->size + 3) >> 2);
350 if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
353 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
354 avctx->color_range = AVCOL_RANGE_JPEG;
356 scaled = avpkt->data[8];
359 int mode = avpkt->data[10];
388 if (s->changed_size == 1 &&
389 (avctx->width != width || avctx->height != height)) {
390 av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
391 return AVERROR_INVALIDDATA;
393 avctx->width = width;
394 avctx->height = height;
398 skip_bits_long(gb, 24 * 8);
399 type = get_bits_long(gb, 32);
400 s->sindex = get_bits_long(gb, 32);
402 return AVERROR_INVALIDDATA;
406 frame->key_frame = 1;
407 frame->pict_type = AV_PICTURE_TYPE_I;
410 frame->key_frame = 0;
411 frame->pict_type = AV_PICTURE_TYPE_P;
414 avpriv_request_sample(avctx, "type %X", type);
415 return AVERROR_PATCHWELCOME;
418 if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
421 if (frame->key_frame) {
422 ret = decode_intra(avctx, gb, frame);
426 av_frame_unref(s->prev_frame);
427 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
430 if (!s->prev_frame->data[0]) {
431 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
432 return AVERROR_INVALIDDATA;
435 ret = decode_inter(avctx, gb, frame, s->prev_frame);
445 static av_cold void imm4_init_static_data(void)
447 INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
448 cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
450 INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
451 cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
453 INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
454 blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
456 INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
457 block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
460 static av_cold int decode_init(AVCodecContext *avctx)
462 static AVOnce init_static_once = AV_ONCE_INIT;
463 IMM4Context *s = avctx->priv_data;
465 avctx->idct_algo = FF_IDCT_FAAN;
466 ff_bswapdsp_init(&s->bdsp);
467 ff_idctdsp_init(&s->idsp, avctx);
469 s->prev_frame = av_frame_alloc();
471 return AVERROR(ENOMEM);
473 ff_thread_once(&init_static_once, imm4_init_static_data);
478 static av_cold int decode_close(AVCodecContext *avctx)
480 IMM4Context *s = avctx->priv_data;
482 av_frame_free(&s->prev_frame);
483 av_freep(&s->bitstream);
484 s->bitstream_size = 0;
489 AVCodec ff_imm4_decoder = {
491 .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
492 .type = AVMEDIA_TYPE_VIDEO,
493 .id = AV_CODEC_ID_IMM4,
494 .priv_data_size = sizeof(IMM4Context),
496 .close = decode_close,
497 .decode = decode_frame,
498 .capabilities = AV_CODEC_CAP_DR1,
499 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
500 FF_CODEC_CAP_INIT_CLEANUP,