Mercurial > libavcodec.hg
annotate vp6.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Fri, 20 Feb 2009 16:20:01 +0000 |
parents | bee83b3f9a6b |
children | 0dce4fe6e6f3 |
rev | line source |
---|---|
3695 | 1 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8329
diff
changeset
|
2 * @file libavcodec/vp6.c |
3695 | 3 * VP6 compatible video decoder |
4 * | |
5 * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |
6 * | |
5214 | 7 * The VP6F decoder accepts an optional 1 byte extradata. It is composed of: |
8 * - upper 4bits: difference between encoded width and visible width | |
9 * - lower 4bits: difference between encoded height and visible height | |
10 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3697
diff
changeset
|
11 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3697
diff
changeset
|
12 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3697
diff
changeset
|
13 * FFmpeg is free software; you can redistribute it and/or |
3695 | 14 * modify it under the terms of the GNU Lesser General Public |
15 * License as published by the Free Software Foundation; either | |
16 * version 2.1 of the License, or (at your option) any later version. | |
17 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3697
diff
changeset
|
18 * FFmpeg is distributed in the hope that it will be useful, |
3695 | 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
21 * Lesser General Public License for more details. | |
22 * | |
23 * 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:
3697
diff
changeset
|
24 * License along with FFmpeg; if not, write to the Free Software |
5214 | 25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3695 | 26 */ |
27 | |
28 #include <stdlib.h> | |
29 | |
30 #include "avcodec.h" | |
31 #include "dsputil.h" | |
32 #include "bitstream.h" | |
5821 | 33 #include "huffman.h" |
3695 | 34 |
35 #include "vp56.h" | |
36 #include "vp56data.h" | |
37 #include "vp6data.h" | |
38 | |
39 | |
8299 | 40 static void vp6_parse_coeff(VP56Context *s); |
41 static void vp6_parse_coeff_huffman(VP56Context *s); | |
5821 | 42 |
8299 | 43 static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, |
3695 | 44 int *golden_frame) |
45 { | |
8299 | 46 VP56RangeCoder *c = &s->c; |
4308 | 47 int parse_filter_info = 0; |
4348 | 48 int coeff_offset = 0; |
4308 | 49 int vrt_shift = 0; |
50 int sub_version; | |
3695 | 51 int rows, cols; |
52 int res = 1; | |
4348 | 53 int separated_coeff = buf[0] & 1; |
3695 | 54 |
4595 | 55 s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); |
3695 | 56 vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); |
57 | |
4595 | 58 if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
4308 | 59 sub_version = buf[1] >> 3; |
60 if (sub_version > 8) | |
61 return 0; | |
4348 | 62 s->filter_header = buf[1] & 0x06; |
3695 | 63 if (buf[1] & 1) { |
64 av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); | |
65 return 0; | |
66 } | |
4348 | 67 if (separated_coeff || !s->filter_header) { |
4364 | 68 coeff_offset = AV_RB16(buf+2) - 2; |
4348 | 69 buf += 2; |
70 buf_size -= 2; | |
71 } | |
3695 | 72 |
73 rows = buf[2]; /* number of stored macroblock rows */ | |
74 cols = buf[3]; /* number of stored macroblock cols */ | |
75 /* buf[4] is number of displayed macroblock rows */ | |
76 /* buf[5] is number of displayed macroblock cols */ | |
77 | |
8329 | 78 if (!s->macroblocks || /* first frame */ |
79 16*cols != s->avctx->coded_width || | |
3695 | 80 16*rows != s->avctx->coded_height) { |
81 avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); | |
4062
683d458a251f
use the adjustment value present in FLV to crop VP6 video
aurel
parents:
4001
diff
changeset
|
82 if (s->avctx->extradata_size == 1) { |
683d458a251f
use the adjustment value present in FLV to crop VP6 video
aurel
parents:
4001
diff
changeset
|
83 s->avctx->width -= s->avctx->extradata[0] >> 4; |
683d458a251f
use the adjustment value present in FLV to crop VP6 video
aurel
parents:
4001
diff
changeset
|
84 s->avctx->height -= s->avctx->extradata[0] & 0x0F; |
683d458a251f
use the adjustment value present in FLV to crop VP6 video
aurel
parents:
4001
diff
changeset
|
85 } |
3695 | 86 res = 2; |
87 } | |
88 | |
89 vp56_init_range_decoder(c, buf+6, buf_size-6); | |
90 vp56_rac_gets(c, 2); | |
91 | |
4348 | 92 parse_filter_info = s->filter_header; |
4308 | 93 if (sub_version < 8) |
94 vrt_shift = 5; | |
95 s->sub_version = sub_version; | |
3695 | 96 } else { |
4308 | 97 if (!s->sub_version) |
98 return 0; | |
99 | |
4348 | 100 if (separated_coeff || !s->filter_header) { |
4364 | 101 coeff_offset = AV_RB16(buf+1) - 2; |
4348 | 102 buf += 2; |
103 buf_size -= 2; | |
104 } | |
3695 | 105 vp56_init_range_decoder(c, buf+1, buf_size-1); |
106 | |
107 *golden_frame = vp56_rac_get(c); | |
4348 | 108 if (s->filter_header) { |
4349 | 109 s->deblock_filtering = vp56_rac_get(c); |
110 if (s->deblock_filtering) | |
111 vp56_rac_get(c); | |
112 if (s->sub_version > 7) | |
113 parse_filter_info = vp56_rac_get(c); | |
4348 | 114 } |
3695 | 115 } |
116 | |
117 if (parse_filter_info) { | |
118 if (vp56_rac_get(c)) { | |
119 s->filter_mode = 2; | |
4308 | 120 s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift; |
3695 | 121 s->max_vector_length = 2 << vp56_rac_gets(c, 3); |
122 } else if (vp56_rac_get(c)) { | |
123 s->filter_mode = 1; | |
124 } else { | |
125 s->filter_mode = 0; | |
126 } | |
4308 | 127 if (s->sub_version > 7) |
128 s->filter_selection = vp56_rac_gets(c, 4); | |
129 else | |
130 s->filter_selection = 16; | |
3695 | 131 } |
132 | |
5821 | 133 s->use_huffman = vp56_rac_get(c); |
4348 | 134 |
5821 | 135 s->parse_coeff = vp6_parse_coeff; |
4348 | 136 if (coeff_offset) { |
5821 | 137 buf += coeff_offset; |
138 buf_size -= coeff_offset; | |
8022
21c3e313709e
vp6dec: ensure we don't try to use a buffer with negative size
aurel
parents:
7093
diff
changeset
|
139 if (buf_size < 0) |
21c3e313709e
vp6dec: ensure we don't try to use a buffer with negative size
aurel
parents:
7093
diff
changeset
|
140 return 0; |
5821 | 141 if (s->use_huffman) { |
142 s->parse_coeff = vp6_parse_coeff_huffman; | |
5945 | 143 init_get_bits(&s->gb, buf, buf_size<<3); |
5821 | 144 } else { |
145 vp56_init_range_decoder(&s->cc, buf, buf_size); | |
146 s->ccp = &s->cc; | |
147 } | |
4348 | 148 } else { |
149 s->ccp = &s->c; | |
150 } | |
151 | |
3695 | 152 return res; |
153 } | |
154 | |
8299 | 155 static void vp6_coeff_order_table_init(VP56Context *s) |
3695 | 156 { |
157 int i, pos, idx = 1; | |
158 | |
5711 | 159 s->modelp->coeff_index_to_pos[0] = 0; |
3695 | 160 for (i=0; i<16; i++) |
161 for (pos=1; pos<64; pos++) | |
5711 | 162 if (s->modelp->coeff_reorder[pos] == i) |
163 s->modelp->coeff_index_to_pos[idx++] = pos; | |
3695 | 164 } |
165 | |
8299 | 166 static void vp6_default_models_init(VP56Context *s) |
3695 | 167 { |
8304 | 168 VP56Model *model = s->modelp; |
3695 | 169 |
5711 | 170 model->vector_dct[0] = 0xA2; |
171 model->vector_dct[1] = 0xA4; | |
172 model->vector_sig[0] = 0x80; | |
173 model->vector_sig[1] = 0x80; | |
174 | |
175 memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); | |
176 memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv)); | |
177 memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv)); | |
178 memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv)); | |
179 memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder)); | |
3695 | 180 |
181 vp6_coeff_order_table_init(s); | |
182 } | |
183 | |
8299 | 184 static void vp6_parse_vector_models(VP56Context *s) |
3695 | 185 { |
8299 | 186 VP56RangeCoder *c = &s->c; |
8304 | 187 VP56Model *model = s->modelp; |
3695 | 188 int comp, node; |
189 | |
190 for (comp=0; comp<2; comp++) { | |
191 if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) | |
5711 | 192 model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 193 if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) |
5711 | 194 model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 195 } |
196 | |
197 for (comp=0; comp<2; comp++) | |
198 for (node=0; node<7; node++) | |
199 if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) | |
5711 | 200 model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); |
3695 | 201 |
202 for (comp=0; comp<2; comp++) | |
203 for (node=0; node<8; node++) | |
204 if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) | |
5711 | 205 model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7); |
3695 | 206 } |
207 | |
7093
544da38cb2c9
vp6: ensure that huffman decoding table is sorted with descending symbol order
aurel
parents:
7040
diff
changeset
|
208 /* nodes must ascend by count, but with descending symbol order */ |
5821 | 209 static int vp6_huff_cmp(const void *va, const void *vb) |
210 { | |
211 const Node *a = va, *b = vb; | |
7093
544da38cb2c9
vp6: ensure that huffman decoding table is sorted with descending symbol order
aurel
parents:
7040
diff
changeset
|
212 return (a->count - b->count)*16 + (b->sym - a->sym); |
5821 | 213 } |
214 | |
8299 | 215 static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], |
5821 | 216 const uint8_t *map, unsigned size, VLC *vlc) |
217 { | |
218 Node nodes[2*size], *tmp = &nodes[size]; | |
219 int a, b, i; | |
220 | |
221 /* first compute probabilities from model */ | |
222 tmp[0].count = 256; | |
223 for (i=0; i<size-1; i++) { | |
224 a = tmp[i].count * coeff_model[i] >> 8; | |
225 b = tmp[i].count * (255 - coeff_model[i]) >> 8; | |
226 nodes[map[2*i ]].count = a + !a; | |
227 nodes[map[2*i+1]].count = b + !b; | |
228 } | |
229 | |
230 /* then build the huffman tree accodring to probabilities */ | |
6472
e39e03d99d24
huffman: pass hnode_first as a flag instead of as an argument on its own
aurel
parents:
6448
diff
changeset
|
231 ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, |
e39e03d99d24
huffman: pass hnode_first as a flag instead of as an argument on its own
aurel
parents:
6448
diff
changeset
|
232 FF_HUFFMAN_FLAG_HNODE_FIRST); |
5821 | 233 } |
234 | |
8299 | 235 static void vp6_parse_coeff_models(VP56Context *s) |
3695 | 236 { |
8299 | 237 VP56RangeCoder *c = &s->c; |
8304 | 238 VP56Model *model = s->modelp; |
3695 | 239 int def_prob[11]; |
240 int node, cg, ctx, pos; | |
241 int ct; /* code type */ | |
242 int pt; /* plane type (0 for Y, 1 for U or V) */ | |
243 | |
244 memset(def_prob, 0x80, sizeof(def_prob)); | |
245 | |
246 for (pt=0; pt<2; pt++) | |
247 for (node=0; node<11; node++) | |
248 if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { | |
249 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 250 model->coeff_dccv[pt][node] = def_prob[node]; |
4595 | 251 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 252 model->coeff_dccv[pt][node] = def_prob[node]; |
3695 | 253 } |
254 | |
255 if (vp56_rac_get(c)) { | |
256 for (pos=1; pos<64; pos++) | |
257 if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) | |
5711 | 258 model->coeff_reorder[pos] = vp56_rac_gets(c, 4); |
3695 | 259 vp6_coeff_order_table_init(s); |
260 } | |
261 | |
262 for (cg=0; cg<2; cg++) | |
263 for (node=0; node<14; node++) | |
264 if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) | |
5711 | 265 model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7); |
3695 | 266 |
267 for (ct=0; ct<3; ct++) | |
268 for (pt=0; pt<2; pt++) | |
269 for (cg=0; cg<6; cg++) | |
270 for (node=0; node<11; node++) | |
271 if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { | |
272 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 273 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
4595 | 274 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 275 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
3695 | 276 } |
277 | |
5821 | 278 if (s->use_huffman) { |
279 for (pt=0; pt<2; pt++) { | |
280 vp6_build_huff_tree(s, model->coeff_dccv[pt], | |
281 vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]); | |
282 vp6_build_huff_tree(s, model->coeff_runv[pt], | |
283 vp6_huff_run_map, 9, &s->runv_vlc[pt]); | |
284 for (ct=0; ct<3; ct++) | |
285 for (cg = 0; cg < 6; cg++) | |
286 vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], | |
287 vp6_huff_coeff_map, 12, | |
288 &s->ract_vlc[pt][ct][cg]); | |
289 } | |
290 memset(s->nb_null, 0, sizeof(s->nb_null)); | |
291 } else { | |
5711 | 292 /* coeff_dcct is a linear combination of coeff_dccv */ |
3695 | 293 for (pt=0; pt<2; pt++) |
294 for (ctx=0; ctx<3; ctx++) | |
295 for (node=0; node<5; node++) | |
5711 | 296 model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); |
5821 | 297 } |
3695 | 298 } |
299 | |
8299 | 300 static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect) |
3695 | 301 { |
8299 | 302 VP56RangeCoder *c = &s->c; |
8304 | 303 VP56Model *model = s->modelp; |
3695 | 304 int comp; |
305 | |
8299 | 306 *vect = (VP56mv) {0,0}; |
3695 | 307 if (s->vector_candidate_pos < 2) |
3697 | 308 *vect = s->vector_candidate[0]; |
3695 | 309 |
310 for (comp=0; comp<2; comp++) { | |
311 int i, delta = 0; | |
312 | |
5711 | 313 if (vp56_rac_get_prob(c, model->vector_dct[comp])) { |
3695 | 314 static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; |
315 for (i=0; i<sizeof(prob_order); i++) { | |
316 int j = prob_order[i]; | |
5711 | 317 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j; |
3695 | 318 } |
319 if (delta & 0xF0) | |
5711 | 320 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3; |
3695 | 321 else |
322 delta |= 8; | |
323 } else { | |
324 delta = vp56_rac_get_tree(c, vp56_pva_tree, | |
5711 | 325 model->vector_pdv[comp]); |
3695 | 326 } |
327 | |
5711 | 328 if (delta && vp56_rac_get_prob(c, model->vector_sig[comp])) |
3695 | 329 delta = -delta; |
330 | |
331 if (!comp) | |
3697 | 332 vect->x += delta; |
3695 | 333 else |
3697 | 334 vect->y += delta; |
3695 | 335 } |
336 } | |
337 | |
5821 | 338 /** |
339 * Read number of consecutive blocks with null DC or AC. | |
340 * This value is < 74. | |
341 */ | |
8299 | 342 static unsigned vp6_get_nb_null(VP56Context *s) |
5821 | 343 { |
344 unsigned val = get_bits(&s->gb, 2); | |
345 if (val == 2) | |
346 val += get_bits(&s->gb, 2); | |
347 else if (val == 3) { | |
348 val = get_bits1(&s->gb) << 2; | |
349 val = 6+val + get_bits(&s->gb, 2+val); | |
350 } | |
351 return val; | |
352 } | |
353 | |
8299 | 354 static void vp6_parse_coeff_huffman(VP56Context *s) |
5821 | 355 { |
8304 | 356 VP56Model *model = s->modelp; |
5821 | 357 uint8_t *permute = s->scantable.permutated; |
358 VLC *vlc_coeff; | |
359 int coeff, sign, coeff_idx; | |
360 int b, cg, idx; | |
361 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
362 | |
363 for (b=0; b<6; b++) { | |
364 int ct = 0; /* code type */ | |
365 if (b > 3) pt = 1; | |
366 vlc_coeff = &s->dccv_vlc[pt]; | |
367 | |
368 for (coeff_idx=0; coeff_idx<64; ) { | |
369 int run = 1; | |
370 if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { | |
371 s->nb_null[coeff_idx][pt]--; | |
372 if (coeff_idx) | |
373 break; | |
374 } else { | |
375 coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); | |
376 if (coeff == 0) { | |
377 if (coeff_idx) { | |
378 int pt = (coeff_idx >= 6); | |
379 run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); | |
380 if (run >= 9) | |
381 run += get_bits(&s->gb, 6); | |
382 } else | |
383 s->nb_null[0][pt] = vp6_get_nb_null(s); | |
384 ct = 0; | |
385 } else if (coeff == 11) { /* end of block */ | |
386 if (coeff_idx == 1) /* first AC coeff ? */ | |
387 s->nb_null[1][pt] = vp6_get_nb_null(s); | |
388 break; | |
389 } else { | |
390 int coeff2 = vp56_coeff_bias[coeff]; | |
391 if (coeff > 4) | |
392 coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); | |
393 ct = 1 + (coeff2 > 1); | |
394 sign = get_bits1(&s->gb); | |
395 coeff2 = (coeff2 ^ -sign) + sign; | |
396 if (coeff_idx) | |
397 coeff2 *= s->dequant_ac; | |
398 idx = model->coeff_index_to_pos[coeff_idx]; | |
399 s->block_coeff[b][permute[idx]] = coeff2; | |
400 } | |
401 } | |
402 coeff_idx+=run; | |
403 cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); | |
404 vlc_coeff = &s->ract_vlc[pt][ct][cg]; | |
405 } | |
406 } | |
407 } | |
408 | |
8299 | 409 static void vp6_parse_coeff(VP56Context *s) |
3695 | 410 { |
8299 | 411 VP56RangeCoder *c = s->ccp; |
8304 | 412 VP56Model *model = s->modelp; |
3695 | 413 uint8_t *permute = s->scantable.permutated; |
5711 | 414 uint8_t *model1, *model2, *model3; |
3695 | 415 int coeff, sign, coeff_idx; |
416 int b, i, cg, idx, ctx; | |
417 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
418 | |
419 for (b=0; b<6; b++) { | |
420 int ct = 1; /* code type */ | |
421 int run = 1; | |
422 | |
423 if (b > 3) pt = 1; | |
424 | |
425 ctx = s->left_block[vp56_b6to4[b]].not_null_dc | |
426 + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |
5711 | 427 model1 = model->coeff_dccv[pt]; |
428 model2 = model->coeff_dcct[pt][ctx]; | |
3695 | 429 |
430 for (coeff_idx=0; coeff_idx<64; ) { | |
431 if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { | |
432 /* parse a coeff */ | |
433 if (vp56_rac_get_prob(c, model2[2])) { | |
434 if (vp56_rac_get_prob(c, model2[3])) { | |
5711 | 435 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); |
5821 | 436 coeff = vp56_coeff_bias[idx+5]; |
3695 | 437 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
438 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |
439 } else { | |
440 if (vp56_rac_get_prob(c, model2[4])) | |
5711 | 441 coeff = 3 + vp56_rac_get_prob(c, model1[5]); |
3695 | 442 else |
443 coeff = 2; | |
444 } | |
445 ct = 2; | |
446 } else { | |
447 ct = 1; | |
448 coeff = 1; | |
449 } | |
450 sign = vp56_rac_get(c); | |
451 coeff = (coeff ^ -sign) + sign; | |
452 if (coeff_idx) | |
453 coeff *= s->dequant_ac; | |
5711 | 454 idx = model->coeff_index_to_pos[coeff_idx]; |
3695 | 455 s->block_coeff[b][permute[idx]] = coeff; |
456 run = 1; | |
457 } else { | |
458 /* parse a run */ | |
459 ct = 0; | |
4925 | 460 if (coeff_idx > 0) { |
3695 | 461 if (!vp56_rac_get_prob(c, model2[1])) |
462 break; | |
463 | |
5711 | 464 model3 = model->coeff_runv[coeff_idx >= 6]; |
3695 | 465 run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); |
466 if (!run) | |
467 for (run=9, i=0; i<6; i++) | |
468 run += vp56_rac_get_prob(c, model3[i+8]) << i; | |
469 } | |
470 } | |
471 | |
472 cg = vp6_coeff_groups[coeff_idx+=run]; | |
5711 | 473 model1 = model2 = model->coeff_ract[pt][ct][cg]; |
3695 | 474 } |
4925 | 475 |
476 s->left_block[vp56_b6to4[b]].not_null_dc = | |
477 s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; | |
3695 | 478 } |
479 } | |
480 | |
481 static int vp6_adjust(int v, int t) | |
482 { | |
483 int V = v, s = v >> 31; | |
484 V ^= s; | |
485 V -= s; | |
486 if (V-t-1 >= (unsigned)(t-1)) | |
487 return v; | |
488 V = 2*t - V; | |
489 V += s; | |
490 V ^= s; | |
491 return V; | |
492 } | |
493 | |
494 static int vp6_block_variance(uint8_t *src, int stride) | |
495 { | |
496 int sum = 0, square_sum = 0; | |
497 int y, x; | |
498 | |
499 for (y=0; y<8; y+=2) { | |
500 for (x=0; x<8; x+=2) { | |
501 sum += src[x]; | |
502 square_sum += src[x]*src[x]; | |
503 } | |
504 src += 2*stride; | |
505 } | |
4306 | 506 return (16*square_sum - sum*sum) >> 8; |
3695 | 507 } |
508 | |
509 static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, | |
510 int delta, const int16_t *weights) | |
511 { | |
512 int x, y; | |
513 | |
514 for (y=0; y<8; y++) { | |
515 for (x=0; x<8; x++) { | |
4594 | 516 dst[x] = av_clip_uint8(( src[x-delta ] * weights[0] |
3695 | 517 + src[x ] * weights[1] |
518 + src[x+delta ] * weights[2] | |
519 + src[x+2*delta] * weights[3] + 64) >> 7); | |
520 } | |
521 src += stride; | |
522 dst += stride; | |
523 } | |
524 } | |
525 | |
8299 | 526 static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, |
3695 | 527 int stride, int h_weight, int v_weight) |
528 { | |
529 uint8_t *tmp = s->edge_emu_buffer+16; | |
4921 | 530 s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); |
531 s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); | |
3695 | 532 } |
533 | |
8299 | 534 static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, |
3695 | 535 int offset1, int offset2, int stride, |
8299 | 536 VP56mv mv, int mask, int select, int luma) |
3695 | 537 { |
538 int filter4 = 0; | |
539 int x8 = mv.x & mask; | |
540 int y8 = mv.y & mask; | |
541 | |
542 if (luma) { | |
543 x8 *= 2; | |
544 y8 *= 2; | |
545 filter4 = s->filter_mode; | |
546 if (filter4 == 2) { | |
547 if (s->max_vector_length && | |
4001 | 548 (FFABS(mv.x) > s->max_vector_length || |
549 FFABS(mv.y) > s->max_vector_length)) { | |
3695 | 550 filter4 = 0; |
4308 | 551 } else if (s->sample_variance_threshold |
552 && (vp6_block_variance(src+offset1, stride) | |
3695 | 553 < s->sample_variance_threshold)) { |
554 filter4 = 0; | |
555 } | |
556 } | |
557 } | |
558 | |
559 if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { | |
560 offset1 = offset2; | |
561 } | |
562 | |
563 if (filter4) { | |
564 if (!y8) { /* left or right combine */ | |
565 vp6_filter_hv4(dst, src+offset1, stride, 1, | |
566 vp6_block_copy_filter[select][x8]); | |
567 } else if (!x8) { /* above or below combine */ | |
568 vp6_filter_hv4(dst, src+offset1, stride, stride, | |
569 vp6_block_copy_filter[select][y8]); | |
4922 | 570 } else { |
8785
bee83b3f9a6b
move vp6_filter_diag4() to a new vp6dsp.c file and use it throught dsputil
aurel
parents:
8718
diff
changeset
|
571 s->dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride, |
3695 | 572 vp6_block_copy_filter[select][x8], |
573 vp6_block_copy_filter[select][y8]); | |
574 } | |
575 } else { | |
4921 | 576 if (!x8 || !y8) { |
577 s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); | |
4922 | 578 } else { |
579 vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); | |
3695 | 580 } |
581 } | |
582 } | |
583 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6472
diff
changeset
|
584 static av_cold int vp6_decode_init(AVCodecContext *avctx) |
3695 | 585 { |
8299 | 586 VP56Context *s = avctx->priv_data; |
3695 | 587 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
588 vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
589 avctx->codec->id == CODEC_ID_VP6A); |
3695 | 590 s->vp56_coord_div = vp6_coord_div; |
591 s->parse_vector_adjustment = vp6_parse_vector_adjustment; | |
592 s->adjust = vp6_adjust; | |
593 s->filter = vp6_filter; | |
594 s->default_models_init = vp6_default_models_init; | |
595 s->parse_vector_models = vp6_parse_vector_models; | |
596 s->parse_coeff_models = vp6_parse_coeff_models; | |
597 s->parse_header = vp6_parse_header; | |
598 | |
599 return 0; | |
600 } | |
601 | |
602 AVCodec vp6_decoder = { | |
603 "vp6", | |
604 CODEC_TYPE_VIDEO, | |
605 CODEC_ID_VP6, | |
8299 | 606 sizeof(VP56Context), |
3695 | 607 vp6_decode_init, |
608 NULL, | |
609 vp56_free, | |
610 vp56_decode_frame, | |
4910 | 611 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
612 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), |
3695 | 613 }; |
614 | |
615 /* flash version, not flipped upside-down */ | |
616 AVCodec vp6f_decoder = { | |
617 "vp6f", | |
618 CODEC_TYPE_VIDEO, | |
619 CODEC_ID_VP6F, | |
8299 | 620 sizeof(VP56Context), |
3695 | 621 vp6_decode_init, |
622 NULL, | |
623 vp56_free, | |
624 vp56_decode_frame, | |
4910 | 625 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
626 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), |
3695 | 627 }; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
628 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
629 /* flash version, not flipped upside-down, with alpha channel */ |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
630 AVCodec vp6a_decoder = { |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
631 "vp6a", |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
632 CODEC_TYPE_VIDEO, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
633 CODEC_ID_VP6A, |
8299 | 634 sizeof(VP56Context), |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
635 vp6_decode_init, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
636 NULL, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
637 vp56_free, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
638 vp56_decode_frame, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
639 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
640 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
641 }; |