Mercurial > libavcodec.hg
annotate vp6.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | 7d9a1a807e91 |
children | 8a4984c5cacc |
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 | |
11342 | 230 free_vlc(vlc); |
5821 | 231 /* 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
|
232 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
|
233 FF_HUFFMAN_FLAG_HNODE_FIRST); |
5821 | 234 } |
235 | |
8299 | 236 static void vp6_parse_coeff_models(VP56Context *s) |
3695 | 237 { |
8299 | 238 VP56RangeCoder *c = &s->c; |
8304 | 239 VP56Model *model = s->modelp; |
3695 | 240 int def_prob[11]; |
241 int node, cg, ctx, pos; | |
242 int ct; /* code type */ | |
243 int pt; /* plane type (0 for Y, 1 for U or V) */ | |
244 | |
245 memset(def_prob, 0x80, sizeof(def_prob)); | |
246 | |
247 for (pt=0; pt<2; pt++) | |
248 for (node=0; node<11; node++) | |
249 if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { | |
250 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 251 model->coeff_dccv[pt][node] = def_prob[node]; |
4595 | 252 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 253 model->coeff_dccv[pt][node] = def_prob[node]; |
3695 | 254 } |
255 | |
256 if (vp56_rac_get(c)) { | |
257 for (pos=1; pos<64; pos++) | |
258 if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) | |
5711 | 259 model->coeff_reorder[pos] = vp56_rac_gets(c, 4); |
3695 | 260 vp6_coeff_order_table_init(s); |
261 } | |
262 | |
263 for (cg=0; cg<2; cg++) | |
264 for (node=0; node<14; node++) | |
265 if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) | |
5711 | 266 model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7); |
3695 | 267 |
268 for (ct=0; ct<3; ct++) | |
269 for (pt=0; pt<2; pt++) | |
270 for (cg=0; cg<6; cg++) | |
271 for (node=0; node<11; node++) | |
272 if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { | |
273 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 274 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
4595 | 275 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 276 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
3695 | 277 } |
278 | |
5821 | 279 if (s->use_huffman) { |
280 for (pt=0; pt<2; pt++) { | |
281 vp6_build_huff_tree(s, model->coeff_dccv[pt], | |
282 vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]); | |
283 vp6_build_huff_tree(s, model->coeff_runv[pt], | |
284 vp6_huff_run_map, 9, &s->runv_vlc[pt]); | |
285 for (ct=0; ct<3; ct++) | |
286 for (cg = 0; cg < 6; cg++) | |
287 vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], | |
288 vp6_huff_coeff_map, 12, | |
289 &s->ract_vlc[pt][ct][cg]); | |
290 } | |
291 memset(s->nb_null, 0, sizeof(s->nb_null)); | |
292 } else { | |
5711 | 293 /* coeff_dcct is a linear combination of coeff_dccv */ |
3695 | 294 for (pt=0; pt<2; pt++) |
295 for (ctx=0; ctx<3; ctx++) | |
296 for (node=0; node<5; node++) | |
5711 | 297 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 | 298 } |
3695 | 299 } |
300 | |
8299 | 301 static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect) |
3695 | 302 { |
8299 | 303 VP56RangeCoder *c = &s->c; |
8304 | 304 VP56Model *model = s->modelp; |
3695 | 305 int comp; |
306 | |
8299 | 307 *vect = (VP56mv) {0,0}; |
3695 | 308 if (s->vector_candidate_pos < 2) |
3697 | 309 *vect = s->vector_candidate[0]; |
3695 | 310 |
311 for (comp=0; comp<2; comp++) { | |
312 int i, delta = 0; | |
313 | |
5711 | 314 if (vp56_rac_get_prob(c, model->vector_dct[comp])) { |
3695 | 315 static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; |
316 for (i=0; i<sizeof(prob_order); i++) { | |
317 int j = prob_order[i]; | |
5711 | 318 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j; |
3695 | 319 } |
320 if (delta & 0xF0) | |
5711 | 321 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3; |
3695 | 322 else |
323 delta |= 8; | |
324 } else { | |
325 delta = vp56_rac_get_tree(c, vp56_pva_tree, | |
5711 | 326 model->vector_pdv[comp]); |
3695 | 327 } |
328 | |
5711 | 329 if (delta && vp56_rac_get_prob(c, model->vector_sig[comp])) |
3695 | 330 delta = -delta; |
331 | |
332 if (!comp) | |
3697 | 333 vect->x += delta; |
3695 | 334 else |
3697 | 335 vect->y += delta; |
3695 | 336 } |
337 } | |
338 | |
5821 | 339 /** |
340 * Read number of consecutive blocks with null DC or AC. | |
341 * This value is < 74. | |
342 */ | |
8299 | 343 static unsigned vp6_get_nb_null(VP56Context *s) |
5821 | 344 { |
345 unsigned val = get_bits(&s->gb, 2); | |
346 if (val == 2) | |
347 val += get_bits(&s->gb, 2); | |
348 else if (val == 3) { | |
349 val = get_bits1(&s->gb) << 2; | |
350 val = 6+val + get_bits(&s->gb, 2+val); | |
351 } | |
352 return val; | |
353 } | |
354 | |
8299 | 355 static void vp6_parse_coeff_huffman(VP56Context *s) |
5821 | 356 { |
8304 | 357 VP56Model *model = s->modelp; |
5821 | 358 uint8_t *permute = s->scantable.permutated; |
359 VLC *vlc_coeff; | |
360 int coeff, sign, coeff_idx; | |
361 int b, cg, idx; | |
362 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
363 | |
364 for (b=0; b<6; b++) { | |
365 int ct = 0; /* code type */ | |
366 if (b > 3) pt = 1; | |
367 vlc_coeff = &s->dccv_vlc[pt]; | |
368 | |
369 for (coeff_idx=0; coeff_idx<64; ) { | |
370 int run = 1; | |
371 if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { | |
372 s->nb_null[coeff_idx][pt]--; | |
373 if (coeff_idx) | |
374 break; | |
375 } 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
|
376 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
|
377 return; |
5821 | 378 coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); |
379 if (coeff == 0) { | |
380 if (coeff_idx) { | |
381 int pt = (coeff_idx >= 6); | |
382 run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); | |
383 if (run >= 9) | |
384 run += get_bits(&s->gb, 6); | |
385 } else | |
386 s->nb_null[0][pt] = vp6_get_nb_null(s); | |
387 ct = 0; | |
388 } else if (coeff == 11) { /* end of block */ | |
389 if (coeff_idx == 1) /* first AC coeff ? */ | |
390 s->nb_null[1][pt] = vp6_get_nb_null(s); | |
391 break; | |
392 } else { | |
393 int coeff2 = vp56_coeff_bias[coeff]; | |
394 if (coeff > 4) | |
395 coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); | |
396 ct = 1 + (coeff2 > 1); | |
397 sign = get_bits1(&s->gb); | |
398 coeff2 = (coeff2 ^ -sign) + sign; | |
399 if (coeff_idx) | |
400 coeff2 *= s->dequant_ac; | |
401 idx = model->coeff_index_to_pos[coeff_idx]; | |
402 s->block_coeff[b][permute[idx]] = coeff2; | |
403 } | |
404 } | |
405 coeff_idx+=run; | |
406 cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); | |
407 vlc_coeff = &s->ract_vlc[pt][ct][cg]; | |
408 } | |
409 } | |
410 } | |
411 | |
8299 | 412 static void vp6_parse_coeff(VP56Context *s) |
3695 | 413 { |
8299 | 414 VP56RangeCoder *c = s->ccp; |
8304 | 415 VP56Model *model = s->modelp; |
3695 | 416 uint8_t *permute = s->scantable.permutated; |
5711 | 417 uint8_t *model1, *model2, *model3; |
3695 | 418 int coeff, sign, coeff_idx; |
419 int b, i, cg, idx, ctx; | |
420 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
421 | |
422 for (b=0; b<6; b++) { | |
423 int ct = 1; /* code type */ | |
424 int run = 1; | |
425 | |
426 if (b > 3) pt = 1; | |
427 | |
428 ctx = s->left_block[vp56_b6to4[b]].not_null_dc | |
429 + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |
5711 | 430 model1 = model->coeff_dccv[pt]; |
431 model2 = model->coeff_dcct[pt][ctx]; | |
3695 | 432 |
433 for (coeff_idx=0; coeff_idx<64; ) { | |
434 if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { | |
435 /* parse a coeff */ | |
436 if (vp56_rac_get_prob(c, model2[2])) { | |
437 if (vp56_rac_get_prob(c, model2[3])) { | |
5711 | 438 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); |
5821 | 439 coeff = vp56_coeff_bias[idx+5]; |
3695 | 440 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
441 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |
442 } else { | |
443 if (vp56_rac_get_prob(c, model2[4])) | |
5711 | 444 coeff = 3 + vp56_rac_get_prob(c, model1[5]); |
3695 | 445 else |
446 coeff = 2; | |
447 } | |
448 ct = 2; | |
449 } else { | |
450 ct = 1; | |
451 coeff = 1; | |
452 } | |
453 sign = vp56_rac_get(c); | |
454 coeff = (coeff ^ -sign) + sign; | |
455 if (coeff_idx) | |
456 coeff *= s->dequant_ac; | |
5711 | 457 idx = model->coeff_index_to_pos[coeff_idx]; |
3695 | 458 s->block_coeff[b][permute[idx]] = coeff; |
459 run = 1; | |
460 } else { | |
461 /* parse a run */ | |
462 ct = 0; | |
4925 | 463 if (coeff_idx > 0) { |
3695 | 464 if (!vp56_rac_get_prob(c, model2[1])) |
465 break; | |
466 | |
5711 | 467 model3 = model->coeff_runv[coeff_idx >= 6]; |
3695 | 468 run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); |
469 if (!run) | |
470 for (run=9, i=0; i<6; i++) | |
471 run += vp56_rac_get_prob(c, model3[i+8]) << i; | |
472 } | |
473 } | |
474 | |
475 cg = vp6_coeff_groups[coeff_idx+=run]; | |
5711 | 476 model1 = model2 = model->coeff_ract[pt][ct][cg]; |
3695 | 477 } |
4925 | 478 |
479 s->left_block[vp56_b6to4[b]].not_null_dc = | |
480 s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; | |
3695 | 481 } |
482 } | |
483 | |
484 static int vp6_adjust(int v, int t) | |
485 { | |
486 int V = v, s = v >> 31; | |
487 V ^= s; | |
488 V -= s; | |
489 if (V-t-1 >= (unsigned)(t-1)) | |
490 return v; | |
491 V = 2*t - V; | |
492 V += s; | |
493 V ^= s; | |
494 return V; | |
495 } | |
496 | |
497 static int vp6_block_variance(uint8_t *src, int stride) | |
498 { | |
499 int sum = 0, square_sum = 0; | |
500 int y, x; | |
501 | |
502 for (y=0; y<8; y+=2) { | |
503 for (x=0; x<8; x+=2) { | |
504 sum += src[x]; | |
505 square_sum += src[x]*src[x]; | |
506 } | |
507 src += 2*stride; | |
508 } | |
4306 | 509 return (16*square_sum - sum*sum) >> 8; |
3695 | 510 } |
511 | |
512 static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, | |
513 int delta, const int16_t *weights) | |
514 { | |
515 int x, y; | |
516 | |
517 for (y=0; y<8; y++) { | |
518 for (x=0; x<8; x++) { | |
4594 | 519 dst[x] = av_clip_uint8(( src[x-delta ] * weights[0] |
3695 | 520 + src[x ] * weights[1] |
521 + src[x+delta ] * weights[2] | |
522 + src[x+2*delta] * weights[3] + 64) >> 7); | |
523 } | |
524 src += stride; | |
525 dst += stride; | |
526 } | |
527 } | |
528 | |
8299 | 529 static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, |
3695 | 530 int stride, int h_weight, int v_weight) |
531 { | |
532 uint8_t *tmp = s->edge_emu_buffer+16; | |
4921 | 533 s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); |
534 s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); | |
3695 | 535 } |
536 | |
8299 | 537 static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, |
3695 | 538 int offset1, int offset2, int stride, |
8299 | 539 VP56mv mv, int mask, int select, int luma) |
3695 | 540 { |
541 int filter4 = 0; | |
542 int x8 = mv.x & mask; | |
543 int y8 = mv.y & mask; | |
544 | |
545 if (luma) { | |
546 x8 *= 2; | |
547 y8 *= 2; | |
548 filter4 = s->filter_mode; | |
549 if (filter4 == 2) { | |
550 if (s->max_vector_length && | |
4001 | 551 (FFABS(mv.x) > s->max_vector_length || |
552 FFABS(mv.y) > s->max_vector_length)) { | |
3695 | 553 filter4 = 0; |
4308 | 554 } else if (s->sample_variance_threshold |
555 && (vp6_block_variance(src+offset1, stride) | |
3695 | 556 < s->sample_variance_threshold)) { |
557 filter4 = 0; | |
558 } | |
559 } | |
560 } | |
561 | |
562 if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { | |
563 offset1 = offset2; | |
564 } | |
565 | |
566 if (filter4) { | |
567 if (!y8) { /* left or right combine */ | |
568 vp6_filter_hv4(dst, src+offset1, stride, 1, | |
569 vp6_block_copy_filter[select][x8]); | |
570 } else if (!x8) { /* above or below combine */ | |
571 vp6_filter_hv4(dst, src+offset1, stride, stride, | |
572 vp6_block_copy_filter[select][y8]); | |
4922 | 573 } else { |
8785
bee83b3f9a6b
move vp6_filter_diag4() to a new vp6dsp.c file and use it throught dsputil
aurel
parents:
8718
diff
changeset
|
574 s->dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride, |
3695 | 575 vp6_block_copy_filter[select][x8], |
576 vp6_block_copy_filter[select][y8]); | |
577 } | |
578 } else { | |
4921 | 579 if (!x8 || !y8) { |
580 s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); | |
4922 | 581 } else { |
582 vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); | |
3695 | 583 } |
584 } | |
585 } | |
586 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6472
diff
changeset
|
587 static av_cold int vp6_decode_init(AVCodecContext *avctx) |
3695 | 588 { |
8299 | 589 VP56Context *s = avctx->priv_data; |
3695 | 590 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
591 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
|
592 avctx->codec->id == CODEC_ID_VP6A); |
3695 | 593 s->vp56_coord_div = vp6_coord_div; |
594 s->parse_vector_adjustment = vp6_parse_vector_adjustment; | |
595 s->adjust = vp6_adjust; | |
596 s->filter = vp6_filter; | |
597 s->default_models_init = vp6_default_models_init; | |
598 s->parse_vector_models = vp6_parse_vector_models; | |
599 s->parse_coeff_models = vp6_parse_coeff_models; | |
600 s->parse_header = vp6_parse_header; | |
601 | |
602 return 0; | |
603 } | |
604 | |
11350
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
605 static av_cold int vp6_decode_free(AVCodecContext *avctx) |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
606 { |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
607 VP56Context *s = avctx->priv_data; |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
608 int pt, ct, cg; |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
609 |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
610 vp56_free(avctx); |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
611 |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
612 for (pt=0; pt<2; pt++) { |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
613 free_vlc(&s->dccv_vlc[pt]); |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
614 free_vlc(&s->runv_vlc[pt]); |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
615 for (ct=0; ct<3; ct++) |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
616 for (cg=0; cg<6; cg++) |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
617 free_vlc(&s->ract_vlc[pt][ct][cg]); |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
618 } |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
619 return 0; |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
620 } |
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
621 |
3695 | 622 AVCodec vp6_decoder = { |
623 "vp6", | |
624 CODEC_TYPE_VIDEO, | |
625 CODEC_ID_VP6, | |
8299 | 626 sizeof(VP56Context), |
3695 | 627 vp6_decode_init, |
628 NULL, | |
11350
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
629 vp6_decode_free, |
3695 | 630 vp56_decode_frame, |
4910 | 631 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
632 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), |
3695 | 633 }; |
634 | |
635 /* flash version, not flipped upside-down */ | |
636 AVCodec vp6f_decoder = { | |
637 "vp6f", | |
638 CODEC_TYPE_VIDEO, | |
639 CODEC_ID_VP6F, | |
8299 | 640 sizeof(VP56Context), |
3695 | 641 vp6_decode_init, |
642 NULL, | |
11350
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
643 vp6_decode_free, |
3695 | 644 vp56_decode_frame, |
4910 | 645 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
646 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), |
3695 | 647 }; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
648 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
649 /* 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
|
650 AVCodec vp6a_decoder = { |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
651 "vp6a", |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
652 CODEC_TYPE_VIDEO, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
653 CODEC_ID_VP6A, |
8299 | 654 sizeof(VP56Context), |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
655 vp6_decode_init, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
656 NULL, |
11350
7d9a1a807e91
move vp6 huffman table freeing code, out of common vp56 code
aurel
parents:
11342
diff
changeset
|
657 vp6_decode_free, |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
658 vp56_decode_frame, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
659 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
660 .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
|
661 }; |