Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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