Libav
|
00001 00028 #include <stdlib.h> 00029 00030 #include "avcodec.h" 00031 #include "dsputil.h" 00032 #include "get_bits.h" 00033 #include "huffman.h" 00034 00035 #include "vp56.h" 00036 #include "vp56data.h" 00037 #include "vp6data.h" 00038 00039 00040 static void vp6_parse_coeff(VP56Context *s); 00041 static void vp6_parse_coeff_huffman(VP56Context *s); 00042 00043 static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, 00044 int *golden_frame) 00045 { 00046 VP56RangeCoder *c = &s->c; 00047 int parse_filter_info = 0; 00048 int coeff_offset = 0; 00049 int vrt_shift = 0; 00050 int sub_version; 00051 int rows, cols; 00052 int res = 1; 00053 int separated_coeff = buf[0] & 1; 00054 00055 s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); 00056 vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); 00057 00058 if (s->framep[VP56_FRAME_CURRENT]->key_frame) { 00059 sub_version = buf[1] >> 3; 00060 if (sub_version > 8) 00061 return 0; 00062 s->filter_header = buf[1] & 0x06; 00063 if (buf[1] & 1) { 00064 av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); 00065 return 0; 00066 } 00067 if (separated_coeff || !s->filter_header) { 00068 coeff_offset = AV_RB16(buf+2) - 2; 00069 buf += 2; 00070 buf_size -= 2; 00071 } 00072 00073 rows = buf[2]; /* number of stored macroblock rows */ 00074 cols = buf[3]; /* number of stored macroblock cols */ 00075 /* buf[4] is number of displayed macroblock rows */ 00076 /* buf[5] is number of displayed macroblock cols */ 00077 00078 if (!s->macroblocks || /* first frame */ 00079 16*cols != s->avctx->coded_width || 00080 16*rows != s->avctx->coded_height) { 00081 avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); 00082 if (s->avctx->extradata_size == 1) { 00083 s->avctx->width -= s->avctx->extradata[0] >> 4; 00084 s->avctx->height -= s->avctx->extradata[0] & 0x0F; 00085 } 00086 res = 2; 00087 } 00088 00089 vp56_init_range_decoder(c, buf+6, buf_size-6); 00090 vp56_rac_gets(c, 2); 00091 00092 parse_filter_info = s->filter_header; 00093 if (sub_version < 8) 00094 vrt_shift = 5; 00095 s->sub_version = sub_version; 00096 } else { 00097 if (!s->sub_version) 00098 return 0; 00099 00100 if (separated_coeff || !s->filter_header) { 00101 coeff_offset = AV_RB16(buf+1) - 2; 00102 buf += 2; 00103 buf_size -= 2; 00104 } 00105 vp56_init_range_decoder(c, buf+1, buf_size-1); 00106 00107 *golden_frame = vp56_rac_get(c); 00108 if (s->filter_header) { 00109 s->deblock_filtering = vp56_rac_get(c); 00110 if (s->deblock_filtering) 00111 vp56_rac_get(c); 00112 if (s->sub_version > 7) 00113 parse_filter_info = vp56_rac_get(c); 00114 } 00115 } 00116 00117 if (parse_filter_info) { 00118 if (vp56_rac_get(c)) { 00119 s->filter_mode = 2; 00120 s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift; 00121 s->max_vector_length = 2 << vp56_rac_gets(c, 3); 00122 } else if (vp56_rac_get(c)) { 00123 s->filter_mode = 1; 00124 } else { 00125 s->filter_mode = 0; 00126 } 00127 if (s->sub_version > 7) 00128 s->filter_selection = vp56_rac_gets(c, 4); 00129 else 00130 s->filter_selection = 16; 00131 } 00132 00133 s->use_huffman = vp56_rac_get(c); 00134 00135 s->parse_coeff = vp6_parse_coeff; 00136 if (coeff_offset) { 00137 buf += coeff_offset; 00138 buf_size -= coeff_offset; 00139 if (buf_size < 0) { 00140 if (s->framep[VP56_FRAME_CURRENT]->key_frame) 00141 avcodec_set_dimensions(s->avctx, 0, 0); 00142 return 0; 00143 } 00144 if (s->use_huffman) { 00145 s->parse_coeff = vp6_parse_coeff_huffman; 00146 init_get_bits(&s->gb, buf, buf_size<<3); 00147 } else { 00148 vp56_init_range_decoder(&s->cc, buf, buf_size); 00149 s->ccp = &s->cc; 00150 } 00151 } else { 00152 s->ccp = &s->c; 00153 } 00154 00155 return res; 00156 } 00157 00158 static void vp6_coeff_order_table_init(VP56Context *s) 00159 { 00160 int i, pos, idx = 1; 00161 00162 s->modelp->coeff_index_to_pos[0] = 0; 00163 for (i=0; i<16; i++) 00164 for (pos=1; pos<64; pos++) 00165 if (s->modelp->coeff_reorder[pos] == i) 00166 s->modelp->coeff_index_to_pos[idx++] = pos; 00167 } 00168 00169 static void vp6_default_models_init(VP56Context *s) 00170 { 00171 VP56Model *model = s->modelp; 00172 00173 model->vector_dct[0] = 0xA2; 00174 model->vector_dct[1] = 0xA4; 00175 model->vector_sig[0] = 0x80; 00176 model->vector_sig[1] = 0x80; 00177 00178 memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); 00179 memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv)); 00180 memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv)); 00181 memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv)); 00182 memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder)); 00183 00184 vp6_coeff_order_table_init(s); 00185 } 00186 00187 static void vp6_parse_vector_models(VP56Context *s) 00188 { 00189 VP56RangeCoder *c = &s->c; 00190 VP56Model *model = s->modelp; 00191 int comp, node; 00192 00193 for (comp=0; comp<2; comp++) { 00194 if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) 00195 model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); 00196 if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) 00197 model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); 00198 } 00199 00200 for (comp=0; comp<2; comp++) 00201 for (node=0; node<7; node++) 00202 if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) 00203 model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); 00204 00205 for (comp=0; comp<2; comp++) 00206 for (node=0; node<8; node++) 00207 if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) 00208 model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7); 00209 } 00210 00211 /* nodes must ascend by count, but with descending symbol order */ 00212 static int vp6_huff_cmp(const void *va, const void *vb) 00213 { 00214 const Node *a = va, *b = vb; 00215 return (a->count - b->count)*16 + (b->sym - a->sym); 00216 } 00217 00218 static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], 00219 const uint8_t *map, unsigned size, VLC *vlc) 00220 { 00221 Node nodes[2*size], *tmp = &nodes[size]; 00222 int a, b, i; 00223 00224 /* first compute probabilities from model */ 00225 tmp[0].count = 256; 00226 for (i=0; i<size-1; i++) { 00227 a = tmp[i].count * coeff_model[i] >> 8; 00228 b = tmp[i].count * (255 - coeff_model[i]) >> 8; 00229 nodes[map[2*i ]].count = a + !a; 00230 nodes[map[2*i+1]].count = b + !b; 00231 } 00232 00233 free_vlc(vlc); 00234 /* then build the huffman tree according to probabilities */ 00235 return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, 00236 FF_HUFFMAN_FLAG_HNODE_FIRST); 00237 } 00238 00239 static int vp6_parse_coeff_models(VP56Context *s) 00240 { 00241 VP56RangeCoder *c = &s->c; 00242 VP56Model *model = s->modelp; 00243 int def_prob[11]; 00244 int node, cg, ctx, pos; 00245 int ct; /* code type */ 00246 int pt; /* plane type (0 for Y, 1 for U or V) */ 00247 00248 memset(def_prob, 0x80, sizeof(def_prob)); 00249 00250 for (pt=0; pt<2; pt++) 00251 for (node=0; node<11; node++) 00252 if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { 00253 def_prob[node] = vp56_rac_gets_nn(c, 7); 00254 model->coeff_dccv[pt][node] = def_prob[node]; 00255 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { 00256 model->coeff_dccv[pt][node] = def_prob[node]; 00257 } 00258 00259 if (vp56_rac_get(c)) { 00260 for (pos=1; pos<64; pos++) 00261 if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) 00262 model->coeff_reorder[pos] = vp56_rac_gets(c, 4); 00263 vp6_coeff_order_table_init(s); 00264 } 00265 00266 for (cg=0; cg<2; cg++) 00267 for (node=0; node<14; node++) 00268 if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) 00269 model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7); 00270 00271 for (ct=0; ct<3; ct++) 00272 for (pt=0; pt<2; pt++) 00273 for (cg=0; cg<6; cg++) 00274 for (node=0; node<11; node++) 00275 if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { 00276 def_prob[node] = vp56_rac_gets_nn(c, 7); 00277 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; 00278 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { 00279 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; 00280 } 00281 00282 if (s->use_huffman) { 00283 for (pt=0; pt<2; pt++) { 00284 if (vp6_build_huff_tree(s, model->coeff_dccv[pt], 00285 vp6_huff_coeff_map, 12, &s->dccv_vlc[pt])) 00286 return -1; 00287 if (vp6_build_huff_tree(s, model->coeff_runv[pt], 00288 vp6_huff_run_map, 9, &s->runv_vlc[pt])) 00289 return -1; 00290 for (ct=0; ct<3; ct++) 00291 for (cg = 0; cg < 6; cg++) 00292 if (vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], 00293 vp6_huff_coeff_map, 12, 00294 &s->ract_vlc[pt][ct][cg])) 00295 return -1; 00296 } 00297 memset(s->nb_null, 0, sizeof(s->nb_null)); 00298 } else { 00299 /* coeff_dcct is a linear combination of coeff_dccv */ 00300 for (pt=0; pt<2; pt++) 00301 for (ctx=0; ctx<3; ctx++) 00302 for (node=0; node<5; node++) 00303 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); 00304 } 00305 return 0; 00306 } 00307 00308 static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect) 00309 { 00310 VP56RangeCoder *c = &s->c; 00311 VP56Model *model = s->modelp; 00312 int comp; 00313 00314 *vect = (VP56mv) {0,0}; 00315 if (s->vector_candidate_pos < 2) 00316 *vect = s->vector_candidate[0]; 00317 00318 for (comp=0; comp<2; comp++) { 00319 int i, delta = 0; 00320 00321 if (vp56_rac_get_prob(c, model->vector_dct[comp])) { 00322 static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; 00323 for (i=0; i<sizeof(prob_order); i++) { 00324 int j = prob_order[i]; 00325 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j; 00326 } 00327 if (delta & 0xF0) 00328 delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3; 00329 else 00330 delta |= 8; 00331 } else { 00332 delta = vp56_rac_get_tree(c, vp56_pva_tree, 00333 model->vector_pdv[comp]); 00334 } 00335 00336 if (delta && vp56_rac_get_prob(c, model->vector_sig[comp])) 00337 delta = -delta; 00338 00339 if (!comp) 00340 vect->x += delta; 00341 else 00342 vect->y += delta; 00343 } 00344 } 00345 00350 static unsigned vp6_get_nb_null(VP56Context *s) 00351 { 00352 unsigned val = get_bits(&s->gb, 2); 00353 if (val == 2) 00354 val += get_bits(&s->gb, 2); 00355 else if (val == 3) { 00356 val = get_bits1(&s->gb) << 2; 00357 val = 6+val + get_bits(&s->gb, 2+val); 00358 } 00359 return val; 00360 } 00361 00362 static void vp6_parse_coeff_huffman(VP56Context *s) 00363 { 00364 VP56Model *model = s->modelp; 00365 uint8_t *permute = s->scantable.permutated; 00366 VLC *vlc_coeff; 00367 int coeff, sign, coeff_idx; 00368 int b, cg, idx; 00369 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ 00370 00371 for (b=0; b<6; b++) { 00372 int ct = 0; /* code type */ 00373 if (b > 3) pt = 1; 00374 vlc_coeff = &s->dccv_vlc[pt]; 00375 00376 for (coeff_idx = 0;;) { 00377 int run = 1; 00378 if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { 00379 s->nb_null[coeff_idx][pt]--; 00380 if (coeff_idx) 00381 break; 00382 } else { 00383 if (get_bits_count(&s->gb) >= s->gb.size_in_bits) 00384 return; 00385 coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); 00386 if (coeff == 0) { 00387 if (coeff_idx) { 00388 int pt = (coeff_idx >= 6); 00389 run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); 00390 if (run >= 9) 00391 run += get_bits(&s->gb, 6); 00392 } else 00393 s->nb_null[0][pt] = vp6_get_nb_null(s); 00394 ct = 0; 00395 } else if (coeff == 11) { /* end of block */ 00396 if (coeff_idx == 1) /* first AC coeff ? */ 00397 s->nb_null[1][pt] = vp6_get_nb_null(s); 00398 break; 00399 } else { 00400 int coeff2 = vp56_coeff_bias[coeff]; 00401 if (coeff > 4) 00402 coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); 00403 ct = 1 + (coeff2 > 1); 00404 sign = get_bits1(&s->gb); 00405 coeff2 = (coeff2 ^ -sign) + sign; 00406 if (coeff_idx) 00407 coeff2 *= s->dequant_ac; 00408 idx = model->coeff_index_to_pos[coeff_idx]; 00409 s->block_coeff[b][permute[idx]] = coeff2; 00410 } 00411 } 00412 coeff_idx+=run; 00413 if (coeff_idx >= 64) 00414 break; 00415 cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); 00416 vlc_coeff = &s->ract_vlc[pt][ct][cg]; 00417 } 00418 } 00419 } 00420 00421 static void vp6_parse_coeff(VP56Context *s) 00422 { 00423 VP56RangeCoder *c = s->ccp; 00424 VP56Model *model = s->modelp; 00425 uint8_t *permute = s->scantable.permutated; 00426 uint8_t *model1, *model2, *model3; 00427 int coeff, sign, coeff_idx; 00428 int b, i, cg, idx, ctx; 00429 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ 00430 00431 for (b=0; b<6; b++) { 00432 int ct = 1; /* code type */ 00433 int run = 1; 00434 00435 if (b > 3) pt = 1; 00436 00437 ctx = s->left_block[vp56_b6to4[b]].not_null_dc 00438 + s->above_blocks[s->above_block_idx[b]].not_null_dc; 00439 model1 = model->coeff_dccv[pt]; 00440 model2 = model->coeff_dcct[pt][ctx]; 00441 00442 coeff_idx = 0; 00443 for (;;) { 00444 if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { 00445 /* parse a coeff */ 00446 if (vp56_rac_get_prob(c, model2[2])) { 00447 if (vp56_rac_get_prob(c, model2[3])) { 00448 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); 00449 coeff = vp56_coeff_bias[idx+5]; 00450 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) 00451 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; 00452 } else { 00453 if (vp56_rac_get_prob(c, model2[4])) 00454 coeff = 3 + vp56_rac_get_prob(c, model1[5]); 00455 else 00456 coeff = 2; 00457 } 00458 ct = 2; 00459 } else { 00460 ct = 1; 00461 coeff = 1; 00462 } 00463 sign = vp56_rac_get(c); 00464 coeff = (coeff ^ -sign) + sign; 00465 if (coeff_idx) 00466 coeff *= s->dequant_ac; 00467 idx = model->coeff_index_to_pos[coeff_idx]; 00468 s->block_coeff[b][permute[idx]] = coeff; 00469 run = 1; 00470 } else { 00471 /* parse a run */ 00472 ct = 0; 00473 if (coeff_idx > 0) { 00474 if (!vp56_rac_get_prob(c, model2[1])) 00475 break; 00476 00477 model3 = model->coeff_runv[coeff_idx >= 6]; 00478 run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); 00479 if (!run) 00480 for (run=9, i=0; i<6; i++) 00481 run += vp56_rac_get_prob(c, model3[i+8]) << i; 00482 } 00483 } 00484 coeff_idx += run; 00485 if (coeff_idx >= 64) 00486 break; 00487 cg = vp6_coeff_groups[coeff_idx]; 00488 model1 = model2 = model->coeff_ract[pt][ct][cg]; 00489 } 00490 00491 s->left_block[vp56_b6to4[b]].not_null_dc = 00492 s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; 00493 } 00494 } 00495 00496 static int vp6_block_variance(uint8_t *src, int stride) 00497 { 00498 int sum = 0, square_sum = 0; 00499 int y, x; 00500 00501 for (y=0; y<8; y+=2) { 00502 for (x=0; x<8; x+=2) { 00503 sum += src[x]; 00504 square_sum += src[x]*src[x]; 00505 } 00506 src += 2*stride; 00507 } 00508 return (16*square_sum - sum*sum) >> 8; 00509 } 00510 00511 static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, 00512 int delta, const int16_t *weights) 00513 { 00514 int x, y; 00515 00516 for (y=0; y<8; y++) { 00517 for (x=0; x<8; x++) { 00518 dst[x] = av_clip_uint8(( src[x-delta ] * weights[0] 00519 + src[x ] * weights[1] 00520 + src[x+delta ] * weights[2] 00521 + src[x+2*delta] * weights[3] + 64) >> 7); 00522 } 00523 src += stride; 00524 dst += stride; 00525 } 00526 } 00527 00528 static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, 00529 int stride, int h_weight, int v_weight) 00530 { 00531 uint8_t *tmp = s->edge_emu_buffer+16; 00532 s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); 00533 s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); 00534 } 00535 00536 static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, 00537 int offset1, int offset2, int stride, 00538 VP56mv mv, int mask, int select, int luma) 00539 { 00540 int filter4 = 0; 00541 int x8 = mv.x & mask; 00542 int y8 = mv.y & mask; 00543 00544 if (luma) { 00545 x8 *= 2; 00546 y8 *= 2; 00547 filter4 = s->filter_mode; 00548 if (filter4 == 2) { 00549 if (s->max_vector_length && 00550 (FFABS(mv.x) > s->max_vector_length || 00551 FFABS(mv.y) > s->max_vector_length)) { 00552 filter4 = 0; 00553 } else if (s->sample_variance_threshold 00554 && (vp6_block_variance(src+offset1, stride) 00555 < s->sample_variance_threshold)) { 00556 filter4 = 0; 00557 } 00558 } 00559 } 00560 00561 if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { 00562 offset1 = offset2; 00563 } 00564 00565 if (filter4) { 00566 if (!y8) { /* left or right combine */ 00567 vp6_filter_hv4(dst, src+offset1, stride, 1, 00568 vp6_block_copy_filter[select][x8]); 00569 } else if (!x8) { /* above or below combine */ 00570 vp6_filter_hv4(dst, src+offset1, stride, stride, 00571 vp6_block_copy_filter[select][y8]); 00572 } else { 00573 s->dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride, 00574 vp6_block_copy_filter[select][x8], 00575 vp6_block_copy_filter[select][y8]); 00576 } 00577 } else { 00578 if (!x8 || !y8) { 00579 s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); 00580 } else { 00581 vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); 00582 } 00583 } 00584 } 00585 00586 static av_cold int vp6_decode_init(AVCodecContext *avctx) 00587 { 00588 VP56Context *s = avctx->priv_data; 00589 00590 vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6, 00591 avctx->codec->id == CODEC_ID_VP6A); 00592 s->vp56_coord_div = vp6_coord_div; 00593 s->parse_vector_adjustment = vp6_parse_vector_adjustment; 00594 s->filter = vp6_filter; 00595 s->default_models_init = vp6_default_models_init; 00596 s->parse_vector_models = vp6_parse_vector_models; 00597 s->parse_coeff_models = vp6_parse_coeff_models; 00598 s->parse_header = vp6_parse_header; 00599 00600 return 0; 00601 } 00602 00603 static av_cold int vp6_decode_free(AVCodecContext *avctx) 00604 { 00605 VP56Context *s = avctx->priv_data; 00606 int pt, ct, cg; 00607 00608 vp56_free(avctx); 00609 00610 for (pt=0; pt<2; pt++) { 00611 free_vlc(&s->dccv_vlc[pt]); 00612 free_vlc(&s->runv_vlc[pt]); 00613 for (ct=0; ct<3; ct++) 00614 for (cg=0; cg<6; cg++) 00615 free_vlc(&s->ract_vlc[pt][ct][cg]); 00616 } 00617 return 0; 00618 } 00619 00620 AVCodec vp6_decoder = { 00621 "vp6", 00622 AVMEDIA_TYPE_VIDEO, 00623 CODEC_ID_VP6, 00624 sizeof(VP56Context), 00625 vp6_decode_init, 00626 NULL, 00627 vp6_decode_free, 00628 vp56_decode_frame, 00629 CODEC_CAP_DR1, 00630 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), 00631 }; 00632 00633 /* flash version, not flipped upside-down */ 00634 AVCodec vp6f_decoder = { 00635 "vp6f", 00636 AVMEDIA_TYPE_VIDEO, 00637 CODEC_ID_VP6F, 00638 sizeof(VP56Context), 00639 vp6_decode_init, 00640 NULL, 00641 vp6_decode_free, 00642 vp56_decode_frame, 00643 CODEC_CAP_DR1, 00644 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), 00645 }; 00646 00647 /* flash version, not flipped upside-down, with alpha channel */ 00648 AVCodec vp6a_decoder = { 00649 "vp6a", 00650 AVMEDIA_TYPE_VIDEO, 00651 CODEC_ID_VP6A, 00652 sizeof(VP56Context), 00653 vp6_decode_init, 00654 NULL, 00655 vp6_decode_free, 00656 vp56_decode_frame, 00657 CODEC_CAP_DR1, 00658 .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), 00659 };