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