]> git.sesse.net Git - ffmpeg/blob - libavcodec/imm4.c
avcodec/imm4: stop using FAAN idct
[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     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)
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]] = 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)
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);
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;
209
210     s->factor = intra_cb[s->sindex];
211
212     for (y = 0; y < avctx->height; y += 16) {
213         for (x = 0; x < avctx->width; x += 16) {
214             unsigned cbphi, cbplo;
215
216             cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
217             skip_bits1(gb);
218
219             cbphi = get_cbphi(gb, 1);
220
221             ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0);
222             if (ret < 0)
223                 return ret;
224
225             s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
226                              frame->linesize[0], s->block[0]);
227             s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
228                              frame->linesize[0], s->block[1]);
229             s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
230                              frame->linesize[0], s->block[2]);
231             s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
232                              frame->linesize[0], s->block[3]);
233             s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
234                              frame->linesize[1], s->block[4]);
235             s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
236                              frame->linesize[2], s->block[5]);
237         }
238     }
239
240     return 0;
241 }
242
243 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
244                         AVFrame *frame, AVFrame *prev)
245 {
246     IMM4Context *s = avctx->priv_data;
247     int ret, x, y;
248
249     s->factor = inter_cb[s->sindex];
250
251     for (y = 0; y < avctx->height; y += 16) {
252         for (x = 0; x < avctx->width; x += 16) {
253             int reverse, intra_block, value;
254             unsigned cbphi, cbplo;
255
256             if (get_bits1(gb)) {
257                 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
258                              prev->data[0] + y * prev->linesize[0] + x,
259                              frame->linesize[0], prev->linesize[0], 16);
260                 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
261                             prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
262                             frame->linesize[1], prev->linesize[1], 8);
263                 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
264                             prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
265                             frame->linesize[2], prev->linesize[2], 8);
266                 continue;
267             }
268
269             value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
270             if (value < 0)
271                 return AVERROR_INVALIDDATA;
272
273             intra_block = value & 0x07;
274             reverse = intra_block == 3;
275             if (reverse)
276                 skip_bits1(gb);
277
278             cbplo = value >> 4;
279             cbphi = get_cbphi(gb, reverse);
280             if (intra_block) {
281                 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0);
282                 if (ret < 0)
283                     return ret;
284
285                 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
286                                  frame->linesize[0], s->block[0]);
287                 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
288                                  frame->linesize[0], s->block[1]);
289                 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
290                                  frame->linesize[0], s->block[2]);
291                 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
292                                  frame->linesize[0], s->block[3]);
293                 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
294                                  frame->linesize[1], s->block[4]);
295                 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
296                                  frame->linesize[2], s->block[5]);
297             } else {
298                 skip_bits(gb, 2);
299                 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1);
300                 if (ret < 0)
301                     return ret;
302
303                 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
304                              prev->data[0] + y * prev->linesize[0] + x,
305                              frame->linesize[0], prev->linesize[0], 16);
306                 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
307                             prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
308                             frame->linesize[1], prev->linesize[1], 8);
309                 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
310                             prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
311                             frame->linesize[2], prev->linesize[2], 8);
312
313                 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
314                                  frame->linesize[0], s->block[0]);
315                 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
316                                  frame->linesize[0], s->block[1]);
317                 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
318                                  frame->linesize[0], s->block[2]);
319                 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
320                                  frame->linesize[0], s->block[3]);
321                 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
322                                  frame->linesize[1], s->block[4]);
323                 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
324                                  frame->linesize[2], s->block[5]);
325             }
326         }
327     }
328
329     return 0;
330 }
331
332 static int decode_frame(AVCodecContext *avctx, void *data,
333                         int *got_frame, AVPacket *avpkt)
334 {
335     IMM4Context *s = avctx->priv_data;
336     GetBitContext *gb = &s->gb;
337     AVFrame *frame = data;
338     unsigned type;
339     int ret, scaled;
340
341     if (avpkt->size <= 32)
342         return AVERROR_INVALIDDATA;
343
344     av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
345                           FFALIGN(avpkt->size, 4));
346     if (!s->bitstream)
347         return AVERROR(ENOMEM);
348
349     s->bdsp.bswap_buf((uint32_t *)s->bitstream,
350                       (uint32_t *)avpkt->data,
351                       (avpkt->size + 3) >> 2);
352
353     if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
354         return ret;
355
356     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
357     avctx->color_range = AVCOL_RANGE_JPEG;
358
359     scaled = avpkt->data[8];
360     if (scaled < 2) {
361         int width, height;
362         int mode = avpkt->data[10];
363
364         switch (mode) {
365         case 1:
366             width = 352;
367             height = 240;
368             break;
369         case 2:
370             width = 704;
371             height = 240;
372             break;
373         case 4:
374             width = 480;
375             height = 704;
376             break;
377         case 17:
378             width = 352;
379             height = 288;
380             break;
381         case 18:
382             width = 704;
383             height = 288;
384             break;
385         default:
386             width = 704;
387             height = 576;
388             break;
389         }
390
391         if (s->changed_size == 1 &&
392             (avctx->width != width || avctx->height != height)) {
393             av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
394             return AVERROR_INVALIDDATA;
395         }
396         avctx->width = width;
397         avctx->height = height;
398     }
399
400     s->changed_size = 1;
401     skip_bits_long(gb, 24 * 8);
402     type = get_bits_long(gb, 32);
403     skip_bits(gb, 16);
404     s->sindex = get_bits(gb, 16);
405     s->sindex = FFMIN(s->sindex, 2);
406
407     switch (type) {
408     case 0x19781977:
409         frame->key_frame = 1;
410         frame->pict_type = AV_PICTURE_TYPE_I;
411         break;
412     case 0x12250926:
413         frame->key_frame = 0;
414         frame->pict_type = AV_PICTURE_TYPE_P;
415         break;
416     default:
417         avpriv_request_sample(avctx, "type %X", type);
418         return AVERROR_PATCHWELCOME;
419     }
420
421     if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
422         return ret;
423
424     if (frame->key_frame) {
425         ret = decode_intra(avctx, gb, frame);
426         if (ret < 0)
427             return ret;
428
429         av_frame_unref(s->prev_frame);
430         if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
431             return ret;
432     } else {
433         if (!s->prev_frame->data[0]) {
434             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
435             return AVERROR_INVALIDDATA;
436         }
437
438         ret = decode_inter(avctx, gb, frame, s->prev_frame);
439         if (ret < 0)
440             return ret;
441     }
442
443     *got_frame = 1;
444
445     return avpkt->size;
446 }
447
448 static av_cold void imm4_init_static_data(void)
449 {
450     INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
451                            cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
452
453     INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
454                            cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
455
456     INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
457                            blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
458
459     INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
460                            block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
461 }
462
463 static av_cold int decode_init(AVCodecContext *avctx)
464 {
465     static AVOnce init_static_once = AV_ONCE_INIT;
466     IMM4Context *s = avctx->priv_data;
467     uint8_t table[64];
468
469     for (int i = 0; i < 64; i++)
470         table[i] = i;
471
472     ff_bswapdsp_init(&s->bdsp);
473     ff_idctdsp_init(&s->idsp, avctx);
474     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
475
476     s->prev_frame = av_frame_alloc();
477     if (!s->prev_frame)
478         return AVERROR(ENOMEM);
479
480     ff_thread_once(&init_static_once, imm4_init_static_data);
481
482     return 0;
483 }
484
485 static av_cold int decode_close(AVCodecContext *avctx)
486 {
487     IMM4Context *s = avctx->priv_data;
488
489     av_frame_free(&s->prev_frame);
490     av_freep(&s->bitstream);
491     s->bitstream_size = 0;
492
493     return 0;
494 }
495
496 AVCodec ff_imm4_decoder = {
497     .name             = "imm4",
498     .long_name        = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
499     .type             = AVMEDIA_TYPE_VIDEO,
500     .id               = AV_CODEC_ID_IMM4,
501     .priv_data_size   = sizeof(IMM4Context),
502     .init             = decode_init,
503     .close            = decode_close,
504     .decode           = decode_frame,
505     .capabilities     = AV_CODEC_CAP_DR1,
506     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
507                         FF_CODEC_CAP_INIT_CLEANUP,
508 };