FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/imm4.c
Date: 2022-07-05 19:52:29
Exec Total Coverage
Lines: 0 277 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 "codec_internal.h"
33 #include "copy_block.h"
34 #include "get_bits.h"
35 #include "idctdsp.h"
36 #include "internal.h"
37
38 #define CBPLO_VLC_BITS 6
39 #define CBPHI_VLC_BITS 6
40 #define BLKTYPE_VLC_BITS 9
41 #define BLOCK_VLC_BITS 12
42
43 typedef struct IMM4Context {
44 BswapDSPContext bdsp;
45 GetBitContext gb;
46
47 AVFrame *prev_frame;
48 uint8_t *bitstream;
49 int bitstream_size;
50
51 int factor;
52 unsigned lo;
53 unsigned hi;
54
55 ScanTable intra_scantable;
56 DECLARE_ALIGNED(32, int16_t, block)[6][64];
57 IDCTDSPContext idsp;
58 } IMM4Context;
59
60 static const uint8_t intra_cb[] = {
61 24, 18, 12
62 };
63
64 static const uint8_t inter_cb[] = {
65 30, 20, 15
66 };
67
68 static const uint8_t cbplo[][2] = {
69 { 0,-6 }, { 0x01, 6 }, { 0x02, 6 }, { 0x03, 6 }, { 0x00, 4 },
70 { 0x01, 3 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 },
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[][2] = {
82 { 0,-8 }, { 0x34, 9 }, { 0,-9 }, { 0x14, 9 }, { 0,-9 },
83 { 0x23, 8 }, { 0x13, 8 }, { 0x32, 8 }, { 0x33, 7 }, { 0x22, 7 },
84 { 0x12, 7 }, { 0x21, 7 }, { 0x11, 7 }, { 0x04, 6 }, { 0x30, 6 },
85 { 0x03, 5 }, { 0x20, 4 }, { 0x10, 4 }, { 0x02, 3 }, { 0x01, 3 },
86 { 0x00, 1 },
87 };
88
89 static const uint16_t block_symbols[] = {
90 0, 0x4082, 0x4003, 0x000B, 0x000A, 0x4E01, 0x4D81, 0x4D01, 0x4C81,
91 0x0482, 0x0402, 0x0382, 0x0302, 0x0282, 0x0183, 0x0103, 0x0084, 0x000C,
92 0x0085, 0x0B81, 0x0C01, 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x0086, 0x0104,
93 0x0203, 0x0283, 0x0303, 0x0502, 0x0C81, 0x0D01, 0x5081, 0x5101, 0x5181,
94 0x5201, 0x5281, 0x5301, 0x5381, 0x5401, 0x0000, 0x0009, 0x0008, 0x4C01,
95 0x4B81, 0x4B01, 0x4A81, 0x4A01, 0x4981, 0x4901, 0x4881, 0x4002, 0x0B01,
96 0x0A81, 0x0A01, 0x0981, 0x0901, 0x0881, 0x0801, 0x0781, 0x0202, 0x0182,
97 0x0007, 0x0006, 0x4801, 0x4781, 0x4701, 0x4681, 0x4601, 0x4581, 0x4501,
98 0x4481, 0x0701, 0x0681, 0x0102, 0x0083, 0x0005, 0x4401, 0x4381, 0x4301,
99 0x4281, 0x0601, 0x0581, 0x0501, 0x0004, 0x4201, 0x4181, 0x4101, 0x4081,
100 0x0481, 0x0401, 0x0381, 0x0301, 0x0082, 0x0003, 0x0281, 0x0201, 0x0181,
101 0x4001, 0x0001, 0x0081, 0x0101, 0x0002,
102 };
103
104 static const uint8_t block_bits[] = {
105 -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
106 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
107 12, 12, 12, 7, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
108 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
109 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6,
110 6, 5, 5, 5, 4, 2, 3, 4, 4,
111 };
112
113 static VLC cbplo_tab;
114 static VLC cbphi_tab;
115 static VLC blktype_tab;
116 static VLC block_tab;
117
118 static int get_cbphi(GetBitContext *gb, int x)
119 {
120 int value;
121
122 value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1);
123 if (value < 0)
124 return AVERROR_INVALIDDATA;
125
126 return x ? value : 15 - value;
127 }
128
129 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
130 int block, int factor, int flag, int offset, int flag2)
131 {
132 IMM4Context *s = avctx->priv_data;
133 const uint8_t *scantable = s->intra_scantable.permutated;
134 int i, last, len, factor2;
135
136 for (i = !flag; i < 64; i++) {
137 int value;
138
139 value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1);
140 if (value < 0)
141 return AVERROR_INVALIDDATA;
142 if (value == 0) {
143 last = get_bits1(gb);
144 len = get_bits(gb, 6);
145 factor2 = get_sbits(gb, 8);
146 } else {
147 factor2 = value & 0x7F;
148 last = (value >> 14) & 1;
149 len = (value >> 7) & 0x3F;
150 if (get_bits1(gb))
151 factor2 = -factor2;
152 }
153 i += len;
154 if (i >= 64)
155 break;
156 s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
157 if (last)
158 break;
159 }
160
161 if (s->hi == 2 && flag2 && block < 4) {
162 if (flag)
163 s->block[block][scantable[0]] *= 2;
164 s->block[block][scantable[1]] *= 2;
165 s->block[block][scantable[8]] *= 2;
166 s->block[block][scantable[16]] *= 2;
167 }
168
169 return 0;
170 }
171
172 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
173 unsigned cbp, int flag, int offset, unsigned flag2)
174 {
175 IMM4Context *s = avctx->priv_data;
176 const uint8_t *scantable = s->intra_scantable.permutated;
177 int ret, i;
178
179 memset(s->block, 0, sizeof(s->block));
180
181 for (i = 0; i < 6; i++) {
182 if (!flag) {
183 int x = get_bits(gb, 8);
184
185 if (x == 255)
186 x = 128;
187 x *= 8;
188
189 s->block[i][scantable[0]] = x;
190 }
191
192 if (cbp & (1 << (5 - i))) {
193 ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
194 if (ret < 0)
195 return ret;
196 }
197 }
198
199 return 0;
200 }
201
202 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
203 {
204 IMM4Context *s = avctx->priv_data;
205 int ret, x, y, offset = 0;
206
207 if (s->hi == 0) {
208 if (s->lo > 2)
209 return AVERROR_INVALIDDATA;
210 s->factor = intra_cb[s->lo];
211 } else {
212 s->factor = s->lo * 2;
213 }
214
215 if (s->hi) {
216 offset = s->factor;
217 offset >>= 1;
218 if (!(offset & 1))
219 offset--;
220 }
221
222 for (y = 0; y < avctx->height; y += 16) {
223 for (x = 0; x < avctx->width; x += 16) {
224 unsigned flag, cbphi, cbplo;
225
226 cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1);
227 flag = get_bits1(gb);
228
229 cbphi = get_cbphi(gb, 1);
230
231 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
232 if (ret < 0)
233 return ret;
234
235 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
236 frame->linesize[0], s->block[0]);
237 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
238 frame->linesize[0], s->block[1]);
239 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
240 frame->linesize[0], s->block[2]);
241 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
242 frame->linesize[0], s->block[3]);
243 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
244 frame->linesize[1], s->block[4]);
245 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
246 frame->linesize[2], s->block[5]);
247 }
248 }
249
250 return 0;
251 }
252
253 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
254 AVFrame *frame, AVFrame *prev)
255 {
256 IMM4Context *s = avctx->priv_data;
257 int ret, x, y, offset = 0;
258
259 if (s->hi == 0) {
260 if (s->lo > 2)
261 return AVERROR_INVALIDDATA;
262 s->factor = inter_cb[s->lo];
263 } else {
264 s->factor = s->lo * 2;
265 }
266
267 if (s->hi) {
268 offset = s->factor;
269 offset >>= 1;
270 if (!(offset & 1))
271 offset--;
272 }
273
274 for (y = 0; y < avctx->height; y += 16) {
275 for (x = 0; x < avctx->width; x += 16) {
276 int reverse, intra_block, value;
277 unsigned cbphi, cbplo, flag2 = 0;
278
279 if (get_bits1(gb)) {
280 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
281 prev->data[0] + y * prev->linesize[0] + x,
282 frame->linesize[0], prev->linesize[0], 16);
283 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
284 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
285 frame->linesize[1], prev->linesize[1], 8);
286 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
287 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
288 frame->linesize[2], prev->linesize[2], 8);
289 continue;
290 }
291
292 value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1);
293 if (value < 0)
294 return AVERROR_INVALIDDATA;
295
296 intra_block = value & 0x07;
297 reverse = intra_block == 3;
298 if (reverse)
299 flag2 = get_bits1(gb);
300
301 cbplo = value >> 4;
302 cbphi = get_cbphi(gb, reverse);
303 if (intra_block) {
304 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
305 if (ret < 0)
306 return ret;
307
308 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
309 frame->linesize[0], s->block[0]);
310 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
311 frame->linesize[0], s->block[1]);
312 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
313 frame->linesize[0], s->block[2]);
314 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
315 frame->linesize[0], s->block[3]);
316 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
317 frame->linesize[1], s->block[4]);
318 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
319 frame->linesize[2], s->block[5]);
320 } else {
321 flag2 = get_bits1(gb);
322 skip_bits1(gb);
323 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
324 if (ret < 0)
325 return ret;
326
327 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
328 prev->data[0] + y * prev->linesize[0] + x,
329 frame->linesize[0], prev->linesize[0], 16);
330 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
331 prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
332 frame->linesize[1], prev->linesize[1], 8);
333 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
334 prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
335 frame->linesize[2], prev->linesize[2], 8);
336
337 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
338 frame->linesize[0], s->block[0]);
339 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
340 frame->linesize[0], s->block[1]);
341 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
342 frame->linesize[0], s->block[2]);
343 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
344 frame->linesize[0], s->block[3]);
345 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
346 frame->linesize[1], s->block[4]);
347 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
348 frame->linesize[2], s->block[5]);
349 }
350 }
351 }
352
353 return 0;
354 }
355
356 static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
357 int *got_frame, AVPacket *avpkt)
358 {
359 IMM4Context *s = avctx->priv_data;
360 GetBitContext *gb = &s->gb;
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 FFCodec ff_imm4_decoder = {
536 .p.name = "imm4",
537 .p.long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
538 .p.type = AVMEDIA_TYPE_VIDEO,
539 .p.id = AV_CODEC_ID_IMM4,
540 .priv_data_size = sizeof(IMM4Context),
541 .init = decode_init,
542 .close = decode_close,
543 FF_CODEC_DECODE_CB(decode_frame),
544 .flush = decode_flush,
545 .p.capabilities = AV_CODEC_CAP_DR1,
546 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
547 FF_CODEC_CAP_INIT_CLEANUP,
548 };
549