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