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