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