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