Mercurial > libavcodec.hg
annotate huffman.c @ 9675:2e84b386a8b6 libavcodec
Fix for a problem with inverted sign of output data from ffvorbis decoder.
Now the sign of audio samples in ffvorbis output is the same as in original
uncompressed audio file and this also allows the use of tiny_psnr to compare
ffvorbis with libvorbis/tremor.
author | serge |
---|---|
date | Wed, 20 May 2009 07:24:38 +0000 |
parents | 0dce4fe6e6f3 |
children | 7dd2a45249a9 |
rev | line source |
---|---|
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
1 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8299
diff
changeset
|
2 * @file libavcodec/huffman.c |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
3 * huffman tree builder and VLC generator |
4140 | 4 * Copyright (c) 2006 Konstantin Shishkov |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
5 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
9 * modify it under the terms of the GNU Lesser General Public |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
10 * 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:
3036
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
12 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
16 * Lesser General Public License for more details. |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
17 * |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
18 * 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:
3036
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
21 */ |
2967 | 22 |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
23 #include "avcodec.h" |
9428 | 24 #include "get_bits.h" |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
25 #include "huffman.h" |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
26 |
4140 | 27 /* symbol for Huffman tree node */ |
28 #define HNODE -1 | |
29 | |
30 | |
6473 | 31 static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos, int no_zero_count) |
4140 | 32 { |
33 int s; | |
34 | |
35 s = nodes[node].sym; | |
6473 | 36 if(s != HNODE || (no_zero_count && !nodes[node].count)){ |
4142
79ddfdee291d
Correct support for Fraps v4 (and Huffman tree for < 256 symbols)
kostya
parents:
4141
diff
changeset
|
37 bits[*pos] = pfx; |
79ddfdee291d
Correct support for Fraps v4 (and Huffman tree for < 256 symbols)
kostya
parents:
4141
diff
changeset
|
38 lens[*pos] = pl; |
79ddfdee291d
Correct support for Fraps v4 (and Huffman tree for < 256 symbols)
kostya
parents:
4141
diff
changeset
|
39 xlat[*pos] = s; |
79ddfdee291d
Correct support for Fraps v4 (and Huffman tree for < 256 symbols)
kostya
parents:
4141
diff
changeset
|
40 (*pos)++; |
4140 | 41 }else{ |
42 pfx <<= 1; | |
43 pl++; | |
6473 | 44 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos, |
45 no_zero_count); | |
4140 | 46 pfx |= 1; |
6473 | 47 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos, |
48 no_zero_count); | |
4140 | 49 } |
50 } | |
51 | |
6473 | 52 static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) |
4140 | 53 { |
6473 | 54 int no_zero_count = !(flags & FF_HUFFMAN_FLAG_ZERO_COUNT); |
4140 | 55 uint32_t bits[256]; |
56 int16_t lens[256]; | |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
57 uint8_t xlat[256]; |
4142
79ddfdee291d
Correct support for Fraps v4 (and Huffman tree for < 256 symbols)
kostya
parents:
4141
diff
changeset
|
58 int pos = 0; |
4140 | 59 |
6473 | 60 get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos, no_zero_count); |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
61 return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); |
4140 | 62 } |
63 | |
64 | |
65 /** | |
5824 | 66 * nodes size must be 2*nb_codes |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
67 * first nb_codes nodes.count must be set |
4140 | 68 */ |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
69 int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, |
8299 | 70 Node *nodes, HuffCmp cmp, int flags) |
4140 | 71 { |
72 int i, j; | |
73 int cur_node; | |
74 int64_t sum = 0; | |
75 | |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
76 for(i = 0; i < nb_codes; i++){ |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
77 nodes[i].sym = i; |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
78 nodes[i].n0 = -2; |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
79 sum += nodes[i].count; |
4140 | 80 } |
81 | |
82 if(sum >> 31) { | |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
83 av_log(avctx, AV_LOG_ERROR, "Too high symbol frequencies. Tree construction is not possible\n"); |
4140 | 84 return -1; |
85 } | |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
86 qsort(nodes, nb_codes, sizeof(Node), cmp); |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
87 cur_node = nb_codes; |
5960
94fa03139210
Fix nodes[nb_codes*2-1].count being uninitialized and used to initialize
reimar
parents:
5824
diff
changeset
|
88 nodes[nb_codes*2-1].count = 0; |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
89 for(i = 0; i < nb_codes*2-1; i += 2){ |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
90 nodes[cur_node].sym = HNODE; |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
91 nodes[cur_node].count = nodes[i].count + nodes[i+1].count; |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
92 nodes[cur_node].n0 = i; |
4140 | 93 for(j = cur_node; j > 0; j--){ |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
94 if(nodes[j].count > nodes[j-1].count || |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
95 (nodes[j].count == nodes[j-1].count && |
6472
e39e03d99d24
huffman: pass hnode_first as a flag instead of as an argument on its own
aurel
parents:
5960
diff
changeset
|
96 (!(flags & FF_HUFFMAN_FLAG_HNODE_FIRST) || |
e39e03d99d24
huffman: pass hnode_first as a flag instead of as an argument on its own
aurel
parents:
5960
diff
changeset
|
97 nodes[j].n0==j-1 || nodes[j].n0==j-2 || |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
98 (nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE)))) |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
99 break; |
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
100 FFSWAP(Node, nodes[j], nodes[j-1]); |
4140 | 101 } |
102 cur_node++; | |
103 } | |
6473 | 104 if(build_huff_tree(vlc, nodes, nb_codes*2-2, flags) < 0){ |
5820
ffac546a3861
moves fraps huffman decoder to its own file, making it more generic
aurel
parents:
5215
diff
changeset
|
105 av_log(avctx, AV_LOG_ERROR, "Error building tree\n"); |
2700
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
106 return -1; |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
107 } |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
108 return 0; |
485571c9182f
Fraps FPS1 video decoder (v1 & v2), courtesy of Roine Gustafsson <roine
melanson
parents:
diff
changeset
|
109 } |