ffmpeg / libavcodec / smacker.c @ 9106a698
History | View | Annotate | Download (20.9 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 libavcodec/smacker.c
|
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 |
c->pic.data[0] = NULL; |
518 |
|
519 |
if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
520 |
return 1; |
521 |
} |
522 |
|
523 |
avctx->pix_fmt = PIX_FMT_PAL8; |
524 |
|
525 |
|
526 |
/* decode huffman trees from extradata */
|
527 |
if(avctx->extradata_size < 16){ |
528 |
av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
|
529 |
return -1; |
530 |
} |
531 |
|
532 |
decode_header_trees(c); |
533 |
|
534 |
|
535 |
return 0; |
536 |
} |
537 |
|
538 |
|
539 |
|
540 |
/*
|
541 |
*
|
542 |
* Uninit smacker decoder
|
543 |
*
|
544 |
*/
|
545 |
static av_cold int decode_end(AVCodecContext *avctx) |
546 |
{ |
547 |
SmackVContext * const smk = avctx->priv_data;
|
548 |
|
549 |
av_freep(&smk->mmap_tbl); |
550 |
av_freep(&smk->mclr_tbl); |
551 |
av_freep(&smk->full_tbl); |
552 |
av_freep(&smk->type_tbl); |
553 |
|
554 |
if (smk->pic.data[0]) |
555 |
avctx->release_buffer(avctx, &smk->pic); |
556 |
|
557 |
return 0; |
558 |
} |
559 |
|
560 |
|
561 |
static av_cold int smka_decode_init(AVCodecContext *avctx) |
562 |
{ |
563 |
avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO;
|
564 |
return 0; |
565 |
} |
566 |
|
567 |
/**
|
568 |
* Decode Smacker audio data
|
569 |
*/
|
570 |
static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) |
571 |
{ |
572 |
const uint8_t *buf = avpkt->data;
|
573 |
int buf_size = avpkt->size;
|
574 |
GetBitContext gb; |
575 |
HuffContext h[4];
|
576 |
VLC vlc[4];
|
577 |
int16_t *samples = data; |
578 |
int8_t *samples8 = data; |
579 |
int val;
|
580 |
int i, res;
|
581 |
int unp_size;
|
582 |
int bits, stereo;
|
583 |
int pred[2] = {0, 0}; |
584 |
|
585 |
unp_size = AV_RL32(buf); |
586 |
|
587 |
init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); |
588 |
|
589 |
if(!get_bits1(&gb)){
|
590 |
av_log(avctx, AV_LOG_INFO, "Sound: no data\n");
|
591 |
*data_size = 0;
|
592 |
return 1; |
593 |
} |
594 |
stereo = get_bits1(&gb); |
595 |
bits = get_bits1(&gb); |
596 |
if (unp_size & 0xC0000000 || unp_size > *data_size) { |
597 |
av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n");
|
598 |
return -1; |
599 |
} |
600 |
|
601 |
memset(vlc, 0, sizeof(VLC) * 4); |
602 |
memset(h, 0, sizeof(HuffContext) * 4); |
603 |
// Initialize
|
604 |
for(i = 0; i < (1 << (bits + stereo)); i++) { |
605 |
h[i].length = 256;
|
606 |
h[i].maxlength = 0;
|
607 |
h[i].current = 0;
|
608 |
h[i].bits = av_mallocz(256 * 4); |
609 |
h[i].lengths = av_mallocz(256 * sizeof(int)); |
610 |
h[i].values = av_mallocz(256 * sizeof(int)); |
611 |
skip_bits1(&gb); |
612 |
smacker_decode_tree(&gb, &h[i], 0, 0); |
613 |
skip_bits1(&gb); |
614 |
if(h[i].current > 1) { |
615 |
res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, |
616 |
h[i].lengths, sizeof(int), sizeof(int), |
617 |
h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); |
618 |
if(res < 0) { |
619 |
av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
|
620 |
return -1; |
621 |
} |
622 |
} |
623 |
} |
624 |
if(bits) { //decode 16-bit data |
625 |
for(i = stereo; i >= 0; i--) |
626 |
pred[i] = bswap_16(get_bits(&gb, 16));
|
627 |
for(i = 0; i < stereo; i++) |
628 |
*samples++ = pred[i]; |
629 |
for(i = 0; i < unp_size / 2; i++) { |
630 |
if(i & stereo) {
|
631 |
if(vlc[2].table) |
632 |
res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); |
633 |
else
|
634 |
res = 0;
|
635 |
val = h[2].values[res];
|
636 |
if(vlc[3].table) |
637 |
res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); |
638 |
else
|
639 |
res = 0;
|
640 |
val |= h[3].values[res] << 8; |
641 |
pred[1] += (int16_t)val;
|
642 |
*samples++ = pred[1];
|
643 |
} else {
|
644 |
if(vlc[0].table) |
645 |
res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
646 |
else
|
647 |
res = 0;
|
648 |
val = h[0].values[res];
|
649 |
if(vlc[1].table) |
650 |
res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
651 |
else
|
652 |
res = 0;
|
653 |
val |= h[1].values[res] << 8; |
654 |
pred[0] += val;
|
655 |
*samples++ = pred[0];
|
656 |
} |
657 |
} |
658 |
} else { //8-bit data |
659 |
for(i = stereo; i >= 0; i--) |
660 |
pred[i] = get_bits(&gb, 8);
|
661 |
for(i = 0; i < stereo; i++) |
662 |
*samples8++ = pred[i]; |
663 |
for(i = 0; i < unp_size; i++) { |
664 |
if(i & stereo){
|
665 |
if(vlc[1].table) |
666 |
res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
667 |
else
|
668 |
res = 0;
|
669 |
pred[1] += (int8_t)h[1].values[res]; |
670 |
*samples8++ = pred[1];
|
671 |
} else {
|
672 |
if(vlc[0].table) |
673 |
res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
674 |
else
|
675 |
res = 0;
|
676 |
pred[0] += (int8_t)h[0].values[res]; |
677 |
*samples8++ = pred[0];
|
678 |
} |
679 |
} |
680 |
} |
681 |
|
682 |
for(i = 0; i < 4; i++) { |
683 |
if(vlc[i].table)
|
684 |
free_vlc(&vlc[i]); |
685 |
if(h[i].bits)
|
686 |
av_free(h[i].bits); |
687 |
if(h[i].lengths)
|
688 |
av_free(h[i].lengths); |
689 |
if(h[i].values)
|
690 |
av_free(h[i].values); |
691 |
} |
692 |
|
693 |
*data_size = unp_size; |
694 |
return buf_size;
|
695 |
} |
696 |
|
697 |
AVCodec smacker_decoder = { |
698 |
"smackvid",
|
699 |
CODEC_TYPE_VIDEO, |
700 |
CODEC_ID_SMACKVIDEO, |
701 |
sizeof(SmackVContext),
|
702 |
decode_init, |
703 |
NULL,
|
704 |
decode_end, |
705 |
decode_frame, |
706 |
.long_name = NULL_IF_CONFIG_SMALL("Smacker video"),
|
707 |
}; |
708 |
|
709 |
AVCodec smackaud_decoder = { |
710 |
"smackaud",
|
711 |
CODEC_TYPE_AUDIO, |
712 |
CODEC_ID_SMACKAUDIO, |
713 |
0,
|
714 |
smka_decode_init, |
715 |
NULL,
|
716 |
NULL,
|
717 |
smka_decode_frame, |
718 |
.long_name = NULL_IF_CONFIG_SMALL("Smacker audio"),
|
719 |
}; |
720 |
|