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