diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 75877860c0..ad72965e4c 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -15,17 +15,17 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * VP3 Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the VP3 coding process, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * Theora decoder by Alex Beregszaszi - * */ /** * @file vp3.c * On2 VP3 Video Decoder + * + * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx) + * For more information about the VP3 coding process, visit: + * http://multimedia.cx/ + * + * Theora decoder by Alex Beregszaszi */ #include @@ -271,6 +271,11 @@ typedef struct Vp3DecodeContext { VLC ac_vlc_3[16]; VLC ac_vlc_4[16]; + VLC superblock_run_length_vlc; + VLC fragment_run_length_vlc; + VLC mode_code_vlc; + VLC motion_vector_vlc; + /* these arrays need to be on 16-byte boundaries since SSE2 operations * index into them */ int16_t __align16 intra_y_dequant[64]; @@ -1274,7 +1279,12 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) * that cares about the fragment coding runs */ if (current_run == 0) { bit ^= 1; +#if 1 + current_run = get_vlc2(gb, + s->fragment_run_length_vlc.table, 5, 2) + 1; +#else current_run = get_fragment_run_length(gb); +#endif } if (bit) { @@ -1404,7 +1414,14 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) if (scheme == 7) coding_mode = get_bits(gb, 3); else +{ +#if 1 + coding_mode = ModeAlphabet[scheme] + [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; +#else coding_mode = ModeAlphabet[scheme][get_mode_code(gb)]; +#endif +} s->macroblock_coding[current_macroblock] = coding_mode; for (k = 0; k < 6; k++) { @@ -1491,8 +1508,13 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) case MODE_GOLDEN_MV: /* all 6 fragments use the same motion vector */ if (coding_mode == 0) { +#if 1 + motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; + motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; +#else motion_x[0] = get_motion_vector_vlc(gb); motion_y[0] = get_motion_vector_vlc(gb); +#endif } else { motion_x[0] = get_motion_vector_fixed(gb); motion_y[0] = get_motion_vector_fixed(gb); @@ -1518,8 +1540,13 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) motion_x[4] = motion_y[4] = 0; for (k = 0; k < 4; k++) { if (coding_mode == 0) { +#if 1 + motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; + motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; +#else motion_x[k] = get_motion_vector_vlc(gb); motion_y[k] = get_motion_vector_vlc(gb); +#endif } else { motion_x[k] = get_motion_vector_fixed(gb); motion_y[k] = get_motion_vector_fixed(gb); @@ -2496,13 +2523,8 @@ static int vp3_decode_init(AVCodecContext *avctx) s->version = 1; s->avctx = avctx; -#if 0 - s->width = avctx->width; - s->height = avctx->height; -#else s->width = (avctx->width + 15) & 0xFFFFFFF0; s->height = (avctx->height + 15) & 0xFFFFFFF0; -#endif avctx->pix_fmt = PIX_FMT_YUV420P; avctx->has_b_frames = 0; if(avctx->idct_algo==FF_IDCT_AUTO) @@ -2608,6 +2630,18 @@ static int vp3_decode_init(AVCodecContext *avctx) &ac_bias_3[i][0][0], 4, 2, 0); } + init_vlc(&s->fragment_run_length_vlc, 5, 31, + &fragment_run_length_vlc_table[0][1], 4, 2, + &fragment_run_length_vlc_table[0][0], 4, 2, 0); + + init_vlc(&s->mode_code_vlc, 3, 8, + &mode_code_vlc_table[0][1], 2, 1, + &mode_code_vlc_table[0][0], 2, 1, 0); + + init_vlc(&s->motion_vector_vlc, 6, 63, + &motion_vector_vlc_table[0][1], 2, 1, + &motion_vector_vlc_table[0][0], 2, 1, 0); + /* work out the block mapping tables */ s->superblock_fragments = av_malloc(s->superblock_count * 16 * sizeof(int)); s->superblock_macroblocks = av_malloc(s->superblock_count * 4 * sizeof(int)); diff --git a/libavcodec/vp3data.h b/libavcodec/vp3data.h index df80e39a16..5a5ff9cac5 100644 --- a/libavcodec/vp3data.h +++ b/libavcodec/vp3data.h @@ -72,6 +72,76 @@ static const uint32_t vp31_filter_limit_values[64] = 0, 0, 0, 0, 0, 0, 0, 0 }; +static const uint16_t fragment_run_length_vlc_table[30][2] = { + /* 1 -> 2 */ + { 0x0, 2 }, { 0x1, 2 }, + + /* 3 -> 4 */ + { 0x4, 3 }, { 0x5, 3 }, + + /* 5 -> 6 */ + { 0xC, 4 }, { 0xD, 4 }, + + /* 7 -> 10 */ + { 0x38, 6 }, { 0x39, 6 }, + { 0x3A, 6 }, { 0x3B, 6 }, + + /* 11 -> 14 */ + { 0x78, 7 }, { 0x79, 7 }, + { 0x7A, 7 }, { 0x7B, 7 }, + + /* 15 -> 30 */ + { 0x1F0, 9 }, { 0x1F1, 9 }, { 0x1F2, 9 }, { 0x1F3, 9 }, + { 0x1F4, 9 }, { 0x1F5, 9 }, { 0x1F6, 9 }, { 0x1F7, 9 }, + { 0x1F8, 9 }, { 0x1F9, 9 }, { 0x1FA, 9 }, { 0x1FB, 9 }, + { 0x1FC, 9 }, { 0x1FD, 9 }, { 0x1FE, 9 }, { 0x1FF, 9 } +}; + +static const uint8_t mode_code_vlc_table[30][2] = { + { 0, 1 }, { 2, 2 }, + { 6, 3 }, { 14, 4 }, + { 30, 5 }, { 62, 6 }, + { 126, 7 }, { 127, 7 } +}; + +static const uint8_t motion_vector_vlc_table[63][2] = { + { 0, 3 }, + { 1, 3 }, + { 2, 3 }, + + { 6, 4 }, { 7, 4 }, + + { 8, 4 }, { 9, 4 }, + + { 40, 6 }, { 41, 6 }, { 42, 6 }, { 43, 6 }, + { 44, 6 }, { 45, 6 }, { 46, 6 }, { 47, 6 }, + + { 96, 7 }, { 97, 7 }, { 98, 7 }, { 99, 7 }, + { 100, 7 }, { 101, 7 }, { 102, 7 }, { 103, 7 }, + { 104, 7 }, { 105, 7 }, { 106, 7 }, { 107, 7 }, + { 108, 7 }, { 109, 7 }, { 110, 7 }, { 111, 7 }, + + { 0xE0, 8 }, { 0xE1, 8 }, { 0xE2, 8 }, { 0xE3, 8 }, + { 0xE4, 8 }, { 0xE5, 8 }, { 0xE6, 8 }, { 0xE7, 8 }, + { 0xE8, 8 }, { 0xE9, 8 }, { 0xEA, 8 }, { 0xEB, 8 }, + { 0xEC, 8 }, { 0xED, 8 }, { 0xEE, 8 }, { 0xEF, 8 }, + + { 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 }, + { 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 }, + { 0xF8, 8 }, { 0xF9, 8 }, { 0xFA, 8 }, { 0xFB, 8 }, + { 0xFC, 8 }, { 0xFD, 8 }, { 0xFE, 8 }, { 0xFF, 8 } +}; + +static const int motion_vector_table[63] = { + 0, 1, -1, + 2, -2, + 3, -3, + 4, -4, 5, -5, 6, -6, 7, -7, + 8, -8, 9, -9, 10, -10, 11, -11, 12, -12, 13, -13, 14, -14, 15, -15, + 16, -16, 17, -17, 18, -18, 19, -19, 20, -20, 21, -21, 22, -22, 23, -23, + 24, -24, 25, -25, 26, -26, 27, -27, 28, -28, 29, -29, 30, -30, 31, -31 +}; + static const uint16_t dc_bias[16][32][2] = { { /* DC bias table 0 */ { 0x2D, 6 },