]> git.sesse.net Git - ffmpeg/blob - libavcodec/escape130.c
Merge commit '3f0b6d7a6248a33df37b98cfcb37a1acce263f62'
[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 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     const uint8_t *buf  = avpkt->data;
195     int buf_size        = avpkt->size;
196     Escape130Context *s = avctx->priv_data;
197     AVFrame *pic        = data;
198     GetBitContext gb;
199     int ret;
200
201     uint8_t *old_y, *old_cb, *old_cr,
202             *new_y, *new_cb, *new_cr;
203     uint8_t *dstY, *dstU, *dstV;
204     unsigned old_y_stride, old_cb_stride, old_cr_stride,
205              new_y_stride, new_cb_stride, new_cr_stride;
206     unsigned total_blocks = avctx->width * avctx->height / 4,
207              block_index, block_x = 0;
208     unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
209     int skip = -1, y_avg = 0, i, j;
210     uint8_t *ya = s->old_y_avg;
211
212     // first 16 bytes are header; no useful information in here
213     if (buf_size <= 16) {
214         av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
215         return AVERROR_INVALIDDATA;
216     }
217
218     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
219         return ret;
220
221     init_get_bits(&gb, buf + 16, (buf_size - 16) * 8);
222
223     new_y  = s->new_y;
224     new_cb = s->new_u;
225     new_cr = s->new_v;
226     new_y_stride  = s->linesize[0];
227     new_cb_stride = s->linesize[1];
228     new_cr_stride = s->linesize[2];
229     old_y  = s->old_y;
230     old_cb = s->old_u;
231     old_cr = s->old_v;
232     old_y_stride  = s->linesize[0];
233     old_cb_stride = s->linesize[1];
234     old_cr_stride = s->linesize[2];
235
236     for (block_index = 0; block_index < total_blocks; block_index++) {
237         // Note that this call will make us skip the rest of the blocks
238         // if the frame ends prematurely.
239         if (skip == -1)
240             skip = decode_skip_count(&gb);
241         if (skip == -1) {
242             av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
243             return AVERROR_INVALIDDATA;
244         }
245
246         if (skip) {
247             y[0] = old_y[0];
248             y[1] = old_y[1];
249             y[2] = old_y[old_y_stride];
250             y[3] = old_y[old_y_stride + 1];
251             y_avg = ya[0];
252             cb = old_cb[0];
253             cr = old_cr[0];
254         } else {
255             if (get_bits1(&gb)) {
256                 unsigned sign_selector       = get_bits(&gb, 6);
257                 unsigned difference_selector = get_bits(&gb, 2);
258                 y_avg = 2 * get_bits(&gb, 5);
259                 for (i = 0; i < 4; i++) {
260                     y[i] = av_clip(y_avg + offset_table[difference_selector] *
261                                    sign_table[sign_selector][i], 0, 63);
262                 }
263             } else if (get_bits1(&gb)) {
264                 if (get_bits1(&gb)) {
265                     y_avg = get_bits(&gb, 6);
266                 } else {
267                     unsigned adjust_index = get_bits(&gb, 3);
268                     y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
269                 }
270                 for (i = 0; i < 4; i++)
271                     y[i] = y_avg;
272             }
273
274             if (get_bits1(&gb)) {
275                 if (get_bits1(&gb)) {
276                     cb = get_bits(&gb, 5);
277                     cr = get_bits(&gb, 5);
278                 } else {
279                     unsigned adjust_index = get_bits(&gb, 3);
280                     cb = (cb + chroma_adjust[0][adjust_index]) & 31;
281                     cr = (cr + chroma_adjust[1][adjust_index]) & 31;
282                 }
283             }
284         }
285         *ya++ = y_avg;
286
287         new_y[0]                = y[0];
288         new_y[1]                = y[1];
289         new_y[new_y_stride]     = y[2];
290         new_y[new_y_stride + 1] = y[3];
291         *new_cb = cb;
292         *new_cr = cr;
293
294         old_y += 2;
295         old_cb++;
296         old_cr++;
297         new_y += 2;
298         new_cb++;
299         new_cr++;
300         block_x++;
301         if (block_x * 2 == avctx->width) {
302             block_x = 0;
303             old_y  += old_y_stride * 2  - avctx->width;
304             old_cb += old_cb_stride     - avctx->width / 2;
305             old_cr += old_cr_stride     - avctx->width / 2;
306             new_y  += new_y_stride * 2  - avctx->width;
307             new_cb += new_cb_stride     - avctx->width / 2;
308             new_cr += new_cr_stride     - avctx->width / 2;
309         }
310
311         skip--;
312     }
313
314     new_y  = s->new_y;
315     new_cb = s->new_u;
316     new_cr = s->new_v;
317     dstY   = pic->data[0];
318     dstU   = pic->data[1];
319     dstV   = pic->data[2];
320     for (j = 0; j < avctx->height; j++) {
321         for (i = 0; i < avctx->width; i++)
322             dstY[i] = new_y[i] << 2;
323         dstY  += pic->linesize[0];
324         new_y += new_y_stride;
325     }
326     for (j = 0; j < avctx->height / 2; j++) {
327         for (i = 0; i < avctx->width / 2; i++) {
328             dstU[i] = chroma_vals[new_cb[i]];
329             dstV[i] = chroma_vals[new_cr[i]];
330         }
331         dstU   += pic->linesize[1];
332         dstV   += pic->linesize[2];
333         new_cb += new_cb_stride;
334         new_cr += new_cr_stride;
335     }
336
337     av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
338             buf_size, get_bits_count(&gb) >> 3);
339
340     FFSWAP(uint8_t*, s->old_y, s->new_y);
341     FFSWAP(uint8_t*, s->old_u, s->new_u);
342     FFSWAP(uint8_t*, s->old_v, s->new_v);
343
344     *got_frame = 1;
345
346     return buf_size;
347 }
348
349 AVCodec ff_escape130_decoder = {
350     .name           = "escape130",
351     .type           = AVMEDIA_TYPE_VIDEO,
352     .id             = AV_CODEC_ID_ESCAPE130,
353     .priv_data_size = sizeof(Escape130Context),
354     .init           = escape130_decode_init,
355     .close          = escape130_decode_close,
356     .decode         = escape130_decode_frame,
357     .capabilities   = CODEC_CAP_DR1,
358     .long_name      = NULL_IF_CONFIG_SMALL("Escape 130"),
359 };