Mercurial > libavcodec.hg
annotate vp6.c @ 6920:d02af7474bff libavcodec
Prevent 128*1<<trellis from becoming 0 and creating 0 sized arrays.
fixes CID84 RUN2
CID85 RUN2
CID86 RUN2
CID87 RUN2
CID88 RUN2
CID89 RUN2
CID90 RUN2
CID91 RUN2
CID92 RUN2
CID93 RUN2
CID94 RUN2
CID95 RUN2
CID96 RUN2
CID97 RUN2
CID98 RUN2
CID99 RUN2
CID100 RUN2
CID101 RUN2
CID102 RUN2
CID103 RUN2
CID104 RUN2
CID105 RUN2
CID106 RUN2
author | michael |
---|---|
date | Wed, 28 May 2008 11:59:41 +0000 |
parents | 5b3acf9fd50a |
children | e943e1409077 |
rev | line source |
---|---|
3695 | 1 /** |
2 * @file vp6.c | |
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 | |
5821 | 40 static void vp6_parse_coeff(vp56_context_t *s); |
41 static void vp6_parse_coeff_huffman(vp56_context_t *s); | |
42 | |
6297 | 43 static int vp6_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size, |
3695 | 44 int *golden_frame) |
45 { | |
46 vp56_range_coder_t *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 | |
78 if (16*cols != s->avctx->coded_width || | |
79 16*rows != s->avctx->coded_height) { | |
80 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
|
81 if (s->avctx->extradata_size == 1) { |
683d458a251f
use the adjustment value present in FLV to crop VP6 video
aurel
parents:
4001
diff
changeset
|
82 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
|
83 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
|
84 } |
3695 | 85 res = 2; |
86 } | |
87 | |
88 vp56_init_range_decoder(c, buf+6, buf_size-6); | |
89 vp56_rac_gets(c, 2); | |
90 | |
4348 | 91 parse_filter_info = s->filter_header; |
4308 | 92 if (sub_version < 8) |
93 vrt_shift = 5; | |
94 s->sub_version = sub_version; | |
3695 | 95 } else { |
4308 | 96 if (!s->sub_version) |
97 return 0; | |
98 | |
4348 | 99 if (separated_coeff || !s->filter_header) { |
4364 | 100 coeff_offset = AV_RB16(buf+1) - 2; |
4348 | 101 buf += 2; |
102 buf_size -= 2; | |
103 } | |
3695 | 104 vp56_init_range_decoder(c, buf+1, buf_size-1); |
105 | |
106 *golden_frame = vp56_rac_get(c); | |
4348 | 107 if (s->filter_header) { |
4349 | 108 s->deblock_filtering = vp56_rac_get(c); |
109 if (s->deblock_filtering) | |
110 vp56_rac_get(c); | |
111 if (s->sub_version > 7) | |
112 parse_filter_info = vp56_rac_get(c); | |
4348 | 113 } |
3695 | 114 } |
115 | |
116 if (parse_filter_info) { | |
117 if (vp56_rac_get(c)) { | |
118 s->filter_mode = 2; | |
4308 | 119 s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift; |
3695 | 120 s->max_vector_length = 2 << vp56_rac_gets(c, 3); |
121 } else if (vp56_rac_get(c)) { | |
122 s->filter_mode = 1; | |
123 } else { | |
124 s->filter_mode = 0; | |
125 } | |
4308 | 126 if (s->sub_version > 7) |
127 s->filter_selection = vp56_rac_gets(c, 4); | |
128 else | |
129 s->filter_selection = 16; | |
3695 | 130 } |
131 | |
5821 | 132 s->use_huffman = vp56_rac_get(c); |
4348 | 133 |
5821 | 134 s->parse_coeff = vp6_parse_coeff; |
4348 | 135 if (coeff_offset) { |
5821 | 136 buf += coeff_offset; |
137 buf_size -= coeff_offset; | |
138 if (s->use_huffman) { | |
139 s->parse_coeff = vp6_parse_coeff_huffman; | |
5945 | 140 init_get_bits(&s->gb, buf, buf_size<<3); |
5821 | 141 } else { |
142 vp56_init_range_decoder(&s->cc, buf, buf_size); | |
143 s->ccp = &s->cc; | |
144 } | |
4348 | 145 } else { |
146 s->ccp = &s->c; | |
147 } | |
148 | |
3695 | 149 return res; |
150 } | |
151 | |
152 static void vp6_coeff_order_table_init(vp56_context_t *s) | |
153 { | |
154 int i, pos, idx = 1; | |
155 | |
5711 | 156 s->modelp->coeff_index_to_pos[0] = 0; |
3695 | 157 for (i=0; i<16; i++) |
158 for (pos=1; pos<64; pos++) | |
5711 | 159 if (s->modelp->coeff_reorder[pos] == i) |
160 s->modelp->coeff_index_to_pos[idx++] = pos; | |
3695 | 161 } |
162 | |
163 static void vp6_default_models_init(vp56_context_t *s) | |
164 { | |
5711 | 165 vp56_model_t *model = s->modelp; |
3695 | 166 |
5711 | 167 model->vector_dct[0] = 0xA2; |
168 model->vector_dct[1] = 0xA4; | |
169 model->vector_sig[0] = 0x80; | |
170 model->vector_sig[1] = 0x80; | |
171 | |
172 memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); | |
173 memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv)); | |
174 memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv)); | |
175 memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv)); | |
176 memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder)); | |
3695 | 177 |
178 vp6_coeff_order_table_init(s); | |
179 } | |
180 | |
181 static void vp6_parse_vector_models(vp56_context_t *s) | |
182 { | |
183 vp56_range_coder_t *c = &s->c; | |
5711 | 184 vp56_model_t *model = s->modelp; |
3695 | 185 int comp, node; |
186 | |
187 for (comp=0; comp<2; comp++) { | |
188 if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) | |
5711 | 189 model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 190 if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) |
5711 | 191 model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 192 } |
193 | |
194 for (comp=0; comp<2; comp++) | |
195 for (node=0; node<7; node++) | |
196 if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) | |
5711 | 197 model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); |
3695 | 198 |
199 for (comp=0; comp<2; comp++) | |
200 for (node=0; node<8; node++) | |
201 if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) | |
5711 | 202 model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7); |
3695 | 203 } |
204 | |
5821 | 205 static int vp6_huff_cmp(const void *va, const void *vb) |
206 { | |
207 const Node *a = va, *b = vb; | |
208 return a->count >= b->count; | |
209 } | |
210 | |
211 static void vp6_build_huff_tree(vp56_context_t *s, uint8_t coeff_model[], | |
212 const uint8_t *map, unsigned size, VLC *vlc) | |
213 { | |
214 Node nodes[2*size], *tmp = &nodes[size]; | |
215 int a, b, i; | |
216 | |
217 /* first compute probabilities from model */ | |
218 tmp[0].count = 256; | |
219 for (i=0; i<size-1; i++) { | |
220 a = tmp[i].count * coeff_model[i] >> 8; | |
221 b = tmp[i].count * (255 - coeff_model[i]) >> 8; | |
222 nodes[map[2*i ]].count = a + !a; | |
223 nodes[map[2*i+1]].count = b + !b; | |
224 } | |
225 | |
226 /* 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
|
227 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
|
228 FF_HUFFMAN_FLAG_HNODE_FIRST); |
5821 | 229 } |
230 | |
3695 | 231 static void vp6_parse_coeff_models(vp56_context_t *s) |
232 { | |
233 vp56_range_coder_t *c = &s->c; | |
5711 | 234 vp56_model_t *model = s->modelp; |
3695 | 235 int def_prob[11]; |
236 int node, cg, ctx, pos; | |
237 int ct; /* code type */ | |
238 int pt; /* plane type (0 for Y, 1 for U or V) */ | |
239 | |
240 memset(def_prob, 0x80, sizeof(def_prob)); | |
241 | |
242 for (pt=0; pt<2; pt++) | |
243 for (node=0; node<11; node++) | |
244 if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { | |
245 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 246 model->coeff_dccv[pt][node] = def_prob[node]; |
4595 | 247 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 248 model->coeff_dccv[pt][node] = def_prob[node]; |
3695 | 249 } |
250 | |
251 if (vp56_rac_get(c)) { | |
252 for (pos=1; pos<64; pos++) | |
253 if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) | |
5711 | 254 model->coeff_reorder[pos] = vp56_rac_gets(c, 4); |
3695 | 255 vp6_coeff_order_table_init(s); |
256 } | |
257 | |
258 for (cg=0; cg<2; cg++) | |
259 for (node=0; node<14; node++) | |
260 if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) | |
5711 | 261 model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7); |
3695 | 262 |
263 for (ct=0; ct<3; ct++) | |
264 for (pt=0; pt<2; pt++) | |
265 for (cg=0; cg<6; cg++) | |
266 for (node=0; node<11; node++) | |
267 if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { | |
268 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 269 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
4595 | 270 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 271 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
3695 | 272 } |
273 | |
5821 | 274 if (s->use_huffman) { |
275 for (pt=0; pt<2; pt++) { | |
276 vp6_build_huff_tree(s, model->coeff_dccv[pt], | |
277 vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]); | |
278 vp6_build_huff_tree(s, model->coeff_runv[pt], | |
279 vp6_huff_run_map, 9, &s->runv_vlc[pt]); | |
280 for (ct=0; ct<3; ct++) | |
281 for (cg = 0; cg < 6; cg++) | |
282 vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], | |
283 vp6_huff_coeff_map, 12, | |
284 &s->ract_vlc[pt][ct][cg]); | |
285 } | |
286 memset(s->nb_null, 0, sizeof(s->nb_null)); | |
287 } else { | |
5711 | 288 /* coeff_dcct is a linear combination of coeff_dccv */ |
3695 | 289 for (pt=0; pt<2; pt++) |
290 for (ctx=0; ctx<3; ctx++) | |
291 for (node=0; node<5; node++) | |
5711 | 292 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 | 293 } |
3695 | 294 } |
295 | |
3697 | 296 static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) |
3695 | 297 { |
298 vp56_range_coder_t *c = &s->c; | |
5711 | 299 vp56_model_t *model = s->modelp; |
3695 | 300 int comp; |
301 | |
3697 | 302 *vect = (vp56_mv_t) {0,0}; |
3695 | 303 if (s->vector_candidate_pos < 2) |
3697 | 304 *vect = s->vector_candidate[0]; |
3695 | 305 |
306 for (comp=0; comp<2; comp++) { | |
307 int i, delta = 0; | |
308 | |
5711 | 309 if (vp56_rac_get_prob(c, model->vector_dct[comp])) { |
3695 | 310 static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; |
311 for (i=0; i<sizeof(prob_order); i++) { | |
312 int j = prob_order[i]; | |
5711 | 313 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j; |
3695 | 314 } |
315 if (delta & 0xF0) | |
5711 | 316 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3; |
3695 | 317 else |
318 delta |= 8; | |
319 } else { | |
320 delta = vp56_rac_get_tree(c, vp56_pva_tree, | |
5711 | 321 model->vector_pdv[comp]); |
3695 | 322 } |
323 | |
5711 | 324 if (delta && vp56_rac_get_prob(c, model->vector_sig[comp])) |
3695 | 325 delta = -delta; |
326 | |
327 if (!comp) | |
3697 | 328 vect->x += delta; |
3695 | 329 else |
3697 | 330 vect->y += delta; |
3695 | 331 } |
332 } | |
333 | |
5821 | 334 /** |
335 * Read number of consecutive blocks with null DC or AC. | |
336 * This value is < 74. | |
337 */ | |
338 static unsigned vp6_get_nb_null(vp56_context_t *s) | |
339 { | |
340 unsigned val = get_bits(&s->gb, 2); | |
341 if (val == 2) | |
342 val += get_bits(&s->gb, 2); | |
343 else if (val == 3) { | |
344 val = get_bits1(&s->gb) << 2; | |
345 val = 6+val + get_bits(&s->gb, 2+val); | |
346 } | |
347 return val; | |
348 } | |
349 | |
350 static void vp6_parse_coeff_huffman(vp56_context_t *s) | |
351 { | |
352 vp56_model_t *model = s->modelp; | |
353 uint8_t *permute = s->scantable.permutated; | |
354 VLC *vlc_coeff; | |
355 int coeff, sign, coeff_idx; | |
356 int b, cg, idx; | |
357 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
358 | |
359 for (b=0; b<6; b++) { | |
360 int ct = 0; /* code type */ | |
361 if (b > 3) pt = 1; | |
362 vlc_coeff = &s->dccv_vlc[pt]; | |
363 | |
364 for (coeff_idx=0; coeff_idx<64; ) { | |
365 int run = 1; | |
366 if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { | |
367 s->nb_null[coeff_idx][pt]--; | |
368 if (coeff_idx) | |
369 break; | |
370 } else { | |
371 coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); | |
372 if (coeff == 0) { | |
373 if (coeff_idx) { | |
374 int pt = (coeff_idx >= 6); | |
375 run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); | |
376 if (run >= 9) | |
377 run += get_bits(&s->gb, 6); | |
378 } else | |
379 s->nb_null[0][pt] = vp6_get_nb_null(s); | |
380 ct = 0; | |
381 } else if (coeff == 11) { /* end of block */ | |
382 if (coeff_idx == 1) /* first AC coeff ? */ | |
383 s->nb_null[1][pt] = vp6_get_nb_null(s); | |
384 break; | |
385 } else { | |
386 int coeff2 = vp56_coeff_bias[coeff]; | |
387 if (coeff > 4) | |
388 coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); | |
389 ct = 1 + (coeff2 > 1); | |
390 sign = get_bits1(&s->gb); | |
391 coeff2 = (coeff2 ^ -sign) + sign; | |
392 if (coeff_idx) | |
393 coeff2 *= s->dequant_ac; | |
394 idx = model->coeff_index_to_pos[coeff_idx]; | |
395 s->block_coeff[b][permute[idx]] = coeff2; | |
396 } | |
397 } | |
398 coeff_idx+=run; | |
399 cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); | |
400 vlc_coeff = &s->ract_vlc[pt][ct][cg]; | |
401 } | |
402 } | |
403 } | |
404 | |
3695 | 405 static void vp6_parse_coeff(vp56_context_t *s) |
406 { | |
4348 | 407 vp56_range_coder_t *c = s->ccp; |
5711 | 408 vp56_model_t *model = s->modelp; |
3695 | 409 uint8_t *permute = s->scantable.permutated; |
5711 | 410 uint8_t *model1, *model2, *model3; |
3695 | 411 int coeff, sign, coeff_idx; |
412 int b, i, cg, idx, ctx; | |
413 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
414 | |
415 for (b=0; b<6; b++) { | |
416 int ct = 1; /* code type */ | |
417 int run = 1; | |
418 | |
419 if (b > 3) pt = 1; | |
420 | |
421 ctx = s->left_block[vp56_b6to4[b]].not_null_dc | |
422 + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |
5711 | 423 model1 = model->coeff_dccv[pt]; |
424 model2 = model->coeff_dcct[pt][ctx]; | |
3695 | 425 |
426 for (coeff_idx=0; coeff_idx<64; ) { | |
427 if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { | |
428 /* parse a coeff */ | |
429 if (vp56_rac_get_prob(c, model2[2])) { | |
430 if (vp56_rac_get_prob(c, model2[3])) { | |
5711 | 431 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); |
5821 | 432 coeff = vp56_coeff_bias[idx+5]; |
3695 | 433 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
434 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |
435 } else { | |
436 if (vp56_rac_get_prob(c, model2[4])) | |
5711 | 437 coeff = 3 + vp56_rac_get_prob(c, model1[5]); |
3695 | 438 else |
439 coeff = 2; | |
440 } | |
441 ct = 2; | |
442 } else { | |
443 ct = 1; | |
444 coeff = 1; | |
445 } | |
446 sign = vp56_rac_get(c); | |
447 coeff = (coeff ^ -sign) + sign; | |
448 if (coeff_idx) | |
449 coeff *= s->dequant_ac; | |
5711 | 450 idx = model->coeff_index_to_pos[coeff_idx]; |
3695 | 451 s->block_coeff[b][permute[idx]] = coeff; |
452 run = 1; | |
453 } else { | |
454 /* parse a run */ | |
455 ct = 0; | |
4925 | 456 if (coeff_idx > 0) { |
3695 | 457 if (!vp56_rac_get_prob(c, model2[1])) |
458 break; | |
459 | |
5711 | 460 model3 = model->coeff_runv[coeff_idx >= 6]; |
3695 | 461 run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); |
462 if (!run) | |
463 for (run=9, i=0; i<6; i++) | |
464 run += vp56_rac_get_prob(c, model3[i+8]) << i; | |
465 } | |
466 } | |
467 | |
468 cg = vp6_coeff_groups[coeff_idx+=run]; | |
5711 | 469 model1 = model2 = model->coeff_ract[pt][ct][cg]; |
3695 | 470 } |
4925 | 471 |
472 s->left_block[vp56_b6to4[b]].not_null_dc = | |
473 s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; | |
3695 | 474 } |
475 } | |
476 | |
477 static int vp6_adjust(int v, int t) | |
478 { | |
479 int V = v, s = v >> 31; | |
480 V ^= s; | |
481 V -= s; | |
482 if (V-t-1 >= (unsigned)(t-1)) | |
483 return v; | |
484 V = 2*t - V; | |
485 V += s; | |
486 V ^= s; | |
487 return V; | |
488 } | |
489 | |
490 static int vp6_block_variance(uint8_t *src, int stride) | |
491 { | |
492 int sum = 0, square_sum = 0; | |
493 int y, x; | |
494 | |
495 for (y=0; y<8; y+=2) { | |
496 for (x=0; x<8; x+=2) { | |
497 sum += src[x]; | |
498 square_sum += src[x]*src[x]; | |
499 } | |
500 src += 2*stride; | |
501 } | |
4306 | 502 return (16*square_sum - sum*sum) >> 8; |
3695 | 503 } |
504 | |
505 static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, | |
506 int delta, const int16_t *weights) | |
507 { | |
508 int x, y; | |
509 | |
510 for (y=0; y<8; y++) { | |
511 for (x=0; x<8; x++) { | |
4594 | 512 dst[x] = av_clip_uint8(( src[x-delta ] * weights[0] |
3695 | 513 + src[x ] * weights[1] |
514 + src[x+delta ] * weights[2] | |
515 + src[x+2*delta] * weights[3] + 64) >> 7); | |
516 } | |
517 src += stride; | |
518 dst += stride; | |
519 } | |
520 } | |
521 | |
522 static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src, | |
523 int stride, int h_weight, int v_weight) | |
524 { | |
525 uint8_t *tmp = s->edge_emu_buffer+16; | |
4921 | 526 s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); |
527 s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); | |
3695 | 528 } |
529 | |
530 static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride, | |
531 const int16_t *h_weights,const int16_t *v_weights) | |
532 { | |
533 int x, y; | |
534 int tmp[8*11]; | |
535 int *t = tmp; | |
536 | |
537 src -= stride; | |
538 | |
539 for (y=0; y<11; y++) { | |
540 for (x=0; x<8; x++) { | |
4594 | 541 t[x] = av_clip_uint8(( src[x-1] * h_weights[0] |
3695 | 542 + src[x ] * h_weights[1] |
543 + src[x+1] * h_weights[2] | |
544 + src[x+2] * h_weights[3] + 64) >> 7); | |
545 } | |
546 src += stride; | |
547 t += 8; | |
548 } | |
549 | |
550 t = tmp + 8; | |
551 for (y=0; y<8; y++) { | |
552 for (x=0; x<8; x++) { | |
4594 | 553 dst[x] = av_clip_uint8(( t[x-8 ] * v_weights[0] |
3695 | 554 + t[x ] * v_weights[1] |
555 + t[x+8 ] * v_weights[2] | |
556 + t[x+16] * v_weights[3] + 64) >> 7); | |
557 } | |
558 dst += stride; | |
559 t += 8; | |
560 } | |
561 } | |
562 | |
563 static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src, | |
564 int offset1, int offset2, int stride, | |
565 vp56_mv_t mv, int mask, int select, int luma) | |
566 { | |
567 int filter4 = 0; | |
568 int x8 = mv.x & mask; | |
569 int y8 = mv.y & mask; | |
570 | |
571 if (luma) { | |
572 x8 *= 2; | |
573 y8 *= 2; | |
574 filter4 = s->filter_mode; | |
575 if (filter4 == 2) { | |
576 if (s->max_vector_length && | |
4001 | 577 (FFABS(mv.x) > s->max_vector_length || |
578 FFABS(mv.y) > s->max_vector_length)) { | |
3695 | 579 filter4 = 0; |
4308 | 580 } else if (s->sample_variance_threshold |
581 && (vp6_block_variance(src+offset1, stride) | |
3695 | 582 < s->sample_variance_threshold)) { |
583 filter4 = 0; | |
584 } | |
585 } | |
586 } | |
587 | |
588 if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { | |
589 offset1 = offset2; | |
590 } | |
591 | |
592 if (filter4) { | |
593 if (!y8) { /* left or right combine */ | |
594 vp6_filter_hv4(dst, src+offset1, stride, 1, | |
595 vp6_block_copy_filter[select][x8]); | |
596 } else if (!x8) { /* above or below combine */ | |
597 vp6_filter_hv4(dst, src+offset1, stride, stride, | |
598 vp6_block_copy_filter[select][y8]); | |
4922 | 599 } else { |
600 vp6_filter_diag4(dst, src+offset1 + ((mv.x^mv.y)>>31), stride, | |
3695 | 601 vp6_block_copy_filter[select][x8], |
602 vp6_block_copy_filter[select][y8]); | |
603 } | |
604 } else { | |
4921 | 605 if (!x8 || !y8) { |
606 s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); | |
4922 | 607 } else { |
608 vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); | |
3695 | 609 } |
610 } | |
611 } | |
612 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6472
diff
changeset
|
613 static av_cold int vp6_decode_init(AVCodecContext *avctx) |
3695 | 614 { |
615 vp56_context_t *s = avctx->priv_data; | |
616 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
617 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
|
618 avctx->codec->id == CODEC_ID_VP6A); |
3695 | 619 s->vp56_coord_div = vp6_coord_div; |
620 s->parse_vector_adjustment = vp6_parse_vector_adjustment; | |
621 s->adjust = vp6_adjust; | |
622 s->filter = vp6_filter; | |
623 s->default_models_init = vp6_default_models_init; | |
624 s->parse_vector_models = vp6_parse_vector_models; | |
625 s->parse_coeff_models = vp6_parse_coeff_models; | |
626 s->parse_header = vp6_parse_header; | |
627 | |
628 return 0; | |
629 } | |
630 | |
631 AVCodec vp6_decoder = { | |
632 "vp6", | |
633 CODEC_TYPE_VIDEO, | |
634 CODEC_ID_VP6, | |
635 sizeof(vp56_context_t), | |
636 vp6_decode_init, | |
637 NULL, | |
638 vp56_free, | |
639 vp56_decode_frame, | |
4910 | 640 CODEC_CAP_DR1, |
6712 | 641 .long_name = "On2 VP6", |
3695 | 642 }; |
643 | |
644 /* flash version, not flipped upside-down */ | |
645 AVCodec vp6f_decoder = { | |
646 "vp6f", | |
647 CODEC_TYPE_VIDEO, | |
648 CODEC_ID_VP6F, | |
649 sizeof(vp56_context_t), | |
650 vp6_decode_init, | |
651 NULL, | |
652 vp56_free, | |
653 vp56_decode_frame, | |
4910 | 654 CODEC_CAP_DR1, |
6712 | 655 .long_name = "On2 VP6 (Flash version)" |
3695 | 656 }; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
657 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
658 /* 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
|
659 AVCodec vp6a_decoder = { |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
660 "vp6a", |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
661 CODEC_TYPE_VIDEO, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
662 CODEC_ID_VP6A, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
663 sizeof(vp56_context_t), |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
664 vp6_decode_init, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
665 NULL, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
666 vp56_free, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
667 vp56_decode_frame, |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
668 CODEC_CAP_DR1, |
6712 | 669 .long_name = "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
|
670 }; |