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