Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6148 | serge | 1 | /* |
2 | * Escape 124 Video Decoder |
||
3 | * Copyright (C) 2008 Eli Friedman (eli.friedman@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 "avcodec.h" |
||
23 | #include "internal.h" |
||
24 | |||
25 | #define BITSTREAM_READER_LE |
||
26 | #include "get_bits.h" |
||
27 | |||
28 | typedef union MacroBlock { |
||
29 | uint16_t pixels[4]; |
||
30 | uint32_t pixels32[2]; |
||
31 | } MacroBlock; |
||
32 | |||
33 | typedef union SuperBlock { |
||
34 | uint16_t pixels[64]; |
||
35 | uint32_t pixels32[32]; |
||
36 | } SuperBlock; |
||
37 | |||
38 | typedef struct CodeBook { |
||
39 | unsigned depth; |
||
40 | unsigned size; |
||
41 | MacroBlock* blocks; |
||
42 | } CodeBook; |
||
43 | |||
44 | typedef struct Escape124Context { |
||
45 | AVFrame frame; |
||
46 | |||
47 | unsigned num_superblocks; |
||
48 | |||
49 | CodeBook codebooks[3]; |
||
50 | } Escape124Context; |
||
51 | |||
52 | /** |
||
53 | * Initialize the decoder |
||
54 | * @param avctx decoder context |
||
55 | * @return 0 success, negative on error |
||
56 | */ |
||
57 | static av_cold int escape124_decode_init(AVCodecContext *avctx) |
||
58 | { |
||
59 | Escape124Context *s = avctx->priv_data; |
||
60 | |||
61 | avcodec_get_frame_defaults(&s->frame); |
||
62 | avctx->pix_fmt = AV_PIX_FMT_RGB555; |
||
63 | |||
64 | s->num_superblocks = ((unsigned)avctx->width / 8) * |
||
65 | ((unsigned)avctx->height / 8); |
||
66 | |||
67 | return 0; |
||
68 | } |
||
69 | |||
70 | static av_cold int escape124_decode_close(AVCodecContext *avctx) |
||
71 | { |
||
72 | unsigned i; |
||
73 | Escape124Context *s = avctx->priv_data; |
||
74 | |||
75 | for (i = 0; i < 3; i++) |
||
76 | av_free(s->codebooks[i].blocks); |
||
77 | |||
78 | av_frame_unref(&s->frame); |
||
79 | |||
80 | return 0; |
||
81 | } |
||
82 | |||
83 | static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, |
||
84 | unsigned size) |
||
85 | { |
||
86 | unsigned i, j; |
||
87 | CodeBook cb = { 0 }; |
||
88 | |||
89 | if (size >= INT_MAX / 34 || get_bits_left(gb) < size * 34) |
||
90 | return cb; |
||
91 | |||
92 | if (size >= INT_MAX / sizeof(MacroBlock)) |
||
93 | return cb; |
||
94 | cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1); |
||
95 | if (!cb.blocks) |
||
96 | return cb; |
||
97 | |||
98 | cb.depth = depth; |
||
99 | cb.size = size; |
||
100 | for (i = 0; i < size; i++) { |
||
101 | unsigned mask_bits = get_bits(gb, 4); |
||
102 | unsigned color0 = get_bits(gb, 15); |
||
103 | unsigned color1 = get_bits(gb, 15); |
||
104 | |||
105 | for (j = 0; j < 4; j++) { |
||
106 | if (mask_bits & (1 << j)) |
||
107 | cb.blocks[i].pixels[j] = color1; |
||
108 | else |
||
109 | cb.blocks[i].pixels[j] = color0; |
||
110 | } |
||
111 | } |
||
112 | return cb; |
||
113 | } |
||
114 | |||
115 | static unsigned decode_skip_count(GetBitContext* gb) |
||
116 | { |
||
117 | unsigned value; |
||
118 | // This function reads a maximum of 23 bits, |
||
119 | // which is within the padding space |
||
120 | if (get_bits_left(gb) < 1) |
||
121 | return -1; |
||
122 | value = get_bits1(gb); |
||
123 | if (!value) |
||
124 | return value; |
||
125 | |||
126 | value += get_bits(gb, 3); |
||
127 | if (value != (1 + ((1 << 3) - 1))) |
||
128 | return value; |
||
129 | |||
130 | value += get_bits(gb, 7); |
||
131 | if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1)) |
||
132 | return value; |
||
133 | |||
134 | return value + get_bits(gb, 12); |
||
135 | } |
||
136 | |||
137 | static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, |
||
138 | int* codebook_index, int superblock_index) |
||
139 | { |
||
140 | // This function reads a maximum of 22 bits; the callers |
||
141 | // guard this function appropriately |
||
142 | unsigned block_index, depth; |
||
143 | |||
144 | if (get_bits1(gb)) { |
||
145 | static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; |
||
146 | *codebook_index = transitions[*codebook_index][get_bits1(gb)]; |
||
147 | } |
||
148 | |||
149 | depth = s->codebooks[*codebook_index].depth; |
||
150 | |||
151 | // depth = 0 means that this shouldn't read any bits; |
||
152 | // in theory, this is the same as get_bits(gb, 0), but |
||
153 | // that doesn't actually work. |
||
154 | block_index = depth ? get_bits(gb, depth) : 0; |
||
155 | |||
156 | if (*codebook_index == 1) { |
||
157 | block_index += superblock_index << s->codebooks[1].depth; |
||
158 | } |
||
159 | |||
160 | // This condition can occur with invalid bitstreams and |
||
161 | // *codebook_index == 2 |
||
162 | if (block_index >= s->codebooks[*codebook_index].size) |
||
163 | return (MacroBlock) { { 0 } }; |
||
164 | |||
165 | return s->codebooks[*codebook_index].blocks[block_index]; |
||
166 | } |
||
167 | |||
168 | static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { |
||
169 | // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2 |
||
170 | uint32_t *dst = sb->pixels32 + index + (index & -4); |
||
171 | |||
172 | // This technically violates C99 aliasing rules, but it should be safe. |
||
173 | dst[0] = mb.pixels32[0]; |
||
174 | dst[4] = mb.pixels32[1]; |
||
175 | } |
||
176 | |||
177 | static void copy_superblock(uint16_t* dest, unsigned dest_stride, |
||
178 | uint16_t* src, unsigned src_stride) |
||
179 | { |
||
180 | unsigned y; |
||
181 | if (src) |
||
182 | for (y = 0; y < 8; y++) |
||
183 | memcpy(dest + y * dest_stride, src + y * src_stride, |
||
184 | sizeof(uint16_t) * 8); |
||
185 | else |
||
186 | for (y = 0; y < 8; y++) |
||
187 | memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8); |
||
188 | } |
||
189 | |||
190 | static const uint16_t mask_matrix[] = {0x1, 0x2, 0x10, 0x20, |
||
191 | 0x4, 0x8, 0x40, 0x80, |
||
192 | 0x100, 0x200, 0x1000, 0x2000, |
||
193 | 0x400, 0x800, 0x4000, 0x8000}; |
||
194 | |||
195 | static int escape124_decode_frame(AVCodecContext *avctx, |
||
196 | void *data, int *got_frame, |
||
197 | AVPacket *avpkt) |
||
198 | { |
||
199 | int buf_size = avpkt->size; |
||
200 | Escape124Context *s = avctx->priv_data; |
||
201 | AVFrame *frame = data; |
||
202 | |||
203 | GetBitContext gb; |
||
204 | unsigned frame_flags, frame_size; |
||
205 | unsigned i; |
||
206 | |||
207 | unsigned superblock_index, cb_index = 1, |
||
208 | superblock_col_index = 0, |
||
209 | superblocks_per_row = avctx->width / 8, skip = -1; |
||
210 | |||
211 | uint16_t* old_frame_data, *new_frame_data; |
||
212 | unsigned old_stride, new_stride; |
||
213 | |||
214 | int ret; |
||
215 | |||
216 | if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) |
||
217 | return ret; |
||
218 | |||
219 | // This call also guards the potential depth reads for the |
||
220 | // codebook unpacking. |
||
221 | if (get_bits_left(&gb) < 64) |
||
222 | return -1; |
||
223 | |||
224 | frame_flags = get_bits_long(&gb, 32); |
||
225 | frame_size = get_bits_long(&gb, 32); |
||
226 | |||
227 | // Leave last frame unchanged |
||
228 | // FIXME: Is this necessary? I haven't seen it in any real samples |
||
229 | if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { |
||
230 | if (!s->frame.data[0]) |
||
231 | return AVERROR_INVALIDDATA; |
||
232 | |||
233 | av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); |
||
234 | |||
235 | *got_frame = 1; |
||
236 | if ((ret = av_frame_ref(frame, &s->frame)) < 0) |
||
237 | return ret; |
||
238 | |||
239 | return frame_size; |
||
240 | } |
||
241 | |||
242 | for (i = 0; i < 3; i++) { |
||
243 | if (frame_flags & (1 << (17 + i))) { |
||
244 | unsigned cb_depth, cb_size; |
||
245 | if (i == 2) { |
||
246 | // This codebook can be cut off at places other than |
||
247 | // powers of 2, leaving some of the entries undefined. |
||
248 | cb_size = get_bits_long(&gb, 20); |
||
249 | cb_depth = av_log2(cb_size - 1) + 1; |
||
250 | } else { |
||
251 | cb_depth = get_bits(&gb, 4); |
||
252 | if (i == 0) { |
||
253 | // This is the most basic codebook: pow(2,depth) entries |
||
254 | // for a depth-length key |
||
255 | cb_size = 1 << cb_depth; |
||
256 | } else { |
||
257 | // This codebook varies per superblock |
||
258 | // FIXME: I don't think this handles integer overflow |
||
259 | // properly |
||
260 | cb_size = s->num_superblocks << cb_depth; |
||
261 | } |
||
262 | } |
||
263 | av_free(s->codebooks[i].blocks); |
||
264 | s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); |
||
265 | if (!s->codebooks[i].blocks) |
||
266 | return -1; |
||
267 | } |
||
268 | } |
||
269 | |||
270 | if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) |
||
271 | return ret; |
||
272 | |||
273 | new_frame_data = (uint16_t*)frame->data[0]; |
||
274 | new_stride = frame->linesize[0] / 2; |
||
275 | old_frame_data = (uint16_t*)s->frame.data[0]; |
||
276 | old_stride = s->frame.linesize[0] / 2; |
||
277 | |||
278 | for (superblock_index = 0; superblock_index < s->num_superblocks; |
||
279 | superblock_index++) { |
||
280 | MacroBlock mb; |
||
281 | SuperBlock sb; |
||
282 | unsigned multi_mask = 0; |
||
283 | |||
284 | if (skip == -1) { |
||
285 | // Note that this call will make us skip the rest of the blocks |
||
286 | // if the frame prematurely ends |
||
287 | skip = decode_skip_count(&gb); |
||
288 | } |
||
289 | |||
290 | if (skip) { |
||
291 | copy_superblock(new_frame_data, new_stride, |
||
292 | old_frame_data, old_stride); |
||
293 | } else { |
||
294 | copy_superblock(sb.pixels, 8, |
||
295 | old_frame_data, old_stride); |
||
296 | |||
297 | while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { |
||
298 | unsigned mask; |
||
299 | mb = decode_macroblock(s, &gb, &cb_index, superblock_index); |
||
300 | mask = get_bits(&gb, 16); |
||
301 | multi_mask |= mask; |
||
302 | for (i = 0; i < 16; i++) { |
||
303 | if (mask & mask_matrix[i]) { |
||
304 | insert_mb_into_sb(&sb, mb, i); |
||
305 | } |
||
306 | } |
||
307 | } |
||
308 | |||
309 | if (!get_bits1(&gb)) { |
||
310 | unsigned inv_mask = get_bits(&gb, 4); |
||
311 | for (i = 0; i < 4; i++) { |
||
312 | if (inv_mask & (1 << i)) { |
||
313 | multi_mask ^= 0xF << i*4; |
||
314 | } else { |
||
315 | multi_mask ^= get_bits(&gb, 4) << i*4; |
||
316 | } |
||
317 | } |
||
318 | |||
319 | for (i = 0; i < 16; i++) { |
||
320 | if (multi_mask & mask_matrix[i]) { |
||
321 | mb = decode_macroblock(s, &gb, &cb_index, |
||
322 | superblock_index); |
||
323 | insert_mb_into_sb(&sb, mb, i); |
||
324 | } |
||
325 | } |
||
326 | } else if (frame_flags & (1 << 16)) { |
||
327 | while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { |
||
328 | mb = decode_macroblock(s, &gb, &cb_index, superblock_index); |
||
329 | insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); |
||
330 | } |
||
331 | } |
||
332 | |||
333 | copy_superblock(new_frame_data, new_stride, sb.pixels, 8); |
||
334 | } |
||
335 | |||
336 | superblock_col_index++; |
||
337 | new_frame_data += 8; |
||
338 | if (old_frame_data) |
||
339 | old_frame_data += 8; |
||
340 | if (superblock_col_index == superblocks_per_row) { |
||
341 | new_frame_data += new_stride * 8 - superblocks_per_row * 8; |
||
342 | if (old_frame_data) |
||
343 | old_frame_data += old_stride * 8 - superblocks_per_row * 8; |
||
344 | superblock_col_index = 0; |
||
345 | } |
||
346 | skip--; |
||
347 | } |
||
348 | |||
349 | av_log(avctx, AV_LOG_DEBUG, |
||
350 | "Escape sizes: %i, %i, %i\n", |
||
351 | frame_size, buf_size, get_bits_count(&gb) / 8); |
||
352 | |||
353 | av_frame_unref(&s->frame); |
||
354 | if ((ret = av_frame_ref(&s->frame, frame)) < 0) |
||
355 | return ret; |
||
356 | |||
357 | *got_frame = 1; |
||
358 | |||
359 | return frame_size; |
||
360 | } |
||
361 | |||
362 | |||
363 | AVCodec ff_escape124_decoder = { |
||
364 | .name = "escape124", |
||
365 | .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), |
||
366 | .type = AVMEDIA_TYPE_VIDEO, |
||
367 | .id = AV_CODEC_ID_ESCAPE124, |
||
368 | .priv_data_size = sizeof(Escape124Context), |
||
369 | .init = escape124_decode_init, |
||
370 | .close = escape124_decode_close, |
||
371 | .decode = escape124_decode_frame, |
||
372 | .capabilities = CODEC_CAP_DR1, |
||
373 | };>><>>><>><>><>>>>>><>><>><>>>>>>>><>><>><>><>>><>>>>> |