xref: /third_party/ffmpeg/libavcodec/escape130.c (revision cabdff1a)
1/*
2 * Escape 130 video decoder
3 * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/attributes.h"
23#include "libavutil/mem.h"
24
25#define BITSTREAM_READER_LE
26#include "avcodec.h"
27#include "codec_internal.h"
28#include "get_bits.h"
29#include "internal.h"
30
31typedef struct Escape130Context {
32    uint8_t *old_y_avg;
33
34    uint8_t *new_y, *old_y;
35    uint8_t *new_u, *old_u;
36    uint8_t *new_v, *old_v;
37
38    uint8_t *buf1, *buf2;
39    int     linesize[3];
40} Escape130Context;
41
42static const uint8_t offset_table[] = { 2, 4, 10, 20 };
43static const int8_t sign_table[64][4] = {
44    {  0,  0,  0,  0 },
45    { -1,  1,  0,  0 },
46    {  1, -1,  0,  0 },
47    { -1,  0,  1,  0 },
48    { -1,  1,  1,  0 },
49    {  0, -1,  1,  0 },
50    {  1, -1,  1,  0 },
51    { -1, -1,  1,  0 },
52    {  1,  0, -1,  0 },
53    {  0,  1, -1,  0 },
54    {  1,  1, -1,  0 },
55    { -1,  1, -1,  0 },
56    {  1, -1, -1,  0 },
57    { -1,  0,  0,  1 },
58    { -1,  1,  0,  1 },
59    {  0, -1,  0,  1 },
60
61    {  0,  0,  0,  0 },
62    {  1, -1,  0,  1 },
63    { -1, -1,  0,  1 },
64    { -1,  0,  1,  1 },
65    { -1,  1,  1,  1 },
66    {  0, -1,  1,  1 },
67    {  1, -1,  1,  1 },
68    { -1, -1,  1,  1 },
69    {  0,  0, -1,  1 },
70    {  1,  0, -1,  1 },
71    { -1,  0, -1,  1 },
72    {  0,  1, -1,  1 },
73    {  1,  1, -1,  1 },
74    { -1,  1, -1,  1 },
75    {  0, -1, -1,  1 },
76    {  1, -1, -1,  1 },
77
78    {  0,  0,  0,  0 },
79    { -1, -1, -1,  1 },
80    {  1,  0,  0, -1 },
81    {  0,  1,  0, -1 },
82    {  1,  1,  0, -1 },
83    { -1,  1,  0, -1 },
84    {  1, -1,  0, -1 },
85    {  0,  0,  1, -1 },
86    {  1,  0,  1, -1 },
87    { -1,  0,  1, -1 },
88    {  0,  1,  1, -1 },
89    {  1,  1,  1, -1 },
90    { -1,  1,  1, -1 },
91    {  0, -1,  1, -1 },
92    {  1, -1,  1, -1 },
93    { -1, -1,  1, -1 },
94
95    {  0,  0,  0,  0 },
96    {  1,  0, -1, -1 },
97    {  0,  1, -1, -1 },
98    {  1,  1, -1, -1 },
99    { -1,  1, -1, -1 },
100    {  1, -1, -1, -1 }
101};
102
103static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
104
105static const int8_t chroma_adjust[2][8] = {
106    { 1, 1, 0, -1, -1, -1,  0,  1 },
107    { 0, 1, 1,  1,  0, -1, -1, -1 }
108};
109
110static const uint8_t chroma_vals[] = {
111     20,  28,  36,  44,  52,  60,  68,  76,
112     84,  92, 100, 106, 112, 116, 120, 124,
113    128, 132, 136, 140, 144, 150, 156, 164,
114    172, 180, 188, 196, 204, 212, 220, 228
115};
116
117static av_cold int escape130_decode_init(AVCodecContext *avctx)
118{
119    Escape130Context *s = avctx->priv_data;
120    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
121
122    if ((avctx->width & 1) || (avctx->height & 1)) {
123        av_log(avctx, AV_LOG_ERROR,
124               "Dimensions should be a multiple of two.\n");
125        return AVERROR_INVALIDDATA;
126    }
127
128    s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
129    s->buf1      = av_malloc(avctx->width * avctx->height * 3 / 2);
130    s->buf2      = av_malloc(avctx->width * avctx->height * 3 / 2);
131    if (!s->old_y_avg || !s->buf1 || !s->buf2) {
132        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
133        return AVERROR(ENOMEM);
134    }
135
136    s->linesize[0] = avctx->width;
137    s->linesize[1] =
138    s->linesize[2] = avctx->width / 2;
139
140    s->new_y = s->buf1;
141    s->new_u = s->new_y + avctx->width * avctx->height;
142    s->new_v = s->new_u + avctx->width * avctx->height / 4;
143    s->old_y = s->buf2;
144    s->old_u = s->old_y + avctx->width * avctx->height;
145    s->old_v = s->old_u + avctx->width * avctx->height / 4;
146    memset(s->old_y, 0,    avctx->width * avctx->height);
147    memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
148    memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
149
150    return 0;
151}
152
153static av_cold int escape130_decode_close(AVCodecContext *avctx)
154{
155    Escape130Context *s = avctx->priv_data;
156
157    av_freep(&s->old_y_avg);
158    av_freep(&s->buf1);
159    av_freep(&s->buf2);
160
161    return 0;
162}
163
164static int decode_skip_count(GetBitContext* gb)
165{
166    int value;
167
168    if (get_bits_left(gb) < 1+3)
169        return -1;
170
171    value = get_bits1(gb);
172    if (value)
173        return 0;
174
175    value = get_bits(gb, 3);
176    if (value)
177        return value;
178
179    value = get_bits(gb, 8);
180    if (value)
181        return value + 7;
182
183    value = get_bits(gb, 15);
184    if (value)
185        return value + 262;
186
187    return -1;
188}
189
190static int escape130_decode_frame(AVCodecContext *avctx, AVFrame *pic,
191                                  int *got_frame, AVPacket *avpkt)
192{
193    int buf_size        = avpkt->size;
194    Escape130Context *s = avctx->priv_data;
195    GetBitContext gb;
196    int ret;
197
198    uint8_t *old_y, *old_cb, *old_cr,
199            *new_y, *new_cb, *new_cr;
200    uint8_t *dstY, *dstU, *dstV;
201    unsigned old_y_stride, old_cb_stride, old_cr_stride,
202             new_y_stride, new_cb_stride, new_cr_stride;
203    unsigned total_blocks = avctx->width * avctx->height / 4,
204             block_index, block_x = 0;
205    unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
206    int skip = -1, y_avg = 0, i, j;
207    uint8_t *ya = s->old_y_avg;
208
209    // first 16 bytes are header; no useful information in here
210    if (buf_size <= 16) {
211        av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
212        return AVERROR_INVALIDDATA;
213    }
214
215    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
216        return ret;
217
218    if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
219        return ret;
220    skip_bits_long(&gb, 16 * 8);
221
222    new_y  = s->new_y;
223    new_cb = s->new_u;
224    new_cr = s->new_v;
225    new_y_stride  = s->linesize[0];
226    new_cb_stride = s->linesize[1];
227    new_cr_stride = s->linesize[2];
228    old_y  = s->old_y;
229    old_cb = s->old_u;
230    old_cr = s->old_v;
231    old_y_stride  = s->linesize[0];
232    old_cb_stride = s->linesize[1];
233    old_cr_stride = s->linesize[2];
234
235    for (block_index = 0; block_index < total_blocks; block_index++) {
236        // Note that this call will make us skip the rest of the blocks
237        // if the frame ends prematurely.
238        if (skip == -1)
239            skip = decode_skip_count(&gb);
240        if (skip == -1) {
241            av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
242            return AVERROR_INVALIDDATA;
243        }
244
245        if (skip) {
246            y[0] = old_y[0];
247            y[1] = old_y[1];
248            y[2] = old_y[old_y_stride];
249            y[3] = old_y[old_y_stride + 1];
250            y_avg = ya[0];
251            cb = old_cb[0];
252            cr = old_cr[0];
253        } else {
254            if (get_bits1(&gb)) {
255                unsigned sign_selector       = get_bits(&gb, 6);
256                unsigned difference_selector = get_bits(&gb, 2);
257                y_avg = 2 * get_bits(&gb, 5);
258                for (i = 0; i < 4; i++) {
259                    y[i] = av_clip(y_avg + offset_table[difference_selector] *
260                                   sign_table[sign_selector][i], 0, 63);
261                }
262            } else if (get_bits1(&gb)) {
263                if (get_bits1(&gb)) {
264                    y_avg = get_bits(&gb, 6);
265                } else {
266                    unsigned adjust_index = get_bits(&gb, 3);
267                    y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
268                }
269                for (i = 0; i < 4; i++)
270                    y[i] = y_avg;
271            }
272
273            if (get_bits1(&gb)) {
274                if (get_bits1(&gb)) {
275                    cb = get_bits(&gb, 5);
276                    cr = get_bits(&gb, 5);
277                } else {
278                    unsigned adjust_index = get_bits(&gb, 3);
279                    cb = (cb + chroma_adjust[0][adjust_index]) & 31;
280                    cr = (cr + chroma_adjust[1][adjust_index]) & 31;
281                }
282            }
283        }
284        *ya++ = y_avg;
285
286        new_y[0]                = y[0];
287        new_y[1]                = y[1];
288        new_y[new_y_stride]     = y[2];
289        new_y[new_y_stride + 1] = y[3];
290        *new_cb = cb;
291        *new_cr = cr;
292
293        old_y += 2;
294        old_cb++;
295        old_cr++;
296        new_y += 2;
297        new_cb++;
298        new_cr++;
299        block_x++;
300        if (block_x * 2 == avctx->width) {
301            block_x = 0;
302            old_y  += old_y_stride * 2  - avctx->width;
303            old_cb += old_cb_stride     - avctx->width / 2;
304            old_cr += old_cr_stride     - avctx->width / 2;
305            new_y  += new_y_stride * 2  - avctx->width;
306            new_cb += new_cb_stride     - avctx->width / 2;
307            new_cr += new_cr_stride     - avctx->width / 2;
308        }
309
310        skip--;
311    }
312
313    new_y  = s->new_y;
314    new_cb = s->new_u;
315    new_cr = s->new_v;
316    dstY   = pic->data[0];
317    dstU   = pic->data[1];
318    dstV   = pic->data[2];
319    for (j = 0; j < avctx->height; j++) {
320        for (i = 0; i < avctx->width; i++)
321            dstY[i] = new_y[i] << 2;
322        dstY  += pic->linesize[0];
323        new_y += new_y_stride;
324    }
325    for (j = 0; j < avctx->height / 2; j++) {
326        for (i = 0; i < avctx->width / 2; i++) {
327            dstU[i] = chroma_vals[new_cb[i]];
328            dstV[i] = chroma_vals[new_cr[i]];
329        }
330        dstU   += pic->linesize[1];
331        dstV   += pic->linesize[2];
332        new_cb += new_cb_stride;
333        new_cr += new_cr_stride;
334    }
335
336    ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
337            buf_size, get_bits_count(&gb) >> 3);
338
339    FFSWAP(uint8_t*, s->old_y, s->new_y);
340    FFSWAP(uint8_t*, s->old_u, s->new_u);
341    FFSWAP(uint8_t*, s->old_v, s->new_v);
342
343    *got_frame = 1;
344
345    return buf_size;
346}
347
348const FFCodec ff_escape130_decoder = {
349    .p.name         = "escape130",
350    .p.long_name    = NULL_IF_CONFIG_SMALL("Escape 130"),
351    .p.type         = AVMEDIA_TYPE_VIDEO,
352    .p.id           = AV_CODEC_ID_ESCAPE130,
353    .priv_data_size = sizeof(Escape130Context),
354    .init           = escape130_decode_init,
355    .close          = escape130_decode_close,
356    FF_CODEC_DECODE_CB(escape130_decode_frame),
357    .p.capabilities = AV_CODEC_CAP_DR1,
358    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
359};
360