2 * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
4 * This file is part of Libav.
6 * Libav 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 * Libav 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 Libav; 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
40 #define VP6_MAX_HUFF_SIZE 12
42 static void vp6_parse_coeff(VP56Context
*s
);
43 static void vp6_parse_coeff_huffman(VP56Context
*s
);
45 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
->framep
[VP56_FRAME_CURRENT
]->key_frame
= !(buf
[0] & 0x80);
58 ff_vp56_init_dequant(s
, (buf
[0] >> 1) & 0x3F);
60 if (s
->framep
[VP56_FRAME_CURRENT
]->key_frame
) {
61 sub_version
= buf
[1] >> 3;
63 return AVERROR_INVALIDDATA
;
64 s
->filter_header
= buf
[1] & 0x06;
66 av_log_missing_feature(s
->avctx
, "Interlacing", 0);
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 avcodec_set_dimensions(s
->avctx
, 16*cols
, 16*rows
);
88 if (s
->avctx
->extradata_size
== 1) {
89 s
->avctx
->width
-= s
->avctx
->extradata
[0] >> 4;
90 s
->avctx
->height
-= s
->avctx
->extradata
[0] & 0x0F;
92 res
= VP56_SIZE_CHANGE
;
95 ff_vp56_init_range_decoder(c
, buf
+6, buf_size
-6);
98 parse_filter_info
= s
->filter_header
;
101 s
->sub_version
= sub_version
;
103 if (!s
->sub_version
|| !s
->avctx
->coded_width
|| !s
->avctx
->coded_height
)
104 return AVERROR_INVALIDDATA
;
106 if (separated_coeff
|| !s
->filter_header
) {
107 coeff_offset
= AV_RB16(buf
+1) - 2;
111 ff_vp56_init_range_decoder(c
, buf
+1, buf_size
-1);
113 *golden_frame
= vp56_rac_get(c
);
114 if (s
->filter_header
) {
115 s
->deblock_filtering
= vp56_rac_get(c
);
116 if (s
->deblock_filtering
)
118 if (s
->sub_version
> 7)
119 parse_filter_info
= vp56_rac_get(c
);
123 if (parse_filter_info
) {
124 if (vp56_rac_get(c
)) {
126 s
->sample_variance_threshold
= vp56_rac_gets(c
, 5) << vrt_shift
;
127 s
->max_vector_length
= 2 << vp56_rac_gets(c
, 3);
128 } else if (vp56_rac_get(c
)) {
133 if (s
->sub_version
> 7)
134 s
->filter_selection
= vp56_rac_gets(c
, 4);
136 s
->filter_selection
= 16;
139 s
->use_huffman
= vp56_rac_get(c
);
141 s
->parse_coeff
= vp6_parse_coeff
;
144 buf_size
-= coeff_offset
;
146 if (s
->framep
[VP56_FRAME_CURRENT
]->key_frame
)
147 avcodec_set_dimensions(s
->avctx
, 0, 0);
148 return AVERROR_INVALIDDATA
;
150 if (s
->use_huffman
) {
151 s
->parse_coeff
= vp6_parse_coeff_huffman
;
152 init_get_bits(&s
->gb
, buf
, buf_size
<<3);
154 ff_vp56_init_range_decoder(&s
->cc
, buf
, buf_size
);
164 static void vp6_coeff_order_table_init(VP56Context
*s
)
168 s
->modelp
->coeff_index_to_pos
[0] = 0;
170 for (pos
=1; pos
<64; pos
++)
171 if (s
->modelp
->coeff_reorder
[pos
] == i
)
172 s
->modelp
->coeff_index_to_pos
[idx
++] = pos
;
175 static void vp6_default_models_init(VP56Context
*s
)
177 VP56Model
*model
= s
->modelp
;
179 model
->vector_dct
[0] = 0xA2;
180 model
->vector_dct
[1] = 0xA4;
181 model
->vector_sig
[0] = 0x80;
182 model
->vector_sig
[1] = 0x80;
184 memcpy(model
->mb_types_stats
, ff_vp56_def_mb_types_stats
, sizeof(model
->mb_types_stats
));
185 memcpy(model
->vector_fdv
, vp6_def_fdv_vector_model
, sizeof(model
->vector_fdv
));
186 memcpy(model
->vector_pdv
, vp6_def_pdv_vector_model
, sizeof(model
->vector_pdv
));
187 memcpy(model
->coeff_runv
, vp6_def_runv_coeff_model
, sizeof(model
->coeff_runv
));
188 memcpy(model
->coeff_reorder
, vp6_def_coeff_reorder
, sizeof(model
->coeff_reorder
));
190 vp6_coeff_order_table_init(s
);
193 static void vp6_parse_vector_models(VP56Context
*s
)
195 VP56RangeCoder
*c
= &s
->c
;
196 VP56Model
*model
= s
->modelp
;
199 for (comp
=0; comp
<2; comp
++) {
200 if (vp56_rac_get_prob(c
, vp6_sig_dct_pct
[comp
][0]))
201 model
->vector_dct
[comp
] = vp56_rac_gets_nn(c
, 7);
202 if (vp56_rac_get_prob(c
, vp6_sig_dct_pct
[comp
][1]))
203 model
->vector_sig
[comp
] = vp56_rac_gets_nn(c
, 7);
206 for (comp
=0; comp
<2; comp
++)
207 for (node
=0; node
<7; node
++)
208 if (vp56_rac_get_prob(c
, vp6_pdv_pct
[comp
][node
]))
209 model
->vector_pdv
[comp
][node
] = vp56_rac_gets_nn(c
, 7);
211 for (comp
=0; comp
<2; comp
++)
212 for (node
=0; node
<8; node
++)
213 if (vp56_rac_get_prob(c
, vp6_fdv_pct
[comp
][node
]))
214 model
->vector_fdv
[comp
][node
] = vp56_rac_gets_nn(c
, 7);
217 /* nodes must ascend by count, but with descending symbol order */
218 static int vp6_huff_cmp(const void *va
, const void *vb
)
220 const Node
*a
= va
, *b
= vb
;
221 return (a
->count
- b
->count
)*16 + (b
->sym
- a
->sym
);
224 static int vp6_build_huff_tree(VP56Context
*s
, uint8_t coeff_model
[],
225 const uint8_t *map
, unsigned size
, VLC
*vlc
)
227 Node nodes
[2*VP6_MAX_HUFF_SIZE
], *tmp
= &nodes
[size
];
230 /* first compute probabilities from model */
232 for (i
=0; i
<size
-1; i
++) {
233 a
= tmp
[i
].count
* coeff_model
[i
] >> 8;
234 b
= tmp
[i
].count
* (255 - coeff_model
[i
]) >> 8;
235 nodes
[map
[2*i
]].count
= a
+ !a
;
236 nodes
[map
[2*i
+1]].count
= b
+ !b
;
240 /* then build the huffman tree according to probabilities */
241 return ff_huff_build_tree(s
->avctx
, vlc
, size
, nodes
, vp6_huff_cmp
,
242 FF_HUFFMAN_FLAG_HNODE_FIRST
);
245 static int vp6_parse_coeff_models(VP56Context
*s
)
247 VP56RangeCoder
*c
= &s
->c
;
248 VP56Model
*model
= s
->modelp
;
250 int node
, cg
, ctx
, pos
;
251 int ct
; /* code type */
252 int pt
; /* plane type (0 for Y, 1 for U or V) */
254 memset(def_prob
, 0x80, sizeof(def_prob
));
256 for (pt
=0; pt
<2; pt
++)
257 for (node
=0; node
<11; node
++)
258 if (vp56_rac_get_prob(c
, vp6_dccv_pct
[pt
][node
])) {
259 def_prob
[node
] = vp56_rac_gets_nn(c
, 7);
260 model
->coeff_dccv
[pt
][node
] = def_prob
[node
];
261 } else if (s
->framep
[VP56_FRAME_CURRENT
]->key_frame
) {
262 model
->coeff_dccv
[pt
][node
] = def_prob
[node
];
265 if (vp56_rac_get(c
)) {
266 for (pos
=1; pos
<64; pos
++)
267 if (vp56_rac_get_prob(c
, vp6_coeff_reorder_pct
[pos
]))
268 model
->coeff_reorder
[pos
] = vp56_rac_gets(c
, 4);
269 vp6_coeff_order_table_init(s
);
272 for (cg
=0; cg
<2; cg
++)
273 for (node
=0; node
<14; node
++)
274 if (vp56_rac_get_prob(c
, vp6_runv_pct
[cg
][node
]))
275 model
->coeff_runv
[cg
][node
] = vp56_rac_gets_nn(c
, 7);
277 for (ct
=0; ct
<3; ct
++)
278 for (pt
=0; pt
<2; pt
++)
279 for (cg
=0; cg
<6; cg
++)
280 for (node
=0; node
<11; node
++)
281 if (vp56_rac_get_prob(c
, vp6_ract_pct
[ct
][pt
][cg
][node
])) {
282 def_prob
[node
] = vp56_rac_gets_nn(c
, 7);
283 model
->coeff_ract
[pt
][ct
][cg
][node
] = def_prob
[node
];
284 } else if (s
->framep
[VP56_FRAME_CURRENT
]->key_frame
) {
285 model
->coeff_ract
[pt
][ct
][cg
][node
] = def_prob
[node
];
288 if (s
->use_huffman
) {
289 for (pt
=0; pt
<2; pt
++) {
290 if (vp6_build_huff_tree(s
, model
->coeff_dccv
[pt
],
291 vp6_huff_coeff_map
, 12, &s
->dccv_vlc
[pt
]))
293 if (vp6_build_huff_tree(s
, model
->coeff_runv
[pt
],
294 vp6_huff_run_map
, 9, &s
->runv_vlc
[pt
]))
296 for (ct
=0; ct
<3; ct
++)
297 for (cg
= 0; cg
< 6; cg
++)
298 if (vp6_build_huff_tree(s
, model
->coeff_ract
[pt
][ct
][cg
],
299 vp6_huff_coeff_map
, 12,
300 &s
->ract_vlc
[pt
][ct
][cg
]))
303 memset(s
->nb_null
, 0, sizeof(s
->nb_null
));
305 /* coeff_dcct is a linear combination of coeff_dccv */
306 for (pt
=0; pt
<2; pt
++)
307 for (ctx
=0; ctx
<3; ctx
++)
308 for (node
=0; node
<5; node
++)
309 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);
314 static void vp6_parse_vector_adjustment(VP56Context
*s
, VP56mv
*vect
)
316 VP56RangeCoder
*c
= &s
->c
;
317 VP56Model
*model
= s
->modelp
;
320 *vect
= (VP56mv
) {0,0};
321 if (s
->vector_candidate_pos
< 2)
322 *vect
= s
->vector_candidate
[0];
324 for (comp
=0; comp
<2; comp
++) {
327 if (vp56_rac_get_prob(c
, model
->vector_dct
[comp
])) {
328 static const uint8_t prob_order
[] = {0, 1, 2, 7, 6, 5, 4};
329 for (i
=0; i
<sizeof(prob_order
); i
++) {
330 int j
= prob_order
[i
];
331 delta
|= vp56_rac_get_prob(c
, model
->vector_fdv
[comp
][j
])<<j
;
334 delta
|= vp56_rac_get_prob(c
, model
->vector_fdv
[comp
][3])<<3;
338 delta
= vp56_rac_get_tree(c
, ff_vp56_pva_tree
,
339 model
->vector_pdv
[comp
]);
342 if (delta
&& vp56_rac_get_prob(c
, model
->vector_sig
[comp
]))
353 * Read number of consecutive blocks with null DC or AC.
354 * This value is < 74.
356 static unsigned vp6_get_nb_null(VP56Context
*s
)
358 unsigned val
= get_bits(&s
->gb
, 2);
360 val
+= get_bits(&s
->gb
, 2);
362 val
= get_bits1(&s
->gb
) << 2;
363 val
= 6+val
+ get_bits(&s
->gb
, 2+val
);
368 static void vp6_parse_coeff_huffman(VP56Context
*s
)
370 VP56Model
*model
= s
->modelp
;
371 uint8_t *permute
= s
->scantable
.permutated
;
373 int coeff
, sign
, coeff_idx
;
375 int pt
= 0; /* plane type (0 for Y, 1 for U or V) */
377 for (b
=0; b
<6; b
++) {
378 int ct
= 0; /* code type */
380 vlc_coeff
= &s
->dccv_vlc
[pt
];
382 for (coeff_idx
= 0;;) {
384 if (coeff_idx
<2 && s
->nb_null
[coeff_idx
][pt
]) {
385 s
->nb_null
[coeff_idx
][pt
]--;
389 if (get_bits_left(&s
->gb
) <= 0)
391 coeff
= get_vlc2(&s
->gb
, vlc_coeff
->table
, 9, 3);
394 int pt
= (coeff_idx
>= 6);
395 run
+= get_vlc2(&s
->gb
, s
->runv_vlc
[pt
].table
, 9, 3);
397 run
+= get_bits(&s
->gb
, 6);
399 s
->nb_null
[0][pt
] = vp6_get_nb_null(s
);
401 } else if (coeff
== 11) { /* end of block */
402 if (coeff_idx
== 1) /* first AC coeff ? */
403 s
->nb_null
[1][pt
] = vp6_get_nb_null(s
);
406 int coeff2
= ff_vp56_coeff_bias
[coeff
];
408 coeff2
+= get_bits(&s
->gb
, coeff
<= 9 ? coeff
- 4 : 11);
409 ct
= 1 + (coeff2
> 1);
410 sign
= get_bits1(&s
->gb
);
411 coeff2
= (coeff2
^ -sign
) + sign
;
413 coeff2
*= s
->dequant_ac
;
414 idx
= model
->coeff_index_to_pos
[coeff_idx
];
415 s
->block_coeff
[b
][permute
[idx
]] = coeff2
;
421 cg
= FFMIN(vp6_coeff_groups
[coeff_idx
], 3);
422 vlc_coeff
= &s
->ract_vlc
[pt
][ct
][cg
];
427 static void vp6_parse_coeff(VP56Context
*s
)
429 VP56RangeCoder
*c
= s
->ccp
;
430 VP56Model
*model
= s
->modelp
;
431 uint8_t *permute
= s
->scantable
.permutated
;
432 uint8_t *model1
, *model2
, *model3
;
433 int coeff
, sign
, coeff_idx
;
434 int b
, i
, cg
, idx
, ctx
;
435 int pt
= 0; /* plane type (0 for Y, 1 for U or V) */
437 for (b
=0; b
<6; b
++) {
438 int ct
= 1; /* code type */
443 ctx
= s
->left_block
[ff_vp56_b6to4
[b
]].not_null_dc
444 + s
->above_blocks
[s
->above_block_idx
[b
]].not_null_dc
;
445 model1
= model
->coeff_dccv
[pt
];
446 model2
= model
->coeff_dcct
[pt
][ctx
];
450 if ((coeff_idx
>1 && ct
==0) || vp56_rac_get_prob(c
, model2
[0])) {
452 if (vp56_rac_get_prob(c
, model2
[2])) {
453 if (vp56_rac_get_prob(c
, model2
[3])) {
454 idx
= vp56_rac_get_tree(c
, ff_vp56_pc_tree
, model1
);
455 coeff
= ff_vp56_coeff_bias
[idx
+5];
456 for (i
=ff_vp56_coeff_bit_length
[idx
]; i
>=0; i
--)
457 coeff
+= vp56_rac_get_prob(c
, ff_vp56_coeff_parse_table
[idx
][i
]) << i
;
459 if (vp56_rac_get_prob(c
, model2
[4]))
460 coeff
= 3 + vp56_rac_get_prob(c
, model1
[5]);
469 sign
= vp56_rac_get(c
);
470 coeff
= (coeff
^ -sign
) + sign
;
472 coeff
*= s
->dequant_ac
;
473 idx
= model
->coeff_index_to_pos
[coeff_idx
];
474 s
->block_coeff
[b
][permute
[idx
]] = coeff
;
480 if (!vp56_rac_get_prob(c
, model2
[1]))
483 model3
= model
->coeff_runv
[coeff_idx
>= 6];
484 run
= vp56_rac_get_tree(c
, vp6_pcr_tree
, model3
);
486 for (run
=9, i
=0; i
<6; i
++)
487 run
+= vp56_rac_get_prob(c
, model3
[i
+8]) << i
;
493 cg
= vp6_coeff_groups
[coeff_idx
];
494 model1
= model2
= model
->coeff_ract
[pt
][ct
][cg
];
497 s
->left_block
[ff_vp56_b6to4
[b
]].not_null_dc
=
498 s
->above_blocks
[s
->above_block_idx
[b
]].not_null_dc
= !!s
->block_coeff
[b
][0];
502 static int vp6_block_variance(uint8_t *src
, int stride
)
504 int sum
= 0, square_sum
= 0;
507 for (y
=0; y
<8; y
+=2) {
508 for (x
=0; x
<8; x
+=2) {
510 square_sum
+= src
[x
]*src
[x
];
514 return (16*square_sum
- sum
*sum
) >> 8;
517 static void vp6_filter_hv4(uint8_t *dst
, uint8_t *src
, int stride
,
518 int delta
, const int16_t *weights
)
522 for (y
=0; y
<8; y
++) {
523 for (x
=0; x
<8; x
++) {
524 dst
[x
] = av_clip_uint8(( src
[x
-delta
] * weights
[0]
525 + src
[x
] * weights
[1]
526 + src
[x
+delta
] * weights
[2]
527 + src
[x
+2*delta
] * weights
[3] + 64) >> 7);
534 static void vp6_filter_diag2(VP56Context
*s
, uint8_t *dst
, uint8_t *src
,
535 int stride
, int h_weight
, int v_weight
)
537 uint8_t *tmp
= s
->edge_emu_buffer
+16;
538 s
->h264chroma
.put_h264_chroma_pixels_tab
[0](tmp
, src
, stride
, 9, h_weight
, 0);
539 s
->h264chroma
.put_h264_chroma_pixels_tab
[0](dst
, tmp
, stride
, 8, 0, v_weight
);
542 static void vp6_filter(VP56Context
*s
, uint8_t *dst
, uint8_t *src
,
543 int offset1
, int offset2
, int stride
,
544 VP56mv mv
, int mask
, int select
, int luma
)
547 int x8
= mv
.x
& mask
;
548 int y8
= mv
.y
& mask
;
553 filter4
= s
->filter_mode
;
555 if (s
->max_vector_length
&&
556 (FFABS(mv
.x
) > s
->max_vector_length
||
557 FFABS(mv
.y
) > s
->max_vector_length
)) {
559 } else if (s
->sample_variance_threshold
560 && (vp6_block_variance(src
+offset1
, stride
)
561 < s
->sample_variance_threshold
)) {
567 if ((y8
&& (offset2
-offset1
)*s
->flip
<0) || (!y8
&& offset1
> offset2
)) {
572 if (!y8
) { /* left or right combine */
573 vp6_filter_hv4(dst
, src
+offset1
, stride
, 1,
574 vp6_block_copy_filter
[select
][x8
]);
575 } else if (!x8
) { /* above or below combine */
576 vp6_filter_hv4(dst
, src
+offset1
, stride
, stride
,
577 vp6_block_copy_filter
[select
][y8
]);
579 s
->vp56dsp
.vp6_filter_diag4(dst
, src
+offset1
+((mv
.x
^mv
.y
)>>31), stride
,
580 vp6_block_copy_filter
[select
][x8
],
581 vp6_block_copy_filter
[select
][y8
]);
585 s
->h264chroma
.put_h264_chroma_pixels_tab
[0](dst
, src
+ offset1
, stride
, 8, x8
, y8
);
587 vp6_filter_diag2(s
, dst
, src
+offset1
+ ((mv
.x
^mv
.y
)>>31), stride
, x8
, y8
);
592 static av_cold
int vp6_decode_init(AVCodecContext
*avctx
)
594 VP56Context
*s
= avctx
->priv_data
;
596 ff_vp56_init(avctx
, avctx
->codec
->id
== AV_CODEC_ID_VP6
,
597 avctx
->codec
->id
== AV_CODEC_ID_VP6A
);
598 s
->vp56_coord_div
= vp6_coord_div
;
599 s
->parse_vector_adjustment
= vp6_parse_vector_adjustment
;
600 s
->filter
= vp6_filter
;
601 s
->default_models_init
= vp6_default_models_init
;
602 s
->parse_vector_models
= vp6_parse_vector_models
;
603 s
->parse_coeff_models
= vp6_parse_coeff_models
;
604 s
->parse_header
= vp6_parse_header
;
609 static av_cold
int vp6_decode_free(AVCodecContext
*avctx
)
611 VP56Context
*s
= avctx
->priv_data
;
616 for (pt
=0; pt
<2; pt
++) {
617 ff_free_vlc(&s
->dccv_vlc
[pt
]);
618 ff_free_vlc(&s
->runv_vlc
[pt
]);
619 for (ct
=0; ct
<3; ct
++)
620 for (cg
=0; cg
<6; cg
++)
621 ff_free_vlc(&s
->ract_vlc
[pt
][ct
][cg
]);
626 AVCodec ff_vp6_decoder
= {
628 .type
= AVMEDIA_TYPE_VIDEO
,
629 .id
= AV_CODEC_ID_VP6
,
630 .priv_data_size
= sizeof(VP56Context
),
631 .init
= vp6_decode_init
,
632 .close
= vp6_decode_free
,
633 .decode
= ff_vp56_decode_frame
,
634 .capabilities
= CODEC_CAP_DR1
,
635 .long_name
= NULL_IF_CONFIG_SMALL("On2 VP6"),
638 /* flash version, not flipped upside-down */
639 AVCodec ff_vp6f_decoder
= {
641 .type
= AVMEDIA_TYPE_VIDEO
,
642 .id
= AV_CODEC_ID_VP6F
,
643 .priv_data_size
= sizeof(VP56Context
),
644 .init
= vp6_decode_init
,
645 .close
= vp6_decode_free
,
646 .decode
= ff_vp56_decode_frame
,
647 .capabilities
= CODEC_CAP_DR1
,
648 .long_name
= NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
651 /* flash version, not flipped upside-down, with alpha channel */
652 AVCodec ff_vp6a_decoder
= {
654 .type
= AVMEDIA_TYPE_VIDEO
,
655 .id
= AV_CODEC_ID_VP6A
,
656 .priv_data_size
= sizeof(VP56Context
),
657 .init
= vp6_decode_init
,
658 .close
= vp6_decode_free
,
659 .decode
= ff_vp56_decode_frame
,
660 .capabilities
= CODEC_CAP_DR1
,
661 .long_name
= NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),