ffmpeg / libavcodec / vp6.c @ f66e4f5f
History | View | Annotate | Download (18.3 KB)
1 |
/**
|
---|---|
2 |
* @file vp6.c
|
3 |
* VP6 compatible video decoder
|
4 |
*
|
5 |
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
|
6 |
*
|
7 |
* This file is part of FFmpeg.
|
8 |
*
|
9 |
* FFmpeg is free software; you can redistribute it and/or
|
10 |
* modify it under the terms of the GNU Lesser General Public
|
11 |
* License as published by the Free Software Foundation; either
|
12 |
* version 2.1 of the License, or (at your option) any later version.
|
13 |
*
|
14 |
* FFmpeg is distributed in the hope that it will be useful,
|
15 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
17 |
* Lesser General Public License for more details.
|
18 |
*
|
19 |
* You should have received a copy of the GNU Lesser General Public
|
20 |
* License along with FFmpeg; if not, write to the Free Software
|
21 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
22 |
*
|
23 |
*
|
24 |
* The VP6F decoder accept an optional 1 byte extradata. It is composed of:
|
25 |
* - upper 4bits: difference between encoded width and visible width
|
26 |
* - lower 4bits: difference between encoded height and visible height
|
27 |
*/
|
28 |
|
29 |
#include <stdlib.h> |
30 |
|
31 |
#include "avcodec.h" |
32 |
#include "dsputil.h" |
33 |
#include "bitstream.h" |
34 |
#include "mpegvideo.h" |
35 |
|
36 |
#include "vp56.h" |
37 |
#include "vp56data.h" |
38 |
#include "vp6data.h" |
39 |
|
40 |
|
41 |
static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, |
42 |
int *golden_frame)
|
43 |
{ |
44 |
vp56_range_coder_t *c = &s->c; |
45 |
int parse_filter_info = 0; |
46 |
int coeff_offset = 0; |
47 |
int vrt_shift = 0; |
48 |
int sub_version;
|
49 |
int rows, cols;
|
50 |
int res = 1; |
51 |
int separated_coeff = buf[0] & 1; |
52 |
|
53 |
s->frames[VP56_FRAME_CURRENT].key_frame = !(buf[0] & 0x80); |
54 |
vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); |
55 |
|
56 |
if (s->frames[VP56_FRAME_CURRENT].key_frame) {
|
57 |
sub_version = buf[1] >> 3; |
58 |
if (sub_version > 8) |
59 |
return 0; |
60 |
s->filter_header = buf[1] & 0x06; |
61 |
if (buf[1] & 1) { |
62 |
av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
|
63 |
return 0; |
64 |
} |
65 |
if (separated_coeff || !s->filter_header) {
|
66 |
coeff_offset = AV_RB16(buf+2) - 2; |
67 |
buf += 2;
|
68 |
buf_size -= 2;
|
69 |
} |
70 |
|
71 |
rows = buf[2]; /* number of stored macroblock rows */ |
72 |
cols = buf[3]; /* number of stored macroblock cols */ |
73 |
/* buf[4] is number of displayed macroblock rows */
|
74 |
/* buf[5] is number of displayed macroblock cols */
|
75 |
|
76 |
if (16*cols != s->avctx->coded_width || |
77 |
16*rows != s->avctx->coded_height) {
|
78 |
avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); |
79 |
if (s->avctx->extradata_size == 1) { |
80 |
s->avctx->width -= s->avctx->extradata[0] >> 4; |
81 |
s->avctx->height -= s->avctx->extradata[0] & 0x0F; |
82 |
} |
83 |
res = 2;
|
84 |
} |
85 |
|
86 |
vp56_init_range_decoder(c, buf+6, buf_size-6); |
87 |
vp56_rac_gets(c, 2);
|
88 |
|
89 |
parse_filter_info = s->filter_header; |
90 |
if (sub_version < 8) |
91 |
vrt_shift = 5;
|
92 |
s->sub_version = sub_version; |
93 |
} else {
|
94 |
if (!s->sub_version)
|
95 |
return 0; |
96 |
|
97 |
if (separated_coeff || !s->filter_header) {
|
98 |
coeff_offset = AV_RB16(buf+1) - 2; |
99 |
buf += 2;
|
100 |
buf_size -= 2;
|
101 |
} |
102 |
vp56_init_range_decoder(c, buf+1, buf_size-1); |
103 |
|
104 |
*golden_frame = vp56_rac_get(c); |
105 |
if (s->filter_header) {
|
106 |
s->deblock_filtering = vp56_rac_get(c); |
107 |
if (s->deblock_filtering)
|
108 |
vp56_rac_get(c); |
109 |
if (s->sub_version > 7) |
110 |
parse_filter_info = vp56_rac_get(c); |
111 |
} |
112 |
} |
113 |
|
114 |
if (parse_filter_info) {
|
115 |
if (vp56_rac_get(c)) {
|
116 |
s->filter_mode = 2;
|
117 |
s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift;
|
118 |
s->max_vector_length = 2 << vp56_rac_gets(c, 3); |
119 |
} else if (vp56_rac_get(c)) { |
120 |
s->filter_mode = 1;
|
121 |
} else {
|
122 |
s->filter_mode = 0;
|
123 |
} |
124 |
if (s->sub_version > 7) |
125 |
s->filter_selection = vp56_rac_gets(c, 4);
|
126 |
else
|
127 |
s->filter_selection = 16;
|
128 |
} |
129 |
|
130 |
vp56_rac_get(c); |
131 |
|
132 |
if (coeff_offset) {
|
133 |
vp56_init_range_decoder(&s->cc, buf+coeff_offset, |
134 |
buf_size-coeff_offset); |
135 |
s->ccp = &s->cc; |
136 |
} else {
|
137 |
s->ccp = &s->c; |
138 |
} |
139 |
|
140 |
return res;
|
141 |
} |
142 |
|
143 |
static void vp6_coeff_order_table_init(vp56_context_t *s) |
144 |
{ |
145 |
int i, pos, idx = 1; |
146 |
|
147 |
s->coeff_index_to_pos[0] = 0; |
148 |
for (i=0; i<16; i++) |
149 |
for (pos=1; pos<64; pos++) |
150 |
if (s->coeff_reorder[pos] == i)
|
151 |
s->coeff_index_to_pos[idx++] = pos; |
152 |
} |
153 |
|
154 |
static void vp6_default_models_init(vp56_context_t *s) |
155 |
{ |
156 |
s->vector_model_dct[0] = 0xA2; |
157 |
s->vector_model_dct[1] = 0xA4; |
158 |
s->vector_model_sig[0] = 0x80; |
159 |
s->vector_model_sig[1] = 0x80; |
160 |
|
161 |
memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats));
|
162 |
memcpy(s->vector_model_fdv, vp6_def_fdv_vector_model, sizeof(s->vector_model_fdv));
|
163 |
memcpy(s->vector_model_pdv, vp6_def_pdv_vector_model, sizeof(s->vector_model_pdv));
|
164 |
memcpy(s->coeff_model_runv, vp6_def_runv_coeff_model, sizeof(s->coeff_model_runv));
|
165 |
memcpy(s->coeff_reorder, vp6_def_coeff_reorder, sizeof(s->coeff_reorder));
|
166 |
|
167 |
vp6_coeff_order_table_init(s); |
168 |
} |
169 |
|
170 |
static void vp6_parse_vector_models(vp56_context_t *s) |
171 |
{ |
172 |
vp56_range_coder_t *c = &s->c; |
173 |
int comp, node;
|
174 |
|
175 |
for (comp=0; comp<2; comp++) { |
176 |
if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) |
177 |
s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7);
|
178 |
if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) |
179 |
s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7);
|
180 |
} |
181 |
|
182 |
for (comp=0; comp<2; comp++) |
183 |
for (node=0; node<7; node++) |
184 |
if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node]))
|
185 |
s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
|
186 |
|
187 |
for (comp=0; comp<2; comp++) |
188 |
for (node=0; node<8; node++) |
189 |
if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node]))
|
190 |
s->vector_model_fdv[comp][node] = vp56_rac_gets_nn(c, 7);
|
191 |
} |
192 |
|
193 |
static void vp6_parse_coeff_models(vp56_context_t *s) |
194 |
{ |
195 |
vp56_range_coder_t *c = &s->c; |
196 |
int def_prob[11]; |
197 |
int node, cg, ctx, pos;
|
198 |
int ct; /* code type */ |
199 |
int pt; /* plane type (0 for Y, 1 for U or V) */ |
200 |
|
201 |
memset(def_prob, 0x80, sizeof(def_prob)); |
202 |
|
203 |
for (pt=0; pt<2; pt++) |
204 |
for (node=0; node<11; node++) |
205 |
if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) {
|
206 |
def_prob[node] = vp56_rac_gets_nn(c, 7);
|
207 |
s->coeff_model_dccv[pt][node] = def_prob[node]; |
208 |
} else if (s->frames[VP56_FRAME_CURRENT].key_frame) { |
209 |
s->coeff_model_dccv[pt][node] = def_prob[node]; |
210 |
} |
211 |
|
212 |
if (vp56_rac_get(c)) {
|
213 |
for (pos=1; pos<64; pos++) |
214 |
if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos]))
|
215 |
s->coeff_reorder[pos] = vp56_rac_gets(c, 4);
|
216 |
vp6_coeff_order_table_init(s); |
217 |
} |
218 |
|
219 |
for (cg=0; cg<2; cg++) |
220 |
for (node=0; node<14; node++) |
221 |
if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node]))
|
222 |
s->coeff_model_runv[cg][node] = vp56_rac_gets_nn(c, 7);
|
223 |
|
224 |
for (ct=0; ct<3; ct++) |
225 |
for (pt=0; pt<2; pt++) |
226 |
for (cg=0; cg<6; cg++) |
227 |
for (node=0; node<11; node++) |
228 |
if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) {
|
229 |
def_prob[node] = vp56_rac_gets_nn(c, 7);
|
230 |
s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; |
231 |
} else if (s->frames[VP56_FRAME_CURRENT].key_frame) { |
232 |
s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; |
233 |
} |
234 |
|
235 |
/* coeff_model_dcct is a linear combination of coeff_model_dccv */
|
236 |
for (pt=0; pt<2; pt++) |
237 |
for (ctx=0; ctx<3; ctx++) |
238 |
for (node=0; node<5; node++) |
239 |
s->coeff_model_dcct[pt][ctx][node] = av_clip(((s->coeff_model_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); |
240 |
} |
241 |
|
242 |
static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) |
243 |
{ |
244 |
vp56_range_coder_t *c = &s->c; |
245 |
int comp;
|
246 |
|
247 |
*vect = (vp56_mv_t) {0,0}; |
248 |
if (s->vector_candidate_pos < 2) |
249 |
*vect = s->vector_candidate[0];
|
250 |
|
251 |
for (comp=0; comp<2; comp++) { |
252 |
int i, delta = 0; |
253 |
|
254 |
if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) {
|
255 |
static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; |
256 |
for (i=0; i<sizeof(prob_order); i++) { |
257 |
int j = prob_order[i];
|
258 |
delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][j])<<j; |
259 |
} |
260 |
if (delta & 0xF0) |
261 |
delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][3])<<3; |
262 |
else
|
263 |
delta |= 8;
|
264 |
} else {
|
265 |
delta = vp56_rac_get_tree(c, vp56_pva_tree, |
266 |
s->vector_model_pdv[comp]); |
267 |
} |
268 |
|
269 |
if (delta && vp56_rac_get_prob(c, s->vector_model_sig[comp]))
|
270 |
delta = -delta; |
271 |
|
272 |
if (!comp)
|
273 |
vect->x += delta; |
274 |
else
|
275 |
vect->y += delta; |
276 |
} |
277 |
} |
278 |
|
279 |
static void vp6_parse_coeff(vp56_context_t *s) |
280 |
{ |
281 |
vp56_range_coder_t *c = s->ccp; |
282 |
uint8_t *permute = s->scantable.permutated; |
283 |
uint8_t *model, *model2, *model3; |
284 |
int coeff, sign, coeff_idx;
|
285 |
int b, i, cg, idx, ctx;
|
286 |
int pt = 0; /* plane type (0 for Y, 1 for U or V) */ |
287 |
|
288 |
for (b=0; b<6; b++) { |
289 |
int ct = 1; /* code type */ |
290 |
int run = 1; |
291 |
|
292 |
if (b > 3) pt = 1; |
293 |
|
294 |
ctx = s->left_block[vp56_b6to4[b]].not_null_dc |
295 |
+ s->above_blocks[s->above_block_idx[b]].not_null_dc; |
296 |
model = s->coeff_model_dccv[pt]; |
297 |
model2 = s->coeff_model_dcct[pt][ctx]; |
298 |
|
299 |
for (coeff_idx=0; coeff_idx<64; ) { |
300 |
if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { |
301 |
/* parse a coeff */
|
302 |
if (coeff_idx == 0) { |
303 |
s->left_block[vp56_b6to4[b]].not_null_dc = 1;
|
304 |
s->above_blocks[s->above_block_idx[b]].not_null_dc = 1;
|
305 |
} |
306 |
|
307 |
if (vp56_rac_get_prob(c, model2[2])) { |
308 |
if (vp56_rac_get_prob(c, model2[3])) { |
309 |
idx = vp56_rac_get_tree(c, vp56_pc_tree, model); |
310 |
coeff = vp56_coeff_bias[idx]; |
311 |
for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
312 |
coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; |
313 |
} else {
|
314 |
if (vp56_rac_get_prob(c, model2[4])) |
315 |
coeff = 3 + vp56_rac_get_prob(c, model[5]); |
316 |
else
|
317 |
coeff = 2;
|
318 |
} |
319 |
ct = 2;
|
320 |
} else {
|
321 |
ct = 1;
|
322 |
coeff = 1;
|
323 |
} |
324 |
sign = vp56_rac_get(c); |
325 |
coeff = (coeff ^ -sign) + sign; |
326 |
if (coeff_idx)
|
327 |
coeff *= s->dequant_ac; |
328 |
idx = s->coeff_index_to_pos[coeff_idx]; |
329 |
s->block_coeff[b][permute[idx]] = coeff; |
330 |
run = 1;
|
331 |
} else {
|
332 |
/* parse a run */
|
333 |
ct = 0;
|
334 |
if (coeff_idx == 0) { |
335 |
s->left_block[vp56_b6to4[b]].not_null_dc = 0;
|
336 |
s->above_blocks[s->above_block_idx[b]].not_null_dc = 0;
|
337 |
} else {
|
338 |
if (!vp56_rac_get_prob(c, model2[1])) |
339 |
break;
|
340 |
|
341 |
model3 = s->coeff_model_runv[coeff_idx >= 6];
|
342 |
run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); |
343 |
if (!run)
|
344 |
for (run=9, i=0; i<6; i++) |
345 |
run += vp56_rac_get_prob(c, model3[i+8]) << i;
|
346 |
} |
347 |
} |
348 |
|
349 |
cg = vp6_coeff_groups[coeff_idx+=run]; |
350 |
model = model2 = s->coeff_model_ract[pt][ct][cg]; |
351 |
} |
352 |
} |
353 |
} |
354 |
|
355 |
static int vp6_adjust(int v, int t) |
356 |
{ |
357 |
int V = v, s = v >> 31; |
358 |
V ^= s; |
359 |
V -= s; |
360 |
if (V-t-1 >= (unsigned)(t-1)) |
361 |
return v;
|
362 |
V = 2*t - V;
|
363 |
V += s; |
364 |
V ^= s; |
365 |
return V;
|
366 |
} |
367 |
|
368 |
static int vp6_block_variance(uint8_t *src, int stride) |
369 |
{ |
370 |
int sum = 0, square_sum = 0; |
371 |
int y, x;
|
372 |
|
373 |
for (y=0; y<8; y+=2) { |
374 |
for (x=0; x<8; x+=2) { |
375 |
sum += src[x]; |
376 |
square_sum += src[x]*src[x]; |
377 |
} |
378 |
src += 2*stride;
|
379 |
} |
380 |
return (16*square_sum - sum*sum) >> 8; |
381 |
} |
382 |
|
383 |
static void vp6_filter_hv2(vp56_context_t *s, uint8_t *dst, uint8_t *src, |
384 |
int stride, int delta, int16_t weight) |
385 |
{ |
386 |
s->dsp.put_pixels_tab[1][0](dst, src, stride, 8); |
387 |
s->dsp.biweight_h264_pixels_tab[3](dst, src+delta, stride, 2, |
388 |
8-weight, weight, 0); |
389 |
} |
390 |
|
391 |
static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, |
392 |
int delta, const int16_t *weights) |
393 |
{ |
394 |
int x, y;
|
395 |
|
396 |
for (y=0; y<8; y++) { |
397 |
for (x=0; x<8; x++) { |
398 |
dst[x] = av_clip_uint8(( src[x-delta ] * weights[0]
|
399 |
+ src[x ] * weights[1]
|
400 |
+ src[x+delta ] * weights[2]
|
401 |
+ src[x+2*delta] * weights[3] + 64) >> 7); |
402 |
} |
403 |
src += stride; |
404 |
dst += stride; |
405 |
} |
406 |
} |
407 |
|
408 |
static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src, |
409 |
int stride, int h_weight, int v_weight) |
410 |
{ |
411 |
uint8_t *tmp = s->edge_emu_buffer+16;
|
412 |
int x, xmax;
|
413 |
|
414 |
s->dsp.put_pixels_tab[1][0](tmp, src, stride, 8); |
415 |
s->dsp.biweight_h264_pixels_tab[3](tmp, src+1, stride, 2, |
416 |
8-h_weight, h_weight, 0); |
417 |
/* we need a 8x9 block to do vertical filter, so compute one more line */
|
418 |
for (x=8*stride, xmax=x+8; x<xmax; x++) |
419 |
tmp[x] = (src[x]*(8-h_weight) + src[x+1]*h_weight + 4) >> 3; |
420 |
|
421 |
s->dsp.put_pixels_tab[1][0](dst, tmp, stride, 8); |
422 |
s->dsp.biweight_h264_pixels_tab[3](dst, tmp+stride, stride, 2, |
423 |
8-v_weight, v_weight, 0); |
424 |
} |
425 |
|
426 |
static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride, |
427 |
const int16_t *h_weights,const int16_t *v_weights) |
428 |
{ |
429 |
int x, y;
|
430 |
int tmp[8*11]; |
431 |
int *t = tmp;
|
432 |
|
433 |
src -= stride; |
434 |
|
435 |
for (y=0; y<11; y++) { |
436 |
for (x=0; x<8; x++) { |
437 |
t[x] = av_clip_uint8(( src[x-1] * h_weights[0] |
438 |
+ src[x ] * h_weights[1]
|
439 |
+ src[x+1] * h_weights[2] |
440 |
+ src[x+2] * h_weights[3] + 64) >> 7); |
441 |
} |
442 |
src += stride; |
443 |
t += 8;
|
444 |
} |
445 |
|
446 |
t = tmp + 8;
|
447 |
for (y=0; y<8; y++) { |
448 |
for (x=0; x<8; x++) { |
449 |
dst[x] = av_clip_uint8(( t[x-8 ] * v_weights[0] |
450 |
+ t[x ] * v_weights[1]
|
451 |
+ t[x+8 ] * v_weights[2] |
452 |
+ t[x+16] * v_weights[3] + 64) >> 7); |
453 |
} |
454 |
dst += stride; |
455 |
t += 8;
|
456 |
} |
457 |
} |
458 |
|
459 |
static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src, |
460 |
int offset1, int offset2, int stride, |
461 |
vp56_mv_t mv, int mask, int select, int luma) |
462 |
{ |
463 |
int filter4 = 0; |
464 |
int x8 = mv.x & mask;
|
465 |
int y8 = mv.y & mask;
|
466 |
|
467 |
if (luma) {
|
468 |
x8 *= 2;
|
469 |
y8 *= 2;
|
470 |
filter4 = s->filter_mode; |
471 |
if (filter4 == 2) { |
472 |
if (s->max_vector_length &&
|
473 |
(FFABS(mv.x) > s->max_vector_length || |
474 |
FFABS(mv.y) > s->max_vector_length)) { |
475 |
filter4 = 0;
|
476 |
} else if (s->sample_variance_threshold |
477 |
&& (vp6_block_variance(src+offset1, stride) |
478 |
< s->sample_variance_threshold)) { |
479 |
filter4 = 0;
|
480 |
} |
481 |
} |
482 |
} |
483 |
|
484 |
if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { |
485 |
offset1 = offset2; |
486 |
} |
487 |
|
488 |
if (filter4) {
|
489 |
if (!y8) { /* left or right combine */ |
490 |
vp6_filter_hv4(dst, src+offset1, stride, 1,
|
491 |
vp6_block_copy_filter[select][x8]); |
492 |
} else if (!x8) { /* above or below combine */ |
493 |
vp6_filter_hv4(dst, src+offset1, stride, stride, |
494 |
vp6_block_copy_filter[select][y8]); |
495 |
} else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ |
496 |
vp6_filter_diag4(dst, src+offset1-1, stride,
|
497 |
vp6_block_copy_filter[select][x8], |
498 |
vp6_block_copy_filter[select][y8]); |
499 |
} else { /* lower-right or upper-left combine */ |
500 |
vp6_filter_diag4(dst, src+offset1, stride, |
501 |
vp6_block_copy_filter[select][x8], |
502 |
vp6_block_copy_filter[select][y8]); |
503 |
} |
504 |
} else {
|
505 |
if (!y8) { /* left or right combine */ |
506 |
vp6_filter_hv2(s, dst, src+offset1, stride, 1, x8);
|
507 |
} else if (!x8) { /* above or below combine */ |
508 |
vp6_filter_hv2(s, dst, src+offset1, stride, stride, y8); |
509 |
} else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ |
510 |
vp6_filter_diag2(s, dst, src+offset1-1, stride, x8, y8);
|
511 |
} else { /* lower-right or upper-left combine */ |
512 |
vp6_filter_diag2(s, dst, src+offset1, stride, x8, y8); |
513 |
} |
514 |
} |
515 |
} |
516 |
|
517 |
static int vp6_decode_init(AVCodecContext *avctx) |
518 |
{ |
519 |
vp56_context_t *s = avctx->priv_data; |
520 |
|
521 |
vp56_init(s, avctx, avctx->codec->id == CODEC_ID_VP6); |
522 |
s->vp56_coord_div = vp6_coord_div; |
523 |
s->parse_vector_adjustment = vp6_parse_vector_adjustment; |
524 |
s->adjust = vp6_adjust; |
525 |
s->filter = vp6_filter; |
526 |
s->parse_coeff = vp6_parse_coeff; |
527 |
s->default_models_init = vp6_default_models_init; |
528 |
s->parse_vector_models = vp6_parse_vector_models; |
529 |
s->parse_coeff_models = vp6_parse_coeff_models; |
530 |
s->parse_header = vp6_parse_header; |
531 |
|
532 |
return 0; |
533 |
} |
534 |
|
535 |
AVCodec vp6_decoder = { |
536 |
"vp6",
|
537 |
CODEC_TYPE_VIDEO, |
538 |
CODEC_ID_VP6, |
539 |
sizeof(vp56_context_t),
|
540 |
vp6_decode_init, |
541 |
NULL,
|
542 |
vp56_free, |
543 |
vp56_decode_frame, |
544 |
}; |
545 |
|
546 |
/* flash version, not flipped upside-down */
|
547 |
AVCodec vp6f_decoder = { |
548 |
"vp6f",
|
549 |
CODEC_TYPE_VIDEO, |
550 |
CODEC_ID_VP6F, |
551 |
sizeof(vp56_context_t),
|
552 |
vp6_decode_init, |
553 |
NULL,
|
554 |
vp56_free, |
555 |
vp56_decode_frame, |
556 |
}; |