annotate bink.c @ 11560:8a4984c5cacc libavcodec

Define AVMediaType enum, and use it instead of enum CodecType, which is deprecated and will be dropped at the next major bump.
author stefano
date Tue, 30 Mar 2010 23:30:55 +0000
parents 34080d73a504
children 2501df1cabc5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1 /*
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
2 * Bink video decoder
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
3 * Copyright (c) 2009 Konstantin Shishkov
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
4 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
5 * This file is part of FFmpeg.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
6 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
11 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
15 * Lesser General Public License for more details.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
16 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
20 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
21
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
22 #include "avcodec.h"
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
23 #include "dsputil.h"
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
24 #include "binkdata.h"
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
25 #include "mathops.h"
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
26
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
27 #define ALT_BITSTREAM_READER_LE
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
28 #include "get_bits.h"
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
29
11251
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
30 #define BINK_FLAG_ALPHA 0x00100000
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
31 #define BINK_FLAG_GRAY 0x00020000
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
32
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
33 static VLC bink_trees[16];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
34
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
35 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
36 * IDs for different data types used in Bink video codec
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
37 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
38 enum Sources {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
39 BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
40 BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
41 BINK_SRC_COLORS, ///< pixel values used for different block types
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
42 BINK_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
43 BINK_SRC_X_OFF, ///< X components of motion value
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
44 BINK_SRC_Y_OFF, ///< Y components of motion value
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
45 BINK_SRC_INTRA_DC, ///< DC values for intrablocks with DCT
11515
34080d73a504 fix minor typo
kostya
parents: 11371
diff changeset
46 BINK_SRC_INTER_DC, ///< DC values for interblocks with DCT
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
47 BINK_SRC_RUN, ///< run lengths for special fill block
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
48
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
49 BINK_NB_SRC
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
50 };
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
51
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
52 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
53 * data needed to decode 4-bit Huffman-coded value
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
54 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
55 typedef struct Tree {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
56 int vlc_num; ///< tree number (in bink_trees[])
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
57 uint8_t syms[16]; ///< leaf value to symbol mapping
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
58 } Tree;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
59
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
60 #define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
61 bink_trees[(tree).vlc_num].bits, 1)]
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
62
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
63 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
64 * data structure used for decoding single Bink data type
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
65 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
66 typedef struct Bundle {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
67 int len; ///< length of number of entries to decode (in bits)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
68 Tree tree; ///< Huffman tree-related data
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
69 uint8_t *data; ///< buffer for decoded symbols
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
70 uint8_t *data_end; ///< buffer end
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
71 uint8_t *cur_dec; ///< pointer to the not yet decoded part of the buffer
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
72 uint8_t *cur_ptr; ///< pointer to the data that is not read from buffer yet
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
73 } Bundle;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
74
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
75 /*
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
76 * Decoder context
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
77 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
78 typedef struct BinkContext {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
79 AVCodecContext *avctx;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
80 DSPContext dsp;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
81 AVFrame pic, last;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
82 int version; ///< internal Bink file version
11247
b48dd9213016 Make Bink decoder able to skip alpha plane
kostya
parents: 11245
diff changeset
83 int has_alpha;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
84 int swap_planes;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
85 ScanTable scantable; ///< permutated scantable for DCT coeffs decoding
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
86
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
87 Bundle bundle[BINK_NB_SRC]; ///< bundles for decoding all data types
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
88 Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
89 int col_lastval; ///< value of last decoded high nibble in "colours" data type
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
90 } BinkContext;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
91
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
92 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
93 * Bink video block types
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
94 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
95 enum BlockTypes {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
96 SKIP_BLOCK = 0, ///< skipped block
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
97 SCALED_BLOCK, ///< block has size 16x16
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
98 MOTION_BLOCK, ///< block is copied from previous frame with some offset
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
99 RUN_BLOCK, ///< block is composed from runs of colours with custom scan order
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
100 RESIDUE_BLOCK, ///< motion block with some difference added
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
101 INTRA_BLOCK, ///< intra DCT block
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
102 FILL_BLOCK, ///< block is filled with single colour
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
103 INTER_BLOCK, ///< motion block with DCT applied to the difference
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
104 PATTERN_BLOCK, ///< block is filled with two colours following custom pattern
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
105 RAW_BLOCK, ///< uncoded 8x8 block
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
106 };
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
107
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
108 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
109 * Initializes length length in all bundles.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
110 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
111 * @param c decoder context
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
112 * @param width plane width
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
113 * @param bw plane width in 8x8 blocks
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
114 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
115 static void init_lengths(BinkContext *c, int width, int bw)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
116 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
117 c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
118
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
119 c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
120
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
121 c->bundle[BINK_SRC_COLORS].len = av_log2((width >> 3)*64 + 511) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
122
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
123 c->bundle[BINK_SRC_INTRA_DC].len =
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
124 c->bundle[BINK_SRC_INTER_DC].len =
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
125 c->bundle[BINK_SRC_X_OFF].len =
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
126 c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
127
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
128 c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
129
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
130 c->bundle[BINK_SRC_RUN].len = av_log2((width >> 3)*48 + 511) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
131 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
132
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
133 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
134 * Allocates memory for bundles.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
135 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
136 * @param c decoder context
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
137 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
138 static av_cold void init_bundles(BinkContext *c)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
139 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
140 int bw, bh, blocks;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
141 int i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
142
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
143 bw = (c->avctx->width + 7) >> 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
144 bh = (c->avctx->height + 7) >> 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
145 blocks = bw * bh;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
146
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
147 for (i = 0; i < BINK_NB_SRC; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
148 c->bundle[i].data = av_malloc(blocks * 64);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
149 c->bundle[i].data_end = c->bundle[i].data + blocks * 64;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
150 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
151 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
152
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
153 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
154 * Frees memory used by bundles.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
155 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
156 * @param c decoder context
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
157 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
158 static av_cold void free_bundles(BinkContext *c)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
159 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
160 int i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
161 for (i = 0; i < BINK_NB_SRC; i++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
162 av_freep(&c->bundle[i].data);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
163 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
164
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
165 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
166 * Merges two consequent lists of equal size depending on bits read.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
167 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
168 * @param gb context for reading bits
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
169 * @param dst buffer where merged list will be written to
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
170 * @param src pointer to the head of the first list (the second lists starts at src+size)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
171 * @param size input lists size
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
172 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
173 static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
174 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
175 uint8_t *src2 = src + size;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
176 int size2 = size;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
177
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
178 do {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
179 if (!get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
180 *dst++ = *src++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
181 size--;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
182 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
183 *dst++ = *src2++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
184 size2--;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
185 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
186 } while (size && size2);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
187
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
188 while (size--)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
189 *dst++ = *src++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
190 while (size2--)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
191 *dst++ = *src2++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
192 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
193
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
194 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
195 * Reads information about Huffman tree used to decode data.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
196 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
197 * @param gb context for reading bits
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
198 * @param tree pointer for storing tree data
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
199 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
200 static void read_tree(GetBitContext *gb, Tree *tree)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
201 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
202 uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
203 int i, t, len;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
204
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
205 tree->vlc_num = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
206 if (!tree->vlc_num) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
207 for (i = 0; i < 16; i++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
208 tree->syms[i] = i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
209 return;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
210 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
211 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
212 len = get_bits(gb, 3);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
213 memset(tmp1, 0, sizeof(tmp1));
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
214 for (i = 0; i <= len; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
215 tree->syms[i] = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
216 tmp1[tree->syms[i]] = 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
217 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
218 for (i = 0; i < 16; i++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
219 if (!tmp1[i])
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
220 tree->syms[++len] = i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
221 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
222 len = get_bits(gb, 2);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
223 for (i = 0; i < 16; i++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
224 in[i] = i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
225 for (i = 0; i <= len; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
226 int size = 1 << i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
227 for (t = 0; t < 16; t += size << 1)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
228 merge(gb, out + t, in + t, size);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
229 FFSWAP(uint8_t*, in, out);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
230 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
231 memcpy(tree->syms, in, 16);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
232 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
233 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
234
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
235 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
236 * Prepares bundle for decoding data.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
237 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
238 * @param gb context for reading bits
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
239 * @param c decoder context
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
240 * @param bundle_num number of the bundle to initialize
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
241 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
242 static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
243 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
244 int i;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
245
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
246 if (bundle_num == BINK_SRC_COLORS) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
247 for (i = 0; i < 16; i++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
248 read_tree(gb, &c->col_high[i]);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
249 c->col_lastval = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
250 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
251 if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
252 read_tree(gb, &c->bundle[bundle_num].tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
253 c->bundle[bundle_num].cur_dec =
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
254 c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
255 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
256
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
257 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
258 * common check before starting decoding bundle data
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
259 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
260 * @param gb context for reading bits
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
261 * @param b bundle
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
262 * @param t variable where number of elements to decode will be stored
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
263 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
264 #define CHECK_READ_VAL(gb, b, t) \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
265 if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
266 return 0; \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
267 t = get_bits(gb, b->len); \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
268 if (!t) { \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
269 b->cur_dec = NULL; \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
270 return 0; \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
271 } \
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
272
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
273 static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
274 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
275 int t, v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
276 const uint8_t *dec_end;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
277
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
278 CHECK_READ_VAL(gb, b, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
279 dec_end = b->cur_dec + t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
280 if (dec_end > b->data_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
281 av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n");
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
282 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
283 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
284 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
285 v = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
286 memset(b->cur_dec, v, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
287 b->cur_dec += t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
288 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
289 while (b->cur_dec < dec_end)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
290 *b->cur_dec++ = GET_HUFF(gb, b->tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
291 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
292 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
293 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
294
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
295 static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
296 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
297 int t, sign, v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
298 const uint8_t *dec_end;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
299
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
300 CHECK_READ_VAL(gb, b, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
301 dec_end = b->cur_dec + t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
302 if (dec_end > b->data_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
303 av_log(avctx, AV_LOG_ERROR, "Too many motion values\n");
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
304 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
305 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
306 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
307 v = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
308 if (v) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
309 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
310 v = (v ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
311 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
312 memset(b->cur_dec, v, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
313 b->cur_dec += t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
314 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
315 do {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
316 v = GET_HUFF(gb, b->tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
317 if (v) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
318 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
319 v = (v ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
320 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
321 *b->cur_dec++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
322 } while (b->cur_dec < dec_end);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
323 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
324 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
325 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
326
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
327 const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 };
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
328
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
329 static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
330 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
331 int t, v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
332 int last = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
333 const uint8_t *dec_end;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
334
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
335 CHECK_READ_VAL(gb, b, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
336 dec_end = b->cur_dec + t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
337 if (dec_end > b->data_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
338 av_log(avctx, AV_LOG_ERROR, "Too many block type values\n");
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
339 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
340 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
341 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
342 v = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
343 memset(b->cur_dec, v, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
344 b->cur_dec += t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
345 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
346 do {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
347 v = GET_HUFF(gb, b->tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
348 if (v < 12) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
349 last = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
350 *b->cur_dec++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
351 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
352 int run = bink_rlelens[v - 12];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
353
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
354 memset(b->cur_dec, last, run);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
355 b->cur_dec += run;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
356 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
357 } while (b->cur_dec < dec_end);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
358 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
359 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
360 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
361
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
362 static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
363 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
364 int t, v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
365 const uint8_t *dec_end;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
366
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
367 CHECK_READ_VAL(gb, b, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
368 dec_end = b->cur_dec + t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
369 if (dec_end > b->data_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
370 av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n");
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
371 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
372 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
373 while (b->cur_dec < dec_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
374 v = GET_HUFF(gb, b->tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
375 v |= GET_HUFF(gb, b->tree) << 4;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
376 *b->cur_dec++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
377 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
378
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
379 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
380 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
381
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
382 static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
383 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
384 int t, sign, v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
385 const uint8_t *dec_end;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
386
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
387 CHECK_READ_VAL(gb, b, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
388 dec_end = b->cur_dec + t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
389 if (dec_end > b->data_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
390 av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n");
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
391 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
392 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
393 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
394 c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
395 v = GET_HUFF(gb, b->tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
396 v = (c->col_lastval << 4) | v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
397 if (c->version < 'i') {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
398 sign = ((int8_t) v) >> 7;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
399 v = ((v & 0x7F) ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
400 v += 0x80;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
401 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
402 memset(b->cur_dec, v, t);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
403 b->cur_dec += t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
404 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
405 while (b->cur_dec < dec_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
406 c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
407 v = GET_HUFF(gb, b->tree);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
408 v = (c->col_lastval << 4) | v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
409 if (c->version < 'i') {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
410 sign = ((int8_t) v) >> 7;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
411 v = ((v & 0x7F) ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
412 v += 0x80;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
413 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
414 *b->cur_dec++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
415 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
416 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
417 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
418 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
419
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
420 /** number of bits used to store first DC value in bundle */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
421 #define DC_START_BITS 11
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
422
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
423 static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
424 int start_bits, int has_sign)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
425 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
426 int i, j, len, len2, bsize, sign, v, v2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
427 int16_t *dst = (int16_t*)b->cur_dec;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
428
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
429 CHECK_READ_VAL(gb, b, len);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
430 v = get_bits(gb, start_bits - has_sign);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
431 if (v && has_sign) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
432 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
433 v = (v ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
434 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
435 *dst++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
436 len--;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
437 for (i = 0; i < len; i += 8) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
438 len2 = FFMIN(len - i, 8);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
439 bsize = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
440 if (bsize) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
441 for (j = 0; j < len2; j++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
442 v2 = get_bits(gb, bsize);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
443 if (v2) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
444 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
445 v2 = (v2 ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
446 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
447 v += v2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
448 *dst++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
449 if (v < -32768 || v > 32767) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
450 av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
451 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
452 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
453 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
454 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
455 for (j = 0; j < len2; j++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
456 *dst++ = v;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
457 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
458 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
459
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
460 b->cur_dec = (uint8_t*)dst;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
461 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
462 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
463
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
464 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
465 * Retrieves next value from bundle.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
466 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
467 * @param c decoder context
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
468 * @param bundle bundle number
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
469 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
470 static inline int get_value(BinkContext *c, int bundle)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
471 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
472 int16_t ret;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
473
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
474 if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
475 return *c->bundle[bundle].cur_ptr++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
476 if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
477 return (int8_t)*c->bundle[bundle].cur_ptr++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
478 ret = *(int16_t*)c->bundle[bundle].cur_ptr;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
479 c->bundle[bundle].cur_ptr += 2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
480 return ret;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
481 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
482
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
483 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
484 * Reads 8x8 block of DCT coefficients.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
485 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
486 * @param gb context for reading bits
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
487 * @param block place for storing coefficients
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
488 * @param scan scan order table
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
489 * @param is_intra tells what set of quantizer matrices to use
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
490 * @return 0 for success, negative value in other cases
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
491 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
492 static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
493 int is_intra)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
494 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
495 int coef_list[128];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
496 int mode_list[128];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
497 int i, t, mask, bits, ccoef, mode, sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
498 int list_start = 64, list_end = 64, list_pos;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
499 int coef_count = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
500 int coef_idx[64];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
501 int quant_idx;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
502 const uint32_t *quant;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
503
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
504 coef_list[list_end] = 4; mode_list[list_end++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
505 coef_list[list_end] = 24; mode_list[list_end++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
506 coef_list[list_end] = 44; mode_list[list_end++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
507 coef_list[list_end] = 1; mode_list[list_end++] = 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
508 coef_list[list_end] = 2; mode_list[list_end++] = 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
509 coef_list[list_end] = 3; mode_list[list_end++] = 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
510
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
511 bits = get_bits(gb, 4) - 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
512 for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
513 list_pos = list_start;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
514 while (list_pos < list_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
515 if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
516 list_pos++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
517 continue;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
518 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
519 ccoef = coef_list[list_pos];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
520 mode = mode_list[list_pos];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
521 switch (mode) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
522 case 0:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
523 coef_list[list_pos] = ccoef + 4;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
524 mode_list[list_pos] = 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
525 case 2:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
526 if (mode == 2) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
527 coef_list[list_pos] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
528 mode_list[list_pos++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
529 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
530 for (i = 0; i < 4; i++, ccoef++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
531 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
532 coef_list[--list_start] = ccoef;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
533 mode_list[ list_start] = 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
534 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
535 int t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
536 if (!bits) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
537 t = 1 - (get_bits1(gb) << 1);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
538 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
539 t = get_bits(gb, bits) | mask;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
540 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
541 t = (t ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
542 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
543 block[scan[ccoef]] = t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
544 coef_idx[coef_count++] = ccoef;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
545 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
546 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
547 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
548 case 1:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
549 mode_list[list_pos] = 2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
550 for (i = 0; i < 3; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
551 ccoef += 4;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
552 coef_list[list_end] = ccoef;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
553 mode_list[list_end++] = 2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
554 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
555 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
556 case 3:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
557 if (!bits) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
558 t = 1 - (get_bits1(gb) << 1);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
559 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
560 t = get_bits(gb, bits) | mask;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
561 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
562 t = (t ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
563 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
564 block[scan[ccoef]] = t;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
565 coef_idx[coef_count++] = ccoef;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
566 coef_list[list_pos] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
567 mode_list[list_pos++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
568 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
569 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
570 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
571 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
572
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
573 quant_idx = get_bits(gb, 4);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
574 quant = is_intra ? bink_intra_quant[quant_idx]
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
575 : bink_inter_quant[quant_idx];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
576 block[0] = (block[0] * quant[0]) >> 11;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
577 for (i = 0; i < coef_count; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
578 int idx = coef_idx[i];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
579 block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
580 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
581
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
582 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
583 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
584
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
585 /**
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
586 * Reads 8x8 block with residue after motion compensation.
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
587 *
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
588 * @param gb context for reading bits
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
589 * @param block place to store read data
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
590 * @param masks_count number of masks to decode
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
591 * @return 0 on success, negative value in other cases
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
592 */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
593 static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
594 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
595 int coef_list[128];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
596 int mode_list[128];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
597 int i, sign, mask, ccoef, mode;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
598 int list_start = 64, list_end = 64, list_pos;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
599 int nz_coeff[64];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
600 int nz_coeff_count = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
601
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
602 coef_list[list_end] = 4; mode_list[list_end++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
603 coef_list[list_end] = 24; mode_list[list_end++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
604 coef_list[list_end] = 44; mode_list[list_end++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
605 coef_list[list_end] = 0; mode_list[list_end++] = 2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
606
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
607 for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
608 for (i = 0; i < nz_coeff_count; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
609 if (!get_bits1(gb))
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
610 continue;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
611 if (block[nz_coeff[i]] < 0)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
612 block[nz_coeff[i]] -= mask;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
613 else
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
614 block[nz_coeff[i]] += mask;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
615 masks_count--;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
616 if (masks_count < 0)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
617 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
618 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
619 list_pos = list_start;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
620 while (list_pos < list_end) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
621 if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
622 list_pos++;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
623 continue;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
624 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
625 ccoef = coef_list[list_pos];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
626 mode = mode_list[list_pos];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
627 switch (mode) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
628 case 0:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
629 coef_list[list_pos] = ccoef + 4;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
630 mode_list[list_pos] = 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
631 case 2:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
632 if (mode == 2) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
633 coef_list[list_pos] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
634 mode_list[list_pos++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
635 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
636 for (i = 0; i < 4; i++, ccoef++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
637 if (get_bits1(gb)) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
638 coef_list[--list_start] = ccoef;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
639 mode_list[ list_start] = 3;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
640 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
641 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
642 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
643 block[bink_scan[ccoef]] = (mask ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
644 masks_count--;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
645 if (masks_count < 0)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
646 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
647 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
648 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
649 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
650 case 1:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
651 mode_list[list_pos] = 2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
652 for (i = 0; i < 3; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
653 ccoef += 4;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
654 coef_list[list_end] = ccoef;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
655 mode_list[list_end++] = 2;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
656 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
657 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
658 case 3:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
659 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
660 sign = -get_bits1(gb);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
661 block[bink_scan[ccoef]] = (mask ^ sign) - sign;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
662 coef_list[list_pos] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
663 mode_list[list_pos++] = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
664 masks_count--;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
665 if (masks_count < 0)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
666 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
667 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
668 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
669 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
670 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
671
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
672 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
673 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
674
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
675 static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
676 int is_chroma)
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
677 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
678 int blk;
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
679 int i, j, bx, by;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
680 uint8_t *dst, *prev, *ref, *ref_start, *ref_end;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
681 int v, col[2];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
682 const uint8_t *scan;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
683 int xoff, yoff;
11369
98970e51365a Remove DECLARE_ALIGNED_{8,16} macros
mru
parents: 11254
diff changeset
684 DECLARE_ALIGNED(16, DCTELEM, block[64]);
98970e51365a Remove DECLARE_ALIGNED_{8,16} macros
mru
parents: 11254
diff changeset
685 DECLARE_ALIGNED(16, uint8_t, ublock[64]);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
686 int coordmap[64];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
687
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
688 const int stride = c->pic.linesize[plane_idx];
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
689 int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
690 int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
691 int width = c->avctx->width >> is_chroma;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
692
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
693 init_lengths(c, FFMAX(width, 8), bw);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
694 for (i = 0; i < BINK_NB_SRC; i++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
695 read_bundle(gb, c, i);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
696
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
697 ref_start = c->last.data[plane_idx];
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
698 ref_end = c->last.data[plane_idx]
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
699 + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
700
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
701 for (i = 0; i < 64; i++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
702 coordmap[i] = (i & 7) + (i >> 3) * stride;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
703
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
704 for (by = 0; by < bh; by++) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
705 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
706 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
707 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
708 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
709 if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
710 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
711 if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
712 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
713 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
714 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
715 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
716 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
717 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
718 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
719 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
720 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
721 if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
722 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
723
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
724 if (by == bh)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
725 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
726 dst = c->pic.data[plane_idx] + 8*by*stride;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
727 prev = c->last.data[plane_idx] + 8*by*stride;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
728 for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
729 blk = get_value(c, BINK_SRC_BLOCK_TYPES);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
730 // 16x16 block type on odd line means part of the already decoded block, so skip it
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
731 if ((by & 1) && blk == SCALED_BLOCK) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
732 bx++;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
733 dst += 8;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
734 prev += 8;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
735 continue;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
736 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
737 switch (blk) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
738 case SKIP_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
739 c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
740 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
741 case SCALED_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
742 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
743 switch (blk) {
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
744 case RUN_BLOCK:
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
745 scan = bink_patterns[get_bits(gb, 4)];
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
746 i = 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
747 do {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
748 int run = get_value(c, BINK_SRC_RUN) + 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
749
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
750 i += run;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
751 if (i > 64) {
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
752 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
753 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
754 }
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
755 if (get_bits1(gb)) {
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
756 v = get_value(c, BINK_SRC_COLORS);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
757 for (j = 0; j < run; j++)
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
758 ublock[*scan++] = v;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
759 } else {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
760 for (j = 0; j < run; j++)
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
761 ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
762 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
763 } while (i < 63);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
764 if (i == 63)
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
765 ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
766 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
767 case INTRA_BLOCK:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
768 c->dsp.clear_block(block);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
769 block[0] = get_value(c, BINK_SRC_INTRA_DC);
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
770 read_dct_coeffs(gb, block, c->scantable.permutated, 1);
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
771 c->dsp.idct(block);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
772 c->dsp.put_pixels_nonclamped(block, ublock, 8);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
773 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
774 case FILL_BLOCK:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
775 v = get_value(c, BINK_SRC_COLORS);
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
776 c->dsp.fill_block_tab[0](dst, v, stride, 16);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
777 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
778 case PATTERN_BLOCK:
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
779 for (i = 0; i < 2; i++)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
780 col[i] = get_value(c, BINK_SRC_COLORS);
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
781 for (j = 0; j < 8; j++) {
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
782 v = get_value(c, BINK_SRC_PATTERN);
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
783 for (i = 0; i < 8; i++, v >>= 1)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
784 ublock[i + j*8] = col[v & 1];
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
785 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
786 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
787 case RAW_BLOCK:
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
788 for (j = 0; j < 8; j++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
789 for (i = 0; i < 8; i++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
790 ublock[i + j*8] = get_value(c, BINK_SRC_COLORS);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
791 break;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
792 default:
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
793 av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
794 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
795 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
796 if (blk != FILL_BLOCK)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
797 c->dsp.scale_block(ublock, dst, stride);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
798 bx++;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
799 dst += 8;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
800 prev += 8;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
801 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
802 case MOTION_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
803 xoff = get_value(c, BINK_SRC_X_OFF);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
804 yoff = get_value(c, BINK_SRC_Y_OFF);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
805 ref = prev + xoff + yoff * stride;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
806 if (ref < ref_start || ref > ref_end) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
807 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
808 bx*8 + xoff, by*8 + yoff);
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
809 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
810 }
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
811 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
812 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
813 case RUN_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
814 scan = bink_patterns[get_bits(gb, 4)];
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
815 i = 0;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
816 do {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
817 int run = get_value(c, BINK_SRC_RUN) + 1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
818
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
819 i += run;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
820 if (i > 64) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
821 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
822 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
823 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
824 if (get_bits1(gb)) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
825 v = get_value(c, BINK_SRC_COLORS);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
826 for (j = 0; j < run; j++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
827 dst[coordmap[*scan++]] = v;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
828 } else {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
829 for (j = 0; j < run; j++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
830 dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
831 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
832 } while (i < 63);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
833 if (i == 63)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
834 dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
835 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
836 case RESIDUE_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
837 xoff = get_value(c, BINK_SRC_X_OFF);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
838 yoff = get_value(c, BINK_SRC_Y_OFF);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
839 ref = prev + xoff + yoff * stride;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
840 if (ref < ref_start || ref > ref_end) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
841 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
842 bx*8 + xoff, by*8 + yoff);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
843 return -1;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
844 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
845 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
846 c->dsp.clear_block(block);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
847 v = get_bits(gb, 7);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
848 read_residue(gb, block, v);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
849 c->dsp.add_pixels8(dst, block, stride);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
850 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
851 case INTRA_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
852 c->dsp.clear_block(block);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
853 block[0] = get_value(c, BINK_SRC_INTRA_DC);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
854 read_dct_coeffs(gb, block, c->scantable.permutated, 1);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
855 c->dsp.idct_put(dst, stride, block);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
856 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
857 case FILL_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
858 v = get_value(c, BINK_SRC_COLORS);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
859 c->dsp.fill_block_tab[1](dst, v, stride, 8);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
860 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
861 case INTER_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
862 xoff = get_value(c, BINK_SRC_X_OFF);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
863 yoff = get_value(c, BINK_SRC_Y_OFF);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
864 ref = prev + xoff + yoff * stride;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
865 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
866 c->dsp.clear_block(block);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
867 block[0] = get_value(c, BINK_SRC_INTER_DC);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
868 read_dct_coeffs(gb, block, c->scantable.permutated, 0);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
869 c->dsp.idct_add(dst, stride, block);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
870 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
871 case PATTERN_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
872 for (i = 0; i < 2; i++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
873 col[i] = get_value(c, BINK_SRC_COLORS);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
874 for (i = 0; i < 8; i++) {
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
875 v = get_value(c, BINK_SRC_PATTERN);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
876 for (j = 0; j < 8; j++, v >>= 1)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
877 dst[i*stride + j] = col[v & 1];
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
878 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
879 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
880 case RAW_BLOCK:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
881 for (i = 0; i < 8; i++)
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
882 memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
883 c->bundle[BINK_SRC_COLORS].cur_ptr += 64;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
884 break;
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
885 default:
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
886 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
887 return -1;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
888 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
889 }
11253
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
890 }
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
891 if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary
100ca092ac34 cosmetics: reindent after last commit
kostya
parents: 11252
diff changeset
892 skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F));
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
893
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
894 return 0;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
895 }
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
896
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
897 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
898 {
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
899 BinkContext * const c = avctx->priv_data;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
900 GetBitContext gb;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
901 int plane, plane_idx;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
902 int bits_count = pkt->size << 3;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
903
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
904 if(c->pic.data[0])
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
905 avctx->release_buffer(avctx, &c->pic);
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
906
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
907 if(avctx->get_buffer(avctx, &c->pic) < 0){
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
908 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
909 return -1;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
910 }
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
911
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
912 init_get_bits(&gb, pkt->data, bits_count);
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
913 if (c->has_alpha) {
11254
e820a9d3f80c Decode alpha plane in Bink video
kostya
parents: 11253
diff changeset
914 if (c->version >= 'i')
e820a9d3f80c Decode alpha plane in Bink video
kostya
parents: 11253
diff changeset
915 skip_bits_long(&gb, 32);
e820a9d3f80c Decode alpha plane in Bink video
kostya
parents: 11253
diff changeset
916 if (bink_decode_plane(c, &gb, 3, 0) < 0)
11252
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
917 return -1;
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
918 }
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
919 if (c->version >= 'i')
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
920 skip_bits_long(&gb, 32);
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
921
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
922 for (plane = 0; plane < 3; plane++) {
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
923 plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3);
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
924
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
925 if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0)
d6513f6a949e Move plane decoding code into separate function in Bink decoder
kostya
parents: 11251
diff changeset
926 return -1;
11245
1e9ff636c3db Make Bink decoder to stop decoding planes after all bits are used.
kostya
parents: 11244
diff changeset
927 if (get_bits_count(&gb) >= bits_count)
1e9ff636c3db Make Bink decoder to stop decoding planes after all bits are used.
kostya
parents: 11244
diff changeset
928 break;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
929 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
930 emms_c();
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
931
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
932 *data_size = sizeof(AVFrame);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
933 *(AVFrame*)data = c->pic;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
934
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
935 FFSWAP(AVFrame, c->pic, c->last);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
936
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
937 /* always report that the buffer was completely consumed */
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
938 return pkt->size;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
939 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
940
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
941 static av_cold int decode_init(AVCodecContext *avctx)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
942 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
943 BinkContext * const c = avctx->priv_data;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
944 static VLC_TYPE table[16 * 128][2];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
945 int i;
11251
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
946 int flags;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
947
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
948 c->version = avctx->codec_tag >> 24;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
949 if (c->version < 'c') {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
950 av_log(avctx, AV_LOG_ERROR, "Too old version '%c'\n", c->version);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
951 return -1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
952 }
11251
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
953 if (avctx->extradata_size < 4) {
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
954 av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n");
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
955 return -1;
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
956 }
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
957 flags = AV_RL32(avctx->extradata);
56e65f21e9c5 Bink video decoder now can use extradata to detect alpha plane presence
kostya
parents: 11247
diff changeset
958 c->has_alpha = flags & BINK_FLAG_ALPHA;
11371
4532987cd74b Bink version 'h' also has chroma planes swapped
kostya
parents: 11369
diff changeset
959 c->swap_planes = c->version >= 'h';
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
960 if (!bink_trees[15].table) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
961 for (i = 0; i < 16; i++) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
962 const int maxbits = bink_tree_lens[i][15];
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
963 bink_trees[i].table = table + i*128;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
964 bink_trees[i].table_allocated = 1 << maxbits;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
965 init_vlc(&bink_trees[i], maxbits, 16,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
966 bink_tree_lens[i], 1, 1,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
967 bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
968 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
969 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
970 c->avctx = avctx;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
971
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
972 c->pic.data[0] = NULL;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
973
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
974 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
975 return 1;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
976 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
977
11254
e820a9d3f80c Decode alpha plane in Bink video
kostya
parents: 11253
diff changeset
978 avctx->pix_fmt = c->has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P;
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
979
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
980 avctx->idct_algo = FF_IDCT_BINK;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
981 dsputil_init(&c->dsp, avctx);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
982 ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
983
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
984 init_bundles(c);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
985
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
986 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
987 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
988
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
989 static av_cold int decode_end(AVCodecContext *avctx)
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
990 {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
991 BinkContext * const c = avctx->priv_data;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
992
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
993 if (c->pic.data[0])
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
994 avctx->release_buffer(avctx, &c->pic);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
995 if (c->last.data[0])
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
996 avctx->release_buffer(avctx, &c->last);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
997
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
998 free_bundles(c);
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
999 return 0;
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1000 }
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1001
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1002 AVCodec bink_decoder = {
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1003 "binkvideo",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11515
diff changeset
1004 AVMEDIA_TYPE_VIDEO,
11231
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1005 CODEC_ID_BINKVIDEO,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1006 sizeof(BinkContext),
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1007 decode_init,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1008 NULL,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1009 decode_end,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1010 decode_frame,
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1011 .long_name = NULL_IF_CONFIG_SMALL("Bink video"),
0fc1cdd984b7 Bink video decoder
kostya
parents:
diff changeset
1012 };