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