1 /*
2 * Infinity IMM4 decoder
3 *
4 * Copyright (c) 2018 Paul B Mahol
5 *
6 * This file is part of FFmpeg.
7 *
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.
12 *
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.
17 *
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
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "libavutil/thread.h"
28
29 #include "avcodec.h"
30 #include "bswapdsp.h"
31 #include "copy_block.h"
32 #include "get_bits.h"
33 #include "idctdsp.h"
34 #include "internal.h"
35
36 typedef struct IMM4Context {
37 BswapDSPContext bdsp;
38 GetBitContext gb;
39
40 AVFrame *prev_frame;
41 uint8_t *bitstream;
42 int bitstream_size;
43
44 int factor;
45 unsigned lo;
46 unsigned hi;
47
48 ScanTable intra_scantable;
49 DECLARE_ALIGNED(32, int16_t, block)[6][64];
50 IDCTDSPContext idsp;
51 } IMM4Context;
52
53 static const uint8_t intra_cb[] = {
54 24, 18, 12
55 };
56
57 static const uint8_t inter_cb[] = {
58 30, 20, 15
59 };
60
61 static const uint8_t cbplo_symbols[] = {
62 3, 4, 19, 20, 35, 36, 51, 52
63 };
64
65 static const uint8_t cbplo_bits[] = {
66 1, 4, 3, 6, 3, 6, 3, 6
67 };
68
69 static const uint8_t cbplo_codes[] = {
70 1, 1, 1, 1, 2, 2, 3, 3
71 };
72
73 static const uint8_t cbphi_bits[] = {
74 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
75 };
76
77 static const uint8_t cbphi_codes[] = {
78 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
79 };
80
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
83 };
84
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
87 };
88
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
91 };
92
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,
103 0x5381, 0x5401
104 };
105
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,
112 12, 12
113 };
114
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
122 };
123
124 static VLC cbplo_tab;
125 static VLC cbphi_tab;
126 static VLC blktype_tab;
127 static VLC block_tab;
128
get_cbphi(GetBitContext * gb,int x)129 static int get_cbphi(GetBitContext *gb, int x)
130 {
131 int value;
132
133 value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1);
134 if (value < 0)
135 return AVERROR_INVALIDDATA;
136
137 return x ? value : 15 - value;
138 }
139
decode_block(AVCodecContext * avctx,GetBitContext * gb,int block,int factor,int flag,int offset,int flag2)140 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
141 int block, int factor, int flag, int offset, int flag2)
142 {
143 IMM4Context *s = avctx->priv_data;
144 const uint8_t *scantable = s->intra_scantable.permutated;
145 int i, last, len, factor2;
146
147 for (i = !flag; i < 64; i++) {
148 int value;
149
150 value = get_vlc2(gb, block_tab.table, block_tab.bits, 1);
151 if (value < 0)
152 return AVERROR_INVALIDDATA;
153 if (value == 0) {
154 last = get_bits1(gb);
155 len = get_bits(gb, 6);
156 factor2 = get_sbits(gb, 8);
157 } else {
158 factor2 = value & 0x7F;
159 last = (value >> 14) & 1;
160 len = (value >> 7) & 0x3F;
161 if (get_bits1(gb))
162 factor2 = -factor2;
163 }
164 i += len;
165 if (i >= 64)
166 break;
167 s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
168 if (last)
169 break;
170 }
171
172 if (s->hi == 2 && flag2 && block < 4) {
173 if (flag)
174 s->block[block][scantable[0]] *= 2;
175 s->block[block][scantable[1]] *= 2;
176 s->block[block][scantable[8]] *= 2;
177 s->block[block][scantable[16]] *= 2;
178 }
179
180 return 0;
181 }
182
decode_blocks(AVCodecContext * avctx,GetBitContext * gb,unsigned cbp,int flag,int offset,unsigned flag2)183 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
184 unsigned cbp, int flag, int offset, unsigned flag2)
185 {
186 IMM4Context *s = avctx->priv_data;
187 const uint8_t *scantable = s->intra_scantable.permutated;
188 int ret, i;
189
190 memset(s->block, 0, sizeof(s->block));
191
192 for (i = 0; i < 6; i++) {
193 if (!flag) {
194 int x = get_bits(gb, 8);
195
196 if (x == 255)
197 x = 128;
198 x *= 8;
199
200 s->block[i][scantable[0]] = x;
201 }
202
203 if (cbp & (1 << (5 - i))) {
204 ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
205 if (ret < 0)
206 return ret;
207 }
208 }
209
210 return 0;
211 }
212
decode_intra(AVCodecContext * avctx,GetBitContext * gb,AVFrame * frame)213 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
214 {
215 IMM4Context *s = avctx->priv_data;
216 int ret, x, y, offset = 0;
217
218 if (s->hi == 0) {
219 if (s->lo > 2)
220 return AVERROR_INVALIDDATA;
221 s->factor = intra_cb[s->lo];
222 } else {
223 s->factor = s->lo * 2;
224 }
225
226 if (s->hi) {
227 offset = s->factor;
228 offset >>= 1;
229 if (!(offset & 1))
230 offset--;
231 }
232
233 for (y = 0; y < avctx->height; y += 16) {
234 for (x = 0; x < avctx->width; x += 16) {
235 unsigned flag, cbphi, cbplo;
236
237 cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
238 flag = get_bits1(gb);
239
240 cbphi = get_cbphi(gb, 1);
241
242 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
243 if (ret < 0)
244 return ret;
245
246 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
247 frame->linesize[0], s->block[0]);
248 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
249 frame->linesize[0], s->block[1]);
250 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
251 frame->linesize[0], s->block[2]);
252 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
253 frame->linesize[0], s->block[3]);
254 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
255 frame->linesize[1], s->block[4]);
256 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
257 frame->linesize[2], s->block[5]);
258 }
259 }
260
261 return 0;
262 }
263
decode_inter(AVCodecContext * avctx,GetBitContext * gb,AVFrame * frame,AVFrame * prev)264 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
265 AVFrame *frame, AVFrame *prev)
266 {
267 IMM4Context *s = avctx->priv_data;
268 int ret, x, y, offset = 0;
269
270 if (s->hi == 0) {
271 if (s->lo > 2)
272 return AVERROR_INVALIDDATA;
273 s->factor = inter_cb[s->lo];
274 } else {
275 s->factor = s->lo * 2;
276 }
277
278 if (s->hi) {
279 offset = s->factor;
280 offset >>= 1;
281 if (!(offset & 1))
282 offset--;
283 }
284
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, flag2 = 0;
289
290 if (get_bits1(gb)) {
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);
300 continue;
301 }
302
303 value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
304 if (value < 0)
305 return AVERROR_INVALIDDATA;
306
307 intra_block = value & 0x07;
308 reverse = intra_block == 3;
309 if (reverse)
310 flag2 = get_bits1(gb);
311
312 cbplo = value >> 4;
313 cbphi = get_cbphi(gb, reverse);
314 if (intra_block) {
315 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
316 if (ret < 0)
317 return ret;
318
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]);
331 } else {
332 flag2 = get_bits1(gb);
333 skip_bits1(gb);
334 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
335 if (ret < 0)
336 return ret;
337
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);
347
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]);
360 }
361 }
362 }
363
364 return 0;
365 }
366
decode_frame(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * avpkt)367 static int decode_frame(AVCodecContext *avctx, void *data,
368 int *got_frame, AVPacket *avpkt)
369 {
370 IMM4Context *s = avctx->priv_data;
371 GetBitContext *gb = &s->gb;
372 AVFrame *frame = data;
373 int width, height;
374 unsigned type;
375 int ret, scaled;
376
377 if (avpkt->size <= 32)
378 return AVERROR_INVALIDDATA;
379
380 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
381 FFALIGN(avpkt->size, 4));
382 if (!s->bitstream)
383 return AVERROR(ENOMEM);
384
385 s->bdsp.bswap_buf((uint32_t *)s->bitstream,
386 (uint32_t *)avpkt->data,
387 (avpkt->size + 3) >> 2);
388
389 if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
390 return ret;
391
392 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
393 avctx->color_range = AVCOL_RANGE_JPEG;
394
395 width = avctx->width;
396 height = avctx->height;
397
398 scaled = avpkt->data[8];
399 if (scaled < 2) {
400 int mode = avpkt->data[10];
401
402 switch (mode) {
403 case 1:
404 width = 352;
405 height = 240;
406 break;
407 case 2:
408 width = 704;
409 height = 240;
410 break;
411 case 4:
412 width = 480;
413 height = 704;
414 break;
415 case 17:
416 width = 352;
417 height = 288;
418 break;
419 case 18:
420 width = 704;
421 height = 288;
422 break;
423 default:
424 width = 704;
425 height = 576;
426 break;
427 }
428 }
429
430 skip_bits_long(gb, 24 * 8);
431 type = get_bits_long(gb, 32);
432 s->hi = get_bits(gb, 16);
433 s->lo = get_bits(gb, 16);
434
435 switch (type) {
436 case 0x19781977:
437 frame->key_frame = 1;
438 frame->pict_type = AV_PICTURE_TYPE_I;
439 break;
440 case 0x12250926:
441 frame->key_frame = 0;
442 frame->pict_type = AV_PICTURE_TYPE_P;
443 break;
444 default:
445 avpriv_request_sample(avctx, "type %X", type);
446 return AVERROR_PATCHWELCOME;
447 }
448
449 if (avctx->width != width ||
450 avctx->height != height) {
451 if (!frame->key_frame) {
452 av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
453 return AVERROR_INVALIDDATA;
454 }
455 av_frame_unref(s->prev_frame);
456 }
457
458 ret = ff_set_dimensions(avctx, width, height);
459 if (ret < 0)
460 return ret;
461
462 if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
463 return ret;
464
465 if (frame->key_frame) {
466 ret = decode_intra(avctx, gb, frame);
467 if (ret < 0)
468 return ret;
469
470 av_frame_unref(s->prev_frame);
471 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
472 return ret;
473 } else {
474 if (!s->prev_frame->data[0]) {
475 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
476 return AVERROR_INVALIDDATA;
477 }
478
479 ret = decode_inter(avctx, gb, frame, s->prev_frame);
480 if (ret < 0)
481 return ret;
482 }
483
484 *got_frame = 1;
485
486 return avpkt->size;
487 }
488
imm4_init_static_data(void)489 static av_cold void imm4_init_static_data(void)
490 {
491 INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
492 cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
493
494 INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
495 cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
496
497 INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
498 blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
499
500 INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
501 block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
502 }
503
decode_init(AVCodecContext * avctx)504 static av_cold int decode_init(AVCodecContext *avctx)
505 {
506 static AVOnce init_static_once = AV_ONCE_INIT;
507 IMM4Context *s = avctx->priv_data;
508 uint8_t table[64];
509
510 for (int i = 0; i < 64; i++)
511 table[i] = i;
512
513 ff_bswapdsp_init(&s->bdsp);
514 ff_idctdsp_init(&s->idsp, avctx);
515 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
516
517 s->prev_frame = av_frame_alloc();
518 if (!s->prev_frame)
519 return AVERROR(ENOMEM);
520
521 ff_thread_once(&init_static_once, imm4_init_static_data);
522
523 return 0;
524 }
525
decode_flush(AVCodecContext * avctx)526 static void decode_flush(AVCodecContext *avctx)
527 {
528 IMM4Context *s = avctx->priv_data;
529
530 av_frame_unref(s->prev_frame);
531 }
532
decode_close(AVCodecContext * avctx)533 static av_cold int decode_close(AVCodecContext *avctx)
534 {
535 IMM4Context *s = avctx->priv_data;
536
537 av_frame_free(&s->prev_frame);
538 av_freep(&s->bitstream);
539 s->bitstream_size = 0;
540
541 return 0;
542 }
543
544 AVCodec ff_imm4_decoder = {
545 .name = "imm4",
546 .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
547 .type = AVMEDIA_TYPE_VIDEO,
548 .id = AV_CODEC_ID_IMM4,
549 .priv_data_size = sizeof(IMM4Context),
550 .init = decode_init,
551 .close = decode_close,
552 .decode = decode_frame,
553 .flush = decode_flush,
554 .capabilities = AV_CODEC_CAP_DR1,
555 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
556 FF_CODEC_CAP_INIT_CLEANUP,
557 };
558