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