xref: /third_party/ffmpeg/libavcodec/imm4.c (revision cabdff1a)
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/mem_internal.h"
28#include "libavutil/thread.h"
29
30#include "avcodec.h"
31#include "bswapdsp.h"
32#include "codec_internal.h"
33#include "copy_block.h"
34#include "get_bits.h"
35#include "idctdsp.h"
36#include "internal.h"
37
38#define CBPLO_VLC_BITS   6
39#define CBPHI_VLC_BITS   6
40#define BLKTYPE_VLC_BITS 9
41#define BLOCK_VLC_BITS  12
42
43typedef struct IMM4Context {
44    BswapDSPContext bdsp;
45    GetBitContext  gb;
46
47    AVFrame *prev_frame;
48    uint8_t *bitstream;
49    int bitstream_size;
50
51    int factor;
52    unsigned lo;
53    unsigned hi;
54
55    ScanTable intra_scantable;
56    DECLARE_ALIGNED(32, int16_t, block)[6][64];
57    IDCTDSPContext idsp;
58} IMM4Context;
59
60static const uint8_t intra_cb[] = {
61    24, 18, 12
62};
63
64static const uint8_t inter_cb[] = {
65    30, 20, 15
66};
67
68static const uint8_t cbplo[][2] = {
69    {    0,-6 }, { 0x01, 6 }, { 0x02, 6 }, { 0x03, 6 }, { 0x00, 4 },
70    { 0x01, 3 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 },
71};
72
73static const uint8_t cbphi_bits[] = {
74    4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
75};
76
77static const uint8_t cbphi_codes[] = {
78    3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
79};
80
81static const uint8_t blktype[][2] = {
82    {    0,-8 }, { 0x34, 9 }, {    0,-9 }, { 0x14, 9 }, {    0,-9 },
83    { 0x23, 8 }, { 0x13, 8 }, { 0x32, 8 }, { 0x33, 7 }, { 0x22, 7 },
84    { 0x12, 7 }, { 0x21, 7 }, { 0x11, 7 }, { 0x04, 6 }, { 0x30, 6 },
85    { 0x03, 5 }, { 0x20, 4 }, { 0x10, 4 }, { 0x02, 3 }, { 0x01, 3 },
86    { 0x00, 1 },
87};
88
89static const uint16_t block_symbols[] = {
90         0, 0x4082, 0x4003, 0x000B, 0x000A, 0x4E01, 0x4D81, 0x4D01, 0x4C81,
91    0x0482, 0x0402, 0x0382, 0x0302, 0x0282, 0x0183, 0x0103, 0x0084, 0x000C,
92    0x0085, 0x0B81, 0x0C01, 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x0086, 0x0104,
93    0x0203, 0x0283, 0x0303, 0x0502, 0x0C81, 0x0D01, 0x5081, 0x5101, 0x5181,
94    0x5201, 0x5281, 0x5301, 0x5381, 0x5401, 0x0000, 0x0009, 0x0008, 0x4C01,
95    0x4B81, 0x4B01, 0x4A81, 0x4A01, 0x4981, 0x4901, 0x4881, 0x4002, 0x0B01,
96    0x0A81, 0x0A01, 0x0981, 0x0901, 0x0881, 0x0801, 0x0781, 0x0202, 0x0182,
97    0x0007, 0x0006, 0x4801, 0x4781, 0x4701, 0x4681, 0x4601, 0x4581, 0x4501,
98    0x4481, 0x0701, 0x0681, 0x0102, 0x0083, 0x0005, 0x4401, 0x4381, 0x4301,
99    0x4281, 0x0601, 0x0581, 0x0501, 0x0004, 0x4201, 0x4181, 0x4101, 0x4081,
100    0x0481, 0x0401, 0x0381, 0x0301, 0x0082, 0x0003, 0x0281, 0x0201, 0x0181,
101    0x4001, 0x0001, 0x0081, 0x0101, 0x0002,
102};
103
104static const uint8_t block_bits[] = {
105    -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
106    11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
107    12, 12, 12,  7, 10, 10,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
108     9,  9,  9,  9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
109     8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,
110     6,  5,  5,  5,  4,  2,  3,  4,  4,
111};
112
113static VLC cbplo_tab;
114static VLC cbphi_tab;
115static VLC blktype_tab;
116static VLC block_tab;
117
118static int get_cbphi(GetBitContext *gb, int x)
119{
120    int value;
121
122    value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1);
123    if (value < 0)
124        return AVERROR_INVALIDDATA;
125
126    return x ? value : 15 - value;
127}
128
129static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
130                        int block, int factor, int flag, int offset, int flag2)
131{
132    IMM4Context *s = avctx->priv_data;
133    const uint8_t *scantable = s->intra_scantable.permutated;
134    int i, last, len, factor2;
135
136    for (i = !flag; i < 64; i++) {
137        int value;
138
139        value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1);
140        if (value < 0)
141            return AVERROR_INVALIDDATA;
142        if (value == 0) {
143            last = get_bits1(gb);
144            len = get_bits(gb, 6);
145            factor2 = get_sbits(gb, 8);
146        } else {
147            factor2 = value & 0x7F;
148            last = (value >> 14) & 1;
149            len = (value >> 7) & 0x3F;
150            if (get_bits1(gb))
151                factor2 = -factor2;
152        }
153        i += len;
154        if (i >= 64)
155            break;
156        s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
157        if (last)
158            break;
159    }
160
161    if (s->hi == 2 && flag2 && block < 4) {
162        if (flag)
163            s->block[block][scantable[0]]  *= 2;
164        s->block[block][scantable[1]]  *= 2;
165        s->block[block][scantable[8]]  *= 2;
166        s->block[block][scantable[16]] *= 2;
167    }
168
169    return 0;
170}
171
172static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
173                         unsigned cbp, int flag, int offset, unsigned flag2)
174{
175    IMM4Context *s = avctx->priv_data;
176    const uint8_t *scantable = s->intra_scantable.permutated;
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][scantable[0]] = x;
190        }
191
192        if (cbp & (1 << (5 - i))) {
193            ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
194            if (ret < 0)
195                return ret;
196        }
197    }
198
199    return 0;
200}
201
202static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
203{
204    IMM4Context *s = avctx->priv_data;
205    int ret, x, y, offset = 0;
206
207    if (s->hi == 0) {
208        if (s->lo > 2)
209            return AVERROR_INVALIDDATA;
210        s->factor = intra_cb[s->lo];
211    } else {
212        s->factor = s->lo * 2;
213    }
214
215    if (s->hi) {
216        offset = s->factor;
217        offset >>= 1;
218        if (!(offset & 1))
219            offset--;
220    }
221
222    for (y = 0; y < avctx->height; y += 16) {
223        for (x = 0; x < avctx->width; x += 16) {
224            unsigned flag, cbphi, cbplo;
225
226            cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1);
227            flag = get_bits1(gb);
228
229            cbphi = get_cbphi(gb, 1);
230
231            ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
232            if (ret < 0)
233                return ret;
234
235            s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
236                             frame->linesize[0], s->block[0]);
237            s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
238                             frame->linesize[0], s->block[1]);
239            s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
240                             frame->linesize[0], s->block[2]);
241            s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
242                             frame->linesize[0], s->block[3]);
243            s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
244                             frame->linesize[1], s->block[4]);
245            s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
246                             frame->linesize[2], s->block[5]);
247        }
248    }
249
250    return 0;
251}
252
253static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
254                        AVFrame *frame, AVFrame *prev)
255{
256    IMM4Context *s = avctx->priv_data;
257    int ret, x, y, offset = 0;
258
259    if (s->hi == 0) {
260        if (s->lo > 2)
261            return AVERROR_INVALIDDATA;
262        s->factor = inter_cb[s->lo];
263    } else {
264        s->factor = s->lo * 2;
265    }
266
267    if (s->hi) {
268        offset = s->factor;
269        offset >>= 1;
270        if (!(offset & 1))
271            offset--;
272    }
273
274    for (y = 0; y < avctx->height; y += 16) {
275        for (x = 0; x < avctx->width; x += 16) {
276            int reverse, intra_block, value;
277            unsigned cbphi, cbplo, flag2 = 0;
278
279            if (get_bits1(gb)) {
280                copy_block16(frame->data[0] + y * frame->linesize[0] + x,
281                             prev->data[0] + y * prev->linesize[0] + x,
282                             frame->linesize[0], prev->linesize[0], 16);
283                copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
284                            prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
285                            frame->linesize[1], prev->linesize[1], 8);
286                copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
287                            prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
288                            frame->linesize[2], prev->linesize[2], 8);
289                continue;
290            }
291
292            value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1);
293            if (value < 0)
294                return AVERROR_INVALIDDATA;
295
296            intra_block = value & 0x07;
297            reverse = intra_block == 3;
298            if (reverse)
299                flag2 = get_bits1(gb);
300
301            cbplo = value >> 4;
302            cbphi = get_cbphi(gb, reverse);
303            if (intra_block) {
304                ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
305                if (ret < 0)
306                    return ret;
307
308                s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
309                                 frame->linesize[0], s->block[0]);
310                s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
311                                 frame->linesize[0], s->block[1]);
312                s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
313                                 frame->linesize[0], s->block[2]);
314                s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
315                                 frame->linesize[0], s->block[3]);
316                s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
317                                 frame->linesize[1], s->block[4]);
318                s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
319                                 frame->linesize[2], s->block[5]);
320            } else {
321                flag2 = get_bits1(gb);
322                skip_bits1(gb);
323                ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
324                if (ret < 0)
325                    return ret;
326
327                copy_block16(frame->data[0] + y * frame->linesize[0] + x,
328                             prev->data[0] + y * prev->linesize[0] + x,
329                             frame->linesize[0], prev->linesize[0], 16);
330                copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
331                            prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
332                            frame->linesize[1], prev->linesize[1], 8);
333                copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
334                            prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
335                            frame->linesize[2], prev->linesize[2], 8);
336
337                s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
338                                 frame->linesize[0], s->block[0]);
339                s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
340                                 frame->linesize[0], s->block[1]);
341                s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
342                                 frame->linesize[0], s->block[2]);
343                s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
344                                 frame->linesize[0], s->block[3]);
345                s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
346                                 frame->linesize[1], s->block[4]);
347                s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
348                                 frame->linesize[2], s->block[5]);
349            }
350        }
351    }
352
353    return 0;
354}
355
356static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
357                        int *got_frame, AVPacket *avpkt)
358{
359    IMM4Context *s = avctx->priv_data;
360    GetBitContext *gb = &s->gb;
361    int width, height;
362    unsigned type;
363    int ret, scaled;
364
365    if (avpkt->size <= 32)
366        return AVERROR_INVALIDDATA;
367
368    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
369                          FFALIGN(avpkt->size, 4));
370    if (!s->bitstream)
371        return AVERROR(ENOMEM);
372
373    s->bdsp.bswap_buf((uint32_t *)s->bitstream,
374                      (uint32_t *)avpkt->data,
375                      (avpkt->size + 3) >> 2);
376
377    if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
378        return ret;
379
380    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
381    avctx->color_range = AVCOL_RANGE_JPEG;
382
383    width = avctx->width;
384    height = avctx->height;
385
386    scaled = avpkt->data[8];
387    if (scaled < 2) {
388        int mode = avpkt->data[10];
389
390        switch (mode) {
391        case 1:
392            width = 352;
393            height = 240;
394            break;
395        case 2:
396            width = 704;
397            height = 240;
398            break;
399        case 4:
400            width = 480;
401            height = 704;
402            break;
403        case 17:
404            width = 352;
405            height = 288;
406            break;
407        case 18:
408            width = 704;
409            height = 288;
410            break;
411        default:
412            width = 704;
413            height = 576;
414            break;
415        }
416    }
417
418    skip_bits_long(gb, 24 * 8);
419    type = get_bits_long(gb, 32);
420    s->hi = get_bits(gb, 16);
421    s->lo = get_bits(gb, 16);
422
423    switch (type) {
424    case 0x19781977:
425        frame->key_frame = 1;
426        frame->pict_type = AV_PICTURE_TYPE_I;
427        break;
428    case 0x12250926:
429        frame->key_frame = 0;
430        frame->pict_type = AV_PICTURE_TYPE_P;
431        break;
432    default:
433        avpriv_request_sample(avctx, "type %X", type);
434        return AVERROR_PATCHWELCOME;
435    }
436
437    if (avctx->width  != width ||
438        avctx->height != height) {
439        if (!frame->key_frame) {
440            av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
441            return AVERROR_INVALIDDATA;
442        }
443        av_frame_unref(s->prev_frame);
444    }
445
446    ret = ff_set_dimensions(avctx, width, height);
447    if (ret < 0)
448        return ret;
449
450    if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
451        return ret;
452
453    if (frame->key_frame) {
454        ret = decode_intra(avctx, gb, frame);
455        if (ret < 0)
456            return ret;
457
458        av_frame_unref(s->prev_frame);
459        if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
460            return ret;
461    } else {
462        if (!s->prev_frame->data[0]) {
463            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
464            return AVERROR_INVALIDDATA;
465        }
466
467        ret = decode_inter(avctx, gb, frame, s->prev_frame);
468        if (ret < 0)
469            return ret;
470    }
471
472    *got_frame = 1;
473
474    return avpkt->size;
475}
476
477static av_cold void imm4_init_static_data(void)
478{
479    INIT_VLC_STATIC_FROM_LENGTHS(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo),
480                                 &cbplo[0][1], 2, &cbplo[0][0], 2, 1,
481                                 0, 0, 1 << CBPLO_VLC_BITS);
482
483    INIT_VLC_SPARSE_STATIC(&cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits),
484                           cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
485
486    INIT_VLC_STATIC_FROM_LENGTHS(&blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype),
487                                 &blktype[0][1], 2, &blktype[0][0], 2, 1,
488                                 0, 0, 1 << BLKTYPE_VLC_BITS);
489
490    INIT_VLC_STATIC_FROM_LENGTHS(&block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits),
491                                 block_bits, 1, block_symbols, 2, 2,
492                                 0, 0, 1 << BLOCK_VLC_BITS);
493}
494
495static av_cold int decode_init(AVCodecContext *avctx)
496{
497    static AVOnce init_static_once = AV_ONCE_INIT;
498    IMM4Context *s = avctx->priv_data;
499    uint8_t table[64];
500
501    for (int i = 0; i < 64; i++)
502        table[i] = i;
503
504    ff_bswapdsp_init(&s->bdsp);
505    ff_idctdsp_init(&s->idsp, avctx);
506    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
507
508    s->prev_frame = av_frame_alloc();
509    if (!s->prev_frame)
510        return AVERROR(ENOMEM);
511
512    ff_thread_once(&init_static_once, imm4_init_static_data);
513
514    return 0;
515}
516
517static void decode_flush(AVCodecContext *avctx)
518{
519    IMM4Context *s = avctx->priv_data;
520
521    av_frame_unref(s->prev_frame);
522}
523
524static av_cold int decode_close(AVCodecContext *avctx)
525{
526    IMM4Context *s = avctx->priv_data;
527
528    av_frame_free(&s->prev_frame);
529    av_freep(&s->bitstream);
530    s->bitstream_size = 0;
531
532    return 0;
533}
534
535const FFCodec ff_imm4_decoder = {
536    .p.name           = "imm4",
537    .p.long_name      = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
538    .p.type           = AVMEDIA_TYPE_VIDEO,
539    .p.id             = AV_CODEC_ID_IMM4,
540    .priv_data_size   = sizeof(IMM4Context),
541    .init             = decode_init,
542    .close            = decode_close,
543    FF_CODEC_DECODE_CB(decode_frame),
544    .flush            = decode_flush,
545    .p.capabilities   = AV_CODEC_CAP_DR1,
546    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
547                        FF_CODEC_CAP_INIT_CLEANUP,
548};
549