Mercurial > libavcodec.hg
annotate vp56.h @ 12092:de9e45d04063 libavcodec
DCA: Occasionally a false XCH sync word can turn up after the core DTS data,
to verify the sync word the extension fsize field should be compared to
the core data length field.
Patch by nick.nbrereton@net
author | banan |
---|---|
date | Mon, 05 Jul 2010 08:16:43 +0000 |
parents | 5a794f3f0d75 |
children | 160eceee6c3d |
rev | line source |
---|---|
3695 | 1 /** |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11369
diff
changeset
|
2 * @file |
3695 | 3 * VP5 and VP6 compatible video decoder (common features) |
4 * | |
5 * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |
6 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
diff
changeset
|
7 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
diff
changeset
|
8 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
diff
changeset
|
9 * FFmpeg is free software; you can redistribute it and/or |
3695 | 10 * modify it under the terms of the GNU Lesser General Public |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
diff
changeset
|
14 * FFmpeg is distributed in the hope that it will be useful, |
3695 | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
diff
changeset
|
20 * License along with FFmpeg; if not, write to the Free Software |
5215 | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3695 | 22 */ |
23 | |
7760 | 24 #ifndef AVCODEC_VP56_H |
25 #define AVCODEC_VP56_H | |
3695 | 26 |
27 #include "vp56data.h" | |
28 #include "dsputil.h" | |
9428 | 29 #include "get_bits.h" |
5089 | 30 #include "bytestream.h" |
12029 | 31 #include "cabac.h" |
11665 | 32 #include "vp56dsp.h" |
3695 | 33 |
8299 | 34 typedef struct vp56_context VP56Context; |
35 typedef struct vp56_mv VP56mv; | |
3695 | 36 |
8299 | 37 typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, |
8300 | 38 VP56mv *vect); |
8299 | 39 typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, |
8300 | 40 int offset1, int offset2, int stride, |
41 VP56mv mv, int mask, int select, int luma); | |
8299 | 42 typedef void (*VP56ParseCoeff)(VP56Context *s); |
43 typedef void (*VP56DefaultModelsInit)(VP56Context *s); | |
44 typedef void (*VP56ParseVectorModels)(VP56Context *s); | |
45 typedef void (*VP56ParseCoeffModels)(VP56Context *s); | |
8300 | 46 typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf, |
47 int buf_size, int *golden_frame); | |
3695 | 48 |
49 typedef struct { | |
50 int high; | |
12038 | 51 int bits; /* stored negated (i.e. negative "bits" is a positive number of |
52 bits left) in order to eliminate a negate in cache refilling */ | |
6297 | 53 const uint8_t *buffer; |
9919
c7c1c6b35a73
vp56dec: ensure range coder won't read past the end of input buffer
aurel
parents:
9428
diff
changeset
|
54 const uint8_t *end; |
3695 | 55 unsigned long code_word; |
8299 | 56 } VP56RangeCoder; |
3695 | 57 |
58 typedef struct { | |
59 uint8_t not_null_dc; | |
8299 | 60 VP56Frame ref_frame; |
3695 | 61 DCTELEM dc_coeff; |
8299 | 62 } VP56RefDc; |
3695 | 63 |
64 struct vp56_mv { | |
65 int x; | |
66 int y; | |
67 }; | |
68 | |
69 typedef struct { | |
70 uint8_t type; | |
8299 | 71 VP56mv mv; |
72 } VP56Macroblock; | |
3695 | 73 |
5711 | 74 typedef struct { |
75 uint8_t coeff_reorder[64]; /* used in vp6 only */ | |
76 uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ | |
77 uint8_t vector_sig[2]; /* delta sign */ | |
78 uint8_t vector_dct[2]; /* delta coding types */ | |
79 uint8_t vector_pdi[2][2]; /* predefined delta init */ | |
80 uint8_t vector_pdv[2][7]; /* predefined delta values */ | |
81 uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */ | |
82 uint8_t coeff_dccv[2][11]; /* DC coeff value */ | |
83 uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ | |
84 uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ | |
85 uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */ | |
86 uint8_t coeff_runv[2][14]; /* run value (vp6 only) */ | |
87 uint8_t mb_type[3][10][10]; /* model for decoding MB type */ | |
88 uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */ | |
8304 | 89 } VP56Model; |
5711 | 90 |
3695 | 91 struct vp56_context { |
92 AVCodecContext *avctx; | |
93 DSPContext dsp; | |
11665 | 94 VP56DSPContext vp56dsp; |
3695 | 95 ScanTable scantable; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
96 AVFrame frames[4]; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
97 AVFrame *framep[6]; |
3695 | 98 uint8_t *edge_emu_buffer_alloc; |
99 uint8_t *edge_emu_buffer; | |
8299 | 100 VP56RangeCoder c; |
101 VP56RangeCoder cc; | |
102 VP56RangeCoder *ccp; | |
4308 | 103 int sub_version; |
3695 | 104 |
105 /* frame info */ | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
106 int plane_width[4]; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
107 int plane_height[4]; |
3695 | 108 int mb_width; /* number of horizontal MB */ |
109 int mb_height; /* number of vertical MB */ | |
110 int block_offset[6]; | |
111 | |
112 int quantizer; | |
113 uint16_t dequant_dc; | |
114 uint16_t dequant_ac; | |
11053
c57e72227d7d
Make VP5 and VP6 decoders output a qscale table to allow for more automatic
reimar
parents:
10961
diff
changeset
|
115 int8_t *qscale_table; |
3695 | 116 |
117 /* DC predictors management */ | |
8299 | 118 VP56RefDc *above_blocks; |
119 VP56RefDc left_block[4]; | |
3695 | 120 int above_block_idx[6]; |
121 DCTELEM prev_dc[3][3]; /* [plan][ref_frame] */ | |
122 | |
123 /* blocks / macroblock */ | |
8299 | 124 VP56mb mb_type; |
125 VP56Macroblock *macroblocks; | |
11369 | 126 DECLARE_ALIGNED(16, DCTELEM, block_coeff)[6][64]; |
3695 | 127 |
128 /* motion vectors */ | |
8299 | 129 VP56mv mv[6]; /* vectors for each block in MB */ |
130 VP56mv vector_candidate[2]; | |
3695 | 131 int vector_candidate_pos; |
132 | |
133 /* filtering hints */ | |
4348 | 134 int filter_header; /* used in vp6 only */ |
3695 | 135 int deblock_filtering; |
136 int filter_selection; | |
137 int filter_mode; | |
138 int max_vector_length; | |
139 int sample_variance_threshold; | |
140 | |
141 uint8_t coeff_ctx[4][64]; /* used in vp5 only */ | |
142 uint8_t coeff_ctx_last[4]; /* used in vp5 only */ | |
143 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
144 int has_alpha; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
145 |
3695 | 146 /* upside-down flipping hints */ |
147 int flip; /* are we flipping ? */ | |
148 int frbi; /* first row block index in MB */ | |
149 int srbi; /* second row block index in MB */ | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
150 int stride[4]; /* stride for each plan */ |
3695 | 151 |
152 const uint8_t *vp56_coord_div; | |
8299 | 153 VP56ParseVectorAdjustment parse_vector_adjustment; |
154 VP56Filter filter; | |
155 VP56ParseCoeff parse_coeff; | |
156 VP56DefaultModelsInit default_models_init; | |
157 VP56ParseVectorModels parse_vector_models; | |
158 VP56ParseCoeffModels parse_coeff_models; | |
159 VP56ParseHeader parse_header; | |
5711 | 160 |
8304 | 161 VP56Model *modelp; |
162 VP56Model models[2]; | |
5821 | 163 |
164 /* huffman decoding */ | |
165 int use_huffman; | |
166 GetBitContext gb; | |
167 VLC dccv_vlc[2]; | |
168 VLC runv_vlc[2]; | |
169 VLC ract_vlc[2][3][6]; | |
170 unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ | |
3695 | 171 }; |
172 | |
173 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
174 void vp56_init(AVCodecContext *avctx, int flip, int has_alpha); |
3695 | 175 int vp56_free(AVCodecContext *avctx); |
8299 | 176 void vp56_init_dequant(VP56Context *s, int quantizer); |
3695 | 177 int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
9356
2983bd7deaf5
fix vp5/vp6 decoding by using new prototype for decode function
aurel
parents:
8718
diff
changeset
|
178 AVPacket *avpkt); |
3695 | 179 |
180 | |
181 /** | |
182 * vp56 specific range coder implementation | |
183 */ | |
184 | |
8299 | 185 static inline void vp56_init_range_decoder(VP56RangeCoder *c, |
6297 | 186 const uint8_t *buf, int buf_size) |
3695 | 187 { |
188 c->high = 255; | |
12031 | 189 c->bits = -8; |
3695 | 190 c->buffer = buf; |
9919
c7c1c6b35a73
vp56dec: ensure range coder won't read past the end of input buffer
aurel
parents:
9428
diff
changeset
|
191 c->end = buf + buf_size; |
5089 | 192 c->code_word = bytestream_get_be16(&c->buffer); |
3695 | 193 } |
194 | |
8299 | 195 static inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) |
3695 | 196 { |
12033
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
197 /* Don't put c->high in a local variable; if we do that, gcc gets |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
198 * the stupids and turns the code below into a branch again. */ |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
199 int bits = c->bits; |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
200 unsigned long code_word = c->code_word; |
11920 | 201 unsigned int low = 1 + (((c->high - 1) * prob) >> 8); |
3695 | 202 unsigned int low_shift = low << 8; |
12033
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
203 int bit = code_word >= low_shift; |
12029 | 204 int shift; |
3695 | 205 |
12033
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
206 /* Incantation to convince GCC to turn these into conditional moves |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
207 * instead of branches -- faster, as this branch is basically |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
208 * unpredictable. */ |
12032 | 209 c->high = bit ? c->high - low : low; |
12033
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
210 code_word = bit ? code_word - low_shift : code_word; |
3695 | 211 |
212 /* normalize */ | |
12029 | 213 shift = ff_h264_norm_shift[c->high] - 1; |
12033
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
214 c->high <<= shift; |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
215 code_word <<= shift; |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
216 bits += shift; |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
217 if(bits >= 0 && c->buffer < c->end) { |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
218 code_word |= *c->buffer++ << bits; |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
219 bits -= 8; |
3695 | 220 } |
12033
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
221 c->bits = bits; |
5de2b84a1fc3
Eliminate another redundant instruction in vp56/8 arithcoder
darkshikari
parents:
12032
diff
changeset
|
222 c->code_word = code_word; |
3695 | 223 return bit; |
224 } | |
225 | |
8299 | 226 static inline int vp56_rac_get(VP56RangeCoder *c) |
3695 | 227 { |
228 /* equiprobable */ | |
229 int low = (c->high + 1) >> 1; | |
230 unsigned int low_shift = low << 8; | |
231 int bit = c->code_word >= low_shift; | |
232 if (bit) { | |
233 c->high = (c->high - low) << 1; | |
234 c->code_word -= low_shift; | |
235 } else { | |
236 c->high = low << 1; | |
237 } | |
238 | |
239 /* normalize */ | |
240 c->code_word <<= 1; | |
12031 | 241 if (++c->bits == 0 && c->buffer < c->end) { |
242 c->bits = -8; | |
3695 | 243 c->code_word |= *c->buffer++; |
244 } | |
245 return bit; | |
246 } | |
247 | |
11921 | 248 // rounding is different than vp56_rac_get, is vp56_rac_get wrong? |
249 static inline int vp8_rac_get(VP56RangeCoder *c) | |
250 { | |
251 return vp56_rac_get_prob(c, 128); | |
252 } | |
253 | |
8299 | 254 static inline int vp56_rac_gets(VP56RangeCoder *c, int bits) |
3695 | 255 { |
256 int value = 0; | |
257 | |
258 while (bits--) { | |
259 value = (value << 1) | vp56_rac_get(c); | |
260 } | |
261 | |
262 return value; | |
263 } | |
264 | |
11921 | 265 static inline int vp8_rac_get_uint(VP56RangeCoder *c, int bits) |
266 { | |
267 int value = 0; | |
268 | |
269 while (bits--) { | |
270 value = (value << 1) | vp8_rac_get(c); | |
271 } | |
272 | |
273 return value; | |
274 } | |
275 | |
276 // fixme: add 1 bit to all the calls to this? | |
277 static inline int vp8_rac_get_sint(VP56RangeCoder *c, int bits) | |
278 { | |
279 int v; | |
280 | |
281 if (!vp8_rac_get(c)) | |
282 return 0; | |
283 | |
284 v = vp8_rac_get_uint(c, bits); | |
285 | |
286 if (vp8_rac_get(c)) | |
287 v = -v; | |
288 | |
289 return v; | |
290 } | |
291 | |
292 // P(7) | |
8299 | 293 static inline int vp56_rac_gets_nn(VP56RangeCoder *c, int bits) |
3695 | 294 { |
295 int v = vp56_rac_gets(c, 7) << 1; | |
296 return v + !v; | |
297 } | |
298 | |
11921 | 299 static inline int vp8_rac_get_nn(VP56RangeCoder *c) |
300 { | |
301 int v = vp8_rac_get_uint(c, 7) << 1; | |
302 return v + !v; | |
303 } | |
304 | |
8299 | 305 static inline int vp56_rac_get_tree(VP56RangeCoder *c, |
306 const VP56Tree *tree, | |
3695 | 307 const uint8_t *probs) |
308 { | |
309 while (tree->val > 0) { | |
310 if (vp56_rac_get_prob(c, probs[tree->prob_idx])) | |
311 tree += tree->val; | |
312 else | |
313 tree++; | |
314 } | |
315 return -tree->val; | |
316 } | |
317 | |
11921 | 318 /** |
319 * This is identical to vp8_rac_get_tree except for the possibility of starting | |
320 * on a node other than the root node, needed for coeff decode where this is | |
321 * used to save a bit after a 0 token (by disallowing EOB to immediately follow.) | |
322 */ | |
323 static inline int vp8_rac_get_tree_with_offset(VP56RangeCoder *c, const int8_t (*tree)[2], | |
324 const uint8_t *probs, int i) | |
325 { | |
326 do { | |
327 i = tree[i][vp56_rac_get_prob(c, probs[i])]; | |
328 } while (i > 0); | |
329 | |
330 return -i; | |
331 } | |
332 | |
333 // how probabilities are associated with decisions is different I think | |
334 // well, the new scheme fits in the old but this way has one fewer branches per decision | |
335 static inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2], | |
336 const uint8_t *probs) | |
337 { | |
338 return vp8_rac_get_tree_with_offset(c, tree, probs, 0); | |
339 } | |
340 | |
341 // DCTextra | |
342 static inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob) | |
343 { | |
344 int v = 0; | |
345 | |
346 do { | |
347 v = (v<<1) + vp56_rac_get_prob(c, *prob++); | |
348 } while (*prob); | |
349 | |
350 return v; | |
351 } | |
352 | |
7760 | 353 #endif /* AVCODEC_VP56_H */ |