Mercurial > libavcodec.hg
annotate vp6.c @ 10852:86d7ab878805 libavcodec
Get rid of #include "svq3.c"
functions called more than per mb are moved into the header, scan8 is also
as it must be known at compiletime.
The code after this patch duplicates h264data.h, this has been done to minimize
the changes in this step and allow more fine grained benchmarking.
Speedwise this is 1% faster on my pentium dual core with diegos cursed cathedral
sample.
author | michael |
---|---|
date | Tue, 12 Jan 2010 05:30:31 +0000 |
parents | 8332746a9db9 |
children | 8d23ea397dda |
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" | |
9428 | 32 #include "get_bits.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 { | |
9920
8332746a9db9
Add a check to vp6_parse_coeff_huffman to ensure it does not overread the input buffer.
reimar
parents:
9428
diff
changeset
|
375 if (get_bits_count(&s->gb) >= s->gb.size_in_bits) |
8332746a9db9
Add a check to vp6_parse_coeff_huffman to ensure it does not overread the input buffer.
reimar
parents:
9428
diff
changeset
|
376 return; |
5821 | 377 coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); |
378 if (coeff == 0) { | |
379 if (coeff_idx) { | |
380 int pt = (coeff_idx >= 6); | |
381 run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); | |
382 if (run >= 9) | |
383 run += get_bits(&s->gb, 6); | |
384 } else | |
385 s->nb_null[0][pt] = vp6_get_nb_null(s); | |
386 ct = 0; | |
387 } else if (coeff == 11) { /* end of block */ | |
388 if (coeff_idx == 1) /* first AC coeff ? */ | |
389 s->nb_null[1][pt] = vp6_get_nb_null(s); | |
390 break; | |
391 } else { | |
392 int coeff2 = vp56_coeff_bias[coeff]; | |
393 if (coeff > 4) | |
394 coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); | |
395 ct = 1 + (coeff2 > 1); | |
396 sign = get_bits1(&s->gb); | |
397 coeff2 = (coeff2 ^ -sign) + sign; | |
398 if (coeff_idx) | |
399 coeff2 *= s->dequant_ac; | |
400 idx = model->coeff_index_to_pos[coeff_idx]; | |
401 s->block_coeff[b][permute[idx]] = coeff2; | |
402 } | |
403 } | |
404 coeff_idx+=run; | |
405 cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); | |
406 vlc_coeff = &s->ract_vlc[pt][ct][cg]; | |
407 } | |
408 } | |
409 } | |
410 | |
8299 | 411 static void vp6_parse_coeff(VP56Context *s) |
3695 | 412 { |
8299 | 413 VP56RangeCoder *c = s->ccp; |
8304 | 414 VP56Model *model = s->modelp; |
3695 | 415 uint8_t *permute = s->scantable.permutated; |
5711 | 416 uint8_t *model1, *model2, *model3; |
3695 | 417 int coeff, sign, coeff_idx; |
418 int b, i, cg, idx, ctx; | |
419 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
420 | |
421 for (b=0; b<6; b++) { | |
422 int ct = 1; /* code type */ | |
423 int run = 1; | |
424 | |
425 if (b > 3) pt = 1; | |
426 | |
427 ctx = s->left_block[vp56_b6to4[b]].not_null_dc | |
428 + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |
5711 | 429 model1 = model->coeff_dccv[pt]; |
430 model2 = model->coeff_dcct[pt][ctx]; | |
3695 | 431 |
432 for (coeff_idx=0; coeff_idx<64; ) { | |
433 if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { | |
434 /* parse a coeff */ | |
435 if (vp56_rac_get_prob(c, model2[2])) { | |
436 if (vp56_rac_get_prob(c, model2[3])) { | |
5711 | 437 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); |
5821 | 438 coeff = vp56_coeff_bias[idx+5]; |
3695 | 439 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
440 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |
441 } else { | |
442 if (vp56_rac_get_prob(c, model2[4])) | |
5711 | 443 coeff = 3 + vp56_rac_get_prob(c, model1[5]); |
3695 | 444 else |
445 coeff = 2; | |
446 } | |
447 ct = 2; | |
448 } else { | |
449 ct = 1; | |
450 coeff = 1; | |
451 } | |
452 sign = vp56_rac_get(c); | |
453 coeff = (coeff ^ -sign) + sign; | |
454 if (coeff_idx) | |
455 coeff *= s->dequant_ac; | |
5711 | 456 idx = model->coeff_index_to_pos[coeff_idx]; |
3695 | 457 s->block_coeff[b][permute[idx]] = coeff; |
458 run = 1; | |
459 } else { | |
460 /* parse a run */ | |
461 ct = 0; | |
4925 | 462 if (coeff_idx > 0) { |
3695 | 463 if (!vp56_rac_get_prob(c, model2[1])) |
464 break; | |
465 | |
5711 | 466 model3 = model->coeff_runv[coeff_idx >= 6]; |
3695 | 467 run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); |
468 if (!run) | |
469 for (run=9, i=0; i<6; i++) | |
470 run += vp56_rac_get_prob(c, model3[i+8]) << i; | |
471 } | |
472 } | |
473 | |
474 cg = vp6_coeff_groups[coeff_idx+=run]; | |
5711 | 475 model1 = model2 = model->coeff_ract[pt][ct][cg]; |
3695 | 476 } |
4925 | 477 |
478 s->left_block[vp56_b6to4[b]].not_null_dc = | |
479 s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; | |
3695 | 480 } |
481 } | |
482 | |
483 static int vp6_adjust(int v, int t) | |
484 { | |
485 int V = v, s = v >> 31; | |
486 V ^= s; | |
487 V -= s; | |
488 if (V-t-1 >= (unsigned)(t-1)) | |
489 return v; | |
490 V = 2*t - V; | |
491 V += s; | |
492 V ^= s; | |
493 return V; | |
494 } | |
495 | |
496 static int vp6_block_variance(uint8_t *src, int stride) | |
497 { | |
498 int sum = 0, square_sum = 0; | |
499 int y, x; | |
500 | |
501 for (y=0; y<8; y+=2) { | |
502 for (x=0; x<8; x+=2) { | |
503 sum += src[x]; | |
504 square_sum += src[x]*src[x]; | |
505 } | |
506 src += 2*stride; | |
507 } | |
4306 | 508 return (16*square_sum - sum*sum) >> 8; |
3695 | 509 } |
510 | |
511 static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, | |
512 int delta, const int16_t *weights) | |
513 { | |
514 int x, y; | |
515 | |
516 for (y=0; y<8; y++) { | |
517 for (x=0; x<8; x++) { | |
4594 | 518 dst[x] = av_clip_uint8(( src[x-delta ] * weights[0] |
3695 | 519 + src[x ] * weights[1] |
520 + src[x+delta ] * weights[2] | |
521 + src[x+2*delta] * weights[3] + 64) >> 7); | |
522 } | |
523 src += stride; | |
524 dst += stride; | |
525 } | |
526 } | |
527 | |
8299 | 528 static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, |
3695 | 529 int stride, int h_weight, int v_weight) |
530 { | |
531 uint8_t *tmp = s->edge_emu_buffer+16; | |
4921 | 532 s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); |
533 s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); | |
3695 | 534 } |
535 | |
8299 | 536 static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, |
3695 | 537 int offset1, int offset2, int stride, |
8299 | 538 VP56mv mv, int mask, int select, int luma) |
3695 | 539 { |
540 int filter4 = 0; | |
541 int x8 = mv.x & mask; | |
542 int y8 = mv.y & mask; | |
543 | |
544 if (luma) { | |
545 x8 *= 2; | |
546 y8 *= 2; | |
547 filter4 = s->filter_mode; | |
548 if (filter4 == 2) { | |
549 if (s->max_vector_length && | |
4001 | 550 (FFABS(mv.x) > s->max_vector_length || |
551 FFABS(mv.y) > s->max_vector_length)) { | |
3695 | 552 filter4 = 0; |
4308 | 553 } else if (s->sample_variance_threshold |
554 && (vp6_block_variance(src+offset1, stride) | |
3695 | 555 < s->sample_variance_threshold)) { |
556 filter4 = 0; | |
557 } | |
558 } | |
559 } | |
560 | |
561 if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { | |
562 offset1 = offset2; | |
563 } | |
564 | |
565 if (filter4) { | |
566 if (!y8) { /* left or right combine */ | |
567 vp6_filter_hv4(dst, src+offset1, stride, 1, | |
568 vp6_block_copy_filter[select][x8]); | |
569 } else if (!x8) { /* above or below combine */ | |
570 vp6_filter_hv4(dst, src+offset1, stride, stride, | |
571 vp6_block_copy_filter[select][y8]); | |
4922 | 572 } else { |
8785
bee83b3f9a6b
move vp6_filter_diag4() to a new vp6dsp.c file and use it throught dsputil
aurel
parents:
8718
diff
changeset
|
573 s->dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride, |
3695 | 574 vp6_block_copy_filter[select][x8], |
575 vp6_block_copy_filter[select][y8]); | |
576 } | |
577 } else { | |
4921 | 578 if (!x8 || !y8) { |
579 s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); | |
4922 | 580 } else { |
581 vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); | |
3695 | 582 } |
583 } | |
584 } | |
585 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6472
diff
changeset
|
586 static av_cold int vp6_decode_init(AVCodecContext *avctx) |
3695 | 587 { |
8299 | 588 VP56Context *s = avctx->priv_data; |
3695 | 589 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
590 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
|
591 avctx->codec->id == CODEC_ID_VP6A); |
3695 | 592 s->vp56_coord_div = vp6_coord_div; |
593 s->parse_vector_adjustment = vp6_parse_vector_adjustment; | |
594 s->adjust = vp6_adjust; | |
595 s->filter = vp6_filter; | |
596 s->default_models_init = vp6_default_models_init; | |
597 s->parse_vector_models = vp6_parse_vector_models; | |
598 s->parse_coeff_models = vp6_parse_coeff_models; | |
599 s->parse_header = vp6_parse_header; | |
600 | |
601 return 0; | |
602 } | |
603 | |
604 AVCodec vp6_decoder = { | |
605 "vp6", | |
606 CODEC_TYPE_VIDEO, | |
607 CODEC_ID_VP6, | |
8299 | 608 sizeof(VP56Context), |
3695 | 609 vp6_decode_init, |
610 NULL, | |
611 vp56_free, | |
612 vp56_decode_frame, | |
4910 | 613 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
614 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), |
3695 | 615 }; |
616 | |
617 /* flash version, not flipped upside-down */ | |
618 AVCodec vp6f_decoder = { | |
619 "vp6f", | |
620 CODEC_TYPE_VIDEO, | |
621 CODEC_ID_VP6F, | |
8299 | 622 sizeof(VP56Context), |
3695 | 623 vp6_decode_init, |
624 NULL, | |
625 vp56_free, | |
626 vp56_decode_frame, | |
4910 | 627 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
628 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), |
3695 | 629 }; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
630 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
631 /* 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
|
632 AVCodec vp6a_decoder = { |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
633 "vp6a", |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
634 CODEC_TYPE_VIDEO, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
635 CODEC_ID_VP6A, |
8299 | 636 sizeof(VP56Context), |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
637 vp6_decode_init, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
638 NULL, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
639 vp56_free, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
640 vp56_decode_frame, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
641 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
642 .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
|
643 }; |