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