]> git.sesse.net Git - ffmpeg/blob - libavcodec/imm4.c
avcodec/imm4: add support for mid-stream size changes
[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 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
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
140 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
141                         int block, int factor, int flag, int offset)
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     return 0;
173 }
174
175 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
176                          unsigned cbp, int flag, int offset)
177 {
178     IMM4Context *s = avctx->priv_data;
179     const uint8_t *scantable = s->intra_scantable.permutated;
180     int ret, i;
181
182     memset(s->block, 0, sizeof(s->block));
183
184     for (i = 0; i < 6; i++) {
185         if (!flag) {
186             int x = get_bits(gb, 8);
187
188             if (x == 255)
189                 x = 128;
190             x *= 8;
191
192             s->block[i][scantable[0]] = x;
193         }
194
195         if (cbp & (1 << (5 - i))) {
196             ret = decode_block(avctx, gb, i, s->factor, flag, offset);
197             if (ret < 0)
198                 return ret;
199         }
200     }
201
202     return 0;
203 }
204
205 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
206 {
207     IMM4Context *s = avctx->priv_data;
208     int ret, x, y, offset = 0;
209
210     if (s->hi == 0) {
211         if (s->lo > 2)
212             return AVERROR_INVALIDDATA;
213         s->factor = intra_cb[s->lo];
214     } else {
215         if (s->hi == 1) {
216             s->factor = s->lo * 2;
217         } else {
218             s->factor = s->lo * 2;
219         }
220     }
221
222     if (s->hi) {
223         offset = s->factor;
224         offset >>= 1;
225         if (!(offset & 1))
226             offset--;
227     }
228
229     for (y = 0; y < avctx->height; y += 16) {
230         for (x = 0; x < avctx->width; x += 16) {
231             unsigned cbphi, cbplo;
232
233             cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
234             skip_bits1(gb);
235
236             cbphi = get_cbphi(gb, 1);
237
238             ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
239             if (ret < 0)
240                 return ret;
241
242             s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
243                              frame->linesize[0], s->block[0]);
244             s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
245                              frame->linesize[0], s->block[1]);
246             s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
247                              frame->linesize[0], s->block[2]);
248             s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
249                              frame->linesize[0], s->block[3]);
250             s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
251                              frame->linesize[1], s->block[4]);
252             s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
253                              frame->linesize[2], s->block[5]);
254         }
255     }
256
257     return 0;
258 }
259
260 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
261                         AVFrame *frame, AVFrame *prev)
262 {
263     IMM4Context *s = avctx->priv_data;
264     int ret, x, y, offset = 0;
265
266     if (s->hi == 0) {
267         if (s->lo > 2)
268             return AVERROR_INVALIDDATA;
269         s->factor = inter_cb[s->lo];
270     } else {
271         if (s->hi == 1) {
272             s->factor = s->lo * 2;
273         } else {
274             s->factor = s->lo * 2;
275         }
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;
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                 skip_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);
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                 skip_bits(gb, 2);
333                 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset);
334                 if (ret < 0)
335                     return ret;
336
337                 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
338                              prev->data[0] + y * prev->linesize[0] + x,
339                              frame->linesize[0], prev->linesize[0], 16);
340                 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
341                             prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
342                             frame->linesize[1], prev->linesize[1], 8);
343                 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
344                             prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
345                             frame->linesize[2], prev->linesize[2], 8);
346
347                 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
348                                  frame->linesize[0], s->block[0]);
349                 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
350                                  frame->linesize[0], s->block[1]);
351                 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
352                                  frame->linesize[0], s->block[2]);
353                 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
354                                  frame->linesize[0], s->block[3]);
355                 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
356                                  frame->linesize[1], s->block[4]);
357                 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
358                                  frame->linesize[2], s->block[5]);
359             }
360         }
361     }
362
363     return 0;
364 }
365
366 static int decode_frame(AVCodecContext *avctx, void *data,
367                         int *got_frame, AVPacket *avpkt)
368 {
369     IMM4Context *s = avctx->priv_data;
370     GetBitContext *gb = &s->gb;
371     AVFrame *frame = data;
372     int width, height;
373     unsigned type;
374     int ret, scaled;
375
376     if (avpkt->size <= 32)
377         return AVERROR_INVALIDDATA;
378
379     av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
380                           FFALIGN(avpkt->size, 4));
381     if (!s->bitstream)
382         return AVERROR(ENOMEM);
383
384     s->bdsp.bswap_buf((uint32_t *)s->bitstream,
385                       (uint32_t *)avpkt->data,
386                       (avpkt->size + 3) >> 2);
387
388     if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
389         return ret;
390
391     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
392     avctx->color_range = AVCOL_RANGE_JPEG;
393
394     width = avctx->width;
395     height = avctx->height;
396
397     scaled = avpkt->data[8];
398     if (scaled < 2) {
399         int mode = avpkt->data[10];
400
401         switch (mode) {
402         case 1:
403             width = 352;
404             height = 240;
405             break;
406         case 2:
407             width = 704;
408             height = 240;
409             break;
410         case 4:
411             width = 480;
412             height = 704;
413             break;
414         case 17:
415             width = 352;
416             height = 288;
417             break;
418         case 18:
419             width = 704;
420             height = 288;
421             break;
422         default:
423             width = 704;
424             height = 576;
425             break;
426         }
427     }
428
429     skip_bits_long(gb, 24 * 8);
430     type = get_bits_long(gb, 32);
431     s->hi = get_bits(gb, 16);
432     s->lo = get_bits(gb, 16);
433
434     switch (type) {
435     case 0x19781977:
436         frame->key_frame = 1;
437         frame->pict_type = AV_PICTURE_TYPE_I;
438         break;
439     case 0x12250926:
440         frame->key_frame = 0;
441         frame->pict_type = AV_PICTURE_TYPE_P;
442         break;
443     default:
444         avpriv_request_sample(avctx, "type %X", type);
445         return AVERROR_PATCHWELCOME;
446     }
447
448     if (!frame->key_frame &&
449         (avctx->width != width ||
450          avctx->height != height)) {
451         av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
452         return AVERROR_INVALIDDATA;
453     }
454
455     ret = ff_set_dimensions(avctx, width, height);
456     if (ret < 0)
457         return ret;
458
459     if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
460         return ret;
461
462     if (frame->key_frame) {
463         ret = decode_intra(avctx, gb, frame);
464         if (ret < 0)
465             return ret;
466
467         av_frame_unref(s->prev_frame);
468         if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
469             return ret;
470     } else {
471         if (!s->prev_frame->data[0]) {
472             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
473             return AVERROR_INVALIDDATA;
474         }
475
476         ret = decode_inter(avctx, gb, frame, s->prev_frame);
477         if (ret < 0)
478             return ret;
479     }
480
481     *got_frame = 1;
482
483     return avpkt->size;
484 }
485
486 static av_cold void imm4_init_static_data(void)
487 {
488     INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
489                            cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
490
491     INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
492                            cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
493
494     INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
495                            blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
496
497     INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
498                            block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
499 }
500
501 static av_cold int decode_init(AVCodecContext *avctx)
502 {
503     static AVOnce init_static_once = AV_ONCE_INIT;
504     IMM4Context *s = avctx->priv_data;
505     uint8_t table[64];
506
507     for (int i = 0; i < 64; i++)
508         table[i] = i;
509
510     ff_bswapdsp_init(&s->bdsp);
511     ff_idctdsp_init(&s->idsp, avctx);
512     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
513
514     s->prev_frame = av_frame_alloc();
515     if (!s->prev_frame)
516         return AVERROR(ENOMEM);
517
518     ff_thread_once(&init_static_once, imm4_init_static_data);
519
520     return 0;
521 }
522
523 static av_cold int decode_close(AVCodecContext *avctx)
524 {
525     IMM4Context *s = avctx->priv_data;
526
527     av_frame_free(&s->prev_frame);
528     av_freep(&s->bitstream);
529     s->bitstream_size = 0;
530
531     return 0;
532 }
533
534 AVCodec ff_imm4_decoder = {
535     .name             = "imm4",
536     .long_name        = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
537     .type             = AVMEDIA_TYPE_VIDEO,
538     .id               = AV_CODEC_ID_IMM4,
539     .priv_data_size   = sizeof(IMM4Context),
540     .init             = decode_init,
541     .close            = decode_close,
542     .decode           = decode_frame,
543     .capabilities     = AV_CODEC_CAP_DR1,
544     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
545                         FF_CODEC_CAP_INIT_CLEANUP,
546 };