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