Commit | Line | Data |
---|---|---|
2ba45a60 DM |
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 | avctx->pix_fmt = AV_PIX_FMT_RGB555; | |
62 | ||
63 | s->num_superblocks = ((unsigned)avctx->width / 8) * | |
64 | ((unsigned)avctx->height / 8); | |
65 | ||
66 | s->frame = av_frame_alloc(); | |
67 | if (!s->frame) | |
68 | return AVERROR(ENOMEM); | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | static av_cold int escape124_decode_close(AVCodecContext *avctx) | |
74 | { | |
75 | unsigned i; | |
76 | Escape124Context *s = avctx->priv_data; | |
77 | ||
78 | for (i = 0; i < 3; i++) | |
f6fa7814 | 79 | av_freep(&s->codebooks[i].blocks); |
2ba45a60 DM |
80 | |
81 | av_frame_free(&s->frame); | |
82 | ||
83 | return 0; | |
84 | } | |
85 | ||
86 | static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, | |
87 | unsigned size) | |
88 | { | |
89 | unsigned i, j; | |
90 | CodeBook cb = { 0 }; | |
91 | ||
92 | if (size >= INT_MAX / 34 || get_bits_left(gb) < size * 34) | |
93 | return cb; | |
94 | ||
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; | |
100 | ||
101 | cb.depth = depth; | |
102 | cb.size = size; | |
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)) | |
110 | cb.blocks[i].pixels[j] = color1; | |
111 | else | |
112 | cb.blocks[i].pixels[j] = color0; | |
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 (get_bits_left(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; | |
f6fa7814 DM |
146 | int value = get_bits1(gb); |
147 | if (value) { | |
2ba45a60 | 148 | static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; |
f6fa7814 DM |
149 | value = get_bits1(gb); |
150 | *codebook_index = transitions[*codebook_index][value]; | |
2ba45a60 DM |
151 | } |
152 | ||
153 | depth = s->codebooks[*codebook_index].depth; | |
154 | ||
155 | // depth = 0 means that this shouldn't read any bits; | |
156 | // in theory, this is the same as get_bits(gb, 0), but | |
157 | // that doesn't actually work. | |
158 | block_index = depth ? get_bits(gb, depth) : 0; | |
159 | ||
160 | if (*codebook_index == 1) { | |
161 | block_index += superblock_index << s->codebooks[1].depth; | |
162 | } | |
163 | ||
164 | // This condition can occur with invalid bitstreams and | |
165 | // *codebook_index == 2 | |
166 | if (block_index >= s->codebooks[*codebook_index].size) | |
167 | return (MacroBlock) { { 0 } }; | |
168 | ||
169 | return s->codebooks[*codebook_index].blocks[block_index]; | |
170 | } | |
171 | ||
172 | static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { | |
173 | // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2 | |
174 | uint32_t *dst = sb->pixels32 + index + (index & -4); | |
175 | ||
176 | // This technically violates C99 aliasing rules, but it should be safe. | |
177 | dst[0] = mb.pixels32[0]; | |
178 | dst[4] = mb.pixels32[1]; | |
179 | } | |
180 | ||
181 | static void copy_superblock(uint16_t* dest, unsigned dest_stride, | |
182 | uint16_t* src, unsigned src_stride) | |
183 | { | |
184 | unsigned y; | |
185 | if (src) | |
186 | for (y = 0; y < 8; y++) | |
187 | memcpy(dest + y * dest_stride, src + y * src_stride, | |
188 | sizeof(uint16_t) * 8); | |
189 | else | |
190 | for (y = 0; y < 8; y++) | |
191 | memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8); | |
192 | } | |
193 | ||
194 | static const uint16_t mask_matrix[] = {0x1, 0x2, 0x10, 0x20, | |
195 | 0x4, 0x8, 0x40, 0x80, | |
196 | 0x100, 0x200, 0x1000, 0x2000, | |
197 | 0x400, 0x800, 0x4000, 0x8000}; | |
198 | ||
199 | static int escape124_decode_frame(AVCodecContext *avctx, | |
200 | void *data, int *got_frame, | |
201 | AVPacket *avpkt) | |
202 | { | |
203 | int buf_size = avpkt->size; | |
204 | Escape124Context *s = avctx->priv_data; | |
205 | AVFrame *frame = data; | |
206 | ||
207 | GetBitContext gb; | |
208 | unsigned frame_flags, frame_size; | |
209 | unsigned i; | |
210 | ||
211 | unsigned superblock_index, cb_index = 1, | |
212 | superblock_col_index = 0, | |
213 | superblocks_per_row = avctx->width / 8, skip = -1; | |
214 | ||
215 | uint16_t* old_frame_data, *new_frame_data; | |
216 | unsigned old_stride, new_stride; | |
217 | ||
218 | int ret; | |
219 | ||
220 | if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) | |
221 | return ret; | |
222 | ||
223 | // This call also guards the potential depth reads for the | |
224 | // codebook unpacking. | |
225 | if (get_bits_left(&gb) < 64) | |
226 | return -1; | |
227 | ||
228 | frame_flags = get_bits_long(&gb, 32); | |
229 | frame_size = get_bits_long(&gb, 32); | |
230 | ||
231 | // Leave last frame unchanged | |
232 | // FIXME: Is this necessary? I haven't seen it in any real samples | |
233 | if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { | |
234 | if (!s->frame->data[0]) | |
235 | return AVERROR_INVALIDDATA; | |
236 | ||
237 | av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); | |
238 | ||
239 | *got_frame = 1; | |
240 | if ((ret = av_frame_ref(frame, s->frame)) < 0) | |
241 | return ret; | |
242 | ||
243 | return frame_size; | |
244 | } | |
245 | ||
246 | for (i = 0; i < 3; i++) { | |
247 | if (frame_flags & (1 << (17 + i))) { | |
248 | unsigned cb_depth, cb_size; | |
249 | if (i == 2) { | |
250 | // This codebook can be cut off at places other than | |
251 | // powers of 2, leaving some of the entries undefined. | |
252 | cb_size = get_bits_long(&gb, 20); | |
253 | cb_depth = av_log2(cb_size - 1) + 1; | |
254 | } else { | |
255 | cb_depth = get_bits(&gb, 4); | |
256 | if (i == 0) { | |
257 | // This is the most basic codebook: pow(2,depth) entries | |
258 | // for a depth-length key | |
259 | cb_size = 1 << cb_depth; | |
260 | } else { | |
261 | // This codebook varies per superblock | |
262 | // FIXME: I don't think this handles integer overflow | |
263 | // properly | |
264 | cb_size = s->num_superblocks << cb_depth; | |
265 | } | |
266 | } | |
f6fa7814 | 267 | av_freep(&s->codebooks[i].blocks); |
2ba45a60 DM |
268 | s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); |
269 | if (!s->codebooks[i].blocks) | |
270 | return -1; | |
271 | } | |
272 | } | |
273 | ||
274 | if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) | |
275 | return ret; | |
276 | ||
277 | new_frame_data = (uint16_t*)frame->data[0]; | |
278 | new_stride = frame->linesize[0] / 2; | |
279 | old_frame_data = (uint16_t*)s->frame->data[0]; | |
280 | old_stride = s->frame->linesize[0] / 2; | |
281 | ||
282 | for (superblock_index = 0; superblock_index < s->num_superblocks; | |
283 | superblock_index++) { | |
284 | MacroBlock mb; | |
285 | SuperBlock sb; | |
286 | unsigned multi_mask = 0; | |
287 | ||
288 | if (skip == -1) { | |
289 | // Note that this call will make us skip the rest of the blocks | |
290 | // if the frame prematurely ends | |
291 | skip = decode_skip_count(&gb); | |
292 | } | |
293 | ||
294 | if (skip) { | |
295 | copy_superblock(new_frame_data, new_stride, | |
296 | old_frame_data, old_stride); | |
297 | } else { | |
298 | copy_superblock(sb.pixels, 8, | |
299 | old_frame_data, old_stride); | |
300 | ||
301 | while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { | |
302 | unsigned mask; | |
303 | mb = decode_macroblock(s, &gb, &cb_index, superblock_index); | |
304 | mask = get_bits(&gb, 16); | |
305 | multi_mask |= mask; | |
306 | for (i = 0; i < 16; i++) { | |
307 | if (mask & mask_matrix[i]) { | |
308 | insert_mb_into_sb(&sb, mb, i); | |
309 | } | |
310 | } | |
311 | } | |
312 | ||
313 | if (!get_bits1(&gb)) { | |
314 | unsigned inv_mask = get_bits(&gb, 4); | |
315 | for (i = 0; i < 4; i++) { | |
316 | if (inv_mask & (1 << i)) { | |
317 | multi_mask ^= 0xF << i*4; | |
318 | } else { | |
319 | multi_mask ^= get_bits(&gb, 4) << i*4; | |
320 | } | |
321 | } | |
322 | ||
323 | for (i = 0; i < 16; i++) { | |
324 | if (multi_mask & mask_matrix[i]) { | |
325 | mb = decode_macroblock(s, &gb, &cb_index, | |
326 | superblock_index); | |
327 | insert_mb_into_sb(&sb, mb, i); | |
328 | } | |
329 | } | |
330 | } else if (frame_flags & (1 << 16)) { | |
331 | while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { | |
332 | mb = decode_macroblock(s, &gb, &cb_index, superblock_index); | |
333 | insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); | |
334 | } | |
335 | } | |
336 | ||
337 | copy_superblock(new_frame_data, new_stride, sb.pixels, 8); | |
338 | } | |
339 | ||
340 | superblock_col_index++; | |
341 | new_frame_data += 8; | |
342 | if (old_frame_data) | |
343 | old_frame_data += 8; | |
344 | if (superblock_col_index == superblocks_per_row) { | |
345 | new_frame_data += new_stride * 8 - superblocks_per_row * 8; | |
346 | if (old_frame_data) | |
347 | old_frame_data += old_stride * 8 - superblocks_per_row * 8; | |
348 | superblock_col_index = 0; | |
349 | } | |
350 | skip--; | |
351 | } | |
352 | ||
353 | av_log(avctx, AV_LOG_DEBUG, | |
354 | "Escape sizes: %i, %i, %i\n", | |
355 | frame_size, buf_size, get_bits_count(&gb) / 8); | |
356 | ||
357 | av_frame_unref(s->frame); | |
358 | if ((ret = av_frame_ref(s->frame, frame)) < 0) | |
359 | return ret; | |
360 | ||
361 | *got_frame = 1; | |
362 | ||
363 | return frame_size; | |
364 | } | |
365 | ||
366 | ||
367 | AVCodec ff_escape124_decoder = { | |
368 | .name = "escape124", | |
369 | .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), | |
370 | .type = AVMEDIA_TYPE_VIDEO, | |
371 | .id = AV_CODEC_ID_ESCAPE124, | |
372 | .priv_data_size = sizeof(Escape124Context), | |
373 | .init = escape124_decode_init, | |
374 | .close = escape124_decode_close, | |
375 | .decode = escape124_decode_frame, | |
376 | .capabilities = CODEC_CAP_DR1, | |
377 | }; |