annotate idcinvideo.c @ 5311:7742d5411c9d libavcodec

AC-3 decoder, soc revision 48, Aug 16 11:27:49 2006 UTC by cloud9 I realized that the bug was not in the imdct routine but in the get_transform_coeffs. Fixed it. Code now uses the ffmpeg's imdct routines. All the mplayer's ac3 samples are decoded successfully. Also improved downmixing. Now all the downmixing coeffcients for channels are normalized such that the sum of coefficients used to construct the output for single channel never exceeds 1.0.
author jbr
date Sat, 14 Jul 2007 15:58:42 +0000
parents 2b72f9bc4f06
children dfdff1ca78a7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
1 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
2 * Id Quake II CIN Video Decoder
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
3 * Copyright (C) 2003 the ffmpeg project
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
4 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
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: 3036
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
15 * Lesser General Public License for more details.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
16 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
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: 3036
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2508
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
20 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
21
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
22 /**
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
23 * @file idcinvideo.c
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
24 * Id Quake II Cin Video Decoder by Dr. Tim Ferguson
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
25 * For more information about the Id CIN format, visit:
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
26 * http://www.csse.monash.edu.au/~timf/
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
27 *
1499
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
28 * This video decoder outputs PAL8 colorspace data. Interacting with this
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
29 * decoder is a little involved. During initialization, the demuxer must
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
30 * transmit the 65536-byte Huffman table(s) to the decoder via extradata.
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
31 * Then, whenever a palette change is encountered while demuxing the file,
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
32 * the demuxer must use the same extradata space to transmit an
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
33 * AVPaletteControl structure.
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
34 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
35 * Id CIN video is purely Huffman-coded, intraframe-only codec. It achieves
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
36 * a little more compression by exploiting the fact that adjacent pixels
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
37 * tend to be similar.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
38 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
39 * Note that this decoder could use ffmpeg's optimized VLC facilities
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
40 * rather than naive, tree-based Huffman decoding. However, there are 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
41 * Huffman tables. Plus, the VLC bit coding order is right -> left instead
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
42 * or left -> right, so all of the bits would have to be reversed. Further,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
43 * the original Quake II implementation likely used a similar naive
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
44 * decoding algorithm and it worked fine on much lower spec machines.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
45 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
46
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
47 #include <stdio.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
48 #include <stdlib.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
49 #include <string.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
50 #include <unistd.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
51
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
52 #include "avcodec.h"
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
53 #include "dsputil.h"
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
54
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
55 #define HUFFMAN_TABLE_SIZE 64 * 1024
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
56 #define HUF_TOKENS 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
57 #define PALETTE_COUNT 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
58
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
59 typedef struct
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
60 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
61 int count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
62 unsigned char used;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
63 int children[2];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
64 } hnode_t;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
65
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
66 typedef struct IdcinContext {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
67
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
68 AVCodecContext *avctx;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
69 DSPContext dsp;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
70 AVFrame frame;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
71
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
72 unsigned char *buf;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
73 int size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
74
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
75 hnode_t huff_nodes[256][HUF_TOKENS*2];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
76 int num_huff_nodes[256];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
77
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
78 } IdcinContext;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
79
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
80 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
81 * Find the lowest probability node in a Huffman table, and mark it as
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
82 * being assigned to a higher probability.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
83 * Returns the node index of the lowest unused node, or -1 if all nodes
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
84 * are used.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
85 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
86 static int huff_smallest_node(hnode_t *hnodes, int num_hnodes) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
87 int i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
88 int best, best_node;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
89
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
90 best = 99999999;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
91 best_node = -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
92 for(i = 0; i < num_hnodes; i++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
93 if(hnodes[i].used)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
94 continue;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
95 if(!hnodes[i].count)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
96 continue;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
97 if(hnodes[i].count < best) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
98 best = hnodes[i].count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
99 best_node = i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
100 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
101 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
102
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
103 if(best_node == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
104 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
105 hnodes[best_node].used = 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
106 return best_node;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
107 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
108
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
109 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
110 * Build the Huffman tree using the generated/loaded probabilities histogram.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
111 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
112 * On completion:
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
113 * huff_nodes[prev][i < HUF_TOKENS] - are the nodes at the base of the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
114 * huff_nodes[prev][i >= HUF_TOKENS] - are used to construct the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
115 * num_huff_nodes[prev] - contains the index to the root node of the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
116 * That is: huff_nodes[prev][num_huff_nodes[prev]] is the root node.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
117 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
118 static void huff_build_tree(IdcinContext *s, int prev) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
119 hnode_t *node, *hnodes;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
120 int num_hnodes, i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
121
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
122 num_hnodes = HUF_TOKENS;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
123 hnodes = s->huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
124 for(i = 0; i < HUF_TOKENS * 2; i++)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
125 hnodes[i].used = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
126
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
127 while (1) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
128 node = &hnodes[num_hnodes]; /* next free node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
129
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
130 /* pick two lowest counts */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
131 node->children[0] = huff_smallest_node(hnodes, num_hnodes);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
132 if(node->children[0] == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
133 break; /* reached the root node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
134
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
135 node->children[1] = huff_smallest_node(hnodes, num_hnodes);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
136 if(node->children[1] == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
137 break; /* reached the root node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
138
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
139 /* combine nodes probability for new node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
140 node->count = hnodes[node->children[0]].count +
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
141 hnodes[node->children[1]].count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
142 num_hnodes++;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
143 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
144
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
145 s->num_huff_nodes[prev] = num_hnodes - 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
146 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
147
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
148 static int idcin_decode_init(AVCodecContext *avctx)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
149 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
150 IdcinContext *s = avctx->priv_data;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
151 int i, j, histogram_index = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
152 unsigned char *histograms;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
153
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
154 s->avctx = avctx;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
155 avctx->pix_fmt = PIX_FMT_PAL8;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
156 dsputil_init(&s->dsp, avctx);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
157
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
158 /* make sure the Huffman tables make it */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
159 if (s->avctx->extradata_size != HUFFMAN_TABLE_SIZE) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
160 av_log(s->avctx, AV_LOG_ERROR, " Id CIN video: expected extradata size of %d\n", HUFFMAN_TABLE_SIZE);
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
161 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
162 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
163
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
164 /* build the 256 Huffman decode trees */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
165 histograms = (unsigned char *)s->avctx->extradata;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
166 for (i = 0; i < 256; i++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
167 for(j = 0; j < HUF_TOKENS; j++)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
168 s->huff_nodes[i][j].count = histograms[histogram_index++];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
169 huff_build_tree(s, i);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
170 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
171
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
172 s->frame.data[0] = NULL;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
173
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
174 return 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
175 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
176
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
177 static void idcin_decode_vlcs(IdcinContext *s)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
178 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
179 hnode_t *hnodes;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
180 long x, y;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
181 int prev;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
182 unsigned char v = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
183 int bit_pos, node_num, dat_pos;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
184
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
185 prev = bit_pos = dat_pos = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
186 for (y = 0; y < (s->frame.linesize[0] * s->avctx->height);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
187 y += s->frame.linesize[0]) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
188 for (x = y; x < y + s->avctx->width; x++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
189 node_num = s->num_huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
190 hnodes = s->huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
191
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
192 while(node_num >= HUF_TOKENS) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
193 if(!bit_pos) {
2508
b0ec6f51b5bd Off-by-one bug in libavcodec/idcinvideo.c, caused
michael
parents: 1598
diff changeset
194 if(dat_pos >= s->size) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
195 av_log(s->avctx, AV_LOG_ERROR, "Huffman decode error.\n");
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
196 return;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
197 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
198 bit_pos = 8;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
199 v = s->buf[dat_pos++];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
200 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
201
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
202 node_num = hnodes[node_num].children[v & 0x01];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
203 v = v >> 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
204 bit_pos--;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
205 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
206
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
207 s->frame.data[0][x] = node_num;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
208 prev = node_num;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
209 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
210 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
211 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
212
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
213 static int idcin_decode_frame(AVCodecContext *avctx,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
214 void *data, int *data_size,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
215 uint8_t *buf, int buf_size)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
216 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
217 IdcinContext *s = avctx->priv_data;
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
218 AVPaletteControl *palette_control = avctx->palctrl;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
219
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
220 s->buf = buf;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
221 s->size = buf_size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
222
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
223 if (s->frame.data[0])
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
224 avctx->release_buffer(avctx, &s->frame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
225
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
226 if (avctx->get_buffer(avctx, &s->frame)) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
227 av_log(avctx, AV_LOG_ERROR, " Id CIN Video: get_buffer() failed\n");
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
228 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
229 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
230
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
231 idcin_decode_vlcs(s);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
232
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
233 /* make the palette available on the way out */
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
234 memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4);
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
235 /* If palette changed inform application*/
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
236 if (palette_control->palette_changed) {
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
237 palette_control->palette_changed = 0;
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
238 s->frame.palette_has_changed = 1;
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
239 }
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
240
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
241 *data_size = sizeof(AVFrame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
242 *(AVFrame*)data = s->frame;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
243
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
244 /* report that the buffer was completely consumed */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
245 return buf_size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
246 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
247
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
248 static int idcin_decode_end(AVCodecContext *avctx)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
249 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
250 IdcinContext *s = avctx->priv_data;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
251
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
252 if (s->frame.data[0])
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
253 avctx->release_buffer(avctx, &s->frame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
254
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
255 return 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
256 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
257
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
258 AVCodec idcin_decoder = {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
259 "idcinvideo",
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
260 CODEC_TYPE_VIDEO,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
261 CODEC_ID_IDCIN,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
262 sizeof(IdcinContext),
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
263 idcin_decode_init,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
264 NULL,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
265 idcin_decode_end,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
266 idcin_decode_frame,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
267 CODEC_CAP_DR1,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
268 };
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
269