ffmpeg / libavcodec / smacker.c @ e4141433
History | View | Annotate | Download (20.6 KB)
1 |
/*
|
---|---|
2 |
* Smacker decoder
|
3 |
* Copyright (c) 2006 Konstantin Shishkov
|
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 |
|
23 |
/**
|
24 |
* @file smacker.c
|
25 |
* Smacker decoder
|
26 |
*/
|
27 |
|
28 |
/*
|
29 |
* Based on http://wiki.multimedia.cx/index.php?title=Smacker
|
30 |
*/
|
31 |
|
32 |
#include <stdio.h> |
33 |
#include <stdlib.h> |
34 |
|
35 |
#include "common.h" |
36 |
#include "avcodec.h" |
37 |
|
38 |
#define ALT_BITSTREAM_READER_LE
|
39 |
#include "bitstream.h" |
40 |
|
41 |
#define SMKTREE_BITS 9 |
42 |
#define SMK_NODE 0x80000000 |
43 |
|
44 |
/*
|
45 |
* Decoder context
|
46 |
*/
|
47 |
typedef struct SmackVContext { |
48 |
AVCodecContext *avctx; |
49 |
AVFrame pic; |
50 |
|
51 |
int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl;
|
52 |
int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; |
53 |
} SmackVContext; |
54 |
|
55 |
/**
|
56 |
* Context used for code reconstructing
|
57 |
*/
|
58 |
typedef struct HuffContext { |
59 |
int length;
|
60 |
int maxlength;
|
61 |
int current;
|
62 |
uint32_t *bits; |
63 |
int *lengths;
|
64 |
int *values;
|
65 |
} HuffContext; |
66 |
|
67 |
/* common parameters used for decode_bigtree */
|
68 |
typedef struct DBCtx { |
69 |
VLC *v1, *v2; |
70 |
int *recode1, *recode2;
|
71 |
int escapes[3]; |
72 |
int *last;
|
73 |
int lcur;
|
74 |
} DBCtx; |
75 |
|
76 |
/* possible runs of blocks */
|
77 |
static const int block_runs[64] = { |
78 |
1, 2, 3, 4, 5, 6, 7, 8, |
79 |
9, 10, 11, 12, 13, 14, 15, 16, |
80 |
17, 18, 19, 20, 21, 22, 23, 24, |
81 |
25, 26, 27, 28, 29, 30, 31, 32, |
82 |
33, 34, 35, 36, 37, 38, 39, 40, |
83 |
41, 42, 43, 44, 45, 46, 47, 48, |
84 |
49, 50, 51, 52, 53, 54, 55, 56, |
85 |
57, 58, 59, 128, 256, 512, 1024, 2048 }; |
86 |
|
87 |
enum SmkBlockTypes {
|
88 |
SMK_BLK_MONO = 0,
|
89 |
SMK_BLK_FULL = 1,
|
90 |
SMK_BLK_SKIP = 2,
|
91 |
SMK_BLK_FILL = 3 };
|
92 |
|
93 |
/**
|
94 |
* Decode local frame tree
|
95 |
*/
|
96 |
static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) |
97 |
{ |
98 |
if(!get_bits1(gb)){ //Leaf |
99 |
if(hc->current >= 256){ |
100 |
av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); |
101 |
return -1; |
102 |
} |
103 |
if(length){
|
104 |
hc->bits[hc->current] = prefix; |
105 |
hc->lengths[hc->current] = length; |
106 |
} else {
|
107 |
hc->bits[hc->current] = 0;
|
108 |
hc->lengths[hc->current] = 0;
|
109 |
} |
110 |
hc->values[hc->current] = get_bits(gb, 8);
|
111 |
hc->current++; |
112 |
if(hc->maxlength < length)
|
113 |
hc->maxlength = length; |
114 |
return 0; |
115 |
} else { //Node |
116 |
int r;
|
117 |
length++; |
118 |
r = smacker_decode_tree(gb, hc, prefix, length); |
119 |
if(r)
|
120 |
return r;
|
121 |
return smacker_decode_tree(gb, hc, prefix | (1 << (length - 1)), length); |
122 |
} |
123 |
} |
124 |
|
125 |
/**
|
126 |
* Decode header tree
|
127 |
*/
|
128 |
static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) |
129 |
{ |
130 |
if(!get_bits1(gb)){ //Leaf |
131 |
int val, i1, i2, b1, b2;
|
132 |
if(hc->current >= hc->length){
|
133 |
av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); |
134 |
return -1; |
135 |
} |
136 |
b1 = get_bits_count(gb); |
137 |
i1 = get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3);
|
138 |
b1 = get_bits_count(gb) - b1; |
139 |
b2 = get_bits_count(gb); |
140 |
i2 = get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3);
|
141 |
b2 = get_bits_count(gb) - b2; |
142 |
val = ctx->recode1[i1] | (ctx->recode2[i2] << 8);
|
143 |
if(val == ctx->escapes[0]) { |
144 |
ctx->last[0] = hc->current;
|
145 |
val = 0;
|
146 |
} else if(val == ctx->escapes[1]) { |
147 |
ctx->last[1] = hc->current;
|
148 |
val = 0;
|
149 |
} else if(val == ctx->escapes[2]) { |
150 |
ctx->last[2] = hc->current;
|
151 |
val = 0;
|
152 |
} |
153 |
|
154 |
hc->values[hc->current++] = val; |
155 |
return 1; |
156 |
} else { //Node |
157 |
int r = 0, t; |
158 |
|
159 |
t = hc->current++; |
160 |
r = smacker_decode_bigtree(gb, hc, ctx); |
161 |
if(r < 0) |
162 |
return r;
|
163 |
hc->values[t] = SMK_NODE | r; |
164 |
r++; |
165 |
r += smacker_decode_bigtree(gb, hc, ctx); |
166 |
return r;
|
167 |
} |
168 |
} |
169 |
|
170 |
/**
|
171 |
* Store large tree as FFmpeg's vlc codes
|
172 |
*/
|
173 |
static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) |
174 |
{ |
175 |
int res;
|
176 |
HuffContext huff; |
177 |
HuffContext tmp1, tmp2; |
178 |
VLC vlc[2];
|
179 |
int escapes[3]; |
180 |
DBCtx ctx; |
181 |
|
182 |
if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow |
183 |
av_log(smk->avctx, AV_LOG_ERROR, "size too large\n");
|
184 |
return -1; |
185 |
} |
186 |
|
187 |
tmp1.length = 256;
|
188 |
tmp1.maxlength = 0;
|
189 |
tmp1.current = 0;
|
190 |
tmp1.bits = av_mallocz(256 * 4); |
191 |
tmp1.lengths = av_mallocz(256 * sizeof(int)); |
192 |
tmp1.values = av_mallocz(256 * sizeof(int)); |
193 |
|
194 |
tmp2.length = 256;
|
195 |
tmp2.maxlength = 0;
|
196 |
tmp2.current = 0;
|
197 |
tmp2.bits = av_mallocz(256 * 4); |
198 |
tmp2.lengths = av_mallocz(256 * sizeof(int)); |
199 |
tmp2.values = av_mallocz(256 * sizeof(int)); |
200 |
|
201 |
memset(&vlc[0], 0, sizeof(VLC)); |
202 |
memset(&vlc[1], 0, sizeof(VLC)); |
203 |
|
204 |
if(get_bits1(gb)) {
|
205 |
smacker_decode_tree(gb, &tmp1, 0, 0); |
206 |
get_bits1(gb); |
207 |
res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length,
|
208 |
tmp1.lengths, sizeof(int), sizeof(int), |
209 |
tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); |
210 |
if(res < 0) { |
211 |
av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
|
212 |
return -1; |
213 |
} |
214 |
} else {
|
215 |
av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n");
|
216 |
} |
217 |
if(get_bits1(gb)){
|
218 |
smacker_decode_tree(gb, &tmp2, 0, 0); |
219 |
get_bits1(gb); |
220 |
res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length,
|
221 |
tmp2.lengths, sizeof(int), sizeof(int), |
222 |
tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); |
223 |
if(res < 0) { |
224 |
av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
|
225 |
return -1; |
226 |
} |
227 |
} else {
|
228 |
av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n");
|
229 |
} |
230 |
|
231 |
escapes[0] = get_bits(gb, 8); |
232 |
escapes[0] |= get_bits(gb, 8) << 8; |
233 |
escapes[1] = get_bits(gb, 8); |
234 |
escapes[1] |= get_bits(gb, 8) << 8; |
235 |
escapes[2] = get_bits(gb, 8); |
236 |
escapes[2] |= get_bits(gb, 8) << 8; |
237 |
|
238 |
last[0] = last[1] = last[2] = -1; |
239 |
|
240 |
ctx.escapes[0] = escapes[0]; |
241 |
ctx.escapes[1] = escapes[1]; |
242 |
ctx.escapes[2] = escapes[2]; |
243 |
ctx.v1 = &vlc[0];
|
244 |
ctx.v2 = &vlc[1];
|
245 |
ctx.recode1 = tmp1.values; |
246 |
ctx.recode2 = tmp2.values; |
247 |
ctx.last = last; |
248 |
|
249 |
huff.length = ((size + 3) >> 2) + 3; |
250 |
huff.maxlength = 0;
|
251 |
huff.current = 0;
|
252 |
huff.values = av_mallocz(huff.length * sizeof(int)); |
253 |
|
254 |
smacker_decode_bigtree(gb, &huff, &ctx); |
255 |
get_bits1(gb); |
256 |
if(ctx.last[0] == -1) ctx.last[0] = huff.current++; |
257 |
if(ctx.last[1] == -1) ctx.last[1] = huff.current++; |
258 |
if(ctx.last[2] == -1) ctx.last[2] = huff.current++; |
259 |
|
260 |
*recodes = huff.values; |
261 |
|
262 |
if(vlc[0].table) |
263 |
free_vlc(&vlc[0]);
|
264 |
if(vlc[1].table) |
265 |
free_vlc(&vlc[1]);
|
266 |
av_free(tmp1.bits); |
267 |
av_free(tmp1.lengths); |
268 |
av_free(tmp1.values); |
269 |
av_free(tmp2.bits); |
270 |
av_free(tmp2.lengths); |
271 |
av_free(tmp2.values); |
272 |
|
273 |
return 0; |
274 |
} |
275 |
|
276 |
static int decode_header_trees(SmackVContext *smk) { |
277 |
GetBitContext gb; |
278 |
int mmap_size, mclr_size, full_size, type_size;
|
279 |
|
280 |
mmap_size = AV_RL32(smk->avctx->extradata); |
281 |
mclr_size = AV_RL32(smk->avctx->extradata + 4);
|
282 |
full_size = AV_RL32(smk->avctx->extradata + 8);
|
283 |
type_size = AV_RL32(smk->avctx->extradata + 12);
|
284 |
|
285 |
init_get_bits(&gb, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); |
286 |
|
287 |
if(!get_bits1(&gb)) {
|
288 |
av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n");
|
289 |
smk->mmap_tbl = av_malloc(sizeof(int) * 2); |
290 |
smk->mmap_tbl[0] = 0; |
291 |
smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; |
292 |
} else {
|
293 |
smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); |
294 |
} |
295 |
if(!get_bits(&gb, 1)) { |
296 |
av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n");
|
297 |
smk->mclr_tbl = av_malloc(sizeof(int) * 2); |
298 |
smk->mclr_tbl[0] = 0; |
299 |
smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; |
300 |
} else {
|
301 |
smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); |
302 |
} |
303 |
if(!get_bits(&gb, 1)) { |
304 |
av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n");
|
305 |
smk->full_tbl = av_malloc(sizeof(int) * 2); |
306 |
smk->full_tbl[0] = 0; |
307 |
smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; |
308 |
} else {
|
309 |
smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); |
310 |
} |
311 |
if(!get_bits(&gb, 1)) { |
312 |
av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n");
|
313 |
smk->type_tbl = av_malloc(sizeof(int) * 2); |
314 |
smk->type_tbl[0] = 0; |
315 |
smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; |
316 |
} else {
|
317 |
smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); |
318 |
} |
319 |
|
320 |
return 0; |
321 |
} |
322 |
|
323 |
static av_always_inline void last_reset(int *recode, int *last) { |
324 |
recode[last[0]] = recode[last[1]] = recode[last[2]] = 0; |
325 |
} |
326 |
|
327 |
/* get code and update history */
|
328 |
static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { |
329 |
register int *table = recode; |
330 |
int v, b;
|
331 |
|
332 |
b = get_bits_count(gb); |
333 |
while(*table & SMK_NODE) {
|
334 |
if(get_bits1(gb))
|
335 |
table += (*table) & (~SMK_NODE); |
336 |
table++; |
337 |
} |
338 |
v = *table; |
339 |
b = get_bits_count(gb) - b; |
340 |
|
341 |
if(v != recode[last[0]]) { |
342 |
recode[last[2]] = recode[last[1]]; |
343 |
recode[last[1]] = recode[last[0]]; |
344 |
recode[last[0]] = v;
|
345 |
} |
346 |
return v;
|
347 |
} |
348 |
|
349 |
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) |
350 |
{ |
351 |
SmackVContext * const smk = avctx->priv_data;
|
352 |
uint8_t *out; |
353 |
uint32_t *pal; |
354 |
GetBitContext gb; |
355 |
int blocks, blk, bw, bh;
|
356 |
int i;
|
357 |
int stride;
|
358 |
|
359 |
if(buf_size == 769) |
360 |
return 0; |
361 |
if(smk->pic.data[0]) |
362 |
avctx->release_buffer(avctx, &smk->pic); |
363 |
|
364 |
smk->pic.reference = 1;
|
365 |
smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; |
366 |
if(avctx->reget_buffer(avctx, &smk->pic) < 0){ |
367 |
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
368 |
return -1; |
369 |
} |
370 |
|
371 |
/* make the palette available on the way out */
|
372 |
out = buf + 1;
|
373 |
pal = (uint32_t*)smk->pic.data[1];
|
374 |
smk->pic.palette_has_changed = buf[0] & 1; |
375 |
smk->pic.key_frame = !!(buf[0] & 2); |
376 |
if(smk->pic.key_frame)
|
377 |
smk->pic.pict_type = FF_I_TYPE; |
378 |
else
|
379 |
smk->pic.pict_type = FF_P_TYPE; |
380 |
|
381 |
for(i = 0; i < 256; i++) { |
382 |
int r, g, b;
|
383 |
r = *out++; |
384 |
g = *out++; |
385 |
b = *out++; |
386 |
*pal++ = (r << 16) | (g << 8) | b; |
387 |
} |
388 |
|
389 |
last_reset(smk->mmap_tbl, smk->mmap_last); |
390 |
last_reset(smk->mclr_tbl, smk->mclr_last); |
391 |
last_reset(smk->full_tbl, smk->full_last); |
392 |
last_reset(smk->type_tbl, smk->type_last); |
393 |
init_get_bits(&gb, buf + 769, (buf_size - 769) * 8); |
394 |
|
395 |
blk = 0;
|
396 |
bw = avctx->width >> 2;
|
397 |
bh = avctx->height >> 2;
|
398 |
blocks = bw * bh; |
399 |
out = smk->pic.data[0];
|
400 |
stride = smk->pic.linesize[0];
|
401 |
while(blk < blocks) {
|
402 |
int type, run, mode;
|
403 |
uint16_t pix; |
404 |
|
405 |
type = smk_get_code(&gb, smk->type_tbl, smk->type_last); |
406 |
run = block_runs[(type >> 2) & 0x3F]; |
407 |
switch(type & 3){ |
408 |
case SMK_BLK_MONO:
|
409 |
while(run-- && blk < blocks){
|
410 |
int clr, map;
|
411 |
int hi, lo;
|
412 |
clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); |
413 |
map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); |
414 |
out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; |
415 |
hi = clr >> 8;
|
416 |
lo = clr & 0xFF;
|
417 |
for(i = 0; i < 4; i++) { |
418 |
if(map & 1) out[0] = hi; else out[0] = lo; |
419 |
if(map & 2) out[1] = hi; else out[1] = lo; |
420 |
if(map & 4) out[2] = hi; else out[2] = lo; |
421 |
if(map & 8) out[3] = hi; else out[3] = lo; |
422 |
map >>= 4;
|
423 |
out += stride; |
424 |
} |
425 |
blk++; |
426 |
} |
427 |
break;
|
428 |
case SMK_BLK_FULL:
|
429 |
mode = 0;
|
430 |
if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes |
431 |
if(get_bits1(&gb)) mode = 1; |
432 |
else if(get_bits1(&gb)) mode = 2; |
433 |
} |
434 |
while(run-- && blk < blocks){
|
435 |
out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; |
436 |
switch(mode){
|
437 |
case 0: |
438 |
for(i = 0; i < 4; i++) { |
439 |
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
440 |
out[2] = pix & 0xFF; |
441 |
out[3] = pix >> 8; |
442 |
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
443 |
out[0] = pix & 0xFF; |
444 |
out[1] = pix >> 8; |
445 |
out += stride; |
446 |
} |
447 |
break;
|
448 |
case 1: |
449 |
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
450 |
out[0] = out[1] = pix & 0xFF; |
451 |
out[2] = out[3] = pix >> 8; |
452 |
out += stride; |
453 |
out[0] = out[1] = pix & 0xFF; |
454 |
out[2] = out[3] = pix >> 8; |
455 |
out += stride; |
456 |
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
457 |
out[0] = out[1] = pix & 0xFF; |
458 |
out[2] = out[3] = pix >> 8; |
459 |
out += stride; |
460 |
out[0] = out[1] = pix & 0xFF; |
461 |
out[2] = out[3] = pix >> 8; |
462 |
out += stride; |
463 |
break;
|
464 |
case 2: |
465 |
for(i = 0; i < 2; i++) { |
466 |
uint16_t pix1, pix2; |
467 |
pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
468 |
pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
469 |
out[0] = pix1 & 0xFF; out[1] = pix1 >> 8; |
470 |
out[2] = pix2 & 0xFF; out[3] = pix2 >> 8; |
471 |
out += stride; |
472 |
out[0] = pix1 & 0xFF; out[1] = pix1 >> 8; |
473 |
out[2] = pix2 & 0xFF; out[3] = pix2 >> 8; |
474 |
out += stride; |
475 |
} |
476 |
break;
|
477 |
} |
478 |
blk++; |
479 |
} |
480 |
break;
|
481 |
case SMK_BLK_SKIP:
|
482 |
while(run-- && blk < blocks)
|
483 |
blk++; |
484 |
break;
|
485 |
case SMK_BLK_FILL:
|
486 |
mode = type >> 8;
|
487 |
while(run-- && blk < blocks){
|
488 |
uint32_t col; |
489 |
out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; |
490 |
col = mode * 0x01010101;
|
491 |
for(i = 0; i < 4; i++) { |
492 |
*((uint32_t*)out) = col; |
493 |
out += stride; |
494 |
} |
495 |
blk++; |
496 |
} |
497 |
break;
|
498 |
} |
499 |
|
500 |
} |
501 |
|
502 |
*data_size = sizeof(AVFrame);
|
503 |
*(AVFrame*)data = smk->pic; |
504 |
|
505 |
/* always report that the buffer was completely consumed */
|
506 |
return buf_size;
|
507 |
} |
508 |
|
509 |
|
510 |
|
511 |
/*
|
512 |
*
|
513 |
* Init smacker decoder
|
514 |
*
|
515 |
*/
|
516 |
static int decode_init(AVCodecContext *avctx) |
517 |
{ |
518 |
SmackVContext * const c = avctx->priv_data;
|
519 |
|
520 |
c->avctx = avctx; |
521 |
|
522 |
c->pic.data[0] = NULL; |
523 |
|
524 |
if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
525 |
return 1; |
526 |
} |
527 |
|
528 |
avctx->pix_fmt = PIX_FMT_PAL8; |
529 |
|
530 |
|
531 |
/* decode huffman trees from extradata */
|
532 |
if(avctx->extradata_size < 16){ |
533 |
av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
|
534 |
return -1; |
535 |
} |
536 |
|
537 |
decode_header_trees(c); |
538 |
|
539 |
|
540 |
return 0; |
541 |
} |
542 |
|
543 |
|
544 |
|
545 |
/*
|
546 |
*
|
547 |
* Uninit smacker decoder
|
548 |
*
|
549 |
*/
|
550 |
static int decode_end(AVCodecContext *avctx) |
551 |
{ |
552 |
SmackVContext * const smk = avctx->priv_data;
|
553 |
|
554 |
av_freep(&smk->mmap_tbl); |
555 |
av_freep(&smk->mclr_tbl); |
556 |
av_freep(&smk->full_tbl); |
557 |
av_freep(&smk->type_tbl); |
558 |
|
559 |
if (smk->pic.data[0]) |
560 |
avctx->release_buffer(avctx, &smk->pic); |
561 |
|
562 |
return 0; |
563 |
} |
564 |
|
565 |
|
566 |
static int smka_decode_init(AVCodecContext *avctx) |
567 |
{ |
568 |
return 0; |
569 |
} |
570 |
|
571 |
/**
|
572 |
* Decode Smacker audio data
|
573 |
*/
|
574 |
static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) |
575 |
{ |
576 |
GetBitContext gb; |
577 |
HuffContext h[4];
|
578 |
VLC vlc[4];
|
579 |
int16_t *samples = data; |
580 |
int val;
|
581 |
int i, res;
|
582 |
int unp_size;
|
583 |
int bits, stereo;
|
584 |
int pred[2] = {0, 0}; |
585 |
|
586 |
unp_size = AV_RL32(buf); |
587 |
|
588 |
init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); |
589 |
|
590 |
if(!get_bits1(&gb)){
|
591 |
av_log(avctx, AV_LOG_INFO, "Sound: no data\n");
|
592 |
*data_size = 0;
|
593 |
return 1; |
594 |
} |
595 |
stereo = get_bits1(&gb); |
596 |
bits = get_bits1(&gb); |
597 |
|
598 |
memset(vlc, 0, sizeof(VLC) * 4); |
599 |
memset(h, 0, sizeof(HuffContext) * 4); |
600 |
// Initialize
|
601 |
for(i = 0; i < (1 << (bits + stereo)); i++) { |
602 |
h[i].length = 256;
|
603 |
h[i].maxlength = 0;
|
604 |
h[i].current = 0;
|
605 |
h[i].bits = av_mallocz(256 * 4); |
606 |
h[i].lengths = av_mallocz(256 * sizeof(int)); |
607 |
h[i].values = av_mallocz(256 * sizeof(int)); |
608 |
get_bits1(&gb); |
609 |
smacker_decode_tree(&gb, &h[i], 0, 0); |
610 |
get_bits1(&gb); |
611 |
if(h[i].current > 1) { |
612 |
res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, |
613 |
h[i].lengths, sizeof(int), sizeof(int), |
614 |
h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); |
615 |
if(res < 0) { |
616 |
av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
|
617 |
return -1; |
618 |
} |
619 |
} |
620 |
} |
621 |
if(bits) { //decode 16-bit data |
622 |
for(i = stereo; i >= 0; i--) |
623 |
pred[i] = bswap_16(get_bits(&gb, 16));
|
624 |
for(i = 0; i < stereo; i++) |
625 |
*samples++ = pred[i]; |
626 |
for(i = 0; i < unp_size / 2; i++) { |
627 |
if(i & stereo) {
|
628 |
if(vlc[2].table) |
629 |
res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); |
630 |
else
|
631 |
res = 0;
|
632 |
val = h[2].values[res];
|
633 |
if(vlc[3].table) |
634 |
res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); |
635 |
else
|
636 |
res = 0;
|
637 |
val |= h[3].values[res] << 8; |
638 |
pred[1] += (int16_t)val;
|
639 |
*samples++ = pred[1];
|
640 |
} else {
|
641 |
if(vlc[0].table) |
642 |
res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
643 |
else
|
644 |
res = 0;
|
645 |
val = h[0].values[res];
|
646 |
if(vlc[1].table) |
647 |
res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
648 |
else
|
649 |
res = 0;
|
650 |
val |= h[1].values[res] << 8; |
651 |
pred[0] += val;
|
652 |
*samples++ = pred[0];
|
653 |
} |
654 |
} |
655 |
} else { //8-bit data |
656 |
for(i = stereo; i >= 0; i--) |
657 |
pred[i] = get_bits(&gb, 8);
|
658 |
for(i = 0; i < stereo; i++) |
659 |
*samples++ = (pred[i] - 0x80) << 8; |
660 |
for(i = 0; i < unp_size; i++) { |
661 |
if(i & stereo){
|
662 |
if(vlc[1].table) |
663 |
res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
664 |
else
|
665 |
res = 0;
|
666 |
pred[1] += (int8_t)h[1].values[res]; |
667 |
*samples++ = (pred[1] - 0x80) << 8; |
668 |
} else {
|
669 |
if(vlc[0].table) |
670 |
res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
671 |
else
|
672 |
res = 0;
|
673 |
pred[0] += (int8_t)h[0].values[res]; |
674 |
*samples++ = (pred[0] - 0x80) << 8; |
675 |
} |
676 |
} |
677 |
unp_size *= 2;
|
678 |
} |
679 |
|
680 |
for(i = 0; i < 4; i++) { |
681 |
if(vlc[i].table)
|
682 |
free_vlc(&vlc[i]); |
683 |
if(h[i].bits)
|
684 |
av_free(h[i].bits); |
685 |
if(h[i].lengths)
|
686 |
av_free(h[i].lengths); |
687 |
if(h[i].values)
|
688 |
av_free(h[i].values); |
689 |
} |
690 |
|
691 |
*data_size = unp_size; |
692 |
return buf_size;
|
693 |
} |
694 |
|
695 |
AVCodec smacker_decoder = { |
696 |
"smackvid",
|
697 |
CODEC_TYPE_VIDEO, |
698 |
CODEC_ID_SMACKVIDEO, |
699 |
sizeof(SmackVContext),
|
700 |
decode_init, |
701 |
NULL,
|
702 |
decode_end, |
703 |
decode_frame |
704 |
}; |
705 |
|
706 |
AVCodec smackaud_decoder = { |
707 |
"smackaud",
|
708 |
CODEC_TYPE_AUDIO, |
709 |
CODEC_ID_SMACKAUDIO, |
710 |
0,
|
711 |
smka_decode_init, |
712 |
NULL,
|
713 |
NULL,
|
714 |
smka_decode_frame |
715 |
}; |
716 |
|