2 * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * VP6 compatible video decoder
25 * The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
26 * - upper 4 bits: difference between encoded width and visible width
27 * - lower 4 bits: difference between encoded height and visible height
41 #define VP6_MAX_HUFF_SIZE 12
43 static void vp6_parse_coeff(VP56Context
*s
);
44 static void vp6_parse_coeff_huffman(VP56Context
*s
);
46 static int vp6_parse_header(VP56Context
*s
, const uint8_t *buf
, int buf_size
)
48 VP56RangeCoder
*c
= &s
->c
;
49 int parse_filter_info
= 0;
55 int separated_coeff
= buf
[0] & 1;
57 s
->frames
[VP56_FRAME_CURRENT
]->key_frame
= !(buf
[0] & 0x80);
58 ff_vp56_init_dequant(s
, (buf
[0] >> 1) & 0x3F);
60 if (s
->frames
[VP56_FRAME_CURRENT
]->key_frame
) {
61 sub_version
= buf
[1] >> 3;
63 return AVERROR_INVALIDDATA
;
64 s
->filter_header
= buf
[1] & 0x06;
66 avpriv_report_missing_feature(s
->avctx
, "Interlacing");
67 return AVERROR_PATCHWELCOME
;
69 if (separated_coeff
|| !s
->filter_header
) {
70 coeff_offset
= AV_RB16(buf
+2) - 2;
75 rows
= buf
[2]; /* number of stored macroblock rows */
76 cols
= buf
[3]; /* number of stored macroblock cols */
77 /* buf[4] is number of displayed macroblock rows */
78 /* buf[5] is number of displayed macroblock cols */
80 av_log(s
->avctx
, AV_LOG_ERROR
, "Invalid size %dx%d\n", cols
<< 4, rows
<< 4);
81 return AVERROR_INVALIDDATA
;
84 if (!s
->macroblocks
|| /* first frame */
85 16*cols
!= s
->avctx
->coded_width
||
86 16*rows
!= s
->avctx
->coded_height
) {
87 if (s
->avctx
->extradata_size
== 0 &&
88 FFALIGN(s
->avctx
->width
, 16) == 16 * cols
&&
89 FFALIGN(s
->avctx
->height
, 16) == 16 * rows
) {
90 // We assume this is properly signalled container cropping,
91 // in an F4V file. Just set the coded_width/height, don't
92 // touch the cropped ones.
93 s
->avctx
->coded_width
= 16 * cols
;
94 s
->avctx
->coded_height
= 16 * rows
;
96 int ret
= ff_set_dimensions(s
->avctx
, 16 * cols
, 16 * rows
);
100 if (s
->avctx
->extradata_size
== 1) {
101 s
->avctx
->width
-= s
->avctx
->extradata
[0] >> 4;
102 s
->avctx
->height
-= s
->avctx
->extradata
[0] & 0x0F;
105 res
= VP56_SIZE_CHANGE
;
108 ff_vp56_init_range_decoder(c
, buf
+6, buf_size
-6);
111 parse_filter_info
= s
->filter_header
;
114 s
->sub_version
= sub_version
;
117 if (!s
->sub_version
|| !s
->avctx
->coded_width
|| !s
->avctx
->coded_height
)
118 return AVERROR_INVALIDDATA
;
120 if (separated_coeff
|| !s
->filter_header
) {
121 coeff_offset
= AV_RB16(buf
+1) - 2;
125 ff_vp56_init_range_decoder(c
, buf
+1, buf_size
-1);
127 s
->golden_frame
= vp56_rac_get(c
);
128 if (s
->filter_header
) {
129 s
->deblock_filtering
= vp56_rac_get(c
);
130 if (s
->deblock_filtering
)
132 if (s
->sub_version
> 7)
133 parse_filter_info
= vp56_rac_get(c
);
137 if (parse_filter_info
) {
138 if (vp56_rac_get(c
)) {
140 s
->sample_variance_threshold
= vp56_rac_gets(c
, 5) << vrt_shift
;
141 s
->max_vector_length
= 2 << vp56_rac_gets(c
, 3);
142 } else if (vp56_rac_get(c
)) {
147 if (s
->sub_version
> 7)
148 s
->filter_selection
= vp56_rac_gets(c
, 4);
150 s
->filter_selection
= 16;
153 s
->use_huffman
= vp56_rac_get(c
);
155 s
->parse_coeff
= vp6_parse_coeff
;
158 buf_size
-= coeff_offset
;
160 if (s
->frames
[VP56_FRAME_CURRENT
]->key_frame
)
161 ff_set_dimensions(s
->avctx
, 0, 0);
162 return AVERROR_INVALIDDATA
;
164 if (s
->use_huffman
) {
165 s
->parse_coeff
= vp6_parse_coeff_huffman
;
166 init_get_bits(&s
->gb
, buf
, buf_size
<<3);
168 ff_vp56_init_range_decoder(&s
->cc
, buf
, buf_size
);
178 static void vp6_coeff_order_table_init(VP56Context
*s
)
182 s
->modelp
->coeff_index_to_pos
[0] = 0;
184 for (pos
=1; pos
<64; pos
++)
185 if (s
->modelp
->coeff_reorder
[pos
] == i
)
186 s
->modelp
->coeff_index_to_pos
[idx
++] = pos
;
189 static void vp6_default_models_init(VP56Context
*s
)
191 VP56Model
*model
= s
->modelp
;
193 model
->vector_dct
[0] = 0xA2;
194 model
->vector_dct
[1] = 0xA4;
195 model
->vector_sig
[0] = 0x80;
196 model
->vector_sig
[1] = 0x80;
198 memcpy(model
->mb_types_stats
, ff_vp56_def_mb_types_stats
, sizeof(model
->mb_types_stats
));
199 memcpy(model
->vector_fdv
, vp6_def_fdv_vector_model
, sizeof(model
->vector_fdv
));
200 memcpy(model
->vector_pdv
, vp6_def_pdv_vector_model
, sizeof(model
->vector_pdv
));
201 memcpy(model
->coeff_runv
, vp6_def_runv_coeff_model
, sizeof(model
->coeff_runv
));
202 memcpy(model
->coeff_reorder
, vp6_def_coeff_reorder
, sizeof(model
->coeff_reorder
));
204 vp6_coeff_order_table_init(s
);
207 static void vp6_parse_vector_models(VP56Context
*s
)
209 VP56RangeCoder
*c
= &s
->c
;
210 VP56Model
*model
= s
->modelp
;
213 for (comp
=0; comp
<2; comp
++) {
214 if (vp56_rac_get_prob_branchy(c
, vp6_sig_dct_pct
[comp
][0]))
215 model
->vector_dct
[comp
] = vp56_rac_gets_nn(c
, 7);
216 if (vp56_rac_get_prob_branchy(c
, vp6_sig_dct_pct
[comp
][1]))
217 model
->vector_sig
[comp
] = vp56_rac_gets_nn(c
, 7);
220 for (comp
=0; comp
<2; comp
++)
221 for (node
=0; node
<7; node
++)
222 if (vp56_rac_get_prob_branchy(c
, vp6_pdv_pct
[comp
][node
]))
223 model
->vector_pdv
[comp
][node
] = vp56_rac_gets_nn(c
, 7);
225 for (comp
=0; comp
<2; comp
++)
226 for (node
=0; node
<8; node
++)
227 if (vp56_rac_get_prob_branchy(c
, vp6_fdv_pct
[comp
][node
]))
228 model
->vector_fdv
[comp
][node
] = vp56_rac_gets_nn(c
, 7);
231 /* nodes must ascend by count, but with descending symbol order */
232 static int vp6_huff_cmp(const void *va
, const void *vb
)
234 const Node
*a
= va
, *b
= vb
;
235 return (a
->count
- b
->count
)*16 + (b
->sym
- a
->sym
);
238 static int vp6_build_huff_tree(VP56Context
*s
, uint8_t coeff_model
[],
239 const uint8_t *map
, unsigned size
, VLC
*vlc
)
241 Node nodes
[2*VP6_MAX_HUFF_SIZE
], *tmp
= &nodes
[size
];
244 /* first compute probabilities from model */
246 for (i
=0; i
<size
-1; i
++) {
247 a
= tmp
[i
].count
* coeff_model
[i
] >> 8;
248 b
= tmp
[i
].count
* (255 - coeff_model
[i
]) >> 8;
249 nodes
[map
[2*i
]].count
= a
+ !a
;
250 nodes
[map
[2*i
+1]].count
= b
+ !b
;
254 /* then build the huffman tree according to probabilities */
255 return ff_huff_build_tree(s
->avctx
, vlc
, size
, FF_HUFFMAN_BITS
,
257 FF_HUFFMAN_FLAG_HNODE_FIRST
);
260 static int vp6_parse_coeff_models(VP56Context
*s
)
262 VP56RangeCoder
*c
= &s
->c
;
263 VP56Model
*model
= s
->modelp
;
265 int node
, cg
, ctx
, pos
;
266 int ct
; /* code type */
267 int pt
; /* plane type (0 for Y, 1 for U or V) */
269 memset(def_prob
, 0x80, sizeof(def_prob
));
271 for (pt
=0; pt
<2; pt
++)
272 for (node
=0; node
<11; node
++)
273 if (vp56_rac_get_prob_branchy(c
, vp6_dccv_pct
[pt
][node
])) {
274 def_prob
[node
] = vp56_rac_gets_nn(c
, 7);
275 model
->coeff_dccv
[pt
][node
] = def_prob
[node
];
276 } else if (s
->frames
[VP56_FRAME_CURRENT
]->key_frame
) {
277 model
->coeff_dccv
[pt
][node
] = def_prob
[node
];
280 if (vp56_rac_get(c
)) {
281 for (pos
=1; pos
<64; pos
++)
282 if (vp56_rac_get_prob_branchy(c
, vp6_coeff_reorder_pct
[pos
]))
283 model
->coeff_reorder
[pos
] = vp56_rac_gets(c
, 4);
284 vp6_coeff_order_table_init(s
);
287 for (cg
=0; cg
<2; cg
++)
288 for (node
=0; node
<14; node
++)
289 if (vp56_rac_get_prob_branchy(c
, vp6_runv_pct
[cg
][node
]))
290 model
->coeff_runv
[cg
][node
] = vp56_rac_gets_nn(c
, 7);
292 for (ct
=0; ct
<3; ct
++)
293 for (pt
=0; pt
<2; pt
++)
294 for (cg
=0; cg
<6; cg
++)
295 for (node
=0; node
<11; node
++)
296 if (vp56_rac_get_prob_branchy(c
, vp6_ract_pct
[ct
][pt
][cg
][node
])) {
297 def_prob
[node
] = vp56_rac_gets_nn(c
, 7);
298 model
->coeff_ract
[pt
][ct
][cg
][node
] = def_prob
[node
];
299 } else if (s
->frames
[VP56_FRAME_CURRENT
]->key_frame
) {
300 model
->coeff_ract
[pt
][ct
][cg
][node
] = def_prob
[node
];
303 if (s
->use_huffman
) {
304 for (pt
=0; pt
<2; pt
++) {
305 if (vp6_build_huff_tree(s
, model
->coeff_dccv
[pt
],
306 vp6_huff_coeff_map
, 12, &s
->dccv_vlc
[pt
]))
308 if (vp6_build_huff_tree(s
, model
->coeff_runv
[pt
],
309 vp6_huff_run_map
, 9, &s
->runv_vlc
[pt
]))
311 for (ct
=0; ct
<3; ct
++)
312 for (cg
= 0; cg
< 6; cg
++)
313 if (vp6_build_huff_tree(s
, model
->coeff_ract
[pt
][ct
][cg
],
314 vp6_huff_coeff_map
, 12,
315 &s
->ract_vlc
[pt
][ct
][cg
]))
318 memset(s
->nb_null
, 0, sizeof(s
->nb_null
));
320 /* coeff_dcct is a linear combination of coeff_dccv */
321 for (pt
=0; pt
<2; pt
++)
322 for (ctx
=0; ctx
<3; ctx
++)
323 for (node
=0; node
<5; node
++)
324 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);
329 static void vp6_parse_vector_adjustment(VP56Context
*s
, VP56mv
*vect
)
331 VP56RangeCoder
*c
= &s
->c
;
332 VP56Model
*model
= s
->modelp
;
335 *vect
= (VP56mv
) {0,0};
336 if (s
->vector_candidate_pos
< 2)
337 *vect
= s
->vector_candidate
[0];
339 for (comp
=0; comp
<2; comp
++) {
342 if (vp56_rac_get_prob_branchy(c
, model
->vector_dct
[comp
])) {
343 static const uint8_t prob_order
[] = {0, 1, 2, 7, 6, 5, 4};
344 for (i
=0; i
<sizeof(prob_order
); i
++) {
345 int j
= prob_order
[i
];
346 delta
|= vp56_rac_get_prob(c
, model
->vector_fdv
[comp
][j
])<<j
;
349 delta
|= vp56_rac_get_prob(c
, model
->vector_fdv
[comp
][3])<<3;
353 delta
= vp56_rac_get_tree(c
, ff_vp56_pva_tree
,
354 model
->vector_pdv
[comp
]);
357 if (delta
&& vp56_rac_get_prob_branchy(c
, model
->vector_sig
[comp
]))
368 * Read number of consecutive blocks with null DC or AC.
369 * This value is < 74.
371 static unsigned vp6_get_nb_null(VP56Context
*s
)
373 unsigned val
= get_bits(&s
->gb
, 2);
375 val
+= get_bits(&s
->gb
, 2);
377 val
= get_bits1(&s
->gb
) << 2;
378 val
= 6+val
+ get_bits(&s
->gb
, 2+val
);
383 static void vp6_parse_coeff_huffman(VP56Context
*s
)
385 VP56Model
*model
= s
->modelp
;
386 uint8_t *permute
= s
->idct_scantable
;
388 int coeff
, sign
, coeff_idx
;
390 int pt
= 0; /* plane type (0 for Y, 1 for U or V) */
392 for (b
=0; b
<6; b
++) {
393 int ct
= 0; /* code type */
395 vlc_coeff
= &s
->dccv_vlc
[pt
];
397 for (coeff_idx
= 0;;) {
399 if (coeff_idx
<2 && s
->nb_null
[coeff_idx
][pt
]) {
400 s
->nb_null
[coeff_idx
][pt
]--;
404 if (get_bits_left(&s
->gb
) <= 0)
406 coeff
= get_vlc2(&s
->gb
, vlc_coeff
->table
, FF_HUFFMAN_BITS
, 3);
409 int pt
= (coeff_idx
>= 6);
410 run
+= get_vlc2(&s
->gb
, s
->runv_vlc
[pt
].table
, FF_HUFFMAN_BITS
, 3);
412 run
+= get_bits(&s
->gb
, 6);
414 s
->nb_null
[0][pt
] = vp6_get_nb_null(s
);
416 } else if (coeff
== 11) { /* end of block */
417 if (coeff_idx
== 1) /* first AC coeff ? */
418 s
->nb_null
[1][pt
] = vp6_get_nb_null(s
);
421 int coeff2
= ff_vp56_coeff_bias
[coeff
];
423 coeff2
+= get_bits(&s
->gb
, coeff
<= 9 ? coeff
- 4 : 11);
424 ct
= 1 + (coeff2
> 1);
425 sign
= get_bits1(&s
->gb
);
426 coeff2
= (coeff2
^ -sign
) + sign
;
428 coeff2
*= s
->dequant_ac
;
429 idx
= model
->coeff_index_to_pos
[coeff_idx
];
430 s
->block_coeff
[b
][permute
[idx
]] = coeff2
;
436 cg
= FFMIN(vp6_coeff_groups
[coeff_idx
], 3);
437 vlc_coeff
= &s
->ract_vlc
[pt
][ct
][cg
];
442 static void vp6_parse_coeff(VP56Context
*s
)
444 VP56RangeCoder
*c
= s
->ccp
;
445 VP56Model
*model
= s
->modelp
;
446 uint8_t *permute
= s
->idct_scantable
;
447 uint8_t *model1
, *model2
, *model3
;
448 int coeff
, sign
, coeff_idx
;
449 int b
, i
, cg
, idx
, ctx
;
450 int pt
= 0; /* plane type (0 for Y, 1 for U or V) */
452 for (b
=0; b
<6; b
++) {
453 int ct
= 1; /* code type */
458 ctx
= s
->left_block
[ff_vp56_b6to4
[b
]].not_null_dc
459 + s
->above_blocks
[s
->above_block_idx
[b
]].not_null_dc
;
460 model1
= model
->coeff_dccv
[pt
];
461 model2
= model
->coeff_dcct
[pt
][ctx
];
465 if ((coeff_idx
>1 && ct
==0) || vp56_rac_get_prob_branchy(c
, model2
[0])) {
467 if (vp56_rac_get_prob_branchy(c
, model2
[2])) {
468 if (vp56_rac_get_prob_branchy(c
, model2
[3])) {
469 idx
= vp56_rac_get_tree(c
, ff_vp56_pc_tree
, model1
);
470 coeff
= ff_vp56_coeff_bias
[idx
+5];
471 for (i
=ff_vp56_coeff_bit_length
[idx
]; i
>=0; i
--)
472 coeff
+= vp56_rac_get_prob(c
, ff_vp56_coeff_parse_table
[idx
][i
]) << i
;
474 if (vp56_rac_get_prob_branchy(c
, model2
[4]))
475 coeff
= 3 + vp56_rac_get_prob(c
, model1
[5]);
484 sign
= vp56_rac_get(c
);
485 coeff
= (coeff
^ -sign
) + sign
;
487 coeff
*= s
->dequant_ac
;
488 idx
= model
->coeff_index_to_pos
[coeff_idx
];
489 s
->block_coeff
[b
][permute
[idx
]] = coeff
;
495 if (!vp56_rac_get_prob_branchy(c
, model2
[1]))
498 model3
= model
->coeff_runv
[coeff_idx
>= 6];
499 run
= vp56_rac_get_tree(c
, vp6_pcr_tree
, model3
);
501 for (run
=9, i
=0; i
<6; i
++)
502 run
+= vp56_rac_get_prob(c
, model3
[i
+8]) << i
;
508 cg
= vp6_coeff_groups
[coeff_idx
];
509 model1
= model2
= model
->coeff_ract
[pt
][ct
][cg
];
512 s
->left_block
[ff_vp56_b6to4
[b
]].not_null_dc
=
513 s
->above_blocks
[s
->above_block_idx
[b
]].not_null_dc
= !!s
->block_coeff
[b
][0];
517 static int vp6_block_variance(uint8_t *src
, int stride
)
519 int sum
= 0, square_sum
= 0;
522 for (y
=0; y
<8; y
+=2) {
523 for (x
=0; x
<8; x
+=2) {
525 square_sum
+= src
[x
]*src
[x
];
529 return (16*square_sum
- sum
*sum
) >> 8;
532 static void vp6_filter_hv4(uint8_t *dst
, uint8_t *src
, int stride
,
533 int delta
, const int16_t *weights
)
537 for (y
=0; y
<8; y
++) {
538 for (x
=0; x
<8; x
++) {
539 dst
[x
] = av_clip_uint8(( src
[x
-delta
] * weights
[0]
540 + src
[x
] * weights
[1]
541 + src
[x
+delta
] * weights
[2]
542 + src
[x
+2*delta
] * weights
[3] + 64) >> 7);
549 static void vp6_filter_diag2(VP56Context
*s
, uint8_t *dst
, uint8_t *src
,
550 int stride
, int h_weight
, int v_weight
)
552 uint8_t *tmp
= s
->edge_emu_buffer
+16;
553 s
->h264chroma
.put_h264_chroma_pixels_tab
[0](tmp
, src
, stride
, 9, h_weight
, 0);
554 s
->h264chroma
.put_h264_chroma_pixels_tab
[0](dst
, tmp
, stride
, 8, 0, v_weight
);
557 static void vp6_filter(VP56Context
*s
, uint8_t *dst
, uint8_t *src
,
558 int offset1
, int offset2
, int stride
,
559 VP56mv mv
, int mask
, int select
, int luma
)
562 int x8
= mv
.x
& mask
;
563 int y8
= mv
.y
& mask
;
568 filter4
= s
->filter_mode
;
570 if (s
->max_vector_length
&&
571 (FFABS(mv
.x
) > s
->max_vector_length
||
572 FFABS(mv
.y
) > s
->max_vector_length
)) {
574 } else if (s
->sample_variance_threshold
575 && (vp6_block_variance(src
+offset1
, stride
)
576 < s
->sample_variance_threshold
)) {
582 if ((y8
&& (offset2
-offset1
)*s
->flip
<0) || (!y8
&& offset1
> offset2
)) {
587 if (!y8
) { /* left or right combine */
588 vp6_filter_hv4(dst
, src
+offset1
, stride
, 1,
589 vp6_block_copy_filter
[select
][x8
]);
590 } else if (!x8
) { /* above or below combine */
591 vp6_filter_hv4(dst
, src
+offset1
, stride
, stride
,
592 vp6_block_copy_filter
[select
][y8
]);
594 s
->vp56dsp
.vp6_filter_diag4(dst
, src
+offset1
+((mv
.x
^mv
.y
)>>31), stride
,
595 vp6_block_copy_filter
[select
][x8
],
596 vp6_block_copy_filter
[select
][y8
]);
600 s
->h264chroma
.put_h264_chroma_pixels_tab
[0](dst
, src
+ offset1
, stride
, 8, x8
, y8
);
602 vp6_filter_diag2(s
, dst
, src
+offset1
+ ((mv
.x
^mv
.y
)>>31), stride
, x8
, y8
);
607 static av_cold
void vp6_decode_init_context(VP56Context
*s
);
609 static av_cold
int vp6_decode_init(AVCodecContext
*avctx
)
611 VP56Context
*s
= avctx
->priv_data
;
614 if ((ret
= ff_vp56_init(avctx
, avctx
->codec
->id
== AV_CODEC_ID_VP6
,
615 avctx
->codec
->id
== AV_CODEC_ID_VP6A
)) < 0)
618 vp6_decode_init_context(s
);
621 s
->alpha_context
= av_mallocz(sizeof(VP56Context
));
622 ff_vp56_init_context(avctx
, s
->alpha_context
,
623 s
->flip
== -1, s
->has_alpha
);
624 vp6_decode_init_context(s
->alpha_context
);
630 static av_cold
void vp6_decode_init_context(VP56Context
*s
)
632 s
->deblock_filtering
= 0;
633 s
->vp56_coord_div
= vp6_coord_div
;
634 s
->parse_vector_adjustment
= vp6_parse_vector_adjustment
;
635 s
->filter
= vp6_filter
;
636 s
->default_models_init
= vp6_default_models_init
;
637 s
->parse_vector_models
= vp6_parse_vector_models
;
638 s
->parse_coeff_models
= vp6_parse_coeff_models
;
639 s
->parse_header
= vp6_parse_header
;
642 static av_cold
void vp6_decode_free_context(VP56Context
*s
);
644 static av_cold
int vp6_decode_free(AVCodecContext
*avctx
)
646 VP56Context
*s
= avctx
->priv_data
;
649 vp6_decode_free_context(s
);
651 if (s
->alpha_context
) {
652 ff_vp56_free_context(s
->alpha_context
);
653 vp6_decode_free_context(s
->alpha_context
);
654 av_freep(&s
->alpha_context
);
660 static av_cold
void vp6_decode_free_context(VP56Context
*s
)
664 for (pt
=0; pt
<2; pt
++) {
665 ff_free_vlc(&s
->dccv_vlc
[pt
]);
666 ff_free_vlc(&s
->runv_vlc
[pt
]);
667 for (ct
=0; ct
<3; ct
++)
668 for (cg
=0; cg
<6; cg
++)
669 ff_free_vlc(&s
->ract_vlc
[pt
][ct
][cg
]);
673 AVCodec ff_vp6_decoder
= {
675 .long_name
= NULL_IF_CONFIG_SMALL("On2 VP6"),
676 .type
= AVMEDIA_TYPE_VIDEO
,
677 .id
= AV_CODEC_ID_VP6
,
678 .priv_data_size
= sizeof(VP56Context
),
679 .init
= vp6_decode_init
,
680 .close
= vp6_decode_free
,
681 .decode
= ff_vp56_decode_frame
,
682 .capabilities
= CODEC_CAP_DR1
,
685 /* flash version, not flipped upside-down */
686 AVCodec ff_vp6f_decoder
= {
688 .long_name
= NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
689 .type
= AVMEDIA_TYPE_VIDEO
,
690 .id
= AV_CODEC_ID_VP6F
,
691 .priv_data_size
= sizeof(VP56Context
),
692 .init
= vp6_decode_init
,
693 .close
= vp6_decode_free
,
694 .decode
= ff_vp56_decode_frame
,
695 .capabilities
= CODEC_CAP_DR1
,
698 /* flash version, not flipped upside-down, with alpha channel */
699 AVCodec ff_vp6a_decoder
= {
701 .long_name
= NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
702 .type
= AVMEDIA_TYPE_VIDEO
,
703 .id
= AV_CODEC_ID_VP6A
,
704 .priv_data_size
= sizeof(VP56Context
),
705 .init
= vp6_decode_init
,
706 .close
= vp6_decode_free
,
707 .decode
= ff_vp56_decode_frame
,
708 .capabilities
= CODEC_CAP_DR1
| CODEC_CAP_SLICE_THREADS
,