yading@10
|
1 /*
|
yading@10
|
2 * Escape 130 Video Decoder
|
yading@10
|
3 * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 #include "avcodec.h"
|
yading@10
|
23
|
yading@10
|
24 #define BITSTREAM_READER_LE
|
yading@10
|
25 #include "get_bits.h"
|
yading@10
|
26 #include "internal.h"
|
yading@10
|
27
|
yading@10
|
28
|
yading@10
|
29 typedef struct Escape130Context {
|
yading@10
|
30 AVFrame frame;
|
yading@10
|
31 uint8_t *bases;
|
yading@10
|
32 } Escape130Context;
|
yading@10
|
33
|
yading@10
|
34 /**
|
yading@10
|
35 * Initialize the decoder
|
yading@10
|
36 * @param avctx decoder context
|
yading@10
|
37 * @return 0 success, negative on error
|
yading@10
|
38 */
|
yading@10
|
39 static av_cold int escape130_decode_init(AVCodecContext *avctx)
|
yading@10
|
40 {
|
yading@10
|
41 Escape130Context *s = avctx->priv_data;
|
yading@10
|
42 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
yading@10
|
43 avcodec_get_frame_defaults(&s->frame);
|
yading@10
|
44
|
yading@10
|
45 if((avctx->width&1) || (avctx->height&1)){
|
yading@10
|
46 av_log(avctx, AV_LOG_ERROR, "Dimensions are not a multiple of the block size\n");
|
yading@10
|
47 return AVERROR(EINVAL);
|
yading@10
|
48 }
|
yading@10
|
49
|
yading@10
|
50 s->bases= av_malloc(avctx->width * avctx->height /4);
|
yading@10
|
51
|
yading@10
|
52 return 0;
|
yading@10
|
53 }
|
yading@10
|
54
|
yading@10
|
55 static av_cold int escape130_decode_close(AVCodecContext *avctx)
|
yading@10
|
56 {
|
yading@10
|
57 Escape130Context *s = avctx->priv_data;
|
yading@10
|
58
|
yading@10
|
59 av_frame_unref(&s->frame);
|
yading@10
|
60
|
yading@10
|
61 av_freep(&s->bases);
|
yading@10
|
62
|
yading@10
|
63 return 0;
|
yading@10
|
64 }
|
yading@10
|
65
|
yading@10
|
66 static unsigned decode_skip_count(GetBitContext* gb) {
|
yading@10
|
67 unsigned value;
|
yading@10
|
68 // This function reads a maximum of 27 bits,
|
yading@10
|
69 // which is within the padding space
|
yading@10
|
70 if (get_bits_left(gb) < 1+3)
|
yading@10
|
71 return -1;
|
yading@10
|
72
|
yading@10
|
73 value = get_bits1(gb);
|
yading@10
|
74 if (value)
|
yading@10
|
75 return 0;
|
yading@10
|
76
|
yading@10
|
77 value = get_bits(gb, 3);
|
yading@10
|
78 if (value)
|
yading@10
|
79 return value;
|
yading@10
|
80
|
yading@10
|
81 value = get_bits(gb, 8);
|
yading@10
|
82 if (value)
|
yading@10
|
83 return value + 7;
|
yading@10
|
84
|
yading@10
|
85 value = get_bits(gb, 15);
|
yading@10
|
86 if (value)
|
yading@10
|
87 return value + 262;
|
yading@10
|
88
|
yading@10
|
89 return -1;
|
yading@10
|
90 }
|
yading@10
|
91
|
yading@10
|
92 /**
|
yading@10
|
93 * Decode a single frame
|
yading@10
|
94 * @param avctx decoder context
|
yading@10
|
95 * @param data decoded frame
|
yading@10
|
96 * @param got_frame have decoded frame
|
yading@10
|
97 * @param buf input buffer
|
yading@10
|
98 * @param buf_size input buffer size
|
yading@10
|
99 * @return 0 success, -1 on error
|
yading@10
|
100 */
|
yading@10
|
101 static int escape130_decode_frame(AVCodecContext *avctx,
|
yading@10
|
102 void *data, int *got_frame,
|
yading@10
|
103 AVPacket *avpkt)
|
yading@10
|
104 {
|
yading@10
|
105 const uint8_t *buf = avpkt->data;
|
yading@10
|
106 int buf_size = avpkt->size;
|
yading@10
|
107 Escape130Context *s = avctx->priv_data;
|
yading@10
|
108
|
yading@10
|
109 GetBitContext gb;
|
yading@10
|
110 unsigned i;
|
yading@10
|
111 int ret;
|
yading@10
|
112
|
yading@10
|
113 uint8_t *old_y, *old_cb, *old_cr,
|
yading@10
|
114 *new_y, *new_cb, *new_cr;
|
yading@10
|
115 unsigned old_y_stride, old_cb_stride, old_cr_stride,
|
yading@10
|
116 new_y_stride, new_cb_stride, new_cr_stride;
|
yading@10
|
117 unsigned total_blocks = avctx->width * avctx->height / 4,
|
yading@10
|
118 block_index, row_index = 0;
|
yading@10
|
119 unsigned y[4] = {0}, cb = 16, cr = 16;
|
yading@10
|
120 unsigned skip = -1;
|
yading@10
|
121 unsigned y_base = 0;
|
yading@10
|
122 uint8_t *yb= s->bases;
|
yading@10
|
123
|
yading@10
|
124 AVFrame *frame = data;
|
yading@10
|
125
|
yading@10
|
126 init_get_bits(&gb, buf, buf_size * 8);
|
yading@10
|
127
|
yading@10
|
128 if (get_bits_left(&gb) < 128)
|
yading@10
|
129 return -1;
|
yading@10
|
130
|
yading@10
|
131 // Header; no useful information in here
|
yading@10
|
132 skip_bits_long(&gb, 128);
|
yading@10
|
133
|
yading@10
|
134 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
|
yading@10
|
135 return ret;
|
yading@10
|
136
|
yading@10
|
137 new_y = frame->data[0];
|
yading@10
|
138 new_cb = frame->data[1];
|
yading@10
|
139 new_cr = frame->data[2];
|
yading@10
|
140 new_y_stride = frame->linesize[0];
|
yading@10
|
141 new_cb_stride = frame->linesize[1];
|
yading@10
|
142 new_cr_stride = frame->linesize[2];
|
yading@10
|
143 old_y = s->frame.data[0];
|
yading@10
|
144 old_cb = s->frame.data[1];
|
yading@10
|
145 old_cr = s->frame.data[2];
|
yading@10
|
146 old_y_stride = s->frame.linesize[0];
|
yading@10
|
147 old_cb_stride = s->frame.linesize[1];
|
yading@10
|
148 old_cr_stride = s->frame.linesize[2];
|
yading@10
|
149
|
yading@10
|
150 av_log(avctx, AV_LOG_DEBUG,
|
yading@10
|
151 "Strides: %i, %i\n",
|
yading@10
|
152 new_y_stride, new_cb_stride);
|
yading@10
|
153
|
yading@10
|
154 for (block_index = 0; block_index < total_blocks; block_index++) {
|
yading@10
|
155 // Note that this call will make us skip the rest of the blocks
|
yading@10
|
156 // if the frame prematurely ends
|
yading@10
|
157 if (skip == -1)
|
yading@10
|
158 skip = decode_skip_count(&gb);
|
yading@10
|
159
|
yading@10
|
160 if (skip) {
|
yading@10
|
161 if (old_y) {
|
yading@10
|
162 y[0] = old_y[0] / 4;
|
yading@10
|
163 y[1] = old_y[1] / 4;
|
yading@10
|
164 y[2] = old_y[old_y_stride] / 4;
|
yading@10
|
165 y[3] = old_y[old_y_stride+1] / 4;
|
yading@10
|
166 y_base= yb[0];
|
yading@10
|
167 cb = old_cb[0] / 8;
|
yading@10
|
168 cr = old_cr[0] / 8;
|
yading@10
|
169 } else {
|
yading@10
|
170 y_base=y[0] = y[1] = y[2] = y[3] = 0;
|
yading@10
|
171 cb = cr = 16;
|
yading@10
|
172 }
|
yading@10
|
173 } else {
|
yading@10
|
174 if (get_bits1(&gb)) {
|
yading@10
|
175 static const uint8_t offset_table[] = {2, 4, 10, 20};
|
yading@10
|
176 static const int8_t sign_table[64][4] =
|
yading@10
|
177 { {0, 0, 0, 0},
|
yading@10
|
178 {-1, 1, 0, 0},
|
yading@10
|
179 {1, -1, 0, 0},
|
yading@10
|
180 {-1, 0, 1, 0},
|
yading@10
|
181 {-1, 1, 1, 0},
|
yading@10
|
182 {0, -1, 1, 0},
|
yading@10
|
183 {1, -1, 1, 0},
|
yading@10
|
184 {-1, -1, 1, 0},
|
yading@10
|
185 {1, 0, -1, 0},
|
yading@10
|
186 {0, 1, -1, 0},
|
yading@10
|
187 {1, 1, -1, 0},
|
yading@10
|
188 {-1, 1, -1, 0},
|
yading@10
|
189 {1, -1, -1, 0},
|
yading@10
|
190 {-1, 0, 0, 1},
|
yading@10
|
191 {-1, 1, 0, 1},
|
yading@10
|
192 {0, -1, 0, 1},
|
yading@10
|
193
|
yading@10
|
194 {0, 0, 0, 0},
|
yading@10
|
195 {1, -1, 0, 1},
|
yading@10
|
196 {-1, -1, 0, 1},
|
yading@10
|
197 {-1, 0, 1, 1},
|
yading@10
|
198 {-1, 1, 1, 1},
|
yading@10
|
199 {0, -1, 1, 1},
|
yading@10
|
200 {1, -1, 1, 1},
|
yading@10
|
201 {-1, -1, 1, 1},
|
yading@10
|
202 {0, 0, -1, 1},
|
yading@10
|
203 {1, 0, -1, 1},
|
yading@10
|
204 {-1, 0, -1, 1},
|
yading@10
|
205 {0, 1, -1, 1},
|
yading@10
|
206 {1, 1, -1, 1},
|
yading@10
|
207 {-1, 1, -1, 1},
|
yading@10
|
208 {0, -1, -1, 1},
|
yading@10
|
209 {1, -1, -1, 1},
|
yading@10
|
210
|
yading@10
|
211 {0, 0, 0, 0},
|
yading@10
|
212 {-1, -1, -1, 1},
|
yading@10
|
213 {1, 0, 0, -1},
|
yading@10
|
214 {0, 1, 0, -1},
|
yading@10
|
215 {1, 1, 0, -1},
|
yading@10
|
216 {-1, 1, 0, -1},
|
yading@10
|
217 {1, -1, 0, -1},
|
yading@10
|
218 {0, 0, 1, -1},
|
yading@10
|
219 {1, 0, 1, -1},
|
yading@10
|
220 {-1, 0, 1, -1},
|
yading@10
|
221 {0, 1, 1, -1},
|
yading@10
|
222 {1, 1, 1, -1},
|
yading@10
|
223 {-1, 1, 1, -1},
|
yading@10
|
224 {0, -1, 1, -1},
|
yading@10
|
225 {1, -1, 1, -1},
|
yading@10
|
226 {-1, -1, 1, -1},
|
yading@10
|
227
|
yading@10
|
228 {0, 0, 0, 0},
|
yading@10
|
229 {1, 0, -1, -1},
|
yading@10
|
230 {0, 1, -1, -1},
|
yading@10
|
231 {1, 1, -1, -1},
|
yading@10
|
232 {-1, 1, -1, -1},
|
yading@10
|
233 {1, -1, -1, -1} };
|
yading@10
|
234 unsigned sign_selector = get_bits(&gb, 6);
|
yading@10
|
235 unsigned difference_selector = get_bits(&gb, 2);
|
yading@10
|
236 y_base = 2 * get_bits(&gb, 5);
|
yading@10
|
237 for (i = 0; i < 4; i++) {
|
yading@10
|
238 y[i] = av_clip((int)y_base + offset_table[difference_selector] *
|
yading@10
|
239 sign_table[sign_selector][i], 0, 63);
|
yading@10
|
240 }
|
yading@10
|
241 } else if (get_bits1(&gb)) {
|
yading@10
|
242 if (get_bits1(&gb)) {
|
yading@10
|
243 y_base = get_bits(&gb, 6);
|
yading@10
|
244 } else {
|
yading@10
|
245 unsigned adjust_index = get_bits(&gb, 3);
|
yading@10
|
246 static const int8_t adjust[] = {-4, -3, -2, -1, 1, 2, 3, 4};
|
yading@10
|
247 y_base = (y_base + adjust[adjust_index]) & 63;
|
yading@10
|
248 }
|
yading@10
|
249 for (i = 0; i < 4; i++)
|
yading@10
|
250 y[i] = y_base;
|
yading@10
|
251 }
|
yading@10
|
252
|
yading@10
|
253 if (get_bits1(&gb)) {
|
yading@10
|
254 if (get_bits1(&gb)) {
|
yading@10
|
255 cb = get_bits(&gb, 5);
|
yading@10
|
256 cr = get_bits(&gb, 5);
|
yading@10
|
257 } else {
|
yading@10
|
258 unsigned adjust_index = get_bits(&gb, 3);
|
yading@10
|
259 static const int8_t adjust[2][8] =
|
yading@10
|
260 { { 1, 1, 0, -1, -1, -1, 0, 1 },
|
yading@10
|
261 { 0, 1, 1, 1, 0, -1, -1, -1 } };
|
yading@10
|
262 cb = (cb + adjust[0][adjust_index]) & 31;
|
yading@10
|
263 cr = (cr + adjust[1][adjust_index]) & 31;
|
yading@10
|
264 }
|
yading@10
|
265 }
|
yading@10
|
266 }
|
yading@10
|
267 *yb++= y_base;
|
yading@10
|
268
|
yading@10
|
269 new_y[0] = y[0] * 4;
|
yading@10
|
270 new_y[1] = y[1] * 4;
|
yading@10
|
271 new_y[new_y_stride] = y[2] * 4;
|
yading@10
|
272 new_y[new_y_stride + 1] = y[3] * 4;
|
yading@10
|
273 *new_cb = cb * 8;
|
yading@10
|
274 *new_cr = cr * 8;
|
yading@10
|
275
|
yading@10
|
276 if (old_y)
|
yading@10
|
277 old_y += 2, old_cb++, old_cr++;
|
yading@10
|
278 new_y += 2, new_cb++, new_cr++;
|
yading@10
|
279 row_index++;
|
yading@10
|
280 if (avctx->width / 2 == row_index) {
|
yading@10
|
281 row_index = 0;
|
yading@10
|
282 if (old_y) {
|
yading@10
|
283 old_y += old_y_stride * 2 - avctx->width;
|
yading@10
|
284 old_cb += old_cb_stride - avctx->width / 2;
|
yading@10
|
285 old_cr += old_cr_stride - avctx->width / 2;
|
yading@10
|
286 }
|
yading@10
|
287 new_y += new_y_stride * 2 - avctx->width;
|
yading@10
|
288 new_cb += new_cb_stride - avctx->width / 2;
|
yading@10
|
289 new_cr += new_cr_stride - avctx->width / 2;
|
yading@10
|
290 }
|
yading@10
|
291
|
yading@10
|
292 skip--;
|
yading@10
|
293 }
|
yading@10
|
294
|
yading@10
|
295 av_log(avctx, AV_LOG_DEBUG,
|
yading@10
|
296 "Escape sizes: %i, %i\n",
|
yading@10
|
297 buf_size, get_bits_count(&gb) / 8);
|
yading@10
|
298
|
yading@10
|
299 av_frame_unref(&s->frame);
|
yading@10
|
300 if ((ret = av_frame_ref(&s->frame, frame)) < 0)
|
yading@10
|
301 return ret;
|
yading@10
|
302
|
yading@10
|
303 *got_frame = 1;
|
yading@10
|
304
|
yading@10
|
305 return buf_size;
|
yading@10
|
306 }
|
yading@10
|
307
|
yading@10
|
308
|
yading@10
|
309 AVCodec ff_escape130_decoder = {
|
yading@10
|
310 .name = "escape130",
|
yading@10
|
311 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
312 .id = AV_CODEC_ID_ESCAPE130,
|
yading@10
|
313 .priv_data_size = sizeof(Escape130Context),
|
yading@10
|
314 .init = escape130_decode_init,
|
yading@10
|
315 .close = escape130_decode_close,
|
yading@10
|
316 .decode = escape130_decode_frame,
|
yading@10
|
317 .capabilities = CODEC_CAP_DR1,
|
yading@10
|
318 .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
|
yading@10
|
319 };
|