• 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 "codec_internal.h"
28 #include "get_bits.h"
29 #include "internal.h"
30 
31 typedef struct Escape130Context {
32     uint8_t *old_y_avg;
33 
34     uint8_t *new_y, *old_y;
35     uint8_t *new_u, *old_u;
36     uint8_t *new_v, *old_v;
37 
38     uint8_t *buf1, *buf2;
39     int     linesize[3];
40 } Escape130Context;
41 
42 static const uint8_t offset_table[] = { 2, 4, 10, 20 };
43 static const int8_t sign_table[64][4] = {
44     {  0,  0,  0,  0 },
45     { -1,  1,  0,  0 },
46     {  1, -1,  0,  0 },
47     { -1,  0,  1,  0 },
48     { -1,  1,  1,  0 },
49     {  0, -1,  1,  0 },
50     {  1, -1,  1,  0 },
51     { -1, -1,  1,  0 },
52     {  1,  0, -1,  0 },
53     {  0,  1, -1,  0 },
54     {  1,  1, -1,  0 },
55     { -1,  1, -1,  0 },
56     {  1, -1, -1,  0 },
57     { -1,  0,  0,  1 },
58     { -1,  1,  0,  1 },
59     {  0, -1,  0,  1 },
60 
61     {  0,  0,  0,  0 },
62     {  1, -1,  0,  1 },
63     { -1, -1,  0,  1 },
64     { -1,  0,  1,  1 },
65     { -1,  1,  1,  1 },
66     {  0, -1,  1,  1 },
67     {  1, -1,  1,  1 },
68     { -1, -1,  1,  1 },
69     {  0,  0, -1,  1 },
70     {  1,  0, -1,  1 },
71     { -1,  0, -1,  1 },
72     {  0,  1, -1,  1 },
73     {  1,  1, -1,  1 },
74     { -1,  1, -1,  1 },
75     {  0, -1, -1,  1 },
76     {  1, -1, -1,  1 },
77 
78     {  0,  0,  0,  0 },
79     { -1, -1, -1,  1 },
80     {  1,  0,  0, -1 },
81     {  0,  1,  0, -1 },
82     {  1,  1,  0, -1 },
83     { -1,  1,  0, -1 },
84     {  1, -1,  0, -1 },
85     {  0,  0,  1, -1 },
86     {  1,  0,  1, -1 },
87     { -1,  0,  1, -1 },
88     {  0,  1,  1, -1 },
89     {  1,  1,  1, -1 },
90     { -1,  1,  1, -1 },
91     {  0, -1,  1, -1 },
92     {  1, -1,  1, -1 },
93     { -1, -1,  1, -1 },
94 
95     {  0,  0,  0,  0 },
96     {  1,  0, -1, -1 },
97     {  0,  1, -1, -1 },
98     {  1,  1, -1, -1 },
99     { -1,  1, -1, -1 },
100     {  1, -1, -1, -1 }
101 };
102 
103 static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
104 
105 static const int8_t chroma_adjust[2][8] = {
106     { 1, 1, 0, -1, -1, -1,  0,  1 },
107     { 0, 1, 1,  1,  0, -1, -1, -1 }
108 };
109 
110 static const uint8_t chroma_vals[] = {
111      20,  28,  36,  44,  52,  60,  68,  76,
112      84,  92, 100, 106, 112, 116, 120, 124,
113     128, 132, 136, 140, 144, 150, 156, 164,
114     172, 180, 188, 196, 204, 212, 220, 228
115 };
116 
escape130_decode_init(AVCodecContext * avctx)117 static av_cold int escape130_decode_init(AVCodecContext *avctx)
118 {
119     Escape130Context *s = avctx->priv_data;
120     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
121 
122     if ((avctx->width & 1) || (avctx->height & 1)) {
123         av_log(avctx, AV_LOG_ERROR,
124                "Dimensions should be a multiple of two.\n");
125         return AVERROR_INVALIDDATA;
126     }
127 
128     s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
129     s->buf1      = av_malloc(avctx->width * avctx->height * 3 / 2);
130     s->buf2      = av_malloc(avctx->width * avctx->height * 3 / 2);
131     if (!s->old_y_avg || !s->buf1 || !s->buf2) {
132         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
133         return AVERROR(ENOMEM);
134     }
135 
136     s->linesize[0] = avctx->width;
137     s->linesize[1] =
138     s->linesize[2] = avctx->width / 2;
139 
140     s->new_y = s->buf1;
141     s->new_u = s->new_y + avctx->width * avctx->height;
142     s->new_v = s->new_u + avctx->width * avctx->height / 4;
143     s->old_y = s->buf2;
144     s->old_u = s->old_y + avctx->width * avctx->height;
145     s->old_v = s->old_u + avctx->width * avctx->height / 4;
146     memset(s->old_y, 0,    avctx->width * avctx->height);
147     memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
148     memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
149 
150     return 0;
151 }
152 
escape130_decode_close(AVCodecContext * avctx)153 static av_cold int escape130_decode_close(AVCodecContext *avctx)
154 {
155     Escape130Context *s = avctx->priv_data;
156 
157     av_freep(&s->old_y_avg);
158     av_freep(&s->buf1);
159     av_freep(&s->buf2);
160 
161     return 0;
162 }
163 
decode_skip_count(GetBitContext * gb)164 static int decode_skip_count(GetBitContext* gb)
165 {
166     int value;
167 
168     if (get_bits_left(gb) < 1+3)
169         return -1;
170 
171     value = get_bits1(gb);
172     if (value)
173         return 0;
174 
175     value = get_bits(gb, 3);
176     if (value)
177         return value;
178 
179     value = get_bits(gb, 8);
180     if (value)
181         return value + 7;
182 
183     value = get_bits(gb, 15);
184     if (value)
185         return value + 262;
186 
187     return -1;
188 }
189 
escape130_decode_frame(AVCodecContext * avctx,AVFrame * pic,int * got_frame,AVPacket * avpkt)190 static int escape130_decode_frame(AVCodecContext *avctx, AVFrame *pic,
191                                   int *got_frame, AVPacket *avpkt)
192 {
193     int buf_size        = avpkt->size;
194     Escape130Context *s = avctx->priv_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 const FFCodec ff_escape130_decoder = {
349     .p.name         = "escape130",
350     .p.long_name    = NULL_IF_CONFIG_SMALL("Escape 130"),
351     .p.type         = AVMEDIA_TYPE_VIDEO,
352     .p.id           = AV_CODEC_ID_ESCAPE130,
353     .priv_data_size = sizeof(Escape130Context),
354     .init           = escape130_decode_init,
355     .close          = escape130_decode_close,
356     FF_CODEC_DECODE_CB(escape130_decode_frame),
357     .p.capabilities = AV_CODEC_CAP_DR1,
358     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
359 };
360