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