FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/imm4.c
Date: 2021-09-26 18:22:30
Exec Total Coverage
Lines: 0 278 0.0%
Branches: 0 115 0.0%

Line Branch Exec Source
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/mem_internal.h"
28 #include "libavutil/thread.h"
29
30 #include "avcodec.h"
31 #include "bswapdsp.h"
32 #include "copy_block.h"
33 #include "get_bits.h"
34 #include "idctdsp.h"
35 #include "internal.h"
36
37 #define CBPLO_VLC_BITS 6
38 #define CBPHI_VLC_BITS 6
39 #define BLKTYPE_VLC_BITS 9
40 #define BLOCK_VLC_BITS 12
41
42 typedef struct IMM4Context {
43 BswapDSPContext bdsp;
44 GetBitContext gb;
45
46 AVFrame *prev_frame;
47 uint8_t *bitstream;
48 int bitstream_size;
49
50 int factor;
51 unsigned lo;
52 unsigned hi;
53
54 ScanTable intra_scantable;
55 DECLARE_ALIGNED(32, int16_t, block)[6][64];
56 IDCTDSPContext idsp;
57 } IMM4Context;
58
59 static const uint8_t intra_cb[] = {
60 24, 18, 12
61 };
62
63 static const uint8_t inter_cb[] = {
64 30, 20, 15
65 };
66
67 static const uint8_t cbplo[][2] = {
68 { 0,-6 }, { 0x01, 6 }, { 0x02, 6 }, { 0x03, 6 }, { 0x00, 4 },
69 { 0x01, 3 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 },
70 };
71
72 static const uint8_t cbphi_bits[] = {
73 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
74 };
75
76 static const uint8_t cbphi_codes[] = {
77 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
78 };
79
80 static const uint8_t blktype[][2] = {
81 { 0,-8 }, { 0x34, 9 }, { 0,-9 }, { 0x14, 9 }, { 0,-9 },
82 { 0x23, 8 }, { 0x13, 8 }, { 0x32, 8 }, { 0x33, 7 }, { 0x22, 7 },
83 { 0x12, 7 }, { 0x21, 7 }, { 0x11, 7 }, { 0x04, 6 }, { 0x30, 6 },
84 { 0x03, 5 }, { 0x20, 4 }, { 0x10, 4 }, { 0x02, 3 }, { 0x01, 3 },
85 { 0x00, 1 },
86 };
87
88 static const uint16_t block_symbols[] = {
89 0, 0x4082, 0x4003, 0x000B, 0x000A, 0x4E01, 0x4D81, 0x4D01, 0x4C81,
90 0x0482, 0x0402, 0x0382, 0x0302, 0x0282, 0x0183, 0x0103, 0x0084, 0x000C,
91 0x0085, 0x0B81, 0x0C01, 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x0086, 0x0104,
92 0x0203, 0x0283, 0x0303, 0x0502, 0x0C81, 0x0D01, 0x5081, 0x5101, 0x5181,
93 0x5201, 0x5281, 0x5301, 0x5381, 0x5401, 0x0000, 0x0009, 0x0008, 0x4C01,
94 0x4B81, 0x4B01, 0x4A81, 0x4A01, 0x4981, 0x4901, 0x4881, 0x4002, 0x0B01,
95 0x0A81, 0x0A01, 0x0981, 0x0901, 0x0881, 0x0801, 0x0781, 0x0202, 0x0182,
96 0x0007, 0x0006, 0x4801, 0x4781, 0x4701, 0x4681, 0x4601, 0x4581, 0x4501,
97 0x4481, 0x0701, 0x0681, 0x0102, 0x0083, 0x0005, 0x4401, 0x4381, 0x4301,
98 0x4281, 0x0601, 0x0581, 0x0501, 0x0004, 0x4201, 0x4181, 0x4101, 0x4081,
99 0x0481, 0x0401, 0x0381, 0x0301, 0x0082, 0x0003, 0x0281, 0x0201, 0x0181,
100 0x4001, 0x0001, 0x0081, 0x0101, 0x0002,
101 };
102
103 static const uint8_t block_bits[] = {
104 -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
105 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
106 12, 12, 12, 7, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
107 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
108 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6,
109 6, 5, 5, 5, 4, 2, 3, 4, 4,
110 };
111
112 static VLC cbplo_tab;
113 static VLC cbphi_tab;
114 static VLC blktype_tab;
115 static VLC block_tab;
116
117 static int get_cbphi(GetBitContext *gb, int x)
118 {
119 int value;
120
121 value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1);
122 if (value < 0)
123 return AVERROR_INVALIDDATA;
124
125 return x ? value : 15 - value;
126 }
127
128 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
129 int block, int factor, int flag, int offset, int flag2)
130 {
131 IMM4Context *s = avctx->priv_data;
132 const uint8_t *scantable = s->intra_scantable.permutated;
133 int i, last, len, factor2;
134
135 for (i = !flag; i < 64; i++) {
136 int value;
137
138 value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1);
139 if (value < 0)
140 return AVERROR_INVALIDDATA;
141 if (value == 0) {
142 last = get_bits1(gb);
143 len = get_bits(gb, 6);
144 factor2 = get_sbits(gb, 8);
145 } else {
146 factor2 = value & 0x7F;
147 last = (value >> 14) & 1;
148 len = (value >> 7) & 0x3F;
149 if (get_bits1(gb))
150 factor2 = -factor2;
151 }
152 i += len;
153 if (i >= 64)
154 break;
155 s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
156 if (last)
157 break;
158 }
159
160 if (s->hi == 2 && flag2 && block < 4) {
161 if (flag)
162 s->block[block][scantable[0]] *= 2;
163 s->block[block][scantable[1]] *= 2;
164 s->block[block][scantable[8]] *= 2;
165 s->block[block][scantable[16]] *= 2;
166 }
167
168 return 0;
169 }
170
171 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
172 unsigned cbp, int flag, int offset, unsigned flag2)
173 {
174 IMM4Context *s = avctx->priv_data;
175 const uint8_t *scantable = s->intra_scantable.permutated;
176 int ret, i;
177
178 memset(s->block, 0, sizeof(s->block));
179
180 for (i = 0; i < 6; i++) {
181 if (!flag) {
182 int x = get_bits(gb, 8);
183
184 if (x == 255)
185 x = 128;
186 x *= 8;
187
188 s->block[i][scantable[0]] = x;
189 }
190
191 if (cbp & (1 << (5 - i))) {
192 ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
193 if (ret < 0)
194 return ret;
195 }
196 }
197
198 return 0;
199 }
200
201 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
202 {
203 IMM4Context *s = avctx->priv_data;
204 int ret, x, y, offset = 0;
205
206 if (s->hi == 0) {
207 if (s->lo > 2)
208 return AVERROR_INVALIDDATA;
209 s->factor = intra_cb[s->lo];
210 } else {
211 s->factor = s->lo * 2;
212 }
213
214 if (s->hi) {
215 offset = s->factor;
216 offset >>= 1;
217 if (!(offset & 1))
218 offset--;
219 }
220
221 for (y = 0; y < avctx->height; y += 16) {
222 for (x = 0; x < avctx->width; x += 16) {
223 unsigned flag, cbphi, cbplo;
224
225 cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1);
226 flag = get_bits1(gb);
227
228 cbphi = get_cbphi(gb, 1);
229
230 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
231 if (ret < 0)
232 return ret;
233
234 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
235 frame->linesize[0], s->block[0]);
236 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
237 frame->linesize[0], s->block[1]);
238 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
239 frame->linesize[0], s->block[2]);
240 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
241 frame->linesize[0], s->block[3]);
242 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
243 frame->linesize[1], s->block[4]);
244 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
245 frame->linesize[2], s->block[5]);
246 }
247 }
248
249 return 0;
250 }
251
252 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
253 AVFrame *frame, AVFrame *prev)
254 {
255 IMM4Context *s = avctx->priv_data;
256 int ret, x, y, offset = 0;
257
258 if (s->hi == 0) {
259 if (s->lo > 2)
260 return AVERROR_INVALIDDATA;
261 s->factor = inter_cb[s->lo];
262 } else {
263 s->factor = s->lo * 2;
264 }
265
266 if (s->hi) {
267 offset = s->factor;
268 offset >>= 1;
269 if (!(offset & 1))
270 offset--;
271 }
272
273 for (y = 0; y < avctx->height; y += 16) {
274 for (x = 0; x < avctx->width; x += 16) {
275 int reverse, intra_block, value;
276 unsigned cbphi, cbplo, flag2 = 0;
277
278 if (get_bits1(gb)) {
279 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
280 prev->data[0] + y * prev->linesize[0] + x,
281 frame->linesize[0], prev->linesize[0], 16);
282 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
283 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
284 frame->linesize[1], prev->linesize[1], 8);
285 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
286 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
287 frame->linesize[2], prev->linesize[2], 8);
288 continue;
289 }
290
291 value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1);
292 if (value < 0)
293 return AVERROR_INVALIDDATA;
294
295 intra_block = value & 0x07;
296 reverse = intra_block == 3;
297 if (reverse)
298 flag2 = get_bits1(gb);
299
300 cbplo = value >> 4;
301 cbphi = get_cbphi(gb, reverse);
302 if (intra_block) {
303 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
304 if (ret < 0)
305 return ret;
306
307 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
308 frame->linesize[0], s->block[0]);
309 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
310 frame->linesize[0], s->block[1]);
311 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
312 frame->linesize[0], s->block[2]);
313 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
314 frame->linesize[0], s->block[3]);
315 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
316 frame->linesize[1], s->block[4]);
317 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
318 frame->linesize[2], s->block[5]);
319 } else {
320 flag2 = get_bits1(gb);
321 skip_bits1(gb);
322 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
323 if (ret < 0)
324 return ret;
325
326 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
327 prev->data[0] + y * prev->linesize[0] + x,
328 frame->linesize[0], prev->linesize[0], 16);
329 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
330 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
331 frame->linesize[1], prev->linesize[1], 8);
332 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
333 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
334 frame->linesize[2], prev->linesize[2], 8);
335
336 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
337 frame->linesize[0], s->block[0]);
338 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
339 frame->linesize[0], s->block[1]);
340 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
341 frame->linesize[0], s->block[2]);
342 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
343 frame->linesize[0], s->block[3]);
344 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
345 frame->linesize[1], s->block[4]);
346 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
347 frame->linesize[2], s->block[5]);
348 }
349 }
350 }
351
352 return 0;
353 }
354
355 static int decode_frame(AVCodecContext *avctx, void *data,
356 int *got_frame, AVPacket *avpkt)
357 {
358 IMM4Context *s = avctx->priv_data;
359 GetBitContext *gb = &s->gb;
360 AVFrame *frame = data;
361 int width, height;
362 unsigned type;
363 int ret, scaled;
364
365 if (avpkt->size <= 32)
366 return AVERROR_INVALIDDATA;
367
368 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
369 FFALIGN(avpkt->size, 4));
370 if (!s->bitstream)
371 return AVERROR(ENOMEM);
372
373 s->bdsp.bswap_buf((uint32_t *)s->bitstream,
374 (uint32_t *)avpkt->data,
375 (avpkt->size + 3) >> 2);
376
377 if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
378 return ret;
379
380 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
381 avctx->color_range = AVCOL_RANGE_JPEG;
382
383 width = avctx->width;
384 height = avctx->height;
385
386 scaled = avpkt->data[8];
387 if (scaled < 2) {
388 int mode = avpkt->data[10];
389
390 switch (mode) {
391 case 1:
392 width = 352;
393 height = 240;
394 break;
395 case 2:
396 width = 704;
397 height = 240;
398 break;
399 case 4:
400 width = 480;
401 height = 704;
402 break;
403 case 17:
404 width = 352;
405 height = 288;
406 break;
407 case 18:
408 width = 704;
409 height = 288;
410 break;
411 default:
412 width = 704;
413 height = 576;
414 break;
415 }
416 }
417
418 skip_bits_long(gb, 24 * 8);
419 type = get_bits_long(gb, 32);
420 s->hi = get_bits(gb, 16);
421 s->lo = get_bits(gb, 16);
422
423 switch (type) {
424 case 0x19781977:
425 frame->key_frame = 1;
426 frame->pict_type = AV_PICTURE_TYPE_I;
427 break;
428 case 0x12250926:
429 frame->key_frame = 0;
430 frame->pict_type = AV_PICTURE_TYPE_P;
431 break;
432 default:
433 avpriv_request_sample(avctx, "type %X", type);
434 return AVERROR_PATCHWELCOME;
435 }
436
437 if (avctx->width != width ||
438 avctx->height != height) {
439 if (!frame->key_frame) {
440 av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
441 return AVERROR_INVALIDDATA;
442 }
443 av_frame_unref(s->prev_frame);
444 }
445
446 ret = ff_set_dimensions(avctx, width, height);
447 if (ret < 0)
448 return ret;
449
450 if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
451 return ret;
452
453 if (frame->key_frame) {
454 ret = decode_intra(avctx, gb, frame);
455 if (ret < 0)
456 return ret;
457
458 av_frame_unref(s->prev_frame);
459 if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
460 return ret;
461 } else {
462 if (!s->prev_frame->data[0]) {
463 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
464 return AVERROR_INVALIDDATA;
465 }
466
467 ret = decode_inter(avctx, gb, frame, s->prev_frame);
468 if (ret < 0)
469 return ret;
470 }
471
472 *got_frame = 1;
473
474 return avpkt->size;
475 }
476
477 static av_cold void imm4_init_static_data(void)
478 {
479 INIT_VLC_STATIC_FROM_LENGTHS(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo),
480 &cbplo[0][1], 2, &cbplo[0][0], 2, 1,
481 0, 0, 1 << CBPLO_VLC_BITS);
482
483 INIT_VLC_SPARSE_STATIC(&cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits),
484 cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
485
486 INIT_VLC_STATIC_FROM_LENGTHS(&blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype),
487 &blktype[0][1], 2, &blktype[0][0], 2, 1,
488 0, 0, 1 << BLKTYPE_VLC_BITS);
489
490 INIT_VLC_STATIC_FROM_LENGTHS(&block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits),
491 block_bits, 1, block_symbols, 2, 2,
492 0, 0, 1 << BLOCK_VLC_BITS);
493 }
494
495 static av_cold int decode_init(AVCodecContext *avctx)
496 {
497 static AVOnce init_static_once = AV_ONCE_INIT;
498 IMM4Context *s = avctx->priv_data;
499 uint8_t table[64];
500
501 for (int i = 0; i < 64; i++)
502 table[i] = i;
503
504 ff_bswapdsp_init(&s->bdsp);
505 ff_idctdsp_init(&s->idsp, avctx);
506 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
507
508 s->prev_frame = av_frame_alloc();
509 if (!s->prev_frame)
510 return AVERROR(ENOMEM);
511
512 ff_thread_once(&init_static_once, imm4_init_static_data);
513
514 return 0;
515 }
516
517 static void decode_flush(AVCodecContext *avctx)
518 {
519 IMM4Context *s = avctx->priv_data;
520
521 av_frame_unref(s->prev_frame);
522 }
523
524 static av_cold int decode_close(AVCodecContext *avctx)
525 {
526 IMM4Context *s = avctx->priv_data;
527
528 av_frame_free(&s->prev_frame);
529 av_freep(&s->bitstream);
530 s->bitstream_size = 0;
531
532 return 0;
533 }
534
535 const AVCodec ff_imm4_decoder = {
536 .name = "imm4",
537 .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
538 .type = AVMEDIA_TYPE_VIDEO,
539 .id = AV_CODEC_ID_IMM4,
540 .priv_data_size = sizeof(IMM4Context),
541 .init = decode_init,
542 .close = decode_close,
543 .decode = decode_frame,
544 .flush = decode_flush,
545 .capabilities = AV_CODEC_CAP_DR1,
546 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
547 FF_CODEC_CAP_INIT_CLEANUP,
548 };
549