annotate idcinvideo.c @ 3990:746a60ba3177 libavcodec

enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author michael
date Wed, 11 Oct 2006 12:23:40 +0000
parents c8c591fe26f8
children 66ef3690d108
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 /**
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
24 * @file idcinvideo.c
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
25 * Id Quake II Cin Video Decoder by Dr. Tim Ferguson
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
26 * For more information about the Id CIN format, visit:
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
27 * http://www.csse.monash.edu.au/~timf/
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
28 *
1499
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
29 * This video decoder outputs PAL8 colorspace data. Interacting with this
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
30 * decoder is a little involved. During initialization, the demuxer must
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
31 * transmit the 65536-byte Huffman table(s) to the decoder via extradata.
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
32 * Then, whenever a palette change is encountered while demuxing the file,
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
33 * the demuxer must use the same extradata space to transmit an
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
34 * AVPaletteControl structure.
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
35 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
36 * Id CIN video is purely Huffman-coded, intraframe-only codec. It achieves
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
37 * a little more compression by exploiting the fact that adjacent pixels
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
38 * tend to be similar.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
39 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
40 * Note that this decoder could use ffmpeg's optimized VLC facilities
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
41 * rather than naive, tree-based Huffman decoding. However, there are 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
42 * Huffman tables. Plus, the VLC bit coding order is right -> left instead
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
43 * 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
44 * the original Quake II implementation likely used a similar naive
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
45 * decoding algorithm and it worked fine on much lower spec machines.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
46 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
47
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
48 #include <stdio.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
49 #include <stdlib.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
50 #include <string.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
51 #include <unistd.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
52
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
53 #include "common.h"
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
54 #include "avcodec.h"
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
55 #include "dsputil.h"
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
56
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
57 #define HUFFMAN_TABLE_SIZE 64 * 1024
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
58 #define HUF_TOKENS 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
59 #define PALETTE_COUNT 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
60
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
61 typedef struct
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
62 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
63 int count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
64 unsigned char used;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
65 int children[2];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
66 } hnode_t;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
67
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
68 typedef struct IdcinContext {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
69
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
70 AVCodecContext *avctx;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
71 DSPContext dsp;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
72 AVFrame frame;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
73
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
74 unsigned char *buf;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
75 int size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
76
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
77 hnode_t huff_nodes[256][HUF_TOKENS*2];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
78 int num_huff_nodes[256];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
79
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
80 } IdcinContext;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
81
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
82 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
83 * Find the lowest probability node in a Huffman table, and mark it as
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
84 * being assigned to a higher probability.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
85 * 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
86 * are used.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
87 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
88 static int huff_smallest_node(hnode_t *hnodes, int num_hnodes) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
89 int i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
90 int best, best_node;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
91
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
92 best = 99999999;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
93 best_node = -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
94 for(i = 0; i < num_hnodes; i++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
95 if(hnodes[i].used)
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)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
98 continue;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
99 if(hnodes[i].count < best) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
100 best = hnodes[i].count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
101 best_node = i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
102 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
103 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
104
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
105 if(best_node == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
106 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
107 hnodes[best_node].used = 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
108 return best_node;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
109 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
110
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
111 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
112 * Build the Huffman tree using the generated/loaded probabilities histogram.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
113 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
114 * On completion:
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
115 * 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
116 * huff_nodes[prev][i >= HUF_TOKENS] - are used to construct the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
117 * 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
118 * That is: huff_nodes[prev][num_huff_nodes[prev]] is the root node.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
119 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
120 static void huff_build_tree(IdcinContext *s, int prev) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
121 hnode_t *node, *hnodes;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
122 int num_hnodes, i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
123
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
124 num_hnodes = HUF_TOKENS;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
125 hnodes = s->huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
126 for(i = 0; i < HUF_TOKENS * 2; i++)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
127 hnodes[i].used = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
128
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
129 while (1) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
130 node = &hnodes[num_hnodes]; /* next free node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
131
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
132 /* pick two lowest counts */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
133 node->children[0] = huff_smallest_node(hnodes, num_hnodes);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
134 if(node->children[0] == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
135 break; /* reached the root node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
136
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
137 node->children[1] = huff_smallest_node(hnodes, num_hnodes);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
138 if(node->children[1] == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
139 break; /* reached the root node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
140
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
141 /* combine nodes probability for new node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
142 node->count = hnodes[node->children[0]].count +
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
143 hnodes[node->children[1]].count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
144 num_hnodes++;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
145 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
146
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
147 s->num_huff_nodes[prev] = num_hnodes - 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
148 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
149
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
150 static int idcin_decode_init(AVCodecContext *avctx)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
151 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
152 IdcinContext *s = (IdcinContext *)avctx->priv_data;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
153 int i, j, histogram_index = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
154 unsigned char *histograms;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
155
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
156 s->avctx = avctx;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
157 avctx->pix_fmt = PIX_FMT_PAL8;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
158 avctx->has_b_frames = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
159 dsputil_init(&s->dsp, avctx);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
160
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
161 /* make sure the Huffman tables make it */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
162 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
163 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
164 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
165 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
166
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
167 /* build the 256 Huffman decode trees */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
168 histograms = (unsigned char *)s->avctx->extradata;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
169 for (i = 0; i < 256; i++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
170 for(j = 0; j < HUF_TOKENS; j++)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
171 s->huff_nodes[i][j].count = histograms[histogram_index++];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
172 huff_build_tree(s, i);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
173 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
174
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
175 s->frame.data[0] = NULL;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
176
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
177 return 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
178 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
179
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
180 static void idcin_decode_vlcs(IdcinContext *s)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
181 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
182 hnode_t *hnodes;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
183 long x, y;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
184 int prev;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
185 unsigned char v = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
186 int bit_pos, node_num, dat_pos;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
187
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
188 prev = bit_pos = dat_pos = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
189 for (y = 0; y < (s->frame.linesize[0] * s->avctx->height);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
190 y += s->frame.linesize[0]) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
191 for (x = y; x < y + s->avctx->width; x++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
192 node_num = s->num_huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
193 hnodes = s->huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
194
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
195 while(node_num >= HUF_TOKENS) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
196 if(!bit_pos) {
2508
b0ec6f51b5bd Off-by-one bug in libavcodec/idcinvideo.c, caused
michael
parents: 1598
diff changeset
197 if(dat_pos >= s->size) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
198 av_log(s->avctx, AV_LOG_ERROR, "Huffman decode error.\n");
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
199 return;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
200 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
201 bit_pos = 8;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
202 v = s->buf[dat_pos++];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
203 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
204
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
205 node_num = hnodes[node_num].children[v & 0x01];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
206 v = v >> 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
207 bit_pos--;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
208 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
209
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
210 s->frame.data[0][x] = node_num;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
211 prev = node_num;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
212 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
213 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
214 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
215
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
216 static int idcin_decode_frame(AVCodecContext *avctx,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
217 void *data, int *data_size,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
218 uint8_t *buf, int buf_size)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
219 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
220 IdcinContext *s = (IdcinContext *)avctx->priv_data;
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
221 AVPaletteControl *palette_control = avctx->palctrl;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
222
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
223 s->buf = buf;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
224 s->size = buf_size;
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 (s->frame.data[0])
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
227 avctx->release_buffer(avctx, &s->frame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
228
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
229 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
230 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
231 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
232 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
233
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
234 idcin_decode_vlcs(s);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
235
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
236 /* 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
237 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
238 /* If palette changed inform application*/
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
239 if (palette_control->palette_changed) {
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
240 palette_control->palette_changed = 0;
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
241 s->frame.palette_has_changed = 1;
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
242 }
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
243
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
244 *data_size = sizeof(AVFrame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
245 *(AVFrame*)data = s->frame;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
246
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
247 /* report that the buffer was completely consumed */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
248 return buf_size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
249 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
250
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
251 static int idcin_decode_end(AVCodecContext *avctx)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
252 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
253 IdcinContext *s = (IdcinContext *)avctx->priv_data;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
254
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
255 if (s->frame.data[0])
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
256 avctx->release_buffer(avctx, &s->frame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
257
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
258 return 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
259 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
260
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
261 AVCodec idcin_decoder = {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
262 "idcinvideo",
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
263 CODEC_TYPE_VIDEO,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
264 CODEC_ID_IDCIN,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
265 sizeof(IdcinContext),
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
266 idcin_decode_init,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
267 NULL,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
268 idcin_decode_end,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
269 idcin_decode_frame,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
270 CODEC_CAP_DR1,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
271 };
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
272