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