]> git.sesse.net Git - ffmpeg/blob - libavcodec/escape130.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / escape130.c
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 #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 };