Originally committed as revision 6213 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -56,6 +56,8 @@ version <next> | |||
| - MacIntel support | |||
| - AVISynth support | |||
| - VMware video decoder | |||
| - VP5 video decoder | |||
| - VP6 video decoder | |||
| version 0.4.9-pre1: | |||
| @@ -164,6 +164,8 @@ Codecs: | |||
| vcr1.c Michael Niedermayer | |||
| vmnc.c Kostya Shishkov | |||
| vp3* Mike Melanson | |||
| vp5 Aurelien Jacobs | |||
| vp6 Aurelien Jacobs | |||
| vqavideo.c Mike Melanson | |||
| wmv2.c Michael Niedermayer | |||
| wnv1.c Kostya Shishkov | |||
| @@ -778,6 +778,8 @@ following image formats are supported: | |||
| @item Sorenson Video 1 @tab X @tab X @tab fourcc: SVQ1 | |||
| @item Sorenson Video 3 @tab @tab X @tab fourcc: SVQ3 | |||
| @item On2 VP3 @tab @tab X @tab still experimental | |||
| @item On2 VP5 @tab @tab X @tab fourcc: VP50 | |||
| @item On2 VP6 @tab @tab X @tab fourcc: VP62 | |||
| @item Theora @tab @tab X @tab still experimental | |||
| @item Intel Indeo 3 @tab @tab X | |||
| @item FLV @tab X @tab X @tab Sorenson H.263 used in Flash | |||
| @@ -123,6 +123,8 @@ OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdav.o | |||
| OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o | |||
| OBJS-$(CONFIG_VORBIS_DECODER) += vorbis.o | |||
| OBJS-$(CONFIG_VP3_DECODER) += vp3.o | |||
| OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o | |||
| OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o | |||
| OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o | |||
| OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o | |||
| OBJS-$(CONFIG_WMAV2_DECODER) += wmadec.o | |||
| @@ -371,6 +371,15 @@ void avcodec_register_all(void) | |||
| #ifdef CONFIG_THEORA_DECODER | |||
| register_avcodec(&theora_decoder); | |||
| #endif //CONFIG_THEORA_DECODER | |||
| #ifdef CONFIG_VP5_DECODER | |||
| register_avcodec(&vp5_decoder); | |||
| #endif //CONFIG_VP5_DECODER | |||
| #ifdef CONFIG_VP6_DECODER | |||
| register_avcodec(&vp6_decoder); | |||
| #endif //CONFIG_VP6_DECODER | |||
| #ifdef CONFIG_VP6F_DECODER | |||
| register_avcodec(&vp6f_decoder); | |||
| #endif //CONFIG_VP6F_DECODER | |||
| #ifdef CONFIG_ASV1_DECODER | |||
| register_avcodec(&asv1_decoder); | |||
| #endif //CONFIG_ASV1_DECODER | |||
| @@ -17,8 +17,8 @@ extern "C" { | |||
| #define AV_STRINGIFY(s) AV_TOSTRING(s) | |||
| #define AV_TOSTRING(s) #s | |||
| #define LIBAVCODEC_VERSION_INT ((51<<16)+(13<<8)+0) | |||
| #define LIBAVCODEC_VERSION 51.13.0 | |||
| #define LIBAVCODEC_VERSION_INT ((51<<16)+(14<<8)+0) | |||
| #define LIBAVCODEC_VERSION 51.14.0 | |||
| #define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT | |||
| #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) | |||
| @@ -121,6 +121,9 @@ enum CodecID { | |||
| CODEC_ID_CAVS, | |||
| CODEC_ID_JPEG2000, | |||
| CODEC_ID_VMNC, | |||
| CODEC_ID_VP5, | |||
| CODEC_ID_VP6, | |||
| CODEC_ID_VP6F, | |||
| /* various pcm "codecs" */ | |||
| CODEC_ID_PCM_S16LE= 0x10000, | |||
| @@ -2192,6 +2195,9 @@ extern AVCodec h264_decoder; | |||
| extern AVCodec indeo3_decoder; | |||
| extern AVCodec vp3_decoder; | |||
| extern AVCodec theora_decoder; | |||
| extern AVCodec vp5_decoder; | |||
| extern AVCodec vp6_decoder; | |||
| extern AVCodec vp6f_decoder; | |||
| extern AVCodec amr_nb_decoder; | |||
| extern AVCodec amr_nb_encoder; | |||
| extern AVCodec amr_wb_encoder; | |||
| @@ -0,0 +1,289 @@ | |||
| /** | |||
| * @file vp5.c | |||
| * VP5 compatible video decoder | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <inttypes.h> | |||
| #include "avcodec.h" | |||
| #include "dsputil.h" | |||
| #include "bitstream.h" | |||
| #include "mpegvideo.h" | |||
| #include "vp56.h" | |||
| #include "vp56data.h" | |||
| #include "vp5data.h" | |||
| static int vp5_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, | |||
| int *golden_frame) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int rows, cols; | |||
| vp56_init_range_decoder(&s->c, buf, buf_size); | |||
| s->frames[VP56_FRAME_CURRENT].key_frame = !vp56_rac_get(c); | |||
| vp56_rac_get(c); | |||
| vp56_init_dequant(s, vp56_rac_gets(c, 6)); | |||
| if (s->frames[VP56_FRAME_CURRENT].key_frame) | |||
| { | |||
| vp56_rac_gets(c, 8); | |||
| if(vp56_rac_gets(c, 5) > 5) | |||
| return 0; | |||
| vp56_rac_gets(c, 2); | |||
| if (vp56_rac_get(c)) { | |||
| av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); | |||
| return 0; | |||
| } | |||
| rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ | |||
| cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ | |||
| vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ | |||
| vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ | |||
| vp56_rac_gets(c, 2); | |||
| if (16*cols != s->avctx->coded_width || | |||
| 16*rows != s->avctx->coded_height) { | |||
| avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); | |||
| return 2; | |||
| } | |||
| } | |||
| return 1; | |||
| } | |||
| /* Gives very similar result than the vp6 version except in a few cases */ | |||
| static int vp5_adjust(int v, int t) | |||
| { | |||
| int s2, s1 = v >> 31; | |||
| v ^= s1; | |||
| v -= s1; | |||
| v *= v < 2*t; | |||
| v -= t; | |||
| s2 = v >> 31; | |||
| v ^= s2; | |||
| v -= s2; | |||
| v = t - v; | |||
| v += s1; | |||
| v ^= s1; | |||
| return v; | |||
| } | |||
| static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vector) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int comp, di; | |||
| for (comp=0; comp<2; comp++) { | |||
| int delta = 0; | |||
| if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) { | |||
| int sign = vp56_rac_get_prob(c, s->vector_model_sig[comp]); | |||
| di = vp56_rac_get_prob(c, s->vector_model_pdi[comp][0]); | |||
| di |= vp56_rac_get_prob(c, s->vector_model_pdi[comp][1]) << 1; | |||
| delta = vp56_rac_get_tree(c, vp56_pva_tree, | |||
| s->vector_model_pdv[comp]); | |||
| delta = di | (delta << 2); | |||
| delta = (delta ^ -sign) + sign; | |||
| } | |||
| if (!comp) | |||
| vector->x = delta; | |||
| else | |||
| vector->y = delta; | |||
| } | |||
| } | |||
| static void vp5_parse_vector_models(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int comp, node; | |||
| for (comp=0; comp<2; comp++) { | |||
| if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0])) | |||
| s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7); | |||
| if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1])) | |||
| s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7); | |||
| if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2])) | |||
| s->vector_model_pdi[comp][0] = vp56_rac_gets_nn(c, 7); | |||
| if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3])) | |||
| s->vector_model_pdi[comp][1] = vp56_rac_gets_nn(c, 7); | |||
| } | |||
| for (comp=0; comp<2; comp++) | |||
| for (node=0; node<7; node++) | |||
| if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node])) | |||
| s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7); | |||
| } | |||
| static void vp5_parse_coeff_models(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| uint8_t def_prob[11]; | |||
| int node, cg, ctx; | |||
| int ct; /* code type */ | |||
| int pt; /* plane type (0 for Y, 1 for U or V) */ | |||
| memset(def_prob, 0x80, sizeof(def_prob)); | |||
| for (pt=0; pt<2; pt++) | |||
| for (node=0; node<11; node++) | |||
| if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { | |||
| def_prob[node] = vp56_rac_gets_nn(c, 7); | |||
| s->coeff_model_dccv[pt][node] = def_prob[node]; | |||
| } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { | |||
| s->coeff_model_dccv[pt][node] = def_prob[node]; | |||
| } | |||
| for (ct=0; ct<3; ct++) | |||
| for (pt=0; pt<2; pt++) | |||
| for (cg=0; cg<6; cg++) | |||
| for (node=0; node<11; node++) | |||
| if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { | |||
| def_prob[node] = vp56_rac_gets_nn(c, 7); | |||
| s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; | |||
| } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { | |||
| s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; | |||
| } | |||
| /* coeff_model_dcct is a linear combination of coeff_model_dccv */ | |||
| for (pt=0; pt<2; pt++) | |||
| for (ctx=0; ctx<36; ctx++) | |||
| for (node=0; node<5; node++) | |||
| s->coeff_model_dcct[pt][ctx][node] = clip(((s->coeff_model_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254); | |||
| /* coeff_model_acct is a linear combination of coeff_model_ract */ | |||
| for (ct=0; ct<3; ct++) | |||
| for (pt=0; pt<2; pt++) | |||
| for (cg=0; cg<3; cg++) | |||
| for (ctx=0; ctx<6; ctx++) | |||
| for (node=0; node<5; node++) | |||
| s->coeff_model_acct[pt][ct][cg][ctx][node] = clip(((s->coeff_model_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); | |||
| } | |||
| static void vp5_parse_coeff(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| uint8_t *permute = s->scantable.permutated; | |||
| uint8_t *model, *model2; | |||
| int coeff, sign, coeff_idx; | |||
| int b, i, cg, idx, ctx, ctx_last; | |||
| int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |||
| for (b=0; b<6; b++) { | |||
| int ct = 1; /* code type */ | |||
| if (b > 3) pt = 1; | |||
| ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0] | |||
| + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |||
| model = s->coeff_model_dccv[pt]; | |||
| model2 = s->coeff_model_dcct[pt][ctx]; | |||
| for (coeff_idx=0; coeff_idx<64; ) { | |||
| if (vp56_rac_get_prob(c, model2[0])) { | |||
| if (vp56_rac_get_prob(c, model2[2])) { | |||
| if (vp56_rac_get_prob(c, model2[3])) { | |||
| s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4; | |||
| idx = vp56_rac_get_tree(c, vp56_pc_tree, model); | |||
| sign = vp56_rac_get(c); | |||
| coeff = vp56_coeff_bias[idx]; | |||
| for (i=vp56_coeff_bit_length[idx]; i>=0; i--) | |||
| coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |||
| } else { | |||
| if (vp56_rac_get_prob(c, model2[4])) { | |||
| coeff = 3 + vp56_rac_get_prob(c, model[5]); | |||
| s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3; | |||
| } else { | |||
| coeff = 2; | |||
| s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2; | |||
| } | |||
| sign = vp56_rac_get(c); | |||
| } | |||
| ct = 2; | |||
| } else { | |||
| ct = 1; | |||
| s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1; | |||
| sign = vp56_rac_get(c); | |||
| coeff = 1; | |||
| } | |||
| coeff = (coeff ^ -sign) + sign; | |||
| if (coeff_idx) | |||
| coeff *= s->dequant_ac; | |||
| s->block_coeff[b][permute[coeff_idx]] = coeff; | |||
| } else { | |||
| if (ct && !vp56_rac_get_prob(c, model2[1])) | |||
| break; | |||
| ct = 0; | |||
| s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0; | |||
| } | |||
| cg = vp5_coeff_groups[++coeff_idx]; | |||
| ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; | |||
| model = s->coeff_model_ract[pt][ct][cg]; | |||
| model2 = cg > 2 ? model : s->coeff_model_acct[pt][ct][cg][ctx]; | |||
| } | |||
| ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24); | |||
| s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx; | |||
| if (coeff_idx < ctx_last) | |||
| for (i=coeff_idx; i<=ctx_last; i++) | |||
| s->coeff_ctx[vp56_b6to4[b]][i] = 5; | |||
| s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0]; | |||
| } | |||
| } | |||
| static void vp5_default_models_init(vp56_context_t *s) | |||
| { | |||
| int i; | |||
| for (i=0; i<2; i++) { | |||
| s->vector_model_sig[i] = 0x80; | |||
| s->vector_model_dct[i] = 0x80; | |||
| s->vector_model_pdi[i][0] = 0x55; | |||
| s->vector_model_pdi[i][1] = 0x80; | |||
| } | |||
| memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats)); | |||
| memset(s->vector_model_pdv, 0x80, sizeof(s->vector_model_pdv)); | |||
| } | |||
| static int vp5_decode_init(AVCodecContext *avctx) | |||
| { | |||
| vp56_context_t *s = avctx->priv_data; | |||
| vp56_init(s, avctx, 1); | |||
| s->vp56_coord_div = vp5_coord_div; | |||
| s->parse_vector_adjustment = vp5_parse_vector_adjustment; | |||
| s->adjust = vp5_adjust; | |||
| s->parse_coeff = vp5_parse_coeff; | |||
| s->default_models_init = vp5_default_models_init; | |||
| s->parse_vector_models = vp5_parse_vector_models; | |||
| s->parse_coeff_models = vp5_parse_coeff_models; | |||
| s->parse_header = vp5_parse_header; | |||
| return 0; | |||
| } | |||
| AVCodec vp5_decoder = { | |||
| "vp5", | |||
| CODEC_TYPE_VIDEO, | |||
| CODEC_ID_VP5, | |||
| sizeof(vp56_context_t), | |||
| vp5_decode_init, | |||
| NULL, | |||
| vp56_free, | |||
| vp56_decode_frame, | |||
| }; | |||
| @@ -0,0 +1,662 @@ | |||
| /** | |||
| * @file vp56.c | |||
| * VP5 and VP6 compatible video decoder (common features) | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "avcodec.h" | |||
| #include "vp56.h" | |||
| #include "vp56data.h" | |||
| void vp56_init_dequant(vp56_context_t *s, int quantizer) | |||
| { | |||
| s->quantizer = quantizer; | |||
| s->dequant_dc = vp56_dc_dequant[quantizer] << 2; | |||
| s->dequant_ac = vp56_ac_dequant[quantizer] << 2; | |||
| } | |||
| static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col, | |||
| vp56_frame_t ref_frame) | |||
| { | |||
| int nb_pred = 0; | |||
| vp56_mv_t vector[2] = {{0,0}, {0,0}}; | |||
| int pos, offset; | |||
| vp56_mv_t mvp; | |||
| for (pos=0; pos<12; pos++) { | |||
| mvp.x = col + vp56_candidate_predictor_pos[pos][0]; | |||
| mvp.y = row + vp56_candidate_predictor_pos[pos][1]; | |||
| if (mvp.x < 0 || mvp.x >= s->mb_width || | |||
| mvp.y < 0 || mvp.y >= s->mb_height) | |||
| continue; | |||
| offset = mvp.x + s->mb_width*mvp.y; | |||
| if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame) | |||
| continue; | |||
| if ((s->macroblocks[offset].mv.x == vector[0].x && | |||
| s->macroblocks[offset].mv.y == vector[0].y) || | |||
| (s->macroblocks[offset].mv.x == 0 && | |||
| s->macroblocks[offset].mv.y == 0)) | |||
| continue; | |||
| vector[nb_pred++] = s->macroblocks[offset].mv; | |||
| if (nb_pred > 1) { | |||
| nb_pred = -1; | |||
| break; | |||
| } | |||
| s->vector_candidate_pos = pos; | |||
| } | |||
| s->vector_candidate[0] = vector[0]; | |||
| s->vector_candidate[1] = vector[1]; | |||
| return nb_pred+1; | |||
| } | |||
| static void vp56_parse_mb_type_models(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int i, ctx, type; | |||
| for (ctx=0; ctx<3; ctx++) { | |||
| if (vp56_rac_get_prob(c, 174)) { | |||
| int idx = vp56_rac_gets(c, 4); | |||
| memcpy(s->mb_types_stats[ctx],vp56_pre_def_mb_type_stats[idx][ctx], | |||
| sizeof(s->mb_types_stats[ctx])); | |||
| } | |||
| if (vp56_rac_get_prob(c, 254)) { | |||
| for (type=0; type<10; type++) { | |||
| for(i=0; i<2; i++) { | |||
| if (vp56_rac_get_prob(c, 205)) { | |||
| int delta, sign = vp56_rac_get(c); | |||
| delta = vp56_rac_get_tree(c, vp56_pmbtm_tree, | |||
| vp56_mb_type_model_model); | |||
| if (!delta) | |||
| delta = 4 * vp56_rac_gets(c, 7); | |||
| s->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /* compute MB type probability tables based on previous MB type */ | |||
| for (ctx=0; ctx<3; ctx++) { | |||
| int p[10]; | |||
| for (type=0; type<10; type++) | |||
| p[type] = 100 * s->mb_types_stats[ctx][type][1]; | |||
| for (type=0; type<10; type++) { | |||
| int p02, p34, p0234, p17, p56, p89, p5689, p156789; | |||
| /* conservative MB type probability */ | |||
| s->mb_type_model[ctx][type][0] = 255 - (255 * s->mb_types_stats[ctx][type][0]) / (1 + s->mb_types_stats[ctx][type][0] + s->mb_types_stats[ctx][type][1]); | |||
| p[type] = 0; /* same MB type => weight is null */ | |||
| /* binary tree parsing probabilities */ | |||
| p02 = p[0] + p[2]; | |||
| p34 = p[3] + p[4]; | |||
| p0234 = p02 + p34; | |||
| p17 = p[1] + p[7]; | |||
| p56 = p[5] + p[6]; | |||
| p89 = p[8] + p[9]; | |||
| p5689 = p56 + p89; | |||
| p156789 = p17 + p5689; | |||
| s->mb_type_model[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789); | |||
| s->mb_type_model[ctx][type][2] = 1 + 255 * p02 / (1+p0234); | |||
| s->mb_type_model[ctx][type][3] = 1 + 255 * p17 / (1+p156789); | |||
| s->mb_type_model[ctx][type][4] = 1 + 255 * p[0] / (1+p02); | |||
| s->mb_type_model[ctx][type][5] = 1 + 255 * p[3] / (1+p34); | |||
| s->mb_type_model[ctx][type][6] = 1 + 255 * p[1] / (1+p17); | |||
| s->mb_type_model[ctx][type][7] = 1 + 255 * p56 / (1+p5689); | |||
| s->mb_type_model[ctx][type][8] = 1 + 255 * p[5] / (1+p56); | |||
| s->mb_type_model[ctx][type][9] = 1 + 255 * p[8] / (1+p89); | |||
| /* restore initial value */ | |||
| p[type] = 100 * s->mb_types_stats[ctx][type][1]; | |||
| } | |||
| } | |||
| } | |||
| static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s, | |||
| vp56_mb_t prev_type, int ctx) | |||
| { | |||
| uint8_t *mb_type_model = s->mb_type_model[ctx][prev_type]; | |||
| vp56_range_coder_t *c = &s->c; | |||
| if (vp56_rac_get_prob(c, mb_type_model[0])) | |||
| return prev_type; | |||
| else | |||
| return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model); | |||
| } | |||
| static void vp56_decode_4mv(vp56_context_t *s, int row, int col) | |||
| { | |||
| vp56_mv_t mv = {0,0}; | |||
| int type[4]; | |||
| int b; | |||
| /* parse each block type */ | |||
| for (b=0; b<4; b++) { | |||
| type[b] = vp56_rac_gets(&s->c, 2); | |||
| if (type[b]) | |||
| type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */ | |||
| } | |||
| /* get vectors */ | |||
| for (b=0; b<4; b++) { | |||
| switch (type[b]) { | |||
| case VP56_MB_INTER_NOVEC_PF: | |||
| s->mv[b] = (vp56_mv_t) {0,0}; | |||
| break; | |||
| case VP56_MB_INTER_DELTA_PF: | |||
| s->parse_vector_adjustment(s, &s->mv[b]); | |||
| break; | |||
| case VP56_MB_INTER_V1_PF: | |||
| s->mv[b] = s->vector_candidate[0]; | |||
| break; | |||
| case VP56_MB_INTER_V2_PF: | |||
| s->mv[b] = s->vector_candidate[1]; | |||
| break; | |||
| } | |||
| mv.x += s->mv[b].x; | |||
| mv.y += s->mv[b].y; | |||
| } | |||
| /* this is the one selected for the whole MB for prediction */ | |||
| s->macroblocks[row * s->mb_width + col].mv = s->mv[3]; | |||
| /* chroma vectors are average luma vectors */ | |||
| if (s->avctx->codec->id == CODEC_ID_VP5) { | |||
| s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2); | |||
| s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2); | |||
| } else { | |||
| s->mv[4] = s->mv[5] = (vp56_mv_t) {mv.x/4, mv.y/4}; | |||
| } | |||
| } | |||
| static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col) | |||
| { | |||
| vp56_mv_t *mv, vector = {0,0}; | |||
| int ctx, b; | |||
| ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS); | |||
| s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx); | |||
| s->macroblocks[row * s->mb_width + col].type = s->mb_type; | |||
| switch (s->mb_type) { | |||
| case VP56_MB_INTER_V1_PF: | |||
| mv = &s->vector_candidate[0]; | |||
| break; | |||
| case VP56_MB_INTER_V2_PF: | |||
| mv = &s->vector_candidate[1]; | |||
| break; | |||
| case VP56_MB_INTER_V1_GF: | |||
| vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); | |||
| mv = &s->vector_candidate[0]; | |||
| break; | |||
| case VP56_MB_INTER_V2_GF: | |||
| vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); | |||
| mv = &s->vector_candidate[1]; | |||
| break; | |||
| case VP56_MB_INTER_DELTA_PF: | |||
| s->parse_vector_adjustment(s, &vector); | |||
| mv = &vector; | |||
| break; | |||
| case VP56_MB_INTER_DELTA_GF: | |||
| vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); | |||
| s->parse_vector_adjustment(s, &vector); | |||
| mv = &vector; | |||
| break; | |||
| case VP56_MB_INTER_4V: | |||
| vp56_decode_4mv(s, row, col); | |||
| return s->mb_type; | |||
| default: | |||
| mv = &vector; | |||
| break; | |||
| } | |||
| s->macroblocks[row*s->mb_width + col].mv = *mv; | |||
| /* same vector for all blocks */ | |||
| for (b=0; b<6; b++) | |||
| s->mv[b] = *mv; | |||
| return s->mb_type; | |||
| } | |||
| static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame) | |||
| { | |||
| int idx = s->scantable.permutated[0]; | |||
| int i; | |||
| for (i=0; i<6; i++) { | |||
| vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[i]]; | |||
| vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[i]]; | |||
| int count = 0; | |||
| int dc = 0; | |||
| if (ref_frame == lb->ref_frame) { | |||
| dc += lb->dc_coeff; | |||
| count++; | |||
| } | |||
| if (ref_frame == ab->ref_frame) { | |||
| dc += ab->dc_coeff; | |||
| count++; | |||
| } | |||
| if (s->avctx->codec->id == CODEC_ID_VP5) { | |||
| if (count < 2 && ref_frame == ab[-1].ref_frame) { | |||
| dc += ab[-1].dc_coeff; | |||
| count++; | |||
| } | |||
| if (count < 2 && ref_frame == ab[1].ref_frame) { | |||
| dc += ab[1].dc_coeff; | |||
| count++; | |||
| } | |||
| } | |||
| if (count == 0) | |||
| dc = s->prev_dc[vp56_b6to3[i]][ref_frame]; | |||
| else if (count == 2) | |||
| dc /= 2; | |||
| s->block_coeff[i][idx] += dc; | |||
| s->prev_dc[vp56_b6to3[i]][ref_frame] = s->block_coeff[i][idx]; | |||
| ab->dc_coeff = s->block_coeff[i][idx]; | |||
| ab->ref_frame = ref_frame; | |||
| lb->dc_coeff = s->block_coeff[i][idx]; | |||
| lb->ref_frame = ref_frame; | |||
| s->block_coeff[i][idx] *= s->dequant_dc; | |||
| } | |||
| } | |||
| static void vp56_edge_filter(vp56_context_t *s, uint8_t *yuv, | |||
| int pix_inc, int line_inc, int t) | |||
| { | |||
| int pix2_inc = 2 * pix_inc; | |||
| int i, v; | |||
| for (i=0; i<12; i++) { | |||
| v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4) >>3; | |||
| v = s->adjust(v, t); | |||
| yuv[-pix_inc] = clip_uint8(yuv[-pix_inc] + v); | |||
| yuv[0] = clip_uint8(yuv[0] - v); | |||
| yuv += line_inc; | |||
| } | |||
| } | |||
| static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv, | |||
| int stride, int dx, int dy) | |||
| { | |||
| int t = vp56_filter_threshold[s->quantizer]; | |||
| if (dx) vp56_edge_filter(s, yuv + 10-dx , 1, stride, t); | |||
| if (dy) vp56_edge_filter(s, yuv + stride*(10-dy), stride, 1, t); | |||
| } | |||
| static void vp56_mc(vp56_context_t *s, int b, uint8_t *src, | |||
| int stride, int x, int y) | |||
| { | |||
| int plane = vp56_b6to3[b]; | |||
| uint8_t *dst= s->frames[VP56_FRAME_CURRENT].data[plane]+s->block_offset[b]; | |||
| uint8_t *src_block; | |||
| int src_offset; | |||
| int overlap_offset = 0; | |||
| int mask = s->vp56_coord_div[b] - 1; | |||
| int deblock_filtering = s->deblock_filtering; | |||
| int dx; | |||
| int dy; | |||
| if (s->avctx->skip_loop_filter >= AVDISCARD_ALL || | |||
| (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY | |||
| && !s->frames[VP56_FRAME_CURRENT].key_frame)) | |||
| deblock_filtering = 0; | |||
| dx = s->mv[b].x / s->vp56_coord_div[b]; | |||
| dy = s->mv[b].y / s->vp56_coord_div[b]; | |||
| if (b >= 4) { | |||
| x /= 2; | |||
| y /= 2; | |||
| } | |||
| x += dx - 2; | |||
| y += dy - 2; | |||
| if (x<0 || x+12>=s->plane_width[plane] || | |||
| y<0 || y+12>=s->plane_height[plane]) { | |||
| ff_emulated_edge_mc(s->edge_emu_buffer, | |||
| src + s->block_offset[b] + (dy-2)*stride + (dx-2), | |||
| stride, 12, 12, x, y, | |||
| s->plane_width[plane], | |||
| s->plane_height[plane]); | |||
| src_block = s->edge_emu_buffer; | |||
| src_offset = 2 + 2*stride; | |||
| } else if (deblock_filtering) { | |||
| /* only need a 12x12 block, but there is no such dsp function, */ | |||
| /* so copy a 16x12 block */ | |||
| s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer, | |||
| src + s->block_offset[b] + (dy-2)*stride + (dx-2), | |||
| stride, 12); | |||
| src_block = s->edge_emu_buffer; | |||
| src_offset = 2 + 2*stride; | |||
| } else { | |||
| src_block = src; | |||
| src_offset = s->block_offset[b] + dy*stride + dx; | |||
| } | |||
| if (deblock_filtering) | |||
| vp56_deblock_filter(s, src_block, stride, dx&7, dy&7); | |||
| if (s->mv[b].x & mask) | |||
| overlap_offset += (s->mv[b].x > 0) ? 1 : -1; | |||
| if (s->mv[b].y & mask) | |||
| overlap_offset += (s->mv[b].y > 0) ? stride : -stride; | |||
| if (overlap_offset) { | |||
| if (s->filter) | |||
| s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset, | |||
| stride, s->mv[b], mask, s->filter_selection, b<4); | |||
| else | |||
| s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset, | |||
| src_block+src_offset+overlap_offset, | |||
| stride, 8); | |||
| } else { | |||
| s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8); | |||
| } | |||
| } | |||
| static void vp56_decode_mb(vp56_context_t *s, int row, int col) | |||
| { | |||
| AVFrame *frame_current, *frame_ref; | |||
| vp56_mb_t mb_type; | |||
| vp56_frame_t ref_frame; | |||
| int b, plan, off; | |||
| if (s->frames[VP56_FRAME_CURRENT].key_frame) | |||
| mb_type = VP56_MB_INTRA; | |||
| else | |||
| mb_type = vp56_decode_mv(s, row, col); | |||
| ref_frame = vp56_reference_frame[mb_type]; | |||
| memset(s->block_coeff, 0, sizeof(s->block_coeff)); | |||
| s->parse_coeff(s); | |||
| vp56_add_predictors_dc(s, ref_frame); | |||
| frame_current = &s->frames[VP56_FRAME_CURRENT]; | |||
| frame_ref = &s->frames[ref_frame]; | |||
| switch (mb_type) { | |||
| case VP56_MB_INTRA: | |||
| for (b=0; b<6; b++) { | |||
| plan = vp56_b6to3[b]; | |||
| s->dsp.idct_put(frame_current->data[plan] + s->block_offset[b], | |||
| s->stride[plan], s->block_coeff[b]); | |||
| } | |||
| break; | |||
| case VP56_MB_INTER_NOVEC_PF: | |||
| case VP56_MB_INTER_NOVEC_GF: | |||
| for (b=0; b<6; b++) { | |||
| plan = vp56_b6to3[b]; | |||
| off = s->block_offset[b]; | |||
| s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off, | |||
| frame_ref->data[plan] + off, | |||
| s->stride[plan], 8); | |||
| s->dsp.idct_add(frame_current->data[plan] + off, | |||
| s->stride[plan], s->block_coeff[b]); | |||
| } | |||
| break; | |||
| case VP56_MB_INTER_DELTA_PF: | |||
| case VP56_MB_INTER_V1_PF: | |||
| case VP56_MB_INTER_V2_PF: | |||
| case VP56_MB_INTER_DELTA_GF: | |||
| case VP56_MB_INTER_4V: | |||
| case VP56_MB_INTER_V1_GF: | |||
| case VP56_MB_INTER_V2_GF: | |||
| for (b=0; b<6; b++) { | |||
| int x_off = b==1 || b==3 ? 8 : 0; | |||
| int y_off = b==2 || b==3 ? 8 : 0; | |||
| plan = vp56_b6to3[b]; | |||
| vp56_mc(s, b, frame_ref->data[plan], s->stride[plan], | |||
| 16*col+x_off, 16*row+y_off); | |||
| s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b], | |||
| s->stride[plan], s->block_coeff[b]); | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| static int vp56_size_changed(AVCodecContext *avctx, vp56_context_t *s) | |||
| { | |||
| int stride = s->frames[VP56_FRAME_CURRENT].linesize[0]; | |||
| int i; | |||
| s->plane_width[0] = s->avctx->width; | |||
| s->plane_width[1] = s->plane_width[2] = s->avctx->width/2; | |||
| s->plane_height[0] = s->avctx->height; | |||
| s->plane_height[1] = s->plane_height[2] = s->avctx->height/2; | |||
| for (i=0; i<3; i++) | |||
| s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT].linesize[i]; | |||
| s->mb_width = (s->avctx->width+15) / 16; | |||
| s->mb_height = (s->avctx->height+15) / 16; | |||
| if (s->mb_width > 1000 || s->mb_height > 1000) { | |||
| av_log(avctx, AV_LOG_ERROR, "picture too big\n"); | |||
| return -1; | |||
| } | |||
| s->above_blocks = av_realloc(s->above_blocks, | |||
| (4*s->mb_width+6) * sizeof(*s->above_blocks)); | |||
| s->macroblocks = av_realloc(s->macroblocks, | |||
| s->mb_width*s->mb_height*sizeof(*s->macroblocks)); | |||
| s->edge_emu_buffer_alloc = av_realloc(s->edge_emu_buffer_alloc, 16*stride); | |||
| s->edge_emu_buffer = s->edge_emu_buffer_alloc; | |||
| if (s->flip < 0) | |||
| s->edge_emu_buffer += 15 * stride; | |||
| return 0; | |||
| } | |||
| int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |||
| uint8_t *buf, int buf_size) | |||
| { | |||
| vp56_context_t *s = avctx->priv_data; | |||
| AVFrame *const p = &s->frames[VP56_FRAME_CURRENT]; | |||
| AVFrame *picture = data; | |||
| int mb_row, mb_col, mb_row_flip, mb_offset = 0; | |||
| int block, y, uv, stride_y, stride_uv; | |||
| int golden_frame = 0; | |||
| int res; | |||
| res = s->parse_header(s, buf, buf_size, &golden_frame); | |||
| if (!res) | |||
| return -1; | |||
| p->reference = 1; | |||
| if (avctx->get_buffer(avctx, p) < 0) { | |||
| av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |||
| return -1; | |||
| } | |||
| if (res == 2) | |||
| if (vp56_size_changed(avctx, s)) { | |||
| avctx->release_buffer(avctx, p); | |||
| return -1; | |||
| } | |||
| if (p->key_frame) { | |||
| p->pict_type = FF_I_TYPE; | |||
| s->default_models_init(s); | |||
| for (block=0; block<s->mb_height*s->mb_width; block++) | |||
| s->macroblocks[block].type = VP56_MB_INTRA; | |||
| } else { | |||
| p->pict_type = FF_P_TYPE; | |||
| vp56_parse_mb_type_models(s); | |||
| s->parse_vector_models(s); | |||
| s->mb_type = VP56_MB_INTER_NOVEC_PF; | |||
| } | |||
| s->parse_coeff_models(s); | |||
| memset(s->prev_dc, 0, sizeof(s->prev_dc)); | |||
| s->prev_dc[1][VP56_FRAME_CURRENT] = 128; | |||
| s->prev_dc[2][VP56_FRAME_CURRENT] = 128; | |||
| for (block=0; block < 4*s->mb_width+6; block++) { | |||
| s->above_blocks[block].ref_frame = -1; | |||
| s->above_blocks[block].dc_coeff = 0; | |||
| s->above_blocks[block].not_null_dc = 0; | |||
| } | |||
| s->above_blocks[2*s->mb_width + 2].ref_frame = 0; | |||
| s->above_blocks[3*s->mb_width + 4].ref_frame = 0; | |||
| stride_y = p->linesize[0]; | |||
| stride_uv = p->linesize[1]; | |||
| if (s->flip < 0) | |||
| mb_offset = 7; | |||
| /* main macroblocks loop */ | |||
| for (mb_row=0; mb_row<s->mb_height; mb_row++) { | |||
| if (s->flip < 0) | |||
| mb_row_flip = s->mb_height - mb_row - 1; | |||
| else | |||
| mb_row_flip = mb_row; | |||
| for (block=0; block<4; block++) { | |||
| s->left_block[block].ref_frame = -1; | |||
| s->left_block[block].dc_coeff = 0; | |||
| s->left_block[block].not_null_dc = 0; | |||
| memset(s->coeff_ctx[block], 0, 64*sizeof(s->coeff_ctx[block][0])); | |||
| } | |||
| memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last)); | |||
| s->above_block_idx[0] = 1; | |||
| s->above_block_idx[1] = 2; | |||
| s->above_block_idx[2] = 1; | |||
| s->above_block_idx[3] = 2; | |||
| s->above_block_idx[4] = 2*s->mb_width + 2 + 1; | |||
| s->above_block_idx[5] = 3*s->mb_width + 4 + 1; | |||
| s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y; | |||
| s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y; | |||
| s->block_offset[1] = s->block_offset[0] + 8; | |||
| s->block_offset[3] = s->block_offset[2] + 8; | |||
| s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; | |||
| s->block_offset[5] = s->block_offset[4]; | |||
| for (mb_col=0; mb_col<s->mb_width; mb_col++) { | |||
| vp56_decode_mb(s, mb_row, mb_col); | |||
| for (y=0; y<4; y++) { | |||
| s->above_block_idx[y] += 2; | |||
| s->block_offset[y] += 16; | |||
| } | |||
| for (uv=4; uv<6; uv++) { | |||
| s->above_block_idx[uv] += 1; | |||
| s->block_offset[uv] += 8; | |||
| } | |||
| } | |||
| } | |||
| if (s->frames[VP56_FRAME_PREVIOUS].data[0] | |||
| && (s->frames[VP56_FRAME_PREVIOUS].data[0] | |||
| != s->frames[VP56_FRAME_GOLDEN].data[0])) { | |||
| avctx->release_buffer(avctx, &s->frames[VP56_FRAME_PREVIOUS]); | |||
| } | |||
| if (p->key_frame || golden_frame) { | |||
| if (s->frames[VP56_FRAME_GOLDEN].data[0]) | |||
| avctx->release_buffer(avctx, &s->frames[VP56_FRAME_GOLDEN]); | |||
| s->frames[VP56_FRAME_GOLDEN] = *p; | |||
| } | |||
| s->frames[VP56_FRAME_PREVIOUS] = *p; | |||
| *picture = *p; | |||
| *data_size = sizeof(AVPicture); | |||
| return buf_size; | |||
| } | |||
| void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip) | |||
| { | |||
| int i; | |||
| s->avctx = avctx; | |||
| avctx->pix_fmt = PIX_FMT_YUV420P; | |||
| if (s->avctx->idct_algo == FF_IDCT_AUTO) | |||
| s->avctx->idct_algo = FF_IDCT_VP3; | |||
| dsputil_init(&s->dsp, s->avctx); | |||
| ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); | |||
| avcodec_set_dimensions(s->avctx, 0, 0); | |||
| for (i=0; i<3; i++) | |||
| s->frames[i].data[0] = NULL; | |||
| s->edge_emu_buffer_alloc = NULL; | |||
| s->above_blocks = NULL; | |||
| s->macroblocks = NULL; | |||
| s->quantizer = -1; | |||
| s->deblock_filtering = 1; | |||
| s->filter = NULL; | |||
| if (flip) { | |||
| s->flip = -1; | |||
| s->frbi = 2; | |||
| s->srbi = 0; | |||
| } else { | |||
| s->flip = 1; | |||
| s->frbi = 0; | |||
| s->srbi = 2; | |||
| } | |||
| } | |||
| int vp56_free(AVCodecContext *avctx) | |||
| { | |||
| vp56_context_t *s = avctx->priv_data; | |||
| av_free(s->above_blocks); | |||
| av_free(s->macroblocks); | |||
| av_free(s->edge_emu_buffer_alloc); | |||
| if (s->frames[VP56_FRAME_GOLDEN].data[0] | |||
| && (s->frames[VP56_FRAME_PREVIOUS].data[0] | |||
| != s->frames[VP56_FRAME_GOLDEN].data[0])) | |||
| avctx->release_buffer(avctx, &s->frames[VP56_FRAME_GOLDEN]); | |||
| if (s->frames[VP56_FRAME_PREVIOUS].data[0]) | |||
| avctx->release_buffer(avctx, &s->frames[VP56_FRAME_PREVIOUS]); | |||
| return 0; | |||
| } | |||
| @@ -0,0 +1,248 @@ | |||
| /** | |||
| * @file vp56.h | |||
| * VP5 and VP6 compatible video decoder (common features) | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef VP56_H | |||
| #define VP56_H | |||
| #include <stdint.h> | |||
| #include "vp56data.h" | |||
| #include "dsputil.h" | |||
| #include "mpegvideo.h" | |||
| typedef struct vp56_context vp56_context_t; | |||
| typedef struct vp56_mv vp56_mv_t; | |||
| typedef void (*vp56_parse_vector_adjustment_t)(vp56_context_t *s, | |||
| vp56_mv_t *vector); | |||
| typedef int (*vp56_adjust_t)(int v, int t); | |||
| typedef void (*vp56_filter_t)(vp56_context_t *s, uint8_t *dst, uint8_t *src, | |||
| int offset1, int offset2, int stride, | |||
| vp56_mv_t mv, int mask, int select, int luma); | |||
| typedef void (*vp56_parse_coeff_t)(vp56_context_t *s); | |||
| typedef void (*vp56_default_models_init_t)(vp56_context_t *s); | |||
| typedef void (*vp56_parse_vector_models_t)(vp56_context_t *s); | |||
| typedef void (*vp56_parse_coeff_models_t)(vp56_context_t *s); | |||
| typedef int (*vp56_parse_header_t)(vp56_context_t *s, uint8_t *buf, | |||
| int buf_size, int *golden_frame); | |||
| typedef struct { | |||
| int high; | |||
| int bits; | |||
| const uint8_t *buffer; | |||
| unsigned long code_word; | |||
| } vp56_range_coder_t; | |||
| typedef struct { | |||
| uint8_t not_null_dc; | |||
| vp56_frame_t ref_frame; | |||
| DCTELEM dc_coeff; | |||
| } vp56_ref_dc_t; | |||
| struct vp56_mv { | |||
| int x; | |||
| int y; | |||
| }; | |||
| typedef struct { | |||
| uint8_t type; | |||
| vp56_mv_t mv; | |||
| } vp56_macroblock_t; | |||
| struct vp56_context { | |||
| AVCodecContext *avctx; | |||
| DSPContext dsp; | |||
| ScanTable scantable; | |||
| AVFrame frames[3]; | |||
| uint8_t *edge_emu_buffer_alloc; | |||
| uint8_t *edge_emu_buffer; | |||
| vp56_range_coder_t c; | |||
| /* frame info */ | |||
| int plane_width[3]; | |||
| int plane_height[3]; | |||
| int mb_width; /* number of horizontal MB */ | |||
| int mb_height; /* number of vertical MB */ | |||
| int block_offset[6]; | |||
| int quantizer; | |||
| uint16_t dequant_dc; | |||
| uint16_t dequant_ac; | |||
| /* DC predictors management */ | |||
| vp56_ref_dc_t *above_blocks; | |||
| vp56_ref_dc_t left_block[4]; | |||
| int above_block_idx[6]; | |||
| DCTELEM prev_dc[3][3]; /* [plan][ref_frame] */ | |||
| /* blocks / macroblock */ | |||
| vp56_mb_t mb_type; | |||
| vp56_macroblock_t *macroblocks; | |||
| DECLARE_ALIGNED_16(DCTELEM, block_coeff[6][64]); | |||
| uint8_t coeff_reorder[64]; /* used in vp6 only */ | |||
| uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ | |||
| /* motion vectors */ | |||
| vp56_mv_t mv[6]; /* vectors for each block in MB */ | |||
| vp56_mv_t vector_candidate[2]; | |||
| int vector_candidate_pos; | |||
| /* filtering hints */ | |||
| int deblock_filtering; | |||
| int filter_selection; | |||
| int filter_mode; | |||
| int max_vector_length; | |||
| int sample_variance_threshold; | |||
| /* AC models */ | |||
| uint8_t vector_model_sig[2]; /* delta sign */ | |||
| uint8_t vector_model_dct[2]; /* delta coding types */ | |||
| uint8_t vector_model_pdi[2][2]; /* predefined delta init */ | |||
| uint8_t vector_model_pdv[2][7]; /* predefined delta values */ | |||
| uint8_t vector_model_fdv[2][8]; /* 8 bit delta value definition */ | |||
| uint8_t mb_type_model[3][10][10]; /* model for decoding MB type */ | |||
| uint8_t coeff_model_dccv[2][11]; /* DC coeff value */ | |||
| uint8_t coeff_model_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ | |||
| uint8_t coeff_model_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ | |||
| uint8_t coeff_model_dcct[2][36][5]; /* DC coeff coding type */ | |||
| uint8_t coeff_model_runv[2][14]; /* run value (vp6 only) */ | |||
| uint8_t mb_types_stats[3][10][2]; /* contextual, next MB type stats */ | |||
| uint8_t coeff_ctx[4][64]; /* used in vp5 only */ | |||
| uint8_t coeff_ctx_last[4]; /* used in vp5 only */ | |||
| /* upside-down flipping hints */ | |||
| int flip; /* are we flipping ? */ | |||
| int frbi; /* first row block index in MB */ | |||
| int srbi; /* second row block index in MB */ | |||
| int stride[3]; /* stride for each plan */ | |||
| const uint8_t *vp56_coord_div; | |||
| vp56_parse_vector_adjustment_t parse_vector_adjustment; | |||
| vp56_adjust_t adjust; | |||
| vp56_filter_t filter; | |||
| vp56_parse_coeff_t parse_coeff; | |||
| vp56_default_models_init_t default_models_init; | |||
| vp56_parse_vector_models_t parse_vector_models; | |||
| vp56_parse_coeff_models_t parse_coeff_models; | |||
| vp56_parse_header_t parse_header; | |||
| }; | |||
| void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip); | |||
| int vp56_free(AVCodecContext *avctx); | |||
| void vp56_init_dequant(vp56_context_t *s, int quantizer); | |||
| int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |||
| uint8_t *buf, int buf_size); | |||
| /** | |||
| * vp56 specific range coder implementation | |||
| */ | |||
| static inline void vp56_init_range_decoder(vp56_range_coder_t *c, | |||
| const uint8_t *buf, int buf_size) | |||
| { | |||
| c->high = 255; | |||
| c->bits = 8; | |||
| c->buffer = buf; | |||
| c->code_word = *c->buffer++ << 8; | |||
| c->code_word |= *c->buffer++; | |||
| } | |||
| static inline int vp56_rac_get_prob(vp56_range_coder_t *c, uint8_t prob) | |||
| { | |||
| unsigned int low = 1 + (((c->high - 1) * prob) / 256); | |||
| unsigned int low_shift = low << 8; | |||
| int bit = c->code_word >= low_shift; | |||
| if (bit) { | |||
| c->high -= low; | |||
| c->code_word -= low_shift; | |||
| } else { | |||
| c->high = low; | |||
| } | |||
| /* normalize */ | |||
| while (c->high < 128) { | |||
| c->high <<= 1; | |||
| c->code_word <<= 1; | |||
| if (--c->bits == 0) { | |||
| c->bits = 8; | |||
| c->code_word |= *c->buffer++; | |||
| } | |||
| } | |||
| return bit; | |||
| } | |||
| static inline int vp56_rac_get(vp56_range_coder_t *c) | |||
| { | |||
| /* equiprobable */ | |||
| int low = (c->high + 1) >> 1; | |||
| unsigned int low_shift = low << 8; | |||
| int bit = c->code_word >= low_shift; | |||
| if (bit) { | |||
| c->high = (c->high - low) << 1; | |||
| c->code_word -= low_shift; | |||
| } else { | |||
| c->high = low << 1; | |||
| } | |||
| /* normalize */ | |||
| c->code_word <<= 1; | |||
| if (--c->bits == 0) { | |||
| c->bits = 8; | |||
| c->code_word |= *c->buffer++; | |||
| } | |||
| return bit; | |||
| } | |||
| static inline int vp56_rac_gets(vp56_range_coder_t *c, int bits) | |||
| { | |||
| int value = 0; | |||
| while (bits--) { | |||
| value = (value << 1) | vp56_rac_get(c); | |||
| } | |||
| return value; | |||
| } | |||
| static inline int vp56_rac_gets_nn(vp56_range_coder_t *c, int bits) | |||
| { | |||
| int v = vp56_rac_gets(c, 7) << 1; | |||
| return v + !v; | |||
| } | |||
| static inline int vp56_rac_get_tree(vp56_range_coder_t *c, | |||
| const vp56_tree_t *tree, | |||
| const uint8_t *probs) | |||
| { | |||
| while (tree->val > 0) { | |||
| if (vp56_rac_get_prob(c, probs[tree->prob_idx])) | |||
| tree += tree->val; | |||
| else | |||
| tree++; | |||
| } | |||
| return -tree->val; | |||
| } | |||
| #endif /* VP56_H */ | |||
| @@ -0,0 +1,65 @@ | |||
| /** | |||
| * @file vp56data.c | |||
| * VP5 and VP6 compatible video decoder (common data) | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include <inttypes.h> | |||
| #include "vp56data.h" | |||
| const uint8_t vp56_b6to3[] = { 0, 0, 0, 0, 1, 2 }; | |||
| const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 }; | |||
| const uint8_t vp56_coeff_parse_table[6][11] = { | |||
| { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | |||
| { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | |||
| { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0 }, | |||
| { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0 }, | |||
| { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0 }, | |||
| { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254 }, | |||
| }; | |||
| const uint8_t vp56_def_mb_types_stats[3][10][2] = { | |||
| { { 69, 42 }, { 1, 2 }, { 1, 7 }, { 44, 42 }, { 6, 22 }, | |||
| { 1, 3 }, { 0, 2 }, { 1, 5 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 229, 8 }, { 1, 1 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, | |||
| { 1, 2 }, { 0, 1 }, { 0, 0 }, { 1, 1 }, { 0, 0 }, }, | |||
| { { 122, 35 }, { 1, 1 }, { 1, 6 }, { 46, 34 }, { 0, 0 }, | |||
| { 1, 2 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, | |||
| }; | |||
| const vp56_tree_t vp56_pva_tree[] = { | |||
| { 8, 0}, | |||
| { 4, 1}, | |||
| { 2, 2}, {-0}, {-1}, | |||
| { 2, 3}, {-2}, {-3}, | |||
| { 4, 4}, | |||
| { 2, 5}, {-4}, {-5}, | |||
| { 2, 6}, {-6}, {-7}, | |||
| }; | |||
| const vp56_tree_t vp56_pc_tree[] = { | |||
| { 4, 6}, | |||
| { 2, 7}, {-0}, {-1}, | |||
| { 4, 8}, | |||
| { 2, 9}, {-2}, {-3}, | |||
| { 2,10}, {-4}, {-5}, | |||
| }; | |||
| const uint8_t vp56_coeff_bias[] = { 5, 7, 11, 19, 35, 67 }; | |||
| const uint8_t vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 }; | |||
| @@ -0,0 +1,246 @@ | |||
| /** | |||
| * @file vp56data.h | |||
| * VP5 and VP6 compatible video decoder (common data) | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef VP56DATA_H | |||
| #define VP56DATA_H | |||
| #include <inttypes.h> | |||
| typedef enum { | |||
| VP56_FRAME_CURRENT = 0, | |||
| VP56_FRAME_PREVIOUS = 1, | |||
| VP56_FRAME_GOLDEN = 2, | |||
| } vp56_frame_t; | |||
| typedef enum { | |||
| VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */ | |||
| VP56_MB_INTRA = 1, /**< Intra MB */ | |||
| VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */ | |||
| VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */ | |||
| VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */ | |||
| VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */ | |||
| VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */ | |||
| VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */ | |||
| VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */ | |||
| VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */ | |||
| } vp56_mb_t; | |||
| typedef struct { | |||
| int8_t val; | |||
| int8_t prob_idx; | |||
| } vp56_tree_t; | |||
| extern const uint8_t vp56_b6to3[]; | |||
| extern const uint8_t vp56_b6to4[]; | |||
| extern const uint8_t vp56_coeff_parse_table[6][11]; | |||
| extern const uint8_t vp56_def_mb_types_stats[3][10][2]; | |||
| extern const vp56_tree_t vp56_pva_tree[]; | |||
| extern const vp56_tree_t vp56_pc_tree[]; | |||
| extern const uint8_t vp56_coeff_bias[]; | |||
| extern const uint8_t vp56_coeff_bit_length[]; | |||
| static const vp56_frame_t vp56_reference_frame[] = { | |||
| VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_NOVEC_PF */ | |||
| VP56_FRAME_CURRENT, /* VP56_MB_INTRA */ | |||
| VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_DELTA_PF */ | |||
| VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V1_PF */ | |||
| VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V2_PF */ | |||
| VP56_FRAME_GOLDEN, /* VP56_MB_INTER_NOVEC_GF */ | |||
| VP56_FRAME_GOLDEN, /* VP56_MB_INTER_DELTA_GF */ | |||
| VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_4V */ | |||
| VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V1_GF */ | |||
| VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V2_GF */ | |||
| }; | |||
| static const uint8_t vp56_ac_dequant[64] = { | |||
| 94, 92, 90, 88, 86, 82, 78, 74, | |||
| 70, 66, 62, 58, 54, 53, 52, 51, | |||
| 50, 49, 48, 47, 46, 45, 44, 43, | |||
| 42, 40, 39, 37, 36, 35, 34, 33, | |||
| 32, 31, 30, 29, 28, 27, 26, 25, | |||
| 24, 23, 22, 21, 20, 19, 18, 17, | |||
| 16, 15, 14, 13, 12, 11, 10, 9, | |||
| 8, 7, 6, 5, 4, 3, 2, 1, | |||
| }; | |||
| static const uint8_t vp56_dc_dequant[64] = { | |||
| 47, 47, 47, 47, 45, 43, 43, 43, | |||
| 43, 43, 42, 41, 41, 40, 40, 40, | |||
| 40, 35, 35, 35, 35, 33, 33, 33, | |||
| 33, 32, 32, 32, 27, 27, 26, 26, | |||
| 25, 25, 24, 24, 23, 23, 19, 19, | |||
| 19, 19, 18, 18, 17, 16, 16, 16, | |||
| 16, 16, 15, 11, 11, 11, 10, 10, | |||
| 9, 8, 7, 5, 3, 3, 2, 2, | |||
| }; | |||
| static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = { | |||
| { { { 9, 15 }, { 32, 25 }, { 7, 19 }, { 9, 21 }, { 1, 12 }, | |||
| { 14, 12 }, { 3, 18 }, { 14, 23 }, { 3, 10 }, { 0, 4 }, }, | |||
| { { 41, 22 }, { 1, 0 }, { 1, 31 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 1 }, { 1, 7 }, { 0, 1 }, { 98, 25 }, { 4, 10 }, }, | |||
| { { 2, 3 }, { 2, 3 }, { 0, 2 }, { 0, 2 }, { 0, 0 }, | |||
| { 11, 4 }, { 1, 4 }, { 0, 2 }, { 3, 2 }, { 0, 4 }, }, }, | |||
| { { { 48, 39 }, { 1, 2 }, { 11, 27 }, { 29, 44 }, { 7, 27 }, | |||
| { 1, 4 }, { 0, 3 }, { 1, 6 }, { 1, 2 }, { 0, 0 }, }, | |||
| { { 123, 37 }, { 6, 4 }, { 1, 27 }, { 0, 0 }, { 0, 0 }, | |||
| { 5, 8 }, { 1, 7 }, { 0, 1 }, { 12, 10 }, { 0, 2 }, }, | |||
| { { 49, 46 }, { 3, 4 }, { 7, 31 }, { 42, 41 }, { 0, 0 }, | |||
| { 2, 6 }, { 1, 7 }, { 1, 4 }, { 2, 4 }, { 0, 1 }, }, }, | |||
| { { { 21, 32 }, { 1, 2 }, { 4, 10 }, { 32, 43 }, { 6, 23 }, | |||
| { 2, 3 }, { 1, 19 }, { 1, 6 }, { 12, 21 }, { 0, 7 }, }, | |||
| { { 26, 14 }, { 14, 12 }, { 0, 24 }, { 0, 0 }, { 0, 0 }, | |||
| { 55, 17 }, { 1, 9 }, { 0, 36 }, { 5, 7 }, { 1, 3 }, }, | |||
| { { 26, 25 }, { 1, 1 }, { 2, 10 }, { 67, 39 }, { 0, 0 }, | |||
| { 1, 1 }, { 0, 14 }, { 0, 2 }, { 31, 26 }, { 1, 6 }, }, }, | |||
| { { { 69, 83 }, { 0, 0 }, { 0, 2 }, { 10, 29 }, { 3, 12 }, | |||
| { 0, 1 }, { 0, 3 }, { 0, 3 }, { 2, 2 }, { 0, 0 }, }, | |||
| { { 209, 5 }, { 0, 0 }, { 0, 27 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, | |||
| { { 103, 46 }, { 1, 2 }, { 2, 10 }, { 33, 42 }, { 0, 0 }, | |||
| { 1, 4 }, { 0, 3 }, { 0, 1 }, { 1, 3 }, { 0, 0 }, }, }, | |||
| { { { 11, 20 }, { 1, 4 }, { 18, 36 }, { 43, 48 }, { 13, 35 }, | |||
| { 0, 2 }, { 0, 5 }, { 3, 12 }, { 1, 2 }, { 0, 0 }, }, | |||
| { { 2, 5 }, { 4, 5 }, { 0, 121 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 3 }, { 2, 4 }, { 1, 4 }, { 2, 2 }, { 0, 1 }, }, | |||
| { { 14, 31 }, { 9, 13 }, { 14, 54 }, { 22, 29 }, { 0, 0 }, | |||
| { 2, 6 }, { 4, 18 }, { 6, 13 }, { 1, 5 }, { 0, 1 }, }, }, | |||
| { { { 70, 44 }, { 0, 1 }, { 2, 10 }, { 37, 46 }, { 8, 26 }, | |||
| { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 175, 5 }, { 0, 1 }, { 0, 48 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 2 }, { 0, 1 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 85, 39 }, { 0, 0 }, { 1, 9 }, { 69, 40 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 0 }, }, }, | |||
| { { { 8, 15 }, { 0, 1 }, { 8, 21 }, { 74, 53 }, { 22, 42 }, | |||
| { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 0, 0 }, }, | |||
| { { 83, 5 }, { 2, 3 }, { 0, 102 }, { 0, 0 }, { 0, 0 }, | |||
| { 1, 3 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, | |||
| { { 31, 28 }, { 0, 0 }, { 3, 14 }, { 130, 34 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 3 }, { 0, 1 }, { 3, 3 }, { 0, 1 }, }, }, | |||
| { { { 141, 42 }, { 0, 0 }, { 1, 4 }, { 11, 24 }, { 1, 11 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, }, | |||
| { { 233, 6 }, { 0, 0 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 171, 25 }, { 0, 0 }, { 1, 5 }, { 25, 21 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, }, | |||
| { { { 8, 19 }, { 4, 10 }, { 24, 45 }, { 21, 37 }, { 9, 29 }, | |||
| { 0, 3 }, { 1, 7 }, { 11, 25 }, { 0, 2 }, { 0, 1 }, }, | |||
| { { 34, 16 }, { 112, 21 }, { 1, 28 }, { 0, 0 }, { 0, 0 }, | |||
| { 6, 8 }, { 1, 7 }, { 0, 3 }, { 2, 5 }, { 0, 2 }, }, | |||
| { { 17, 21 }, { 68, 29 }, { 6, 15 }, { 13, 22 }, { 0, 0 }, | |||
| { 6, 12 }, { 3, 14 }, { 4, 10 }, { 1, 7 }, { 0, 3 }, }, }, | |||
| { { { 46, 42 }, { 0, 1 }, { 2, 10 }, { 54, 51 }, { 10, 30 }, | |||
| { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 159, 35 }, { 2, 2 }, { 0, 25 }, { 0, 0 }, { 0, 0 }, | |||
| { 3, 6 }, { 0, 5 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, | |||
| { { 51, 39 }, { 0, 1 }, { 2, 12 }, { 91, 44 }, { 0, 0 }, | |||
| { 0, 2 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 1 }, }, }, | |||
| { { { 28, 32 }, { 0, 0 }, { 3, 10 }, { 75, 51 }, { 14, 33 }, | |||
| { 0, 1 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, | |||
| { { 75, 39 }, { 5, 7 }, { 2, 48 }, { 0, 0 }, { 0, 0 }, | |||
| { 3, 11 }, { 2, 16 }, { 1, 4 }, { 7, 10 }, { 0, 2 }, }, | |||
| { { 81, 25 }, { 0, 0 }, { 2, 9 }, { 106, 26 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, | |||
| { { { 100, 46 }, { 0, 1 }, { 3, 9 }, { 21, 37 }, { 5, 20 }, | |||
| { 0, 1 }, { 0, 2 }, { 1, 2 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 212, 21 }, { 0, 1 }, { 0, 9 }, { 0, 0 }, { 0, 0 }, | |||
| { 1, 2 }, { 0, 2 }, { 0, 0 }, { 2, 2 }, { 0, 0 }, }, | |||
| { { 140, 37 }, { 0, 1 }, { 1, 8 }, { 24, 33 }, { 0, 0 }, | |||
| { 1, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, }, | |||
| { { { 27, 29 }, { 0, 1 }, { 9, 25 }, { 53, 51 }, { 12, 34 }, | |||
| { 0, 1 }, { 0, 3 }, { 1, 5 }, { 0, 2 }, { 0, 0 }, }, | |||
| { { 4, 2 }, { 0, 0 }, { 0, 172 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 2 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, }, | |||
| { { 14, 23 }, { 1, 3 }, { 11, 53 }, { 90, 31 }, { 0, 0 }, | |||
| { 0, 3 }, { 1, 5 }, { 2, 6 }, { 1, 2 }, { 0, 0 }, }, }, | |||
| { { { 80, 38 }, { 0, 0 }, { 1, 4 }, { 69, 33 }, { 5, 16 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, | |||
| { { 187, 22 }, { 1, 1 }, { 0, 17 }, { 0, 0 }, { 0, 0 }, | |||
| { 3, 6 }, { 0, 4 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, | |||
| { { 123, 29 }, { 0, 0 }, { 1, 7 }, { 57, 30 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, }, | |||
| { { { 16, 20 }, { 0, 0 }, { 2, 8 }, { 104, 49 }, { 15, 33 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, | |||
| { { 133, 6 }, { 1, 2 }, { 1, 70 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 2 }, { 0, 4 }, { 0, 3 }, { 1, 1 }, { 0, 0 }, }, | |||
| { { 13, 14 }, { 0, 0 }, { 4, 20 }, { 175, 20 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, | |||
| { { { 194, 16 }, { 0, 0 }, { 1, 1 }, { 1, 9 }, { 1, 3 }, | |||
| { 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, | |||
| { { 251, 1 }, { 0, 0 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, | |||
| { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, | |||
| { { 202, 23 }, { 0, 0 }, { 1, 3 }, { 2, 9 }, { 0, 0 }, | |||
| { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, }, | |||
| }; | |||
| static const uint8_t vp56_filter_threshold[] = { | |||
| 14, 14, 13, 13, 12, 12, 10, 10, | |||
| 10, 10, 8, 8, 8, 8, 8, 8, | |||
| 8, 8, 8, 8, 8, 8, 8, 8, | |||
| 8, 8, 8, 8, 8, 8, 8, 8, | |||
| 8, 8, 8, 8, 7, 7, 7, 7, | |||
| 7, 7, 6, 6, 6, 6, 6, 6, | |||
| 5, 5, 5, 5, 4, 4, 4, 4, | |||
| 4, 4, 4, 3, 3, 3, 3, 2, | |||
| }; | |||
| static const uint8_t vp56_mb_type_model_model[] = { | |||
| 171, 83, 199, 140, 125, 104, | |||
| }; | |||
| static const vp56_tree_t vp56_pmbtm_tree[] = { | |||
| { 4, 0}, | |||
| { 2, 1}, {-8}, {-4}, | |||
| { 8, 2}, | |||
| { 6, 3}, | |||
| { 4, 4}, | |||
| { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0}, | |||
| }; | |||
| static const vp56_tree_t vp56_pmbt_tree[] = { | |||
| { 8, 1}, | |||
| { 4, 2}, | |||
| { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF}, | |||
| { 2, 5}, {-VP56_MB_INTER_V1_PF}, {-VP56_MB_INTER_V2_PF}, | |||
| { 4, 3}, | |||
| { 2, 6}, {-VP56_MB_INTRA}, {-VP56_MB_INTER_4V}, | |||
| { 4, 7}, | |||
| { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF}, | |||
| { 2, 9}, {-VP56_MB_INTER_V1_GF}, {-VP56_MB_INTER_V2_GF}, | |||
| }; | |||
| /* relative pos of surrounding blocks, from closest to farthest */ | |||
| static const int8_t vp56_candidate_predictor_pos[12][2] = { | |||
| { 0, -1 }, | |||
| { -1, 0 }, | |||
| { -1, -1 }, | |||
| { 1, -1 }, | |||
| { 0, -2 }, | |||
| { -2, 0 }, | |||
| { -2, -1 }, | |||
| { -1, -2 }, | |||
| { 1, -2 }, | |||
| { 2, -1 }, | |||
| { -2, -2 }, | |||
| { 2, -2 }, | |||
| }; | |||
| #endif /* VP56DATA */ | |||
| @@ -0,0 +1,173 @@ | |||
| /** | |||
| * @file vp5data.h | |||
| * VP5 compatible video decoder | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef VP5DATA_H | |||
| #define VP5DATA_H | |||
| #include <inttypes.h> | |||
| static const uint8_t vp5_coeff_groups[] = { | |||
| -1, 0, 1, 1, 2, 1, 1, 2, | |||
| 2, 1, 1, 2, 2, 2, 1, 2, | |||
| 2, 2, 2, 2, 1, 1, 2, 2, | |||
| 3, 3, 4, 3, 4, 4, 4, 3, | |||
| 3, 3, 3, 3, 4, 3, 3, 3, | |||
| 4, 4, 4, 4, 4, 3, 3, 4, | |||
| 4, 4, 3, 4, 4, 4, 4, 4, | |||
| 4, 4, 5, 5, 5, 5, 5, 5, | |||
| }; | |||
| static const uint8_t vp5_vmc_pct[2][11] = { | |||
| { 243, 220, 251, 253, 237, 232, 241, 245, 247, 251, 253 }, | |||
| { 235, 211, 246, 249, 234, 231, 248, 249, 252, 252, 254 }, | |||
| }; | |||
| static const uint8_t vp5_dccv_pct[2][11] = { | |||
| { 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 }, | |||
| { 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 }, | |||
| }; | |||
| static const uint8_t vp5_ract_pct[3][2][6][11] = { | |||
| { { { 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 }, | |||
| { 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 }, | |||
| { 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 }, | |||
| { 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 }, | |||
| { 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, | |||
| { { 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, | |||
| { { { 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 }, | |||
| { 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 }, | |||
| { 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 }, | |||
| { 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 }, | |||
| { 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, | |||
| { { 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, | |||
| { { { 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 }, | |||
| { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 }, | |||
| { 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 }, | |||
| { 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, | |||
| { { 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, | |||
| { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, | |||
| }; | |||
| static const int16_t vp5_dccv_lc[5][36][2] = { | |||
| { {154, 61}, {141, 54}, { 90, 45}, { 54, 34}, { 54, 13}, {128, 109}, | |||
| {136, 54}, {148, 45}, { 92, 41}, { 54, 33}, { 51, 15}, { 87, 113}, | |||
| { 87, 44}, { 97, 40}, { 67, 36}, { 46, 29}, { 41, 15}, { 64, 80}, | |||
| { 59, 33}, { 61, 31}, { 51, 28}, { 44, 22}, { 33, 12}, { 49, 63}, | |||
| { 69, 12}, { 59, 16}, { 46, 14}, { 31, 13}, { 26, 6}, { 92, 26}, | |||
| {128, 108}, { 77, 119}, { 54, 84}, { 26, 71}, { 87, 19}, { 95, 155} }, | |||
| { {154, 4}, {182, 0}, {159, -8}, {128, -5}, {143, -5}, {187, 55}, | |||
| {182, 0}, {228, -3}, {187, -7}, {174, -9}, {189, -11}, {169, 79}, | |||
| {161, -9}, {192, -8}, {187, -9}, {169, -10}, {136, -9}, {184, 40}, | |||
| {164, -11}, {179, -10}, {174, -10}, {161, -10}, {115, -7}, {197, 20}, | |||
| {195, -11}, {195, -11}, {146, -10}, {110, -6}, { 95, -4}, {195, 39}, | |||
| {182, 55}, {172, 77}, {177, 37}, {169, 29}, {172, 52}, { 92, 162} }, | |||
| { {174, 80}, {164, 80}, { 95, 80}, { 46, 66}, { 56, 24}, { 36, 193}, | |||
| {164, 80}, {166, 77}, {105, 76}, { 49, 68}, { 46, 31}, { 49, 186}, | |||
| { 97, 78}, {110, 74}, { 72, 72}, { 44, 60}, { 33, 30}, { 69, 131}, | |||
| { 61, 61}, { 69, 63}, { 51, 57}, { 31, 48}, { 26, 27}, { 64, 89}, | |||
| { 67, 23}, { 51, 32}, { 36, 33}, { 26, 28}, { 20, 12}, { 44, 68}, | |||
| { 26, 197}, { 41, 189}, { 61, 129}, { 28, 103}, { 49, 52}, {-12, 245} }, | |||
| { {102, 141}, { 79, 166}, { 72, 162}, { 97, 125}, {179, 4}, {307, 0}, | |||
| { 72, 168}, { 69, 175}, { 84, 160}, {105, 127}, {148, 34}, {310, 0}, | |||
| { 84, 151}, { 82, 161}, { 87, 153}, { 87, 135}, {115, 51}, {317, 0}, | |||
| { 97, 125}, {102, 131}, {105, 125}, { 87, 122}, { 84, 64}, { 54, 184}, | |||
| {166, 18}, {146, 43}, {125, 51}, { 90, 64}, { 95, 7}, { 38, 154}, | |||
| {294, 0}, { 13, 225}, { 10, 225}, { 67, 168}, { 0, 167}, {161, 94} }, | |||
| { {172, 76}, {172, 75}, {136, 80}, { 64, 98}, { 74, 67}, {315, 0}, | |||
| {169, 76}, {207, 56}, {164, 66}, { 97, 80}, { 67, 72}, {328, 0}, | |||
| {136, 80}, {187, 53}, {154, 62}, { 72, 85}, { -2, 105}, {305, 0}, | |||
| { 74, 91}, {128, 64}, {113, 64}, { 61, 77}, { 41, 75}, {259, 0}, | |||
| { 46, 84}, { 51, 81}, { 28, 89}, { 31, 78}, { 23, 77}, {202, 0}, | |||
| {323, 0}, {323, 0}, {300, 0}, {236, 0}, {195, 0}, {328, 0} }, | |||
| }; | |||
| static const int16_t vp5_ract_lc[3][3][5][6][2] = { | |||
| { { { {276, 0}, {238, 0}, {195, 0}, {156, 0}, {113, 0}, {274, 0} }, | |||
| { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, | |||
| { {192, 59}, {182, 50}, {141, 48}, {110, 40}, { 92, 19}, {125,128} }, | |||
| { {169, 87}, {169, 83}, {184, 62}, {220, 16}, {184, 0}, {264, 0} }, | |||
| { {212, 40}, {212, 36}, {169, 49}, {174, 27}, { 8,120}, {182, 71} } }, | |||
| { { {259, 10}, {197, 19}, {143, 22}, {123, 16}, {110, 8}, {133, 88} }, | |||
| { { 0, 1}, {256, 0}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, | |||
| { {207, 46}, {187, 50}, { 97, 83}, { 23,100}, { 41, 56}, { 56,188} }, | |||
| { {166, 90}, {146,108}, {161, 88}, {136, 95}, {174, 0}, {266, 0} }, | |||
| { {264, 7}, {243, 18}, {184, 43}, {-14,154}, { 20,112}, { 20,199} } }, | |||
| { { {230, 26}, {197, 22}, {159, 20}, {146, 12}, {136, 4}, { 54,162} }, | |||
| { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, | |||
| { {192, 59}, {156, 72}, { 84,101}, { 49,101}, { 79, 47}, { 79,167} }, | |||
| { {138,115}, {136,116}, {166, 80}, {238, 0}, {195, 0}, {261, 0} }, | |||
| { {225, 33}, {205, 42}, {159, 61}, { 79, 96}, { 92, 66}, { 28,195} } }, | |||
| }, { | |||
| { { {200, 37}, {197, 18}, {159, 13}, {143, 7}, {102, 5}, {123,126} }, | |||
| { {197, 3}, {220, -9}, {210,-12}, {187, -6}, {151, -2}, {174, 80} }, | |||
| { {200, 53}, {187, 47}, {159, 40}, {118, 38}, {100, 18}, {141,111} }, | |||
| { {179, 78}, {166, 86}, {197, 50}, {207, 27}, {187, 0}, {115,139} }, | |||
| { {218, 34}, {220, 29}, {174, 46}, {128, 61}, { 54, 89}, {187, 65} } }, | |||
| { { {238, 14}, {197, 18}, {125, 26}, { 90, 25}, { 82, 13}, {161, 86} }, | |||
| { {189, 1}, {205, -2}, {156, -4}, {143, -4}, {146, -4}, {172, 72} }, | |||
| { {230, 31}, {192, 45}, {102, 76}, { 38, 85}, { 56, 41}, { 64,173} }, | |||
| { {166, 91}, {141,111}, {128,116}, {118,109}, {177, 0}, { 23,222} }, | |||
| { {253, 14}, {236, 21}, {174, 49}, { 33,118}, { 44, 93}, { 23,187} } }, | |||
| { { {218, 28}, {179, 28}, {118, 35}, { 95, 30}, { 72, 24}, {128,108} }, | |||
| { {187, 1}, {174, -1}, {125, -1}, {110, -1}, {108, -1}, {202, 52} }, | |||
| { {197, 53}, {146, 75}, { 46,118}, { 33,103}, { 64, 50}, {118,126} }, | |||
| { {138,114}, {128,122}, {161, 86}, {243, -6}, {195, 0}, { 38,210} }, | |||
| { {215, 39}, {179, 58}, { 97,101}, { 95, 85}, { 87, 70}, { 69,152} } }, | |||
| }, { | |||
| { { {236, 24}, {205, 18}, {172, 12}, {154, 6}, {125, 1}, {169, 75} }, | |||
| { {187, 4}, {230, -2}, {228, -4}, {236, -4}, {241, -2}, {192, 66} }, | |||
| { {200, 46}, {187, 42}, {159, 34}, {136, 25}, {105, 10}, {179, 62} }, | |||
| { {207, 55}, {192, 63}, {192, 54}, {195, 36}, {177, 1}, {143, 98} }, | |||
| { {225, 27}, {207, 34}, {200, 30}, {131, 57}, { 97, 60}, {197, 45} } }, | |||
| { { {271, 8}, {218, 13}, {133, 19}, { 90, 19}, { 72, 7}, {182, 51} }, | |||
| { {179, 1}, {225, -1}, {154, -2}, {110, -1}, { 92, 0}, {195, 41} }, | |||
| { {241, 26}, {189, 40}, { 82, 64}, { 33, 60}, { 67, 17}, {120, 94} }, | |||
| { {192, 68}, {151, 94}, {146, 90}, {143, 72}, {161, 0}, {113,128} }, | |||
| { {256, 12}, {218, 29}, {166, 48}, { 44, 99}, { 31, 87}, {148, 78} } }, | |||
| { { {238, 20}, {184, 22}, {113, 27}, { 90, 22}, { 74, 9}, {192, 37} }, | |||
| { {184, 0}, {215, -1}, {141, -1}, { 97, 0}, { 49, 0}, {264, 13} }, | |||
| { {182, 51}, {138, 61}, { 95, 63}, { 54, 59}, { 64, 25}, {200, 45} }, | |||
| { {179, 75}, {156, 87}, {174, 65}, {177, 44}, {174, 0}, {164, 85} }, | |||
| { {195, 45}, {148, 65}, {105, 79}, { 95, 72}, { 87, 60}, {169, 63} } }, | |||
| } | |||
| }; | |||
| static const uint8_t vp5_coord_div[] = { 2, 2, 2, 2, 4, 4 }; | |||
| #endif /* VP5DATA_H */ | |||
| @@ -0,0 +1,512 @@ | |||
| /** | |||
| * @file vp6.c | |||
| * VP6 compatible video decoder | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include <stdlib.h> | |||
| #include <inttypes.h> | |||
| #include "avcodec.h" | |||
| #include "dsputil.h" | |||
| #include "bitstream.h" | |||
| #include "mpegvideo.h" | |||
| #include "vp56.h" | |||
| #include "vp56data.h" | |||
| #include "vp6data.h" | |||
| static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, | |||
| int *golden_frame) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int parse_filter_info; | |||
| int rows, cols; | |||
| int res = 1; | |||
| if (buf[0] & 1) | |||
| return 0; | |||
| s->frames[VP56_FRAME_CURRENT].key_frame = !(buf[0] & 0x80); | |||
| vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); | |||
| if (s->frames[VP56_FRAME_CURRENT].key_frame) { | |||
| if ((buf[1] & 0xFE) != 0x46) /* would be 0x36 for VP61 */ | |||
| return 0; | |||
| if (buf[1] & 1) { | |||
| av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); | |||
| return 0; | |||
| } | |||
| rows = buf[2]; /* number of stored macroblock rows */ | |||
| cols = buf[3]; /* number of stored macroblock cols */ | |||
| /* buf[4] is number of displayed macroblock rows */ | |||
| /* buf[5] is number of displayed macroblock cols */ | |||
| if (16*cols != s->avctx->coded_width || | |||
| 16*rows != s->avctx->coded_height) { | |||
| avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); | |||
| res = 2; | |||
| } | |||
| vp56_init_range_decoder(c, buf+6, buf_size-6); | |||
| vp56_rac_gets(c, 2); | |||
| parse_filter_info = 1; | |||
| } else { | |||
| vp56_init_range_decoder(c, buf+1, buf_size-1); | |||
| *golden_frame = vp56_rac_get(c); | |||
| s->deblock_filtering = vp56_rac_get(c); | |||
| if (s->deblock_filtering) | |||
| vp56_rac_get(c); | |||
| parse_filter_info = vp56_rac_get(c); | |||
| } | |||
| if (parse_filter_info) { | |||
| if (vp56_rac_get(c)) { | |||
| s->filter_mode = 2; | |||
| s->sample_variance_threshold = vp56_rac_gets(c, 5); | |||
| s->max_vector_length = 2 << vp56_rac_gets(c, 3); | |||
| } else if (vp56_rac_get(c)) { | |||
| s->filter_mode = 1; | |||
| } else { | |||
| s->filter_mode = 0; | |||
| } | |||
| s->filter_selection = vp56_rac_gets(c, 4); | |||
| } | |||
| vp56_rac_get(c); | |||
| return res; | |||
| } | |||
| static void vp6_coeff_order_table_init(vp56_context_t *s) | |||
| { | |||
| int i, pos, idx = 1; | |||
| s->coeff_index_to_pos[0] = 0; | |||
| for (i=0; i<16; i++) | |||
| for (pos=1; pos<64; pos++) | |||
| if (s->coeff_reorder[pos] == i) | |||
| s->coeff_index_to_pos[idx++] = pos; | |||
| } | |||
| static void vp6_default_models_init(vp56_context_t *s) | |||
| { | |||
| s->vector_model_dct[0] = 0xA2; | |||
| s->vector_model_dct[1] = 0xA4; | |||
| s->vector_model_sig[0] = 0x80; | |||
| s->vector_model_sig[1] = 0x80; | |||
| memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats)); | |||
| memcpy(s->vector_model_fdv, vp6_def_fdv_vector_model, sizeof(s->vector_model_fdv)); | |||
| memcpy(s->vector_model_pdv, vp6_def_pdv_vector_model, sizeof(s->vector_model_pdv)); | |||
| memcpy(s->coeff_model_runv, vp6_def_runv_coeff_model, sizeof(s->coeff_model_runv)); | |||
| memcpy(s->coeff_reorder, vp6_def_coeff_reorder, sizeof(s->coeff_reorder)); | |||
| vp6_coeff_order_table_init(s); | |||
| } | |||
| static void vp6_parse_vector_models(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int comp, node; | |||
| for (comp=0; comp<2; comp++) { | |||
| if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) | |||
| s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7); | |||
| if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) | |||
| s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7); | |||
| } | |||
| for (comp=0; comp<2; comp++) | |||
| for (node=0; node<7; node++) | |||
| if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) | |||
| s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7); | |||
| for (comp=0; comp<2; comp++) | |||
| for (node=0; node<8; node++) | |||
| if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) | |||
| s->vector_model_fdv[comp][node] = vp56_rac_gets_nn(c, 7); | |||
| } | |||
| static void vp6_parse_coeff_models(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int def_prob[11]; | |||
| int node, cg, ctx, pos; | |||
| int ct; /* code type */ | |||
| int pt; /* plane type (0 for Y, 1 for U or V) */ | |||
| memset(def_prob, 0x80, sizeof(def_prob)); | |||
| for (pt=0; pt<2; pt++) | |||
| for (node=0; node<11; node++) | |||
| if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { | |||
| def_prob[node] = vp56_rac_gets_nn(c, 7); | |||
| s->coeff_model_dccv[pt][node] = def_prob[node]; | |||
| } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { | |||
| s->coeff_model_dccv[pt][node] = def_prob[node]; | |||
| } | |||
| if (vp56_rac_get(c)) { | |||
| for (pos=1; pos<64; pos++) | |||
| if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) | |||
| s->coeff_reorder[pos] = vp56_rac_gets(c, 4); | |||
| vp6_coeff_order_table_init(s); | |||
| } | |||
| for (cg=0; cg<2; cg++) | |||
| for (node=0; node<14; node++) | |||
| if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) | |||
| s->coeff_model_runv[cg][node] = vp56_rac_gets_nn(c, 7); | |||
| for (ct=0; ct<3; ct++) | |||
| for (pt=0; pt<2; pt++) | |||
| for (cg=0; cg<6; cg++) | |||
| for (node=0; node<11; node++) | |||
| if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { | |||
| def_prob[node] = vp56_rac_gets_nn(c, 7); | |||
| s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; | |||
| } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { | |||
| s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; | |||
| } | |||
| /* coeff_model_dcct is a linear combination of coeff_model_dccv */ | |||
| for (pt=0; pt<2; pt++) | |||
| for (ctx=0; ctx<3; ctx++) | |||
| for (node=0; node<5; node++) | |||
| s->coeff_model_dcct[pt][ctx][node] = clip(((s->coeff_model_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); | |||
| } | |||
| static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vector) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| int comp; | |||
| *vector = (vp56_mv_t) {0,0}; | |||
| if (s->vector_candidate_pos < 2) | |||
| *vector = s->vector_candidate[0]; | |||
| for (comp=0; comp<2; comp++) { | |||
| int i, delta = 0; | |||
| if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) { | |||
| static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; | |||
| for (i=0; i<sizeof(prob_order); i++) { | |||
| int j = prob_order[i]; | |||
| delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][j])<<j; | |||
| } | |||
| if (delta & 0xF0) | |||
| delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][3])<<3; | |||
| else | |||
| delta |= 8; | |||
| } else { | |||
| delta = vp56_rac_get_tree(c, vp56_pva_tree, | |||
| s->vector_model_pdv[comp]); | |||
| } | |||
| if (delta && vp56_rac_get_prob(c, s->vector_model_sig[comp])) | |||
| delta = -delta; | |||
| if (!comp) | |||
| vector->x += delta; | |||
| else | |||
| vector->y += delta; | |||
| } | |||
| } | |||
| static void vp6_parse_coeff(vp56_context_t *s) | |||
| { | |||
| vp56_range_coder_t *c = &s->c; | |||
| uint8_t *permute = s->scantable.permutated; | |||
| uint8_t *model, *model2, *model3; | |||
| int coeff, sign, coeff_idx; | |||
| int b, i, cg, idx, ctx; | |||
| int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |||
| for (b=0; b<6; b++) { | |||
| int ct = 1; /* code type */ | |||
| int run = 1; | |||
| if (b > 3) pt = 1; | |||
| ctx = s->left_block[vp56_b6to4[b]].not_null_dc | |||
| + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |||
| model = s->coeff_model_dccv[pt]; | |||
| model2 = s->coeff_model_dcct[pt][ctx]; | |||
| for (coeff_idx=0; coeff_idx<64; ) { | |||
| if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { | |||
| /* parse a coeff */ | |||
| if (coeff_idx == 0) { | |||
| s->left_block[vp56_b6to4[b]].not_null_dc = 1; | |||
| s->above_blocks[s->above_block_idx[b]].not_null_dc = 1; | |||
| } | |||
| if (vp56_rac_get_prob(c, model2[2])) { | |||
| if (vp56_rac_get_prob(c, model2[3])) { | |||
| idx = vp56_rac_get_tree(c, vp56_pc_tree, model); | |||
| coeff = vp56_coeff_bias[idx]; | |||
| for (i=vp56_coeff_bit_length[idx]; i>=0; i--) | |||
| coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |||
| } else { | |||
| if (vp56_rac_get_prob(c, model2[4])) | |||
| coeff = 3 + vp56_rac_get_prob(c, model[5]); | |||
| else | |||
| coeff = 2; | |||
| } | |||
| ct = 2; | |||
| } else { | |||
| ct = 1; | |||
| coeff = 1; | |||
| } | |||
| sign = vp56_rac_get(c); | |||
| coeff = (coeff ^ -sign) + sign; | |||
| if (coeff_idx) | |||
| coeff *= s->dequant_ac; | |||
| idx = s->coeff_index_to_pos[coeff_idx]; | |||
| s->block_coeff[b][permute[idx]] = coeff; | |||
| run = 1; | |||
| } else { | |||
| /* parse a run */ | |||
| ct = 0; | |||
| if (coeff_idx == 0) { | |||
| s->left_block[vp56_b6to4[b]].not_null_dc = 0; | |||
| s->above_blocks[s->above_block_idx[b]].not_null_dc = 0; | |||
| } else { | |||
| if (!vp56_rac_get_prob(c, model2[1])) | |||
| break; | |||
| model3 = s->coeff_model_runv[coeff_idx >= 6]; | |||
| run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); | |||
| if (!run) | |||
| for (run=9, i=0; i<6; i++) | |||
| run += vp56_rac_get_prob(c, model3[i+8]) << i; | |||
| } | |||
| } | |||
| cg = vp6_coeff_groups[coeff_idx+=run]; | |||
| model = model2 = s->coeff_model_ract[pt][ct][cg]; | |||
| } | |||
| } | |||
| } | |||
| static int vp6_adjust(int v, int t) | |||
| { | |||
| int V = v, s = v >> 31; | |||
| V ^= s; | |||
| V -= s; | |||
| if (V-t-1 >= (unsigned)(t-1)) | |||
| return v; | |||
| V = 2*t - V; | |||
| V += s; | |||
| V ^= s; | |||
| return V; | |||
| } | |||
| static int vp6_block_variance(uint8_t *src, int stride) | |||
| { | |||
| int sum = 0, square_sum = 0; | |||
| int y, x; | |||
| for (y=0; y<8; y+=2) { | |||
| for (x=0; x<8; x+=2) { | |||
| sum += src[x]; | |||
| square_sum += src[x]*src[x]; | |||
| } | |||
| src += 2*stride; | |||
| } | |||
| return (16*square_sum - sum*sum) / (16*16); | |||
| } | |||
| static void vp6_filter_hv2(vp56_context_t *s, uint8_t *dst, uint8_t *src, | |||
| int stride, int delta, int16_t weight) | |||
| { | |||
| s->dsp.put_pixels_tab[1][0](dst, src, stride, 8); | |||
| s->dsp.biweight_h264_pixels_tab[3](dst, src+delta, stride, 2, | |||
| 8-weight, weight, 0); | |||
| } | |||
| static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, | |||
| int delta, const int16_t *weights) | |||
| { | |||
| int x, y; | |||
| for (y=0; y<8; y++) { | |||
| for (x=0; x<8; x++) { | |||
| dst[x] = clip_uint8(( src[x-delta ] * weights[0] | |||
| + src[x ] * weights[1] | |||
| + src[x+delta ] * weights[2] | |||
| + src[x+2*delta] * weights[3] + 64) >> 7); | |||
| } | |||
| src += stride; | |||
| dst += stride; | |||
| } | |||
| } | |||
| static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src, | |||
| int stride, int h_weight, int v_weight) | |||
| { | |||
| uint8_t *tmp = s->edge_emu_buffer+16; | |||
| int x, xmax; | |||
| s->dsp.put_pixels_tab[1][0](tmp, src, stride, 8); | |||
| s->dsp.biweight_h264_pixels_tab[3](tmp, src+1, stride, 2, | |||
| 8-h_weight, h_weight, 0); | |||
| /* we need a 8x9 block to do vertical filter, so compute one more line */ | |||
| for (x=8*stride, xmax=x+8; x<xmax; x++) | |||
| tmp[x] = (src[x]*(8-h_weight) + src[x+1]*h_weight + 4) >> 3; | |||
| s->dsp.put_pixels_tab[1][0](dst, tmp, stride, 8); | |||
| s->dsp.biweight_h264_pixels_tab[3](dst, tmp+stride, stride, 2, | |||
| 8-v_weight, v_weight, 0); | |||
| } | |||
| static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride, | |||
| const int16_t *h_weights,const int16_t *v_weights) | |||
| { | |||
| int x, y; | |||
| int tmp[8*11]; | |||
| int *t = tmp; | |||
| src -= stride; | |||
| for (y=0; y<11; y++) { | |||
| for (x=0; x<8; x++) { | |||
| t[x] = clip_uint8(( src[x-1] * h_weights[0] | |||
| + src[x ] * h_weights[1] | |||
| + src[x+1] * h_weights[2] | |||
| + src[x+2] * h_weights[3] + 64) >> 7); | |||
| } | |||
| src += stride; | |||
| t += 8; | |||
| } | |||
| t = tmp + 8; | |||
| for (y=0; y<8; y++) { | |||
| for (x=0; x<8; x++) { | |||
| dst[x] = clip_uint8(( t[x-8 ] * v_weights[0] | |||
| + t[x ] * v_weights[1] | |||
| + t[x+8 ] * v_weights[2] | |||
| + t[x+16] * v_weights[3] + 64) >> 7); | |||
| } | |||
| dst += stride; | |||
| t += 8; | |||
| } | |||
| } | |||
| static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src, | |||
| int offset1, int offset2, int stride, | |||
| vp56_mv_t mv, int mask, int select, int luma) | |||
| { | |||
| int filter4 = 0; | |||
| int x8 = mv.x & mask; | |||
| int y8 = mv.y & mask; | |||
| if (luma) { | |||
| x8 *= 2; | |||
| y8 *= 2; | |||
| filter4 = s->filter_mode; | |||
| if (filter4 == 2) { | |||
| if (s->max_vector_length && | |||
| (ABS(mv.x) > s->max_vector_length || | |||
| ABS(mv.y) > s->max_vector_length)) { | |||
| filter4 = 0; | |||
| } else if (!s->sample_variance_threshold | |||
| || (vp6_block_variance(src+offset1, stride) | |||
| < s->sample_variance_threshold)) { | |||
| filter4 = 0; | |||
| } | |||
| } | |||
| } | |||
| if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { | |||
| offset1 = offset2; | |||
| } | |||
| if (filter4) { | |||
| if (!y8) { /* left or right combine */ | |||
| vp6_filter_hv4(dst, src+offset1, stride, 1, | |||
| vp6_block_copy_filter[select][x8]); | |||
| } else if (!x8) { /* above or below combine */ | |||
| vp6_filter_hv4(dst, src+offset1, stride, stride, | |||
| vp6_block_copy_filter[select][y8]); | |||
| } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ | |||
| vp6_filter_diag4(dst, src+offset1-1, stride, | |||
| vp6_block_copy_filter[select][x8], | |||
| vp6_block_copy_filter[select][y8]); | |||
| } else { /* lower-right or upper-left combine */ | |||
| vp6_filter_diag4(dst, src+offset1, stride, | |||
| vp6_block_copy_filter[select][x8], | |||
| vp6_block_copy_filter[select][y8]); | |||
| } | |||
| } else { | |||
| if (!y8) { /* left or right combine */ | |||
| vp6_filter_hv2(s, dst, src+offset1, stride, 1, x8); | |||
| } else if (!x8) { /* above or below combine */ | |||
| vp6_filter_hv2(s, dst, src+offset1, stride, stride, y8); | |||
| } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ | |||
| vp6_filter_diag2(s, dst, src+offset1-1, stride, x8, y8); | |||
| } else { /* lower-right or upper-left combine */ | |||
| vp6_filter_diag2(s, dst, src+offset1, stride, x8, y8); | |||
| } | |||
| } | |||
| } | |||
| static int vp6_decode_init(AVCodecContext *avctx) | |||
| { | |||
| vp56_context_t *s = avctx->priv_data; | |||
| vp56_init(s, avctx, avctx->codec->id == CODEC_ID_VP6); | |||
| s->vp56_coord_div = vp6_coord_div; | |||
| s->parse_vector_adjustment = vp6_parse_vector_adjustment; | |||
| s->adjust = vp6_adjust; | |||
| s->filter = vp6_filter; | |||
| s->parse_coeff = vp6_parse_coeff; | |||
| s->default_models_init = vp6_default_models_init; | |||
| s->parse_vector_models = vp6_parse_vector_models; | |||
| s->parse_coeff_models = vp6_parse_coeff_models; | |||
| s->parse_header = vp6_parse_header; | |||
| return 0; | |||
| } | |||
| AVCodec vp6_decoder = { | |||
| "vp6", | |||
| CODEC_TYPE_VIDEO, | |||
| CODEC_ID_VP6, | |||
| sizeof(vp56_context_t), | |||
| vp6_decode_init, | |||
| NULL, | |||
| vp56_free, | |||
| vp56_decode_frame, | |||
| }; | |||
| /* flash version, not flipped upside-down */ | |||
| AVCodec vp6f_decoder = { | |||
| "vp6f", | |||
| CODEC_TYPE_VIDEO, | |||
| CODEC_ID_VP6F, | |||
| sizeof(vp56_context_t), | |||
| vp6_decode_init, | |||
| NULL, | |||
| vp56_free, | |||
| vp56_decode_frame, | |||
| }; | |||
| @@ -0,0 +1,291 @@ | |||
| /** | |||
| * @file vp6data.h | |||
| * VP6 compatible video decoder | |||
| * | |||
| * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef VP6DATA_H | |||
| #define VP6DATA_H | |||
| #include <inttypes.h> | |||
| #include "vp56data.h" | |||
| static const uint8_t vp6_def_fdv_vector_model[2][8] = { | |||
| { 247, 210, 135, 68, 138, 220, 239, 246 }, | |||
| { 244, 184, 201, 44, 173, 221, 239, 253 }, | |||
| }; | |||
| static const uint8_t vp6_def_pdv_vector_model[2][7] = { | |||
| { 225, 146, 172, 147, 214, 39, 156 }, | |||
| { 204, 170, 119, 235, 140, 230, 228 }, | |||
| }; | |||
| static const uint8_t vp6_def_coeff_reorder[] = { | |||
| 0, 0, 1, 1, 1, 2, 2, 2, | |||
| 2, 2, 2, 3, 3, 4, 4, 4, | |||
| 5, 5, 5, 5, 6, 6, 7, 7, | |||
| 7, 7, 7, 8, 8, 9, 9, 9, | |||
| 9, 9, 9, 10, 10, 11, 11, 11, | |||
| 11, 11, 11, 12, 12, 12, 12, 12, | |||
| 12, 13, 13, 13, 13, 13, 14, 14, | |||
| 14, 14, 15, 15, 15, 15, 15, 15, | |||
| }; | |||
| static const uint8_t vp6_def_runv_coeff_model[2][14] = { | |||
| { 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 }, | |||
| { 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 }, | |||
| }; | |||
| static const uint8_t vp6_sig_dct_pct[2][2] = { | |||
| { 237, 246 }, | |||
| { 231, 243 }, | |||
| }; | |||
| static const uint8_t vp6_pdv_pct[2][7] = { | |||
| { 253, 253, 254, 254, 254, 254, 254 }, | |||
| { 245, 253, 254, 254, 254, 254, 254 }, | |||
| }; | |||
| static const uint8_t vp6_fdv_pct[2][8] = { | |||
| { 254, 254, 254, 254, 254, 250, 250, 252 }, | |||
| { 254, 254, 254, 254, 254, 251, 251, 254 }, | |||
| }; | |||
| static const uint8_t vp6_dccv_pct[2][11] = { | |||
| { 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 }, | |||
| { 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 }, | |||
| }; | |||
| static const uint8_t vp6_coeff_reorder_pct[] = { | |||
| 255, 132, 132, 159, 153, 151, 161, 170, | |||
| 164, 162, 136, 110, 103, 114, 129, 118, | |||
| 124, 125, 132, 136, 114, 110, 142, 135, | |||
| 134, 123, 143, 126, 153, 183, 166, 161, | |||
| 171, 180, 179, 164, 203, 218, 225, 217, | |||
| 215, 206, 203, 217, 229, 241, 248, 243, | |||
| 253, 255, 253, 255, 255, 255, 255, 255, | |||
| 255, 255, 255, 255, 255, 255, 255, 255, | |||
| }; | |||
| static const uint8_t vp6_runv_pct[2][14] = { | |||
| { 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 }, | |||
| { 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 }, | |||
| }; | |||
| static const uint8_t vp6_ract_pct[3][2][6][11] = { | |||
| { { { 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 }, | |||
| { 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 }, | |||
| { 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, | |||
| { { 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, | |||
| { { { 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 }, | |||
| { 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 }, | |||
| { 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 }, | |||
| { 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 }, | |||
| { 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, | |||
| { { 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, | |||
| { { { 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 }, | |||
| { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 }, | |||
| { 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 }, | |||
| { 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, | |||
| { { 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } } | |||
| }; | |||
| static const int vp6_dccv_lc[3][5][2] = { | |||
| { { 122, 133 }, { 0, 1 }, { 78, 171 }, { 139, 117 }, { 168, 79 } }, | |||
| { { 133, 51 }, { 0, 1 }, { 169, 71 }, { 214, 44 }, { 210, 38 } }, | |||
| { { 142, -16 }, { 0, 1 }, { 221, -30 }, { 246, -3 }, { 203, 17 } }, | |||
| }; | |||
| static const uint8_t vp6_coeff_groups[] = { | |||
| 0, 0, 1, 1, 1, 2, 2, 2, | |||
| 2, 2, 2, 3, 3, 3, 3, 3, | |||
| 3, 3, 3, 3, 3, 3, 4, 4, | |||
| 4, 4, 4, 4, 4, 4, 4, 4, | |||
| 4, 4, 4, 4, 4, 5, 5, 5, | |||
| 5, 5, 5, 5, 5, 5, 5, 5, | |||
| 5, 5, 5, 5, 5, 5, 5, 5, | |||
| 5, 5, 5, 5, 5, 5, 5, 5, | |||
| }; | |||
| static const int16_t vp6_block_copy_filter[16][8][4] = { | |||
| { { 0, 128, 0, 0 }, /* 0 */ | |||
| { -3, 122, 9, 0 }, | |||
| { -4, 109, 24, -1 }, | |||
| { -5, 91, 45, -3 }, | |||
| { -4, 68, 68, -4 }, | |||
| { -3, 45, 91, -5 }, | |||
| { -1, 24, 109, -4 }, | |||
| { 0, 9, 122, -3 } }, | |||
| { { 0, 128, 0, 0 }, /* 1 */ | |||
| { -4, 124, 9, -1 }, | |||
| { -5, 110, 25, -2 }, | |||
| { -6, 91, 46, -3 }, | |||
| { -5, 69, 69, -5 }, | |||
| { -3, 46, 91, -6 }, | |||
| { -2, 25, 110, -5 }, | |||
| { -1, 9, 124, -4 } }, | |||
| { { 0, 128, 0, 0 }, /* 2 */ | |||
| { -4, 123, 10, -1 }, | |||
| { -6, 110, 26, -2 }, | |||
| { -7, 92, 47, -4 }, | |||
| { -6, 70, 70, -6 }, | |||
| { -4, 47, 92, -7 }, | |||
| { -2, 26, 110, -6 }, | |||
| { -1, 10, 123, -4 } }, | |||
| { { 0, 128, 0, 0 }, /* 3 */ | |||
| { -5, 124, 10, -1 }, | |||
| { -7, 110, 27, -2 }, | |||
| { -7, 91, 48, -4 }, | |||
| { -6, 70, 70, -6 }, | |||
| { -4, 48, 92, -8 }, | |||
| { -2, 27, 110, -7 }, | |||
| { -1, 10, 124, -5 } }, | |||
| { { 0, 128, 0, 0 }, /* 4 */ | |||
| { -6, 124, 11, -1 }, | |||
| { -8, 111, 28, -3 }, | |||
| { -8, 92, 49, -5 }, | |||
| { -7, 71, 71, -7 }, | |||
| { -5, 49, 92, -8 }, | |||
| { -3, 28, 111, -8 }, | |||
| { -1, 11, 124, -6 } }, | |||
| { { 0, 128, 0, 0 }, /* 5 */ | |||
| { -6, 123, 12, -1 }, | |||
| { -9, 111, 29, -3 }, | |||
| { -9, 93, 50, -6 }, | |||
| { -8, 72, 72, -8 }, | |||
| { -6, 50, 93, -9 }, | |||
| { -3, 29, 111, -9 }, | |||
| { -1, 12, 123, -6 } }, | |||
| { { 0, 128, 0, 0 }, /* 6 */ | |||
| { -7, 124, 12, -1 }, | |||
| { -10, 111, 30, -3 }, | |||
| { -10, 93, 51, -6 }, | |||
| { -9, 73, 73, -9 }, | |||
| { -6, 51, 93, -10 }, | |||
| { -3, 30, 111, -10 }, | |||
| { -1, 12, 124, -7 } }, | |||
| { { 0, 128, 0, 0 }, /* 7 */ | |||
| { -7, 123, 13, -1 }, | |||
| { -11, 112, 31, -4 }, | |||
| { -11, 94, 52, -7 }, | |||
| { -10, 74, 74, -10 }, | |||
| { -7, 52, 94, -11 }, | |||
| { -4, 31, 112, -11 }, | |||
| { -1, 13, 123, -7 } }, | |||
| { { 0, 128, 0, 0 }, /* 8 */ | |||
| { -8, 124, 13, -1 }, | |||
| { -12, 112, 32, -4 }, | |||
| { -12, 94, 53, -7 }, | |||
| { -10, 74, 74, -10 }, | |||
| { -7, 53, 94, -12 }, | |||
| { -4, 32, 112, -12 }, | |||
| { -1, 13, 124, -8 } }, | |||
| { { 0, 128, 0, 0 }, /* 9 */ | |||
| { -9, 124, 14, -1 }, | |||
| { -13, 112, 33, -4 }, | |||
| { -13, 95, 54, -8 }, | |||
| { -11, 75, 75, -11 }, | |||
| { -8, 54, 95, -13 }, | |||
| { -4, 33, 112, -13 }, | |||
| { -1, 14, 124, -9 } }, | |||
| { { 0, 128, 0, 0 }, /* 10 */ | |||
| { -9, 123, 15, -1 }, | |||
| { -14, 113, 34, -5 }, | |||
| { -14, 95, 55, -8 }, | |||
| { -12, 76, 76, -12 }, | |||
| { -8, 55, 95, -14 }, | |||
| { -5, 34, 112, -13 }, | |||
| { -1, 15, 123, -9 } }, | |||
| { { 0, 128, 0, 0 }, /* 11 */ | |||
| { -10, 124, 15, -1 }, | |||
| { -14, 113, 34, -5 }, | |||
| { -15, 96, 56, -9 }, | |||
| { -13, 77, 77, -13 }, | |||
| { -9, 56, 96, -15 }, | |||
| { -5, 34, 113, -14 }, | |||
| { -1, 15, 124, -10 } }, | |||
| { { 0, 128, 0, 0 }, /* 12 */ | |||
| { -10, 123, 16, -1 }, | |||
| { -15, 113, 35, -5 }, | |||
| { -16, 98, 56, -10 }, | |||
| { -14, 78, 78, -14 }, | |||
| { -10, 56, 98, -16 }, | |||
| { -5, 35, 113, -15 }, | |||
| { -1, 16, 123, -10 } }, | |||
| { { 0, 128, 0, 0 }, /* 13 */ | |||
| { -11, 124, 17, -2 }, | |||
| { -16, 113, 36, -5 }, | |||
| { -17, 98, 57, -10 }, | |||
| { -14, 78, 78, -14 }, | |||
| { -10, 57, 98, -17 }, | |||
| { -5, 36, 113, -16 }, | |||
| { -2, 17, 124, -11 } }, | |||
| { { 0, 128, 0, 0 }, /* 14 */ | |||
| { -12, 125, 17, -2 }, | |||
| { -17, 114, 37, -6 }, | |||
| { -18, 99, 58, -11 }, | |||
| { -15, 79, 79, -15 }, | |||
| { -11, 58, 99, -18 }, | |||
| { -6, 37, 114, -17 }, | |||
| { -2, 17, 125, -12 } }, | |||
| { { 0, 128, 0, 0 }, /* 15 */ | |||
| { -12, 124, 18, -2 }, | |||
| { -18, 114, 38, -6 }, | |||
| { -19, 99, 59, -11 }, | |||
| { -16, 80, 80, -16 }, | |||
| { -11, 59, 99, -19 }, | |||
| { -6, 38, 114, -18 }, | |||
| { -2, 18, 124, -12 } }, | |||
| }; | |||
| const vp56_tree_t vp6_pcr_tree[] = { | |||
| { 8, 0}, | |||
| { 4, 1}, | |||
| { 2, 2}, {-1}, {-2}, | |||
| { 2, 3}, {-3}, {-4}, | |||
| { 8, 4}, | |||
| { 4, 5}, | |||
| { 2, 6}, {-5}, {-6}, | |||
| { 2, 7}, {-7}, {-8}, | |||
| {-0}, | |||
| }; | |||
| static const uint8_t vp6_coord_div[] = { 4, 4, 4, 4, 8, 8 }; | |||
| #endif /* VP6DATA_H */ | |||
| @@ -184,6 +184,11 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) | |||
| switch(flags & 0xF){ | |||
| case 2: st->codec->codec_id = CODEC_ID_FLV1; break; | |||
| case 3: st->codec->codec_id = CODEC_ID_FLASHSV; break; | |||
| case 4: | |||
| st->codec->codec_id = CODEC_ID_VP6F; | |||
| get_byte(&s->pb); /* width and height adjustment */ | |||
| size--; | |||
| break; | |||
| default: | |||
| av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flags & 0xf); | |||
| st->codec->codec_tag= flags & 0xF; | |||
| @@ -182,15 +182,15 @@ static const CodecTag nsv_codec_video_tags[] = { | |||
| { CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') }, | |||
| { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') }, | |||
| { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, | |||
| { CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') }, | |||
| { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, | |||
| { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, | |||
| /* | |||
| { CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') }, | |||
| { CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') }, | |||
| { CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') }, | |||
| { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, | |||
| { CODEC_ID_VP6, MKTAG('V', 'P', '6', ' ') }, | |||
| { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') }, | |||
| { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') }, | |||
| { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, | |||
| */ | |||
| { CODEC_ID_XVID, MKTAG('X', 'V', 'I', 'D') }, /* cf sample xvid decoder from nsv_codec_sdk.zip */ | |||
| { CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', '3') }, | |||
| @@ -114,6 +114,8 @@ const CodecTag codec_bmp_tags[] = { | |||
| { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') }, | |||
| { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, | |||
| { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') }, | |||
| { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, | |||
| { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, | |||
| { CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') }, | |||
| { CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') }, | |||
| { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') }, | |||
| @@ -19,6 +19,7 @@ | |||
| */ | |||
| #include "avformat.h" | |||
| #include "bitstream.h" | |||
| #include "riff.h" /* for CodecTag */ | |||
| /* should have a generic way to indicate probable size */ | |||
| #define DUMMY_FILE_SIZE (100 * 1024 * 1024) | |||
| @@ -45,8 +46,6 @@ | |||
| #define FLAG_SETFILL0 0x02 | |||
| #define FLAG_SETFILL1 0x04 | |||
| #define SWF_VIDEO_CODEC_FLV1 0x02 | |||
| #define AUDIO_FIFO_SIZE 65536 | |||
| /* character id used */ | |||
| @@ -80,6 +79,12 @@ typedef struct { | |||
| int audio_type; | |||
| } SWFContext; | |||
| static const CodecTag swf_codec_tags[] = { | |||
| {CODEC_ID_FLV1, 0x02}, | |||
| {CODEC_ID_VP6F, 0x04}, | |||
| {0, 0}, | |||
| }; | |||
| static const int sSampleRates[3][4] = { | |||
| {44100, 48000, 32000, 0}, | |||
| {22050, 24000, 16000, 0}, | |||
| @@ -328,10 +333,12 @@ static int swf_write_header(AVFormatContext *s) | |||
| if (enc->codec_type == CODEC_TYPE_AUDIO) | |||
| audio_enc = enc; | |||
| else { | |||
| if ( enc->codec_id == CODEC_ID_FLV1 || enc->codec_id == CODEC_ID_MJPEG ) { | |||
| if ( enc->codec_id == CODEC_ID_VP6F || | |||
| enc->codec_id == CODEC_ID_FLV1 || | |||
| enc->codec_id == CODEC_ID_MJPEG ) { | |||
| video_enc = enc; | |||
| } else { | |||
| av_log(enc, AV_LOG_ERROR, "SWF only supports FLV1 and MJPEG\n"); | |||
| av_log(enc, AV_LOG_ERROR, "SWF only supports VP6, FLV1 and MJPEG\n"); | |||
| return -1; | |||
| } | |||
| } | |||
| @@ -361,7 +368,9 @@ static int swf_write_header(AVFormatContext *s) | |||
| } | |||
| put_tag(pb, "FWS"); | |||
| if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) { | |||
| if ( video_enc && video_enc->codec_id == CODEC_ID_VP6F ) { | |||
| put_byte(pb, 8); /* version (version 8 and above support VP6 codec) */ | |||
| } else if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) { | |||
| put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */ | |||
| } else { | |||
| put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */ | |||
| @@ -375,7 +384,8 @@ static int swf_write_header(AVFormatContext *s) | |||
| put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */ | |||
| /* define a shape with the jpeg inside */ | |||
| if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) { | |||
| if ( video_enc && (video_enc->codec_id == CODEC_ID_VP6F || | |||
| video_enc->codec_id == CODEC_ID_FLV1 )) { | |||
| } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) { | |||
| put_swf_tag(s, TAG_DEFINESHAPE); | |||
| @@ -512,7 +522,8 @@ retry_swf_audio_packet: | |||
| } | |||
| } | |||
| if ( swf->video_type == CODEC_ID_FLV1 ) { | |||
| if ( swf->video_type == CODEC_ID_VP6F || | |||
| swf->video_type == CODEC_ID_FLV1 ) { | |||
| if ( swf->video_frame_number == 0 ) { | |||
| /* create a new video object */ | |||
| put_swf_tag(s, TAG_VIDEOSTREAM); | |||
| @@ -521,7 +532,7 @@ retry_swf_audio_packet: | |||
| put_le16(pb, enc->width); | |||
| put_le16(pb, enc->height); | |||
| put_byte(pb, 0); | |||
| put_byte(pb, SWF_VIDEO_CODEC_FLV1); | |||
| put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type)); | |||
| put_swf_end_tag(s); | |||
| /* place the video object for the first time */ | |||
| @@ -784,18 +795,20 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| return AVERROR_IO; | |||
| } | |||
| if ( tag == TAG_VIDEOSTREAM && !vst) { | |||
| int codec_id; | |||
| swf->ch_id = get_le16(pb); | |||
| get_le16(pb); | |||
| get_le16(pb); | |||
| get_le16(pb); | |||
| get_byte(pb); | |||
| /* Check for FLV1 */ | |||
| if ( get_byte(pb) == SWF_VIDEO_CODEC_FLV1 ) { | |||
| codec_id = codec_get_id(swf_codec_tags, get_byte(pb)); | |||
| if ( codec_id ) { | |||
| vst = av_new_stream(s, 0); | |||
| av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */ | |||
| vst->codec->codec_type = CODEC_TYPE_VIDEO; | |||
| vst->codec->codec_id = CODEC_ID_FLV1; | |||
| vst->codec->codec_id = codec_id; | |||
| if ( swf->samples_per_frame ) { | |||
| vst->codec->time_base.den = 1000. / swf->ms_per_frame; | |||
| vst->codec->time_base.num = 1; | |||