Mercurial > libavcodec.hg
annotate smacker.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | ccad7a2ff75f |
children | 8a4984c5cacc |
rev | line source |
---|---|
3209 | 1 /* |
2 * Smacker decoder | |
3 * Copyright (c) 2006 Konstantin Shishkov | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
3209 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
3209 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
3209 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3209 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | |
21 | |
22 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8332
diff
changeset
|
23 * @file libavcodec/smacker.c |
3209 | 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 | |
9428 | 37 #include "get_bits.h" |
6316
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
38 #include "bytestream.h" |
3209 | 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 | |
3303
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
181 if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
182 av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
183 return -1; |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
184 } |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
185 |
3209 | 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); | |
5518 | 205 skip_bits1(gb); |
3209 | 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); | |
5518 | 218 skip_bits1(gb); |
3209 | 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); | |
5518 | 254 skip_bits1(gb); |
3209 | 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 | |
4364 | 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); | |
3209 | 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 } | |
5513 | 294 if(!get_bits1(&gb)) { |
3209 | 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 } | |
5513 | 302 if(!get_bits1(&gb)) { |
3209 | 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 } | |
5513 | 310 if(!get_bits1(&gb)) { |
3209 | 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 | |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
3947
diff
changeset
|
322 static av_always_inline void last_reset(int *recode, int *last) { |
3209 | 323 recode[last[0]] = recode[last[1]] = recode[last[2]] = 0; |
324 } | |
325 | |
326 /* get code and update history */ | |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
3947
diff
changeset
|
327 static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { |
3209 | 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 | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9219
diff
changeset
|
348 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) |
3209 | 349 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9219
diff
changeset
|
350 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9219
diff
changeset
|
351 int buf_size = avpkt->size; |
4827 | 352 SmackVContext * const smk = avctx->priv_data; |
3209 | 353 uint8_t *out; |
354 uint32_t *pal; | |
355 GetBitContext gb; | |
356 int blocks, blk, bw, bh; | |
357 int i; | |
358 int stride; | |
359 | |
6317
2f44646383c8
100l, since we already check for buf_size == 769 we should also
reimar
parents:
6316
diff
changeset
|
360 if(buf_size <= 769) |
3209 | 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 | |
6316
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
381 buf++; |
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
382 for(i = 0; i < 256; i++) |
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
383 *pal++ = bytestream_get_be24(&buf); |
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
384 buf_size -= 769; |
3209 | 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); | |
6316
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
390 init_get_bits(&gb, buf, buf_size * 8); |
3209 | 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; | |
3310
48fc664f7348
Now MPlayer should understand Smacker audio and video codecs.
kostya
parents:
3303
diff
changeset
|
427 if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes |
3209 | 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); | |
5089 | 437 AV_WL16(out+2,pix); |
3209 | 438 pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
5089 | 439 AV_WL16(out,pix); |
3209 | 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; | |
8332 | 462 pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
3209 | 463 pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
5089 | 464 AV_WL16(out,pix1); |
465 AV_WL16(out+2,pix2); | |
3209 | 466 out += stride; |
5089 | 467 AV_WL16(out,pix1); |
468 AV_WL16(out+2,pix2); | |
3209 | 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 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6317
diff
changeset
|
511 static av_cold int decode_init(AVCodecContext *avctx) |
3209 | 512 { |
4827 | 513 SmackVContext * const c = avctx->priv_data; |
3209 | 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 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6317
diff
changeset
|
539 static av_cold int decode_end(AVCodecContext *avctx) |
3209 | 540 { |
4827 | 541 SmackVContext * const smk = avctx->priv_data; |
3209 | 542 |
3694
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
543 av_freep(&smk->mmap_tbl); |
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
544 av_freep(&smk->mclr_tbl); |
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
545 av_freep(&smk->full_tbl); |
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
546 av_freep(&smk->type_tbl); |
3209 | 547 |
548 if (smk->pic.data[0]) | |
549 avctx->release_buffer(avctx, &smk->pic); | |
550 | |
551 return 0; | |
552 } | |
553 | |
554 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6317
diff
changeset
|
555 static av_cold int smka_decode_init(AVCodecContext *avctx) |
3209 | 556 { |
8174
f11197441364
Add channel layout to several audio decoders I maintain
kostya
parents:
7451
diff
changeset
|
557 avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; |
10484
ccad7a2ff75f
Set the sample format for Smacker audio in the decoder rather than in the
jbr
parents:
10397
diff
changeset
|
558 avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? SAMPLE_FMT_U8 : SAMPLE_FMT_S16; |
3209 | 559 return 0; |
560 } | |
561 | |
562 /** | |
563 * Decode Smacker audio data | |
564 */ | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9219
diff
changeset
|
565 static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) |
3209 | 566 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9219
diff
changeset
|
567 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9219
diff
changeset
|
568 int buf_size = avpkt->size; |
3209 | 569 GetBitContext gb; |
570 HuffContext h[4]; | |
571 VLC vlc[4]; | |
572 int16_t *samples = data; | |
9219
00a9a7336fc6
Make Smacker audio decoder output audio in original bit depth
kostya
parents:
8718
diff
changeset
|
573 int8_t *samples8 = data; |
3209 | 574 int val; |
575 int i, res; | |
576 int unp_size; | |
577 int bits, stereo; | |
578 int pred[2] = {0, 0}; | |
579 | |
4364 | 580 unp_size = AV_RL32(buf); |
3209 | 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); | |
9219
00a9a7336fc6
Make Smacker audio decoder output audio in original bit depth
kostya
parents:
8718
diff
changeset
|
591 if (unp_size & 0xC0000000 || unp_size > *data_size) { |
5674
ca944f1db2b3
Add checks on input/output buffers size for some audio decoders
kostya
parents:
5518
diff
changeset
|
592 av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); |
ca944f1db2b3
Add checks on input/output buffers size for some audio decoders
kostya
parents:
5518
diff
changeset
|
593 return -1; |
ca944f1db2b3
Add checks on input/output buffers size for some audio decoders
kostya
parents:
5518
diff
changeset
|
594 } |
3209 | 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)); | |
5518 | 606 skip_bits1(&gb); |
3209 | 607 smacker_decode_tree(&gb, &h[i], 0, 0); |
5518 | 608 skip_bits1(&gb); |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
609 if(h[i].current > 1) { |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
610 res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, |
3209 | 611 h[i].lengths, sizeof(int), sizeof(int), |
612 h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
613 if(res < 0) { |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
614 av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
615 return -1; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
616 } |
3209 | 617 } |
618 } | |
619 if(bits) { //decode 16-bit data | |
4693 | 620 for(i = stereo; i >= 0; i--) |
621 pred[i] = bswap_16(get_bits(&gb, 16)); | |
622 for(i = 0; i < stereo; i++) | |
623 *samples++ = pred[i]; | |
3209 | 624 for(i = 0; i < unp_size / 2; i++) { |
625 if(i & stereo) { | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
626 if(vlc[2].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
627 res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
628 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
629 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
630 val = h[2].values[res]; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
631 if(vlc[3].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
632 res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
633 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
634 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
635 val |= h[3].values[res] << 8; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
636 pred[1] += (int16_t)val; |
3209 | 637 *samples++ = pred[1]; |
638 } else { | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
639 if(vlc[0].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
640 res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
641 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
642 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
643 val = h[0].values[res]; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
644 if(vlc[1].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
645 res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
646 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
647 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
648 val |= h[1].values[res] << 8; |
3209 | 649 pred[0] += val; |
650 *samples++ = pred[0]; | |
651 } | |
652 } | |
653 } else { //8-bit data | |
4693 | 654 for(i = stereo; i >= 0; i--) |
655 pred[i] = get_bits(&gb, 8); | |
656 for(i = 0; i < stereo; i++) | |
9219
00a9a7336fc6
Make Smacker audio decoder output audio in original bit depth
kostya
parents:
8718
diff
changeset
|
657 *samples8++ = pred[i]; |
3209 | 658 for(i = 0; i < unp_size; i++) { |
659 if(i & stereo){ | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
660 if(vlc[1].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
661 res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
662 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
663 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
664 pred[1] += (int8_t)h[1].values[res]; |
9219
00a9a7336fc6
Make Smacker audio decoder output audio in original bit depth
kostya
parents:
8718
diff
changeset
|
665 *samples8++ = pred[1]; |
3209 | 666 } else { |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
667 if(vlc[0].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
668 res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
669 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
670 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
671 pred[0] += (int8_t)h[0].values[res]; |
9219
00a9a7336fc6
Make Smacker audio decoder output audio in original bit depth
kostya
parents:
8718
diff
changeset
|
672 *samples8++ = pred[0]; |
3209 | 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 smacker_decoder = { | |
693 "smackvid", | |
694 CODEC_TYPE_VIDEO, | |
695 CODEC_ID_SMACKVIDEO, | |
696 sizeof(SmackVContext), | |
697 decode_init, | |
698 NULL, | |
699 decode_end, | |
6712 | 700 decode_frame, |
9807
08b84fcd478c
smacker video decoder uses reget_buffer, set CODEC_CAP_DR1
bcoudurier
parents:
9553
diff
changeset
|
701 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
702 .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), |
3209 | 703 }; |
704 | |
705 AVCodec smackaud_decoder = { | |
706 "smackaud", | |
707 CODEC_TYPE_AUDIO, | |
708 CODEC_ID_SMACKAUDIO, | |
709 0, | |
710 smka_decode_init, | |
711 NULL, | |
712 NULL, | |
6712 | 713 smka_decode_frame, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
714 .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), |
3209 | 715 }; |
716 |