Mercurial > libavcodec.hg
annotate escape124.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | 9cfc564bc3e6 |
children |
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 static int escape124_decode_frame(AVCodecContext *avctx, | |
199 void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
7040
diff
changeset
|
200 AVPacket *avpkt) |
6549 | 201 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
7040
diff
changeset
|
202 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
7040
diff
changeset
|
203 int buf_size = avpkt->size; |
6549 | 204 Escape124Context *s = avctx->priv_data; |
205 | |
206 GetBitContext gb; | |
207 unsigned frame_flags, frame_size; | |
208 unsigned i; | |
209 | |
210 unsigned superblock_index, cb_index = 1, | |
211 superblock_col_index = 0, | |
212 superblocks_per_row = avctx->width / 8, skip = -1; | |
213 | |
214 uint16_t* old_frame_data, *new_frame_data; | |
215 unsigned old_stride, new_stride; | |
216 | |
217 AVFrame new_frame = { { 0 } }; | |
218 | |
219 init_get_bits(&gb, buf, buf_size * 8); | |
220 | |
221 // This call also guards the potential depth reads for the | |
222 // codebook unpacking. | |
223 if (!can_safely_read(&gb, 64)) | |
224 return -1; | |
225 | |
226 frame_flags = get_bits_long(&gb, 32); | |
227 frame_size = get_bits_long(&gb, 32); | |
228 | |
229 // Leave last frame unchanged | |
230 // FIXME: Is this necessary? I haven't seen it in any real samples | |
231 if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { | |
232 av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n"); | |
233 | |
234 *data_size = sizeof(AVFrame); | |
235 *(AVFrame*)data = s->frame; | |
236 | |
237 return frame_size; | |
238 } | |
239 | |
240 for (i = 0; i < 3; i++) { | |
241 if (frame_flags & (1 << (17 + i))) { | |
242 unsigned cb_depth, cb_size; | |
243 if (i == 2) { | |
244 // This codebook can be cut off at places other than | |
245 // powers of 2, leaving some of the entries undefined. | |
246 cb_size = get_bits_long(&gb, 20); | |
247 cb_depth = av_log2(cb_size - 1) + 1; | |
248 } else { | |
249 cb_depth = get_bits(&gb, 4); | |
250 if (i == 0) { | |
251 // This is the most basic codebook: pow(2,depth) entries | |
252 // for a depth-length key | |
253 cb_size = 1 << cb_depth; | |
254 } else { | |
255 // This codebook varies per superblock | |
256 // FIXME: I don't think this handles integer overflow | |
257 // properly | |
258 cb_size = s->num_superblocks << cb_depth; | |
259 } | |
260 } | |
6556 | 261 av_free(s->codebooks[i].blocks); |
6549 | 262 s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); |
6556 | 263 if (!s->codebooks[i].blocks) |
6549 | 264 return -1; |
265 } | |
266 } | |
267 | |
268 new_frame.reference = 3; | |
269 if (avctx->get_buffer(avctx, &new_frame)) { | |
270 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
271 return -1; | |
272 } | |
273 | |
274 new_frame_data = (uint16_t*)new_frame.data[0]; | |
275 new_stride = new_frame.linesize[0] / 2; | |
276 old_frame_data = (uint16_t*)s->frame.data[0]; | |
277 old_stride = s->frame.linesize[0] / 2; | |
278 | |
279 for (superblock_index = 0; superblock_index < s->num_superblocks; | |
280 superblock_index++) { | |
281 MacroBlock mb; | |
282 SuperBlock sb; | |
283 unsigned multi_mask = 0; | |
284 | |
285 if (skip == -1) { | |
286 // Note that this call will make us skip the rest of the blocks | |
287 // if the frame prematurely ends | |
288 skip = decode_skip_count(&gb); | |
289 } | |
290 | |
291 if (skip) { | |
292 copy_superblock(new_frame_data, new_stride, | |
293 old_frame_data, old_stride); | |
294 } else { | |
295 copy_superblock(sb.pixels, 8, | |
296 old_frame_data, old_stride); | |
297 | |
298 while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { | |
299 unsigned mask; | |
300 mb = decode_macroblock(s, &gb, &cb_index, superblock_index); | |
301 mask = get_bits(&gb, 16); | |
302 multi_mask |= mask; | |
303 for (i = 0; i < 16; i++) { | |
304 if (mask & mask_matrix[i]) { | |
305 insert_mb_into_sb(&sb, mb, i); | |
306 } | |
307 } | |
308 } | |
309 | |
310 if (can_safely_read(&gb, 1) && !get_bits1(&gb)) { | |
311 unsigned inv_mask = get_bits(&gb, 4); | |
312 for (i = 0; i < 4; i++) { | |
313 if (inv_mask & (1 << i)) { | |
314 multi_mask ^= 0xF << i*4; | |
315 } else { | |
316 multi_mask ^= get_bits(&gb, 4) << i*4; | |
317 } | |
318 } | |
319 | |
320 for (i = 0; i < 16; i++) { | |
321 if (multi_mask & mask_matrix[i]) { | |
322 if (!can_safely_read(&gb, 1)) | |
323 break; | |
324 mb = decode_macroblock(s, &gb, &cb_index, | |
325 superblock_index); | |
326 insert_mb_into_sb(&sb, mb, i); | |
327 } | |
328 } | |
329 } else if (frame_flags & (1 << 16)) { | |
330 while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { | |
331 mb = decode_macroblock(s, &gb, &cb_index, superblock_index); | |
332 insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); | |
333 } | |
334 } | |
335 | |
336 copy_superblock(new_frame_data, new_stride, sb.pixels, 8); | |
337 } | |
338 | |
339 superblock_col_index++; | |
340 new_frame_data += 8; | |
341 if (old_frame_data) | |
342 old_frame_data += 8; | |
343 if (superblock_col_index == superblocks_per_row) { | |
344 new_frame_data += new_stride * 8 - superblocks_per_row * 8; | |
345 if (old_frame_data) | |
346 old_frame_data += old_stride * 8 - superblocks_per_row * 8; | |
347 superblock_col_index = 0; | |
348 } | |
349 skip--; | |
350 } | |
351 | |
352 av_log(NULL, AV_LOG_DEBUG, | |
353 "Escape sizes: %i, %i, %i\n", | |
354 frame_size, buf_size, get_bits_count(&gb) / 8); | |
355 | |
356 if (s->frame.data[0]) | |
357 avctx->release_buffer(avctx, &s->frame); | |
358 | |
359 *(AVFrame*)data = s->frame = new_frame; | |
360 *data_size = sizeof(AVFrame); | |
361 | |
362 return frame_size; | |
363 } | |
364 | |
365 | |
366 AVCodec escape124_decoder = { | |
367 "escape124", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
9428
diff
changeset
|
368 AVMEDIA_TYPE_VIDEO, |
6549 | 369 CODEC_ID_ESCAPE124, |
370 sizeof(Escape124Context), | |
371 escape124_decode_init, | |
372 NULL, | |
373 escape124_decode_close, | |
374 escape124_decode_frame, | |
375 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
376 .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), |
6549 | 377 }; |
378 |