• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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