• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
escape130_decode_init(AVCodecContext * avctx)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_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
132         return AVERROR(ENOMEM);
133     }
134 
135     s->linesize[0] = avctx->width;
136     s->linesize[1] =
137     s->linesize[2] = avctx->width / 2;
138 
139     s->new_y = s->buf1;
140     s->new_u = s->new_y + avctx->width * avctx->height;
141     s->new_v = s->new_u + avctx->width * avctx->height / 4;
142     s->old_y = s->buf2;
143     s->old_u = s->old_y + avctx->width * avctx->height;
144     s->old_v = s->old_u + avctx->width * avctx->height / 4;
145     memset(s->old_y, 0,    avctx->width * avctx->height);
146     memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
147     memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
148 
149     return 0;
150 }
151 
escape130_decode_close(AVCodecContext * avctx)152 static av_cold int escape130_decode_close(AVCodecContext *avctx)
153 {
154     Escape130Context *s = avctx->priv_data;
155 
156     av_freep(&s->old_y_avg);
157     av_freep(&s->buf1);
158     av_freep(&s->buf2);
159 
160     return 0;
161 }
162 
decode_skip_count(GetBitContext * gb)163 static int decode_skip_count(GetBitContext* gb)
164 {
165     int value;
166 
167     if (get_bits_left(gb) < 1+3)
168         return -1;
169 
170     value = get_bits1(gb);
171     if (value)
172         return 0;
173 
174     value = get_bits(gb, 3);
175     if (value)
176         return value;
177 
178     value = get_bits(gb, 8);
179     if (value)
180         return value + 7;
181 
182     value = get_bits(gb, 15);
183     if (value)
184         return value + 262;
185 
186     return -1;
187 }
188 
escape130_decode_frame(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * avpkt)189 static int escape130_decode_frame(AVCodecContext *avctx, void *data,
190                                   int *got_frame, AVPacket *avpkt)
191 {
192     int buf_size        = avpkt->size;
193     Escape130Context *s = avctx->priv_data;
194     AVFrame *pic        = data;
195     GetBitContext gb;
196     int ret;
197 
198     uint8_t *old_y, *old_cb, *old_cr,
199             *new_y, *new_cb, *new_cr;
200     uint8_t *dstY, *dstU, *dstV;
201     unsigned old_y_stride, old_cb_stride, old_cr_stride,
202              new_y_stride, new_cb_stride, new_cr_stride;
203     unsigned total_blocks = avctx->width * avctx->height / 4,
204              block_index, block_x = 0;
205     unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
206     int skip = -1, y_avg = 0, i, j;
207     uint8_t *ya = s->old_y_avg;
208 
209     // first 16 bytes are header; no useful information in here
210     if (buf_size <= 16) {
211         av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
212         return AVERROR_INVALIDDATA;
213     }
214 
215     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
216         return ret;
217 
218     if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
219         return ret;
220     skip_bits_long(&gb, 16 * 8);
221 
222     new_y  = s->new_y;
223     new_cb = s->new_u;
224     new_cr = s->new_v;
225     new_y_stride  = s->linesize[0];
226     new_cb_stride = s->linesize[1];
227     new_cr_stride = s->linesize[2];
228     old_y  = s->old_y;
229     old_cb = s->old_u;
230     old_cr = s->old_v;
231     old_y_stride  = s->linesize[0];
232     old_cb_stride = s->linesize[1];
233     old_cr_stride = s->linesize[2];
234 
235     for (block_index = 0; block_index < total_blocks; block_index++) {
236         // Note that this call will make us skip the rest of the blocks
237         // if the frame ends prematurely.
238         if (skip == -1)
239             skip = decode_skip_count(&gb);
240         if (skip == -1) {
241             av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
242             return AVERROR_INVALIDDATA;
243         }
244 
245         if (skip) {
246             y[0] = old_y[0];
247             y[1] = old_y[1];
248             y[2] = old_y[old_y_stride];
249             y[3] = old_y[old_y_stride + 1];
250             y_avg = ya[0];
251             cb = old_cb[0];
252             cr = old_cr[0];
253         } else {
254             if (get_bits1(&gb)) {
255                 unsigned sign_selector       = get_bits(&gb, 6);
256                 unsigned difference_selector = get_bits(&gb, 2);
257                 y_avg = 2 * get_bits(&gb, 5);
258                 for (i = 0; i < 4; i++) {
259                     y[i] = av_clip(y_avg + offset_table[difference_selector] *
260                                    sign_table[sign_selector][i], 0, 63);
261                 }
262             } else if (get_bits1(&gb)) {
263                 if (get_bits1(&gb)) {
264                     y_avg = get_bits(&gb, 6);
265                 } else {
266                     unsigned adjust_index = get_bits(&gb, 3);
267                     y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
268                 }
269                 for (i = 0; i < 4; i++)
270                     y[i] = y_avg;
271             }
272 
273             if (get_bits1(&gb)) {
274                 if (get_bits1(&gb)) {
275                     cb = get_bits(&gb, 5);
276                     cr = get_bits(&gb, 5);
277                 } else {
278                     unsigned adjust_index = get_bits(&gb, 3);
279                     cb = (cb + chroma_adjust[0][adjust_index]) & 31;
280                     cr = (cr + chroma_adjust[1][adjust_index]) & 31;
281                 }
282             }
283         }
284         *ya++ = y_avg;
285 
286         new_y[0]                = y[0];
287         new_y[1]                = y[1];
288         new_y[new_y_stride]     = y[2];
289         new_y[new_y_stride + 1] = y[3];
290         *new_cb = cb;
291         *new_cr = cr;
292 
293         old_y += 2;
294         old_cb++;
295         old_cr++;
296         new_y += 2;
297         new_cb++;
298         new_cr++;
299         block_x++;
300         if (block_x * 2 == avctx->width) {
301             block_x = 0;
302             old_y  += old_y_stride * 2  - avctx->width;
303             old_cb += old_cb_stride     - avctx->width / 2;
304             old_cr += old_cr_stride     - avctx->width / 2;
305             new_y  += new_y_stride * 2  - avctx->width;
306             new_cb += new_cb_stride     - avctx->width / 2;
307             new_cr += new_cr_stride     - avctx->width / 2;
308         }
309 
310         skip--;
311     }
312 
313     new_y  = s->new_y;
314     new_cb = s->new_u;
315     new_cr = s->new_v;
316     dstY   = pic->data[0];
317     dstU   = pic->data[1];
318     dstV   = pic->data[2];
319     for (j = 0; j < avctx->height; j++) {
320         for (i = 0; i < avctx->width; i++)
321             dstY[i] = new_y[i] << 2;
322         dstY  += pic->linesize[0];
323         new_y += new_y_stride;
324     }
325     for (j = 0; j < avctx->height / 2; j++) {
326         for (i = 0; i < avctx->width / 2; i++) {
327             dstU[i] = chroma_vals[new_cb[i]];
328             dstV[i] = chroma_vals[new_cr[i]];
329         }
330         dstU   += pic->linesize[1];
331         dstV   += pic->linesize[2];
332         new_cb += new_cb_stride;
333         new_cr += new_cr_stride;
334     }
335 
336     ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
337             buf_size, get_bits_count(&gb) >> 3);
338 
339     FFSWAP(uint8_t*, s->old_y, s->new_y);
340     FFSWAP(uint8_t*, s->old_u, s->new_u);
341     FFSWAP(uint8_t*, s->old_v, s->new_v);
342 
343     *got_frame = 1;
344 
345     return buf_size;
346 }
347 
348 AVCodec ff_escape130_decoder = {
349     .name           = "escape130",
350     .long_name      = NULL_IF_CONFIG_SMALL("Escape 130"),
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   = AV_CODEC_CAP_DR1,
358     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
359 };
360