X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp3.c;h=163847013e36d0e6f9324af66f0d7cedd85a05b7;hb=913e93d5f2639bf46d2e9acfc7df0e15b200e005;hp=e5ecd67dd98a91a3ec52eedaaf7bbb86e390c8ca;hpb=0433188259be2c7db9f28ae9be1baf5680a88e1c;p=ffmpeg diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index e5ecd67dd98..163847013e3 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1,6 +1,5 @@ /* - * - * Copyright (C) 2003 the ffmpeg project + * Copyright (C) 2003-2004 the ffmpeg project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,15 +13,19 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * VP3 Video Decoder by Mike Melanson (melanson@pcisys.net) + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * @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 @@ -34,19 +37,18 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" -#include "dsputil.h" -#include "bswap.h" #include "vp3data.h" #define FRAGMENT_PIXELS 8 -/* +/* * Debugging Variables - * + * * Define one or more of the following compile-time variables to 1 to obtain * elaborate information about certain aspects of the decoding process. * + * KEYFRAMES_ONLY: set this to 1 to only see keyframes (VP3 slideshow mode) * DEBUG_VP3: high-level decoding flow * DEBUG_INIT: initialization parameters * DEBUG_DEQUANTIZERS: display how the dequanization tables are built @@ -59,6 +61,8 @@ * DEBUG_IDCT: show every detail of the IDCT process */ +#define KEYFRAMES_ONLY 0 + #define DEBUG_VP3 0 #define DEBUG_INIT 0 #define DEBUG_DEQUANTIZERS 0 @@ -71,80 +75,83 @@ #define DEBUG_IDCT 0 #if DEBUG_VP3 -#define debug_vp3 printf +#define debug_vp3(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_vp3(const char *format, ...) { } #endif #if DEBUG_INIT -#define debug_init printf +#define debug_init(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_init(const char *format, ...) { } #endif #if DEBUG_DEQUANTIZERS -#define debug_dequantizers printf +#define debug_dequantizers(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_dequantizers(const char *format, ...) { } +static inline void debug_dequantizers(const char *format, ...) { } #endif #if DEBUG_BLOCK_CODING -#define debug_block_coding printf +#define debug_block_coding(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_block_coding(const char *format, ...) { } +static inline void debug_block_coding(const char *format, ...) { } #endif #if DEBUG_MODES -#define debug_modes printf +#define debug_modes(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_modes(const char *format, ...) { } +static inline void debug_modes(const char *format, ...) { } #endif #if DEBUG_VECTORS -#define debug_vectors printf +#define debug_vectors(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_vectors(const char *format, ...) { } +static inline void debug_vectors(const char *format, ...) { } #endif -#if DEBUG_TOKEN -#define debug_token printf +#if DEBUG_TOKEN +#define debug_token(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_token(const char *format, ...) { } +static inline void debug_token(const char *format, ...) { } #endif #if DEBUG_VLC -#define debug_vlc printf +#define debug_vlc(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_vlc(const char *format, ...) { } +static inline void debug_vlc(const char *format, ...) { } #endif #if DEBUG_DC_PRED -#define debug_dc_pred printf +#define debug_dc_pred(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_dc_pred(const char *format, ...) { } +static inline void debug_dc_pred(const char *format, ...) { } #endif #if DEBUG_IDCT -#define debug_idct printf +#define debug_idct(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else -static inline void debug_idct(const char *format, ...) { } +static inline void debug_idct(const char *format, ...) { } #endif +typedef struct Coeff { + struct Coeff *next; + DCTELEM coeff; + uint8_t index; +} Coeff; + +//FIXME split things out into their own arrays typedef struct Vp3Fragment { - DCTELEM coeffs[64]; - int coding_method; - int coeff_count; - int last_coeff; - int motion_x; - int motion_y; - /* this indicates which ffmpeg put_pixels() function to use: - * 00b = no halfpel, 01b = x halfpel, 10b = y halfpel, 11b = both halfpel */ - int motion_halfpel_index; + Coeff *next_coeff; /* address of first pixel taking into account which plane the fragment * lives on as well as the plane stride */ int first_pixel; /* this is the macroblock that the fragment belongs to */ - int macroblock; + uint16_t macroblock; + uint8_t coding_method; + uint8_t coeff_count; + int8_t motion_x; + int8_t motion_y; } Vp3Fragment; #define SB_NOT_CODED 0 @@ -171,39 +178,39 @@ static int ModeAlphabet[7][CODING_MODE_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0 }, /* scheme 1: Last motion vector dominates */ - { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, + { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, - MODE_INTRA, MODE_USING_GOLDEN, + MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 2 */ - { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, + { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV, MODE_INTER_PLUS_MV, - MODE_INTRA, MODE_USING_GOLDEN, + MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 3 */ - { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, + { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV, - MODE_INTRA, MODE_USING_GOLDEN, + MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 4 */ - { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, + { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, MODE_INTER_PRIOR_LAST, - MODE_INTRA, MODE_USING_GOLDEN, + MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 5: No motion vector dominates */ - { MODE_INTER_NO_MV, MODE_INTER_LAST_MV, + { MODE_INTER_NO_MV, MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, - MODE_INTRA, MODE_USING_GOLDEN, + MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 6 */ - { MODE_INTER_NO_MV, MODE_USING_GOLDEN, + { MODE_INTER_NO_MV, MODE_USING_GOLDEN, MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, - MODE_INTER_PLUS_MV, MODE_INTRA, + MODE_INTER_PLUS_MV, MODE_INTRA, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, }; @@ -212,12 +219,15 @@ static int ModeAlphabet[7][CODING_MODE_COUNT] = typedef struct Vp3DecodeContext { AVCodecContext *avctx; + int theora, theora_tables; + int version; int width, height; AVFrame golden_frame; AVFrame last_frame; AVFrame current_frame; int keyframe; DSPContext dsp; + int flipped_image; int quality_index; int last_quality_index; @@ -225,6 +235,10 @@ typedef struct Vp3DecodeContext { int superblock_count; int superblock_width; int superblock_height; + int y_superblock_width; + int y_superblock_height; + int c_superblock_width; + int c_superblock_height; int u_superblock_start; int v_superblock_start; unsigned char *superblock_coding; @@ -238,9 +252,20 @@ typedef struct Vp3DecodeContext { int fragment_height; Vp3Fragment *all_fragments; + Coeff *coeffs; + Coeff *next_coeff; int u_fragment_start; int v_fragment_start; + ScanTable scantable; + + /* tables */ + uint16_t coded_dc_scale_factor[64]; + uint32_t coded_ac_scale_factor[64]; + uint16_t coded_intra_y_dequant[64]; + uint16_t coded_intra_c_dequant[64]; + uint16_t coded_inter_dequant[64]; + /* this is a list of indices into the all_fragments array indicating * which of the fragments are coded */ int *coded_fragment_list; @@ -253,9 +278,16 @@ typedef struct Vp3DecodeContext { VLC ac_vlc_3[16]; VLC ac_vlc_4[16]; - int16_t intra_y_dequant[64]; - int16_t intra_c_dequant[64]; - int16_t inter_dequant[64]; + 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 */ + DECLARE_ALIGNED_16(int16_t, intra_y_dequant[64]); + DECLARE_ALIGNED_16(int16_t, intra_c_dequant[64]); + DECLARE_ALIGNED_16(int16_t, inter_dequant[64]); /* This table contains superblock_count * 16 entries. Each set of 16 * numbers corresponds to the fragment indices 0..15 of the superblock. @@ -273,17 +305,31 @@ typedef struct Vp3DecodeContext { * numbers corresponds to the fragment indices 0..5 which comprise * the macroblock (4 Y fragments and 2 C fragments). */ int *macroblock_fragments; - /* This is an array of flags indicating whether a particular - * macroblock is coded. */ - unsigned char *macroblock_coded; + /* This is an array that indicates how a particular macroblock + * is coded. */ + unsigned char *macroblock_coding; int first_coded_y_fragment; int first_coded_c_fragment; int last_coded_y_fragment; int last_coded_c_fragment; + uint8_t edge_emu_buffer[9*2048]; //FIXME dynamic alloc + uint8_t qscale_table[2048]; //FIXME dynamic alloc (width+15)/16 + + /* Huffman decode */ + int hti; + unsigned int hbits; + int entries; + int huff_code_size; + uint16_t huffman_table[80][32][2]; + + uint32_t filter_limit_values[64]; + int bounding_values_array[256]; } Vp3DecodeContext; +static int theora_decode_tables(AVCodecContext *avctx, GetBitContext gb); + /************************************************************************ * VP3 specific functions ************************************************************************/ @@ -292,8 +338,10 @@ typedef struct Vp3DecodeContext { * This function sets up all of the various blocks mappings: * superblocks <-> fragments, macroblocks <-> fragments, * superblocks <-> macroblocks + * + * Returns 0 is successful; returns 1 if *anything* went wrong. */ -static void init_block_mapping(Vp3DecodeContext *s) +static int init_block_mapping(Vp3DecodeContext *s) { int i, j; signed int hilbert_walk_y[16]; @@ -313,7 +361,7 @@ static void init_block_mapping(Vp3DecodeContext *s) int c_fragment; signed char travel_width[16] = { - 1, 1, 0, -1, + 1, 1, 0, -1, 0, 0, 1, 0, 1, 0, 1, 0, 0, -1, 0, 1 @@ -387,9 +435,10 @@ static void init_block_mapping(Vp3DecodeContext *s) /* start of Y superblocks */ right_edge = s->fragment_width; bottom_edge = s->fragment_height; - current_width = 0; + current_width = -1; current_height = 0; - superblock_row_inc = 3 * s->fragment_width; + superblock_row_inc = 3 * s->fragment_width - + (s->y_superblock_width * 4 - s->fragment_width); hilbert = hilbert_walk_y; /* the first operation for this variable is to advance by 1 */ @@ -400,9 +449,10 @@ static void init_block_mapping(Vp3DecodeContext *s) /* start of U superblocks */ right_edge = s->fragment_width / 2; bottom_edge = s->fragment_height / 2; - current_width = 0; + current_width = -1; current_height = 0; - superblock_row_inc = 3 * (s->fragment_width / 2); + superblock_row_inc = 3 * (s->fragment_width / 2) - + (s->c_superblock_width * 4 - s->fragment_width / 2); hilbert = hilbert_walk_c; /* the first operation for this variable is to advance by 1 */ @@ -413,9 +463,10 @@ static void init_block_mapping(Vp3DecodeContext *s) /* start of V superblocks */ right_edge = s->fragment_width / 2; bottom_edge = s->fragment_height / 2; - current_width = 0; + current_width = -1; current_height = 0; - superblock_row_inc = 3 * (s->fragment_width / 2); + superblock_row_inc = 3 * (s->fragment_width / 2) - + (s->c_superblock_width * 4 - s->fragment_width / 2); hilbert = hilbert_walk_c; /* the first operation for this variable is to advance by 1 */ @@ -423,9 +474,9 @@ static void init_block_mapping(Vp3DecodeContext *s) } - if (current_width >= right_edge) { + if (current_width >= right_edge - 1) { /* reset width and move to next superblock row */ - current_width = 0; + current_width = -1; current_height += 4; /* fragment is now at the start of a new superblock row */ @@ -435,21 +486,23 @@ static void init_block_mapping(Vp3DecodeContext *s) /* iterate through all 16 fragments in a superblock */ for (j = 0; j < 16; j++) { current_fragment += hilbert[j]; + current_width += travel_width[j]; current_height += travel_height[j]; /* check if the fragment is in bounds */ - if ((current_width <= right_edge) && + if ((current_width < right_edge) && (current_height < bottom_edge)) { s->superblock_fragments[mapping_index] = current_fragment; - debug_init(" mapping fragment %d to superblock %d, position %d\n", - s->superblock_fragments[mapping_index], i, j); + debug_init(" mapping fragment %d to superblock %d, position %d (%d/%d x %d/%d)\n", + s->superblock_fragments[mapping_index], i, j, + current_width, right_edge, current_height, bottom_edge); } else { s->superblock_fragments[mapping_index] = -1; - debug_init(" superblock %d, position %d has no fragment\n", - i, j); + debug_init(" superblock %d, position %d has no fragment (%d/%d x %d/%d)\n", + i, j, + current_width, right_edge, current_height, bottom_edge); } - current_width += travel_width[j]; mapping_index++; } } @@ -458,17 +511,18 @@ static void init_block_mapping(Vp3DecodeContext *s) * all of the Y plane superblocks to build this mapping */ right_edge = s->macroblock_width; bottom_edge = s->macroblock_height; - current_width = 0; + current_width = -1; current_height = 0; - superblock_row_inc = s->macroblock_width; + superblock_row_inc = s->macroblock_width - + (s->y_superblock_width * 2 - s->macroblock_width);; hilbert = hilbert_walk_mb; mapping_index = 0; current_macroblock = -1; for (i = 0; i < s->u_superblock_start; i++) { - if (current_width >= right_edge) { + if (current_width >= right_edge - 1) { /* reset width and move to next superblock row */ - current_width = 0; + current_width = -1; current_height += 2; /* macroblock is now at the start of a new superblock row */ @@ -478,21 +532,23 @@ static void init_block_mapping(Vp3DecodeContext *s) /* iterate through each potential macroblock in the superblock */ for (j = 0; j < 4; j++) { current_macroblock += hilbert_walk_mb[j]; + current_width += travel_width_mb[j]; current_height += travel_height_mb[j]; /* check if the macroblock is in bounds */ - if ((current_width <= right_edge) && + if ((current_width < right_edge) && (current_height < bottom_edge)) { s->superblock_macroblocks[mapping_index] = current_macroblock; - debug_init(" mapping macroblock %d to superblock %d, position %d\n", - s->superblock_macroblocks[mapping_index], i, j); + debug_init(" mapping macroblock %d to superblock %d, position %d (%d/%d x %d/%d)\n", + s->superblock_macroblocks[mapping_index], i, j, + current_width, right_edge, current_height, bottom_edge); } else { s->superblock_macroblocks[mapping_index] = -1; - debug_init(" superblock %d, position %d has no macroblock\n", - i, j); + debug_init(" superblock %d, position %d has no macroblock (%d/%d x %d/%d)\n", + i, j, + current_width, right_edge, current_height, bottom_edge); } - current_width += travel_width_mb[j]; mapping_index++; } } @@ -518,33 +574,33 @@ static void init_block_mapping(Vp3DecodeContext *s) s->macroblock_fragments[mapping_index++] = -1; if (i + 1 < s->fragment_height) { - s->all_fragments[current_fragment + s->fragment_width].macroblock = + s->all_fragments[current_fragment + s->fragment_width].macroblock = current_macroblock; - s->macroblock_fragments[mapping_index++] = + s->macroblock_fragments[mapping_index++] = current_fragment + s->fragment_width; debug_init("%d ", current_fragment + s->fragment_width); } else s->macroblock_fragments[mapping_index++] = -1; if ((j + 1 < s->fragment_width) && (i + 1 < s->fragment_height)) { - s->all_fragments[current_fragment + s->fragment_width + 1].macroblock = + s->all_fragments[current_fragment + s->fragment_width + 1].macroblock = current_macroblock; - s->macroblock_fragments[mapping_index++] = + s->macroblock_fragments[mapping_index++] = current_fragment + s->fragment_width + 1; debug_init("%d ", current_fragment + s->fragment_width + 1); } else s->macroblock_fragments[mapping_index++] = -1; /* C planes */ - c_fragment = s->u_fragment_start + + c_fragment = s->u_fragment_start + (i * s->fragment_width / 4) + (j / 2); - s->all_fragments[c_fragment].macroblock = s->macroblock_count; + s->all_fragments[c_fragment].macroblock = s->macroblock_count; s->macroblock_fragments[mapping_index++] = c_fragment; debug_init("%d ", c_fragment); - c_fragment = s->v_fragment_start + + c_fragment = s->v_fragment_start + (i * s->fragment_width / 4) + (j / 2); - s->all_fragments[c_fragment].macroblock = s->macroblock_count; + s->all_fragments[c_fragment].macroblock = s->macroblock_count; s->macroblock_fragments[mapping_index++] = c_fragment; debug_init("%d ", c_fragment); @@ -552,237 +608,15 @@ static void init_block_mapping(Vp3DecodeContext *s) if (j + 2 <= s->fragment_width) current_fragment += 2; - else + else current_fragment++; current_macroblock++; } current_fragment += s->fragment_width; } -} - -/* - * This function unpacks a single token (which should be in the range 0..31) - * and returns a zero run (number of zero coefficients in current DCT matrix - * before next non-zero coefficient), the next DCT coefficient, and the - * number of consecutive, non-EOB'd DCT blocks to EOB. - */ -static void unpack_token(GetBitContext *gb, int token, int *zero_run, - DCTELEM *coeff, int *eob_run) -{ - int sign; - - *zero_run = 0; - *eob_run = 0; - *coeff = 0; - - debug_token(" vp3 token %d: ", token); - switch (token) { - - case 0: - debug_token("DCT_EOB_TOKEN, EOB next block\n"); - *eob_run = 1; - break; - - case 1: - debug_token("DCT_EOB_PAIR_TOKEN, EOB next 2 blocks\n"); - *eob_run = 2; - break; - - case 2: - debug_token("DCT_EOB_TRIPLE_TOKEN, EOB next 3 blocks\n"); - *eob_run = 3; - break; - - case 3: - debug_token("DCT_REPEAT_RUN_TOKEN, "); - *eob_run = get_bits(gb, 2) + 4; - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 4: - debug_token("DCT_REPEAT_RUN2_TOKEN, "); - *eob_run = get_bits(gb, 3) + 8; - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 5: - debug_token("DCT_REPEAT_RUN3_TOKEN, "); - *eob_run = get_bits(gb, 4) + 16; - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 6: - debug_token("DCT_REPEAT_RUN4_TOKEN, "); - *eob_run = get_bits(gb, 12); - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 7: - debug_token("DCT_SHORT_ZRL_TOKEN, "); - /* note that this token actually indicates that (3 extra bits) + 1 0s - * should be output; this case specifies a run of (3 EBs) 0s and a - * coefficient of 0. */ - *zero_run = get_bits(gb, 3); - *coeff = 0; - debug_token("skip the next %d positions in output matrix\n", *zero_run + 1); - break; - - case 8: - debug_token("DCT_ZRL_TOKEN, "); - /* note that this token actually indicates that (6 extra bits) + 1 0s - * should be output; this case specifies a run of (6 EBs) 0s and a - * coefficient of 0. */ - *zero_run = get_bits(gb, 6); - *coeff = 0; - debug_token("skip the next %d positions in output matrix\n", *zero_run + 1); - break; - - case 9: - debug_token("ONE_TOKEN, output 1\n"); - *coeff = 1; - break; - - case 10: - debug_token("MINUS_ONE_TOKEN, output -1\n"); - *coeff = -1; - break; - - case 11: - debug_token("TWO_TOKEN, output 2\n"); - *coeff = 2; - break; - - case 12: - debug_token("MINUS_TWO_TOKEN, output -2\n"); - *coeff = -2; - break; - - case 13: - case 14: - case 15: - case 16: - debug_token("LOW_VAL_TOKENS, "); - if (get_bits(gb, 1)) - *coeff = -(3 + (token - 13)); - else - *coeff = 3 + (token - 13); - debug_token("output %d\n", *coeff); - break; - - case 17: - debug_token("DCT_VAL_CATEGORY3, "); - sign = get_bits(gb, 1); - *coeff = 7 + get_bits(gb, 1); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 18: - debug_token("DCT_VAL_CATEGORY4, "); - sign = get_bits(gb, 1); - *coeff = 9 + get_bits(gb, 2); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 19: - debug_token("DCT_VAL_CATEGORY5, "); - sign = get_bits(gb, 1); - *coeff = 13 + get_bits(gb, 3); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 20: - debug_token("DCT_VAL_CATEGORY6, "); - sign = get_bits(gb, 1); - *coeff = 21 + get_bits(gb, 4); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 21: - debug_token("DCT_VAL_CATEGORY7, "); - sign = get_bits(gb, 1); - *coeff = 37 + get_bits(gb, 5); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 22: - debug_token("DCT_VAL_CATEGORY8, "); - sign = get_bits(gb, 1); - *coeff = 69 + get_bits(gb, 9); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 23: - case 24: - case 25: - case 26: - case 27: - debug_token("DCT_RUN_CATEGORY1, "); - *zero_run = token - 22; - if (get_bits(gb, 1)) - *coeff = -1; - else - *coeff = 1; - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 28: - debug_token("DCT_RUN_CATEGORY1B, "); - if (get_bits(gb, 1)) - *coeff = -1; - else - *coeff = 1; - *zero_run = 6 + get_bits(gb, 2); - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 29: - debug_token("DCT_RUN_CATEGORY1C, "); - if (get_bits(gb, 1)) - *coeff = -1; - else - *coeff = 1; - *zero_run = 10 + get_bits(gb, 3); - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 30: - debug_token("DCT_RUN_CATEGORY2, "); - sign = get_bits(gb, 1); - *coeff = 2 + get_bits(gb, 1); - if (sign) - *coeff = -(*coeff); - *zero_run = 1; - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 31: - debug_token("DCT_RUN_CATEGORY2, "); - sign = get_bits(gb, 1); - *coeff = 2 + get_bits(gb, 1); - if (sign) - *coeff = -(*coeff); - *zero_run = 2 + get_bits(gb, 1); - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - default: - printf (" vp3: help! Got a bad token: %d > 31\n", token); - break; - } + return 0; /* successful path out */ } /* @@ -795,26 +629,30 @@ static void init_frame(Vp3DecodeContext *s, GetBitContext *gb) /* zero out all of the fragment information */ s->coded_fragment_list_index = 0; for (i = 0; i < s->fragment_count; i++) { - memset(s->all_fragments[i].coeffs, 0, 64 * sizeof(DCTELEM)); s->all_fragments[i].coeff_count = 0; - s->all_fragments[i].last_coeff = 0; + s->all_fragments[i].motion_x = 127; + s->all_fragments[i].motion_y = 127; + s->all_fragments[i].next_coeff= NULL; + s->coeffs[i].index= + s->coeffs[i].coeff=0; + s->coeffs[i].next= NULL; } } /* - * This function sets of the dequantization tables used for a particular + * This function sets up the dequantization tables used for a particular * frame. */ static void init_dequantizer(Vp3DecodeContext *s) { - int quality_scale = vp31_quality_threshold[s->quality_index]; - int dc_scale_factor = vp31_dc_scale_factor[s->quality_index]; + int ac_scale_factor = s->coded_ac_scale_factor[s->quality_index]; + int dc_scale_factor = s->coded_dc_scale_factor[s->quality_index]; int i, j; debug_vp3(" vp3: initializing dequantization tables\n"); - /* + /* * Scale dequantizers: * * quantizer * sf @@ -822,24 +660,24 @@ static void init_dequantizer(Vp3DecodeContext *s) * 100 * * where sf = dc_scale_factor for DC quantizer - * or quality_scale for AC quantizer + * or ac_scale_factor for AC quantizer * * Then, saturate the result to a lower limit of MIN_DEQUANT_VAL. */ -#define SCALER 1 +#define SCALER 4 /* scale DC quantizers */ - s->intra_y_dequant[0] = vp31_intra_y_dequant[0] * dc_scale_factor / 100; + s->intra_y_dequant[0] = s->coded_intra_y_dequant[0] * dc_scale_factor / 100; if (s->intra_y_dequant[0] < MIN_DEQUANT_VAL * 2) s->intra_y_dequant[0] = MIN_DEQUANT_VAL * 2; s->intra_y_dequant[0] *= SCALER; - s->intra_c_dequant[0] = vp31_intra_c_dequant[0] * dc_scale_factor / 100; + s->intra_c_dequant[0] = s->coded_intra_c_dequant[0] * dc_scale_factor / 100; if (s->intra_c_dequant[0] < MIN_DEQUANT_VAL * 2) s->intra_c_dequant[0] = MIN_DEQUANT_VAL * 2; s->intra_c_dequant[0] *= SCALER; - s->inter_dequant[0] = vp31_inter_dequant[0] * dc_scale_factor / 100; + s->inter_dequant[0] = s->coded_inter_dequant[0] * dc_scale_factor / 100; if (s->inter_dequant[0] < MIN_DEQUANT_VAL * 4) s->inter_dequant[0] = MIN_DEQUANT_VAL * 4; s->inter_dequant[0] *= SCALER; @@ -847,25 +685,27 @@ static void init_dequantizer(Vp3DecodeContext *s) /* scale AC quantizers, zigzag at the same time in preparation for * the dequantization phase */ for (i = 1; i < 64; i++) { + int k= s->scantable.scantable[i]; + j = s->scantable.permutated[i]; - j = quant_index[i]; - - s->intra_y_dequant[j] = vp31_intra_y_dequant[i] * quality_scale / 100; + s->intra_y_dequant[j] = s->coded_intra_y_dequant[k] * ac_scale_factor / 100; if (s->intra_y_dequant[j] < MIN_DEQUANT_VAL) s->intra_y_dequant[j] = MIN_DEQUANT_VAL; s->intra_y_dequant[j] *= SCALER; - s->intra_c_dequant[j] = vp31_intra_c_dequant[i] * quality_scale / 100; + s->intra_c_dequant[j] = s->coded_intra_c_dequant[k] * ac_scale_factor / 100; if (s->intra_c_dequant[j] < MIN_DEQUANT_VAL) s->intra_c_dequant[j] = MIN_DEQUANT_VAL; s->intra_c_dequant[j] *= SCALER; - s->inter_dequant[j] = vp31_inter_dequant[i] * quality_scale / 100; + s->inter_dequant[j] = s->coded_inter_dequant[k] * ac_scale_factor / 100; if (s->inter_dequant[j] < MIN_DEQUANT_VAL * 2) s->inter_dequant[j] = MIN_DEQUANT_VAL * 2; s->inter_dequant[j] *= SCALER; } + memset(s->qscale_table, (FFMAX(s->intra_y_dequant[1], s->intra_c_dequant[1])+8)/16, 512); //FIXME finetune + /* print debug information as requested */ debug_dequantizers("intra Y dequantizers:\n"); for (i = 0; i < 8; i++) { @@ -896,223 +736,39 @@ static void init_dequantizer(Vp3DecodeContext *s) } /* - * This function is used to fetch runs of 1s or 0s from the bitstream for - * use in determining which superblocks are fully and partially coded. - * - * Codeword RunLength - * 0 1 - * 10x 2-3 - * 110x 4-5 - * 1110xx 6-9 - * 11110xxx 10-17 - * 111110xxxx 18-33 - * 111111xxxxxxxxxxxx 34-4129 - */ -static int get_superblock_run_length(GetBitContext *gb) -{ - - if (get_bits(gb, 1) == 0) - return 1; - - else if (get_bits(gb, 1) == 0) - return (2 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (4 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (6 + get_bits(gb, 2)); - - else if (get_bits(gb, 1) == 0) - return (10 + get_bits(gb, 3)); - - else if (get_bits(gb, 1) == 0) - return (18 + get_bits(gb, 4)); - - else - return (34 + get_bits(gb, 12)); - -} - -/* - * This function is used to fetch runs of 1s or 0s from the bitstream for - * use in determining which particular fragments are coded. - * - * Codeword RunLength - * 0x 1-2 - * 10x 3-4 - * 110x 5-6 - * 1110xx 7-10 - * 11110xx 11-14 - * 11111xxxx 15-30 - */ -static int get_fragment_run_length(GetBitContext *gb) -{ - - if (get_bits(gb, 1) == 0) - return (1 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (3 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (5 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (7 + get_bits(gb, 2)); - - else if (get_bits(gb, 1) == 0) - return (11 + get_bits(gb, 2)); - - else - return (15 + get_bits(gb, 4)); - -} - -/* - * This function decodes a VLC from the bitstream and returns a number - * that ranges from 0..7. The number indicates which of the 8 coding - * modes to use. - * - * VLC Number - * 0 0 - * 10 1 - * 110 2 - * 1110 3 - * 11110 4 - * 111110 5 - * 1111110 6 - * 1111111 7 - * - */ -static int get_mode_code(GetBitContext *gb) -{ - - if (get_bits(gb, 1) == 0) - return 0; - - else if (get_bits(gb, 1) == 0) - return 1; - - else if (get_bits(gb, 1) == 0) - return 2; - - else if (get_bits(gb, 1) == 0) - return 3; - - else if (get_bits(gb, 1) == 0) - return 4; - - else if (get_bits(gb, 1) == 0) - return 5; - - else if (get_bits(gb, 1) == 0) - return 6; - - else - return 7; - -} - -/* - * This function extracts a motion vector from the bitstream using a VLC - * scheme. 3 bits are fetched from the bitstream and 1 of 8 actions is - * taken depending on the value on those 3 bits: - * - * 0: return 0 - * 1: return 1 - * 2: return -1 - * 3: if (next bit is 1) return -2, else return 2 - * 4: if (next bit is 1) return -3, else return 3 - * 5: return 4 + (next 2 bits), next bit is sign - * 6: return 8 + (next 3 bits), next bit is sign - * 7: return 16 + (next 4 bits), next bit is sign + * This function initializes the loop filter boundary limits if the frame's + * quality index is different from the previous frame's. */ -static int get_motion_vector_vlc(GetBitContext *gb) +static void init_loop_filter(Vp3DecodeContext *s) { - int bits; - - bits = get_bits(gb, 3); - - switch(bits) { - - case 0: - bits = 0; - break; - - case 1: - bits = 1; - break; - - case 2: - bits = -1; - break; - - case 3: - if (get_bits(gb, 1) == 0) - bits = 2; - else - bits = -2; - break; - - case 4: - if (get_bits(gb, 1) == 0) - bits = 3; - else - bits = -3; - break; - - case 5: - bits = 4 + get_bits(gb, 2); - if (get_bits(gb, 1) == 1) - bits = -bits; - break; - - case 6: - bits = 8 + get_bits(gb, 3); - if (get_bits(gb, 1) == 1) - bits = -bits; - break; - - case 7: - bits = 16 + get_bits(gb, 4); - if (get_bits(gb, 1) == 1) - bits = -bits; - break; - + int *bounding_values= s->bounding_values_array+127; + int filter_limit; + int x; + + filter_limit = s->filter_limit_values[s->quality_index]; + + /* set up the bounding values */ + memset(s->bounding_values_array, 0, 256 * sizeof(int)); + for (x = 0; x < filter_limit; x++) { + bounding_values[-x - filter_limit] = -filter_limit + x; + bounding_values[-x] = -x; + bounding_values[x] = x; + bounding_values[x + filter_limit] = filter_limit - x; } - - return bits; } /* - * This function fetches a 5-bit number from the stream followed by - * a sign and calls it a motion vector. - */ -static int get_motion_vector_fixed(GetBitContext *gb) -{ - - int bits; - - bits = get_bits(gb, 5); - - if (get_bits(gb, 1) == 1) - bits = -bits; - - return bits; -} - -/* - * This function unpacks all of the superblock/macroblock/fragment coding + * This function unpacks all of the superblock/macroblock/fragment coding * information from the bitstream. */ -static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) +static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) { int bit = 0; int current_superblock = 0; int current_run = 0; int decode_fully_flags = 0; int decode_partial_blocks = 0; + int first_c_fragment_seen; int i, j; int current_fragment; @@ -1128,13 +784,16 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) /* unpack the list of partially-coded superblocks */ bit = get_bits(gb, 1); - /* toggle the bit because as soon as the first run length is + /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; while (current_superblock < s->superblock_count) { - if (current_run == 0) { + if (current_run-- == 0) { bit ^= 1; - current_run = get_superblock_run_length(gb); + current_run = get_vlc2(gb, + s->superblock_run_length_vlc.table, 6, 2); + if (current_run == 33) + current_run += get_bits(gb, 12); debug_block_coding(" setting superblocks %d..%d to %s\n", current_superblock, current_superblock + current_run - 1, @@ -1142,18 +801,16 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) /* if any of the superblocks are not partially coded, flag * a boolean to decode the list of fully-coded superblocks */ - if (bit == 0) + if (bit == 0) { decode_fully_flags = 1; - } else { - - /* make a note of the fact that there are partially coded - * superblocks */ - decode_partial_blocks = 1; + } else { + /* make a note of the fact that there are partially coded + * superblocks */ + decode_partial_blocks = 1; + } } - s->superblock_coding[current_superblock++] = - (bit) ? SB_PARTIALLY_CODED : SB_NOT_CODED; - current_run--; + s->superblock_coding[current_superblock++] = bit; } /* unpack the list of fully coded superblocks if any of the blocks were @@ -1163,7 +820,7 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) current_superblock = 0; current_run = 0; bit = get_bits(gb, 1); - /* toggle the bit because as soon as the first run length is + /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; while (current_superblock < s->superblock_count) { @@ -1171,17 +828,18 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) /* skip any superblocks already marked as partially coded */ if (s->superblock_coding[current_superblock] == SB_NOT_CODED) { - if (current_run == 0) { + if (current_run-- == 0) { bit ^= 1; - current_run = get_superblock_run_length(gb); + current_run = get_vlc2(gb, + s->superblock_run_length_vlc.table, 6, 2); + if (current_run == 33) + current_run += get_bits(gb, 12); } debug_block_coding(" setting superblock %d to %s\n", current_superblock, (bit) ? "fully coded" : "not coded"); - s->superblock_coding[current_superblock] = - (bit) ? SB_FULLY_CODED : SB_NOT_CODED; - current_run--; + s->superblock_coding[current_superblock] = 2*bit; } current_superblock++; } @@ -1193,7 +851,7 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) current_run = 0; bit = get_bits(gb, 1); - /* toggle the bit because as soon as the first run length is + /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; } @@ -1202,9 +860,11 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) /* figure out which fragments are coded; iterate through each * superblock (all planes) */ s->coded_fragment_list_index = 0; + s->next_coeff= s->coeffs + s->fragment_count; s->first_coded_y_fragment = s->first_coded_c_fragment = 0; s->last_coded_y_fragment = s->last_coded_c_fragment = -1; - memset(s->macroblock_coded, 0, s->macroblock_count); + first_c_fragment_seen = 0; + memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); for (i = 0; i < s->superblock_count; i++) { /* iterate through all 16 fragments in a superblock */ @@ -1212,35 +872,45 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) /* if the fragment is in bounds, check its coding status */ current_fragment = s->superblock_fragments[i * 16 + j]; + if (current_fragment >= s->fragment_count) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_superblocks(): bad fragment number (%d >= %d)\n", + current_fragment, s->fragment_count); + return 1; + } if (current_fragment != -1) { if (s->superblock_coding[i] == SB_NOT_CODED) { /* copy all the fragments from the prior frame */ - s->all_fragments[current_fragment].coding_method = + s->all_fragments[current_fragment].coding_method = MODE_COPY; } else if (s->superblock_coding[i] == SB_PARTIALLY_CODED) { /* fragment may or may not be coded; this is the case * that cares about the fragment coding runs */ - if (current_run == 0) { + if (current_run-- == 0) { bit ^= 1; - current_run = get_fragment_run_length(gb); + current_run = get_vlc2(gb, + s->fragment_run_length_vlc.table, 5, 2); } if (bit) { - /* mode will be decoded in the next phase */ - s->all_fragments[current_fragment].coding_method = + /* default mode; actual mode will be decoded in + * the next phase */ + s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; - s->coded_fragment_list[s->coded_fragment_list_index] = + s->all_fragments[current_fragment].next_coeff= s->coeffs + current_fragment; + s->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->u_fragment_start) && - (s->last_coded_y_fragment == -1)) { + (s->last_coded_y_fragment == -1) && + (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; s->last_coded_y_fragment = s->first_coded_c_fragment - 1; + first_c_fragment_seen = 1; } s->coded_fragment_list_index++; - s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1; + s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; debug_block_coding(" superblock %d is partially coded, fragment %d is coded\n", i, current_fragment); } else { @@ -1251,23 +921,24 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) i, current_fragment); } - current_run--; - } else { /* fragments are fully coded in this superblock; actual * coding will be determined in next step */ - s->all_fragments[current_fragment].coding_method = + s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; - s->coded_fragment_list[s->coded_fragment_list_index] = + s->all_fragments[current_fragment].next_coeff= s->coeffs + current_fragment; + s->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->u_fragment_start) && - (s->last_coded_y_fragment == -1)) { + (s->last_coded_y_fragment == -1) && + (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; s->last_coded_y_fragment = s->first_coded_c_fragment - 1; + first_c_fragment_seen = 1; } s->coded_fragment_list_index++; - s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1; + s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; debug_block_coding(" superblock %d is fully coded, fragment %d is coded\n", i, current_fragment); } @@ -1275,24 +946,28 @@ static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) } } - if (s->first_coded_c_fragment == 0) - /* no C fragments coded */ + if (!first_c_fragment_seen) + /* only Y fragments coded in this frame */ s->last_coded_y_fragment = s->coded_fragment_list_index - 1; else + /* end the list of coded C fragments */ s->last_coded_c_fragment = s->coded_fragment_list_index - 1; + debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", s->coded_fragment_list_index, s->first_coded_y_fragment, s->last_coded_y_fragment, s->first_coded_c_fragment, s->last_coded_c_fragment); + + return 0; } /* * This function unpacks all the coding mode data for individual macroblocks * from the bitstream. */ -static void unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) +static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) { int i, j, k; int scheme; @@ -1322,7 +997,7 @@ static void unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) } for (i = 0; i < 8; i++) - debug_modes(" mode[%d][%d] = %d\n", scheme, i, + debug_modes(" mode[%d][%d] = %d\n", scheme, i, ModeAlphabet[scheme][i]); /* iterate through all of the macroblocks that contain 1 or more @@ -1332,19 +1007,33 @@ static void unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) for (j = 0; j < 4; j++) { current_macroblock = s->superblock_macroblocks[i * 4 + j]; if ((current_macroblock == -1) || - (!s->macroblock_coded[current_macroblock])) + (s->macroblock_coding[current_macroblock] == MODE_COPY)) continue; + if (current_macroblock >= s->macroblock_count) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_modes(): bad macroblock number (%d >= %d)\n", + current_macroblock, s->macroblock_count); + return 1; + } /* mode 7 means get 3 bits for each coding mode */ if (scheme == 7) coding_mode = get_bits(gb, 3); else - coding_mode = ModeAlphabet[scheme][get_mode_code(gb)]; + coding_mode = ModeAlphabet[scheme] + [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; + s->macroblock_coding[current_macroblock] = coding_mode; for (k = 0; k < 6; k++) { - current_fragment = + current_fragment = s->macroblock_fragments[current_macroblock * 6 + k]; - if (s->all_fragments[current_fragment].coding_method != + if (current_fragment == -1) + continue; + if (current_fragment >= s->fragment_count) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_modes(): bad fragment number (%d >= %d)\n", + current_fragment, s->fragment_count); + return 1; + } + if (s->all_fragments[current_fragment].coding_method != MODE_COPY) s->all_fragments[current_fragment].coding_method = coding_mode; @@ -1355,62 +1044,15 @@ static void unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) } } } -} -/* - * This function adjusts the components of a motion vector for the halfpel - * motion grid. c_plane indicates whether the vector applies to the U or V - * plane. The function returns the halfpel function index to be used in - * ffmpeg's put_pixels[]() array of functions. - */ -static inline int adjust_vector(int *x, int *y, int c_plane) -{ - int motion_halfpel_index = 0; - int x_halfpel; - int y_halfpel; - - if (!c_plane) { - - x_halfpel = *x & 1; - motion_halfpel_index |= x_halfpel; - if (*x >= 0) - *x >>= 1; - else - *x = -( (-(*x) >> 1) + x_halfpel); - - y_halfpel = *y & 1; - motion_halfpel_index |= (y_halfpel << 1); - if (*y >= 0) - *y >>= 1; - else - *y = -( (-(*y) >> 1) + y_halfpel); - - } else { - - x_halfpel = ((*x & 0x03) != 0); - motion_halfpel_index |= x_halfpel; - if (*x >= 0) - *x >>= 2; - else - *x = -( (-(*x) >> 2) + x_halfpel); - - y_halfpel = ((*y & 0x03) != 0); - motion_halfpel_index |= (y_halfpel << 1); - if (*y >= 0) - *y >>= 2; - else - *y = -( (-(*y) >> 2) + y_halfpel); - - } - - return motion_halfpel_index; + return 0; } /* * This function unpacks all the motion vectors for the individual * macroblocks from the bitstream. */ -static void unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) +static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) { int i, j, k; int coding_mode; @@ -1424,7 +1066,6 @@ static void unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) int current_fragment; debug_vp3(" vp3: unpacking motion vectors\n"); - if (s->keyframe) { debug_vp3(" keyframe-- there are no motion vectors\n"); @@ -1446,29 +1087,40 @@ static void unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) for (j = 0; j < 4; j++) { current_macroblock = s->superblock_macroblocks[i * 4 + j]; if ((current_macroblock == -1) || - (!s->macroblock_coded[current_macroblock])) + (s->macroblock_coding[current_macroblock] == MODE_COPY)) continue; + if (current_macroblock >= s->macroblock_count) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad macroblock number (%d >= %d)\n", + current_macroblock, s->macroblock_count); + return 1; + } current_fragment = s->macroblock_fragments[current_macroblock * 6]; - switch (s->all_fragments[current_fragment].coding_method) { + if (current_fragment >= s->fragment_count) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad fragment number (%d >= %d\n", + current_fragment, s->fragment_count); + return 1; + } + switch (s->macroblock_coding[current_macroblock]) { case MODE_INTER_PLUS_MV: case MODE_GOLDEN_MV: /* all 6 fragments use the same motion vector */ if (coding_mode == 0) { - motion_x[0] = get_motion_vector_vlc(gb); - motion_y[0] = get_motion_vector_vlc(gb); + 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_fixed(gb); - motion_y[0] = get_motion_vector_fixed(gb); + motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)]; + motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)]; } + for (k = 1; k < 6; k++) { motion_x[k] = motion_x[0]; motion_y[k] = motion_y[0]; } /* vector maintenance, only on MODE_INTER_PLUS_MV */ - if (s->all_fragments[current_fragment].coding_method == + if (s->macroblock_coding[current_macroblock] == MODE_INTER_PLUS_MV) { prior_last_motion_x = last_motion_x; prior_last_motion_y = last_motion_y; @@ -1483,23 +1135,23 @@ static void unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) motion_x[4] = motion_y[4] = 0; for (k = 0; k < 4; k++) { if (coding_mode == 0) { - motion_x[k] = get_motion_vector_vlc(gb); - motion_y[k] = get_motion_vector_vlc(gb); + motion_x[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; + motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; } else { - motion_x[k] = get_motion_vector_fixed(gb); - motion_y[k] = get_motion_vector_fixed(gb); + motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)]; + motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)]; } motion_x[4] += motion_x[k]; motion_y[4] += motion_y[k]; } - if (motion_x[4] >= 0) + if (motion_x[4] >= 0) motion_x[4] = (motion_x[4] + 2) / 4; else motion_x[4] = (motion_x[4] - 2) / 4; motion_x[5] = motion_x[4]; - if (motion_y[4] >= 0) + if (motion_y[4] >= 0) motion_y[4] = (motion_y[4] + 2) / 4; else motion_y[4] = (motion_y[4] - 2) / 4; @@ -1555,25 +1207,30 @@ static void unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) /* assign the motion vectors to the correct fragments */ debug_vectors(" vectors for macroblock starting @ fragment %d (coding method %d):\n", current_fragment, - s->all_fragments[current_fragment].coding_method); + s->macroblock_coding[current_macroblock]); for (k = 0; k < 6; k++) { - current_fragment = + current_fragment = s->macroblock_fragments[current_macroblock * 6 + k]; - s->all_fragments[current_fragment].motion_halfpel_index = - adjust_vector(&motion_x[k], &motion_y[k], - ((k == 4) || (k == 5))); + if (current_fragment == -1) + continue; + if (current_fragment >= s->fragment_count) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad fragment number (%d >= %d)\n", + current_fragment, s->fragment_count); + return 1; + } s->all_fragments[current_fragment].motion_x = motion_x[k]; s->all_fragments[current_fragment].motion_y = motion_y[k]; - debug_vectors(" vector %d: fragment %d = (%d, %d), index %d\n", - k, current_fragment, motion_x[k], motion_y[k], - s->all_fragments[current_fragment].motion_halfpel_index); + debug_vectors(" vector %d: fragment %d = (%d, %d)\n", + k, current_fragment, motion_x[k], motion_y[k]); } } } } + + return 0; } -/* +/* * This function is called by unpack_dct_coeffs() to extract the VLCs from * the bitstream. The VLCs encode tokens which are used to unpack DCT * data. This function unpacks all the VLCs for either the Y plane or both @@ -1592,9 +1249,19 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, { int i; int token; - int zero_run; - DCTELEM coeff; + int zero_run = 0; + DCTELEM coeff = 0; Vp3Fragment *fragment; + uint8_t *perm= s->scantable.permutated; + int bits_to_get; + + if ((first_fragment >= s->fragment_count) || + (last_fragment >= s->fragment_count)) { + + av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n", + first_fragment, last_fragment); + return 0; + } for (i = first_fragment; i <= last_fragment; i++) { @@ -1607,20 +1274,39 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, token = get_vlc2(gb, table->table, 5, 3); debug_vlc(" token = %2d, ", token); /* use the token to get a zero run, a coefficient, and an eob run */ - unpack_token(gb, token, &zero_run, &coeff, &eob_run); + if (token <= 6) { + eob_run = eob_run_base[token]; + if (eob_run_get_bits[token]) + eob_run += get_bits(gb, eob_run_get_bits[token]); + coeff = zero_run = 0; + } else { + bits_to_get = coeff_get_bits[token]; + if (!bits_to_get) + coeff = coeff_tables[token][0]; + else + coeff = coeff_tables[token][get_bits(gb, bits_to_get)]; + + zero_run = zero_run_base[token]; + if (zero_run_get_bits[token]) + zero_run += get_bits(gb, zero_run_get_bits[token]); + } } if (!eob_run) { fragment->coeff_count += zero_run; - if (fragment->coeff_count < 64) - fragment->coeffs[fragment->coeff_count++] = coeff; + if (fragment->coeff_count < 64){ + fragment->next_coeff->coeff= coeff; + fragment->next_coeff->index= perm[fragment->coeff_count++]; //FIXME perm here already? + fragment->next_coeff->next= s->next_coeff; + s->next_coeff->next=NULL; + fragment->next_coeff= s->next_coeff++; + } debug_vlc(" fragment %d coeff = %d\n", - s->coded_fragment_list[i], fragment->coeffs[coeff_index]); + s->coded_fragment_list[i], fragment->next_coeff[coeff_index]); } else { - fragment->last_coeff = fragment->coeff_count; - fragment->coeff_count = 64; - debug_vlc(" fragment %d eob with %d coefficients\n", - s->coded_fragment_list[i], fragment->last_coeff); + fragment->coeff_count |= 128; + debug_vlc(" fragment %d eob with %d coefficients\n", + s->coded_fragment_list[i], fragment->coeff_count&127); eob_run--; } } @@ -1632,7 +1318,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, * This function unpacks all of the DCT coefficient data from the * bitstream. */ -static void unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) +static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) { int i; int dc_y_table; @@ -1648,7 +1334,7 @@ static void unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* unpack the Y plane DC coefficients */ debug_vp3(" vp3: unpacking Y plane DC coefficients using table %d\n", dc_y_table); - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, + residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); /* unpack the C plane DC coefficients */ @@ -1666,12 +1352,12 @@ static void unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_y_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); debug_vp3(" vp3: unpacking level %d C plane AC coefficients using table %d\n", i, ac_c_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_c_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } @@ -1680,12 +1366,12 @@ static void unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_y_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); debug_vp3(" vp3: unpacking level %d C plane AC coefficients using table %d\n", i, ac_c_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_c_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } @@ -1694,12 +1380,12 @@ static void unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_3[ac_y_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_3[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); debug_vp3(" vp3: unpacking level %d C plane AC coefficients using table %d\n", i, ac_c_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_3[ac_c_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_3[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } @@ -1708,30 +1394,33 @@ static void unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_4[ac_y_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_4[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); debug_vp3(" vp3: unpacking level %d C plane AC coefficients using table %d\n", i, ac_c_table); - residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_4[ac_c_table], i, + residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_4[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } + + return 0; } /* * This function reverses the DC prediction for each coded fragment in - * the frame. Much of this function is adapted directly from the original + * the frame. Much of this function is adapted directly from the original * VP3 source code. */ #define COMPATIBLE_FRAME(x) \ (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type) #define FRAME_CODED(x) (s->all_fragments[x].coding_method != MODE_COPY) +#define DC_COEFF(u) (s->coeffs[u].index ? 0 : s->coeffs[u].coeff) //FIXME do somethin to simplify this static inline int iabs (int x) { return ((x < 0) ? -x : x); } static void reverse_dc_prediction(Vp3DecodeContext *s, int first_fragment, int fragment_width, - int fragment_height) + int fragment_height) { #define PUL 8 @@ -1751,7 +1440,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, * 10000000004 * 10000000004 * - * Note: Groups 5 and 7 do not exist as it would mean that the + * Note: Groups 5 and 7 do not exist as it would mean that the * fragment's x coordinate is both 0 and (width - 1) at the same time. */ int predictor_group; @@ -1766,7 +1455,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, /* indices for the left, up-left, up, and up-right fragments */ int l, ul, u, ur; - /* + /* * The 6 fields mean: * 0: up-left multiplier * 1: up multiplier @@ -1797,7 +1486,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, /* This table shows which types of blocks can use other blocks for * prediction. For example, INTRA is the only mode in this table to * have a frame number of 0. That means INTRA blocks can only predict - * from other INTRA blocks. There are 2 golden frame coding types; + * from other INTRA blocks. There are 2 golden frame coding types; * blocks encoding in these modes can only predict from other blocks * that were encoded with these 1 of these 2 modes. */ unsigned char compatible_frame[8] = { @@ -1831,12 +1520,12 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, /* reverse prediction if this block was coded */ if (s->all_fragments[i].coding_method != MODE_COPY) { - current_frame_type = + current_frame_type = compatible_frame[s->all_fragments[i].coding_method]; predictor_group = (x == 0) + ((y == 0) << 1) + ((x + 1 == fragment_width) << 2); debug_dc_pred(" frag %d: group %d, orig DC = %d, ", - i, predictor_group, s->all_fragments[i].coeffs[0]); + i, predictor_group, DC_COEFF(i)); switch (predictor_group) { @@ -1851,10 +1540,10 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, l = i - 1; /* fetch the DC values for the predicting fragments */ - vul = s->all_fragments[ul].coeffs[0]; - vu = s->all_fragments[u].coeffs[0]; - vur = s->all_fragments[ur].coeffs[0]; - vl = s->all_fragments[l].coeffs[0]; + vul = DC_COEFF(ul); + vu = DC_COEFF(u); + vur = DC_COEFF(ur); + vl = DC_COEFF(l); /* figure out which fragments are valid */ ful = FRAME_CODED(ul) && COMPATIBLE_FRAME(ul); @@ -1876,8 +1565,8 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, ur = i - fragment_width + 1; /* fetch the DC values for the predicting fragments */ - vu = s->all_fragments[u].coeffs[0]; - vur = s->all_fragments[ur].coeffs[0]; + vu = DC_COEFF(u); + vur = DC_COEFF(ur); /* figure out which fragments are valid */ fur = FRAME_CODED(ur) && COMPATIBLE_FRAME(ur); @@ -1897,7 +1586,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, l = i - 1; /* fetch the DC values for the predicting fragments */ - vl = s->all_fragments[l].coeffs[0]; + vl = DC_COEFF(l); /* figure out which fragments are valid */ fl = FRAME_CODED(l) && COMPATIBLE_FRAME(l); @@ -1926,9 +1615,9 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, l = i - 1; /* fetch the DC values for the predicting fragments */ - vul = s->all_fragments[ul].coeffs[0]; - vu = s->all_fragments[u].coeffs[0]; - vl = s->all_fragments[l].coeffs[0]; + vul = DC_COEFF(ul); + vu = DC_COEFF(u); + vl = DC_COEFF(l); /* figure out which fragments are valid */ ful = FRAME_CODED(ul) && COMPATIBLE_FRAME(ul); @@ -1948,9 +1637,9 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, /* if there were no fragments to predict from, use last * DC saved */ - s->all_fragments[i].coeffs[0] += last_dc[current_frame_type]; - debug_dc_pred("from last DC (%d) = %d\n", - current_frame_type, s->all_fragments[i].coeffs[0]); + predicted_dc = last_dc[current_frame_type]; + debug_dc_pred("from last DC (%d) = %d\n", + current_frame_type, DC_COEFF(i)); } else { @@ -1964,7 +1653,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, /* if there is a shift value in the transform, add * the sign bit before the shift */ if (predictor_transform[transform][5] != 0) { - predicted_dc += ((predicted_dc >> 15) & + predicted_dc += ((predicted_dc >> 15) & predictor_transform[transform][4]); predicted_dc >>= predictor_transform[transform][5]; } @@ -1980,184 +1669,448 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, predicted_dc = vul; } - /* at long last, apply the predictor */ - s->all_fragments[i].coeffs[0] += predicted_dc; - debug_dc_pred("from pred DC = %d\n", - s->all_fragments[i].coeffs[0]); + debug_dc_pred("from pred DC = %d\n", + DC_COEFF(i)); } + /* at long last, apply the predictor */ + if(s->coeffs[i].index){ + *s->next_coeff= s->coeffs[i]; + s->coeffs[i].index=0; + s->coeffs[i].coeff=0; + s->coeffs[i].next= s->next_coeff++; + } + s->coeffs[i].coeff += predicted_dc; /* save the DC */ - last_dc[current_frame_type] = s->all_fragments[i].coeffs[0]; + last_dc[current_frame_type] = DC_COEFF(i); + if(DC_COEFF(i) && !(s->all_fragments[i].coeff_count&127)){ + s->all_fragments[i].coeff_count= 129; +// s->all_fragments[i].next_coeff= s->next_coeff; + s->coeffs[i].next= s->next_coeff; + (s->next_coeff++)->next=NULL; + } } } } } + +static void horizontal_filter(unsigned char *first_pixel, int stride, + int *bounding_values); +static void vertical_filter(unsigned char *first_pixel, int stride, + int *bounding_values); + /* - * This function performs the final rendering of each fragment's data - * onto the output frame. + * Perform the final rendering for a particular slice of data. + * The slice number ranges from 0..(macroblock_height - 1). */ -static void render_fragments(Vp3DecodeContext *s, - int first_fragment, - int width, - int height, - int plane /* 0 = Y, 1 = U, 2 = V */) +static void render_slice(Vp3DecodeContext *s, int slice) { int x, y; int m, n; - int i = first_fragment; - int j; + int i; /* indicates current fragment */ int16_t *dequantizer; - DCTELEM dequant_block[64]; + DECLARE_ALIGNED_16(DCTELEM, block[64]); unsigned char *output_plane; unsigned char *last_plane; unsigned char *golden_plane; int stride; - int motion_x, motion_y; + int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef; int upper_motion_limit, lower_motion_limit; int motion_halfpel_index; - unsigned int motion_source; - - debug_vp3(" vp3: rendering final fragments for %s\n", - (plane == 0) ? "Y plane" : (plane == 1) ? "U plane" : "V plane"); - - /* set up plane-specific parameters */ - if (plane == 0) { - dequantizer = s->intra_y_dequant; - output_plane = s->current_frame.data[0]; - last_plane = s->last_frame.data[0]; - golden_plane = s->golden_frame.data[0]; - stride = -s->current_frame.linesize[0]; - upper_motion_limit = 7 * s->current_frame.linesize[0]; - lower_motion_limit = height * s->current_frame.linesize[0] + width - 8; - } else if (plane == 1) { - dequantizer = s->intra_c_dequant; - output_plane = s->current_frame.data[1]; - last_plane = s->last_frame.data[1]; - golden_plane = s->golden_frame.data[1]; - stride = -s->current_frame.linesize[1]; - upper_motion_limit = 7 * s->current_frame.linesize[1]; - lower_motion_limit = height * s->current_frame.linesize[1] + width - 8; - } else { - dequantizer = s->intra_c_dequant; - output_plane = s->current_frame.data[2]; - last_plane = s->last_frame.data[2]; - golden_plane = s->golden_frame.data[2]; - stride = -s->current_frame.linesize[2]; - upper_motion_limit = 7 * s->current_frame.linesize[2]; - lower_motion_limit = height * s->current_frame.linesize[2] + width - 8; - } + uint8_t *motion_source; + int plane; + int plane_width; + int plane_height; + int slice_height; + int current_macroblock_entry = slice * s->macroblock_width * 6; + int fragment_width; - /* for each fragment row... */ - for (y = 0; y < height; y += 8) { + if (slice >= s->macroblock_height) + return; + + for (plane = 0; plane < 3; plane++) { + + /* set up plane-specific parameters */ + if (plane == 0) { + output_plane = s->current_frame.data[0]; + last_plane = s->last_frame.data[0]; + golden_plane = s->golden_frame.data[0]; + stride = s->current_frame.linesize[0]; + if (!s->flipped_image) stride = -stride; + upper_motion_limit = 7 * s->current_frame.linesize[0]; + lower_motion_limit = s->height * s->current_frame.linesize[0] + s->width - 8; + y = slice * FRAGMENT_PIXELS * 2; + plane_width = s->width; + plane_height = s->height; + slice_height = y + FRAGMENT_PIXELS * 2; + i = s->macroblock_fragments[current_macroblock_entry + 0]; + } else if (plane == 1) { + output_plane = s->current_frame.data[1]; + last_plane = s->last_frame.data[1]; + golden_plane = s->golden_frame.data[1]; + stride = s->current_frame.linesize[1]; + if (!s->flipped_image) stride = -stride; + upper_motion_limit = 7 * s->current_frame.linesize[1]; + lower_motion_limit = (s->height / 2) * s->current_frame.linesize[1] + (s->width / 2) - 8; + y = slice * FRAGMENT_PIXELS; + plane_width = s->width / 2; + plane_height = s->height / 2; + slice_height = y + FRAGMENT_PIXELS; + i = s->macroblock_fragments[current_macroblock_entry + 4]; + } else { + output_plane = s->current_frame.data[2]; + last_plane = s->last_frame.data[2]; + golden_plane = s->golden_frame.data[2]; + stride = s->current_frame.linesize[2]; + if (!s->flipped_image) stride = -stride; + upper_motion_limit = 7 * s->current_frame.linesize[2]; + lower_motion_limit = (s->height / 2) * s->current_frame.linesize[2] + (s->width / 2) - 8; + y = slice * FRAGMENT_PIXELS; + plane_width = s->width / 2; + plane_height = s->height / 2; + slice_height = y + FRAGMENT_PIXELS; + i = s->macroblock_fragments[current_macroblock_entry + 5]; + } + fragment_width = plane_width / FRAGMENT_PIXELS; - /* for each fragment in a row... */ - for (x = 0; x < width; x += 8, i++) { + if(ABS(stride) > 2048) + return; //various tables are fixed size - /* transform if this block was coded */ - if (s->all_fragments[i].coding_method != MODE_COPY) { + /* for each fragment row in the slice (both of them)... */ + for (; y < slice_height; y += 8) { + + /* for each fragment in a row... */ + for (x = 0; x < plane_width; x += 8, i++) { - /* sort out the motion vector */ - motion_x = s->all_fragments[i].motion_x; - motion_y = s->all_fragments[i].motion_y; - motion_halfpel_index = s->all_fragments[i].motion_halfpel_index; - - motion_source = s->all_fragments[i].first_pixel; - motion_source += motion_x; - motion_source += (motion_y * stride); - - /* if the are any problems with a motion vector, refuse - * to render the block */ - if ((motion_source < upper_motion_limit) || - (motion_source > lower_motion_limit)) { -// printf (" vp3: help! motion source (%d) out of range (%d..%d)\n", -// motion_source, upper_motion_limit, lower_motion_limit); + if ((i < 0) || (i >= s->fragment_count)) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:render_slice(): bad fragment number (%d)\n", i); + return; } - /* first, take care of copying a block from either the - * previous or the golden frame */ - if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) || - (s->all_fragments[i].coding_method == MODE_GOLDEN_MV)) { + /* transform if this block was coded */ + if ((s->all_fragments[i].coding_method != MODE_COPY) && + !((s->avctx->flags & CODEC_FLAG_GRAY) && plane)) { - s->dsp.put_pixels_tab[1][motion_halfpel_index]( - output_plane + s->all_fragments[i].first_pixel, - golden_plane + motion_source, - stride, 8); + if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) || + (s->all_fragments[i].coding_method == MODE_GOLDEN_MV)) + motion_source= golden_plane; + else + motion_source= last_plane; + + motion_source += s->all_fragments[i].first_pixel; + motion_halfpel_index = 0; + + /* sort out the motion vector if this fragment is coded + * using a motion vector method */ + if ((s->all_fragments[i].coding_method > MODE_INTRA) && + (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) { + int src_x, src_y; + motion_x = s->all_fragments[i].motion_x; + motion_y = s->all_fragments[i].motion_y; + if(plane){ + motion_x= (motion_x>>1) | (motion_x&1); + motion_y= (motion_y>>1) | (motion_y&1); + } - } else - if (s->all_fragments[i].coding_method != MODE_INTRA) { + src_x= (motion_x>>1) + x; + src_y= (motion_y>>1) + y; + if ((motion_x == 127) || (motion_y == 127)) + av_log(s->avctx, AV_LOG_ERROR, " help! got invalid motion vector! (%X, %X)\n", motion_x, motion_y); - s->dsp.put_pixels_tab[1][motion_halfpel_index]( - output_plane + s->all_fragments[i].first_pixel, - last_plane + motion_source, - stride, 8); - } + motion_halfpel_index = motion_x & 0x01; + motion_source += (motion_x >> 1); - /* dequantize the DCT coefficients */ - debug_idct("fragment %d, coding mode %d, DC = %d, dequant = %d:\n", - i, s->all_fragments[i].coding_method, - s->all_fragments[i].coeffs[0], dequantizer[0]); - for (j = 0; j < 64; j++) - dequant_block[dequant_index[j]] = - s->all_fragments[i].coeffs[j] * - dequantizer[j]; - - debug_idct("dequantized block:\n"); - for (m = 0; m < 8; m++) { - for (n = 0; n < 8; n++) { - debug_idct(" %5d", dequant_block[m * 8 + n]); + motion_halfpel_index |= (motion_y & 0x01) << 1; + motion_source += ((motion_y >> 1) * stride); + + if(src_x<0 || src_y<0 || src_x + 9 >= plane_width || src_y + 9 >= plane_height){ + uint8_t *temp= s->edge_emu_buffer; + if(stride<0) temp -= 9*stride; + else temp += 9*stride; + + ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height); + motion_source= temp; + } } - debug_idct("\n"); - } - debug_idct("\n"); - /* invert DCT and place (or add) in final output */ - if (s->all_fragments[i].coding_method == MODE_INTRA) { - dequant_block[0] += 1024; - s->dsp.idct_put( - output_plane + s->all_fragments[i].first_pixel, - stride, dequant_block); - } else { - s->dsp.idct_add( - output_plane + s->all_fragments[i].first_pixel, - stride, dequant_block); - } + /* first, take care of copying a block from either the + * previous or the golden frame */ + if (s->all_fragments[i].coding_method != MODE_INTRA) { + /* Note, it is possible to implement all MC cases with + put_no_rnd_pixels_l2 which would look more like the + VP3 source but this would be slower as + put_no_rnd_pixels_tab is better optimzed */ + if(motion_halfpel_index != 3){ + s->dsp.put_no_rnd_pixels_tab[1][motion_halfpel_index]( + output_plane + s->all_fragments[i].first_pixel, + motion_source, stride, 8); + }else{ + int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1 + s->dsp.put_no_rnd_pixels_l2[1]( + output_plane + s->all_fragments[i].first_pixel, + motion_source - d, + motion_source + stride + 1 + d, + stride, 8); + } + dequantizer = s->inter_dequant; + }else{ + if (plane == 0) + dequantizer = s->intra_y_dequant; + else + dequantizer = s->intra_c_dequant; + } + + /* dequantize the DCT coefficients */ + debug_idct("fragment %d, coding mode %d, DC = %d, dequant = %d:\n", + i, s->all_fragments[i].coding_method, + DC_COEFF(i), dequantizer[0]); + + if(s->avctx->idct_algo==FF_IDCT_VP3){ + Coeff *coeff= s->coeffs + i; + memset(block, 0, sizeof(block)); + while(coeff->next){ + block[coeff->index]= coeff->coeff * dequantizer[coeff->index]; + coeff= coeff->next; + } + }else{ + Coeff *coeff= s->coeffs + i; + memset(block, 0, sizeof(block)); + while(coeff->next){ + block[coeff->index]= (coeff->coeff * dequantizer[coeff->index] + 2)>>2; + coeff= coeff->next; + } + } + + /* invert DCT and place (or add) in final output */ + + if (s->all_fragments[i].coding_method == MODE_INTRA) { + if(s->avctx->idct_algo!=FF_IDCT_VP3) + block[0] += 128<<3; + s->dsp.idct_put( + output_plane + s->all_fragments[i].first_pixel, + stride, + block); + } else { + s->dsp.idct_add( + output_plane + s->all_fragments[i].first_pixel, + stride, + block); + } - debug_idct("block after idct_%s():\n", - (s->all_fragments[i].coding_method == MODE_INTRA)? - "put" : "add"); - for (m = 0; m < 8; m++) { - for (n = 0; n < 8; n++) { - debug_idct(" %3d", *(output_plane + - s->all_fragments[i].first_pixel + (m * stride + n))); + debug_idct("block after idct_%s():\n", + (s->all_fragments[i].coding_method == MODE_INTRA)? + "put" : "add"); + for (m = 0; m < 8; m++) { + for (n = 0; n < 8; n++) { + debug_idct(" %3d", *(output_plane + + s->all_fragments[i].first_pixel + (m * stride + n))); + } + debug_idct("\n"); } debug_idct("\n"); - } - debug_idct("\n"); - } else { + } else { - /* copy directly from the previous frame */ - s->dsp.put_pixels_tab[1][0]( - output_plane + s->all_fragments[i].first_pixel, - last_plane + s->all_fragments[i].first_pixel, - stride, 8); + /* copy directly from the previous frame */ + s->dsp.put_pixels_tab[1][0]( + output_plane + s->all_fragments[i].first_pixel, + last_plane + s->all_fragments[i].first_pixel, + stride, 8); + } +#if 0 + /* perform the left edge filter if: + * - the fragment is not on the left column + * - the fragment is coded in this frame + * - the fragment is not coded in this frame but the left + * fragment is coded in this frame (this is done instead + * of a right edge filter when rendering the left fragment + * since this fragment is not available yet) */ + if ((x > 0) && + ((s->all_fragments[i].coding_method != MODE_COPY) || + ((s->all_fragments[i].coding_method == MODE_COPY) && + (s->all_fragments[i - 1].coding_method != MODE_COPY)) )) { + horizontal_filter( + output_plane + s->all_fragments[i].first_pixel + 7*stride, + -stride, bounding_values); + } + + /* perform the top edge filter if: + * - the fragment is not on the top row + * - the fragment is coded in this frame + * - the fragment is not coded in this frame but the above + * fragment is coded in this frame (this is done instead + * of a bottom edge filter when rendering the above + * fragment since this fragment is not available yet) */ + if ((y > 0) && + ((s->all_fragments[i].coding_method != MODE_COPY) || + ((s->all_fragments[i].coding_method == MODE_COPY) && + (s->all_fragments[i - fragment_width].coding_method != MODE_COPY)) )) { + vertical_filter( + output_plane + s->all_fragments[i].first_pixel - stride, + -stride, bounding_values); + } +#endif } } } + /* this looks like a good place for slice dispatch... */ + /* algorithm: + * if (slice == s->macroblock_height - 1) + * dispatch (both last slice & 2nd-to-last slice); + * else if (slice > 0) + * dispatch (slice - 1); + */ + emms_c(); +} + +static void horizontal_filter(unsigned char *first_pixel, int stride, + int *bounding_values) +{ + unsigned char *end; + int filter_value; + + for (end= first_pixel + 8*stride; first_pixel < end; first_pixel += stride) { + filter_value = + (first_pixel[-2] - first_pixel[ 1]) + +3*(first_pixel[ 0] - first_pixel[-1]); + filter_value = bounding_values[(filter_value + 4) >> 3]; + first_pixel[-1] = clip_uint8(first_pixel[-1] + filter_value); + first_pixel[ 0] = clip_uint8(first_pixel[ 0] - filter_value); + } +} +static void vertical_filter(unsigned char *first_pixel, int stride, + int *bounding_values) +{ + unsigned char *end; + int filter_value; + const int nstride= -stride; + + for (end= first_pixel + 8; first_pixel < end; first_pixel++) { + filter_value = + (first_pixel[2 * nstride] - first_pixel[ stride]) + +3*(first_pixel[0 ] - first_pixel[nstride]); + filter_value = bounding_values[(filter_value + 4) >> 3]; + first_pixel[nstride] = clip_uint8(first_pixel[nstride] + filter_value); + first_pixel[0] = clip_uint8(first_pixel[0] - filter_value); + } } -/* +static void apply_loop_filter(Vp3DecodeContext *s) +{ + int x, y, plane; + int width, height; + int fragment; + int stride; + unsigned char *plane_data; + int *bounding_values= s->bounding_values_array+127; + +#if 0 + int bounding_values_array[256]; + int filter_limit; + + /* find the right loop limit value */ + for (x = 63; x >= 0; x--) { + if (vp31_ac_scale_factor[x] >= s->quality_index) + break; + } + filter_limit = vp31_filter_limit_values[s->quality_index]; + + /* set up the bounding values */ + memset(bounding_values_array, 0, 256 * sizeof(int)); + for (x = 0; x < filter_limit; x++) { + bounding_values[-x - filter_limit] = -filter_limit + x; + bounding_values[-x] = -x; + bounding_values[x] = x; + bounding_values[x + filter_limit] = filter_limit - x; + } +#endif + + for (plane = 0; plane < 3; plane++) { + + if (plane == 0) { + /* Y plane parameters */ + fragment = 0; + width = s->fragment_width; + height = s->fragment_height; + stride = s->current_frame.linesize[0]; + plane_data = s->current_frame.data[0]; + } else if (plane == 1) { + /* U plane parameters */ + fragment = s->u_fragment_start; + width = s->fragment_width / 2; + height = s->fragment_height / 2; + stride = s->current_frame.linesize[1]; + plane_data = s->current_frame.data[1]; + } else { + /* V plane parameters */ + fragment = s->v_fragment_start; + width = s->fragment_width / 2; + height = s->fragment_height / 2; + stride = s->current_frame.linesize[2]; + plane_data = s->current_frame.data[2]; + } + + for (y = 0; y < height; y++) { + + for (x = 0; x < width; x++) { +START_TIMER + /* do not perform left edge filter for left columns frags */ + if ((x > 0) && + (s->all_fragments[fragment].coding_method != MODE_COPY)) { + horizontal_filter( + plane_data + s->all_fragments[fragment].first_pixel - 7*stride, + stride, bounding_values); + } + + /* do not perform top edge filter for top row fragments */ + if ((y > 0) && + (s->all_fragments[fragment].coding_method != MODE_COPY)) { + vertical_filter( + plane_data + s->all_fragments[fragment].first_pixel + stride, + stride, bounding_values); + } + + /* do not perform right edge filter for right column + * fragments or if right fragment neighbor is also coded + * in this frame (it will be filtered in next iteration) */ + if ((x < width - 1) && + (s->all_fragments[fragment].coding_method != MODE_COPY) && + (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) { + horizontal_filter( + plane_data + s->all_fragments[fragment + 1].first_pixel - 7*stride, + stride, bounding_values); + } + + /* do not perform bottom edge filter for bottom row + * fragments or if bottom fragment neighbor is also coded + * in this frame (it will be filtered in the next row) */ + if ((y < height - 1) && + (s->all_fragments[fragment].coding_method != MODE_COPY) && + (s->all_fragments[fragment + width].coding_method == MODE_COPY)) { + vertical_filter( + plane_data + s->all_fragments[fragment + width].first_pixel + stride, + stride, bounding_values); + } + + fragment++; +STOP_TIMER("loop filter") + } + } + } +} + +/* * This function computes the first pixel addresses for each fragment. * This function needs to be invoked after the first frame is allocated * so that it has access to the plane strides. */ -static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) +static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) { int i, x, y; @@ -2167,11 +2120,11 @@ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) i = 0; for (y = s->fragment_height; y > 0; y--) { for (x = 0; x < s->fragment_width; x++) { - s->all_fragments[i++].first_pixel = + s->all_fragments[i++].first_pixel = s->golden_frame.linesize[0] * y * FRAGMENT_PIXELS - s->golden_frame.linesize[0] + x * FRAGMENT_PIXELS; - debug_init(" fragment %d, first pixel @ %d\n", + debug_init(" fragment %d, first pixel @ %d\n", i-1, s->all_fragments[i-1].first_pixel); } } @@ -2180,11 +2133,11 @@ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) i = s->u_fragment_start; for (y = s->fragment_height / 2; y > 0; y--) { for (x = 0; x < s->fragment_width / 2; x++) { - s->all_fragments[i++].first_pixel = + s->all_fragments[i++].first_pixel = s->golden_frame.linesize[1] * y * FRAGMENT_PIXELS - s->golden_frame.linesize[1] + x * FRAGMENT_PIXELS; - debug_init(" fragment %d, first pixel @ %d\n", + debug_init(" fragment %d, first pixel @ %d\n", i-1, s->all_fragments[i-1].first_pixel); } } @@ -2193,11 +2146,58 @@ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) i = s->v_fragment_start; for (y = s->fragment_height / 2; y > 0; y--) { for (x = 0; x < s->fragment_width / 2; x++) { - s->all_fragments[i++].first_pixel = + s->all_fragments[i++].first_pixel = + s->golden_frame.linesize[2] * y * FRAGMENT_PIXELS - + s->golden_frame.linesize[2] + + x * FRAGMENT_PIXELS; + debug_init(" fragment %d, first pixel @ %d\n", + i-1, s->all_fragments[i-1].first_pixel); + } + } +} + +/* FIXME: this should be merged with the above! */ +static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) +{ + + int i, x, y; + + /* figure out the first pixel addresses for each of the fragments */ + /* Y plane */ + i = 0; + for (y = 1; y <= s->fragment_height; y++) { + for (x = 0; x < s->fragment_width; x++) { + s->all_fragments[i++].first_pixel = + s->golden_frame.linesize[0] * y * FRAGMENT_PIXELS - + s->golden_frame.linesize[0] + + x * FRAGMENT_PIXELS; + debug_init(" fragment %d, first pixel @ %d\n", + i-1, s->all_fragments[i-1].first_pixel); + } + } + + /* U plane */ + i = s->u_fragment_start; + for (y = 1; y <= s->fragment_height / 2; y++) { + for (x = 0; x < s->fragment_width / 2; x++) { + s->all_fragments[i++].first_pixel = + s->golden_frame.linesize[1] * y * FRAGMENT_PIXELS - + s->golden_frame.linesize[1] + + x * FRAGMENT_PIXELS; + debug_init(" fragment %d, first pixel @ %d\n", + i-1, s->all_fragments[i-1].first_pixel); + } + } + + /* V plane */ + i = s->v_fragment_start; + for (y = 1; y <= s->fragment_height / 2; y++) { + for (x = 0; x < s->fragment_width / 2; x++) { + s->all_fragments[i++].first_pixel = s->golden_frame.linesize[2] * y * FRAGMENT_PIXELS - s->golden_frame.linesize[2] + x * FRAGMENT_PIXELS; - debug_init(" fragment %d, first pixel @ %d\n", + debug_init(" fragment %d, first pixel @ %d\n", i-1, s->all_fragments[i-1].first_pixel); } } @@ -2210,23 +2210,45 @@ static int vp3_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; int i; + int c_width; + int c_height; + int y_superblock_count; + int c_superblock_count; + + if (avctx->codec_tag == MKTAG('V','P','3','0')) + s->version = 0; + else + s->version = 1; s->avctx = avctx; - s->width = avctx->width; - s->height = avctx->height; + s->width = (avctx->width + 15) & 0xFFFFFFF0; + s->height = (avctx->height + 15) & 0xFFFFFFF0; avctx->pix_fmt = PIX_FMT_YUV420P; avctx->has_b_frames = 0; + if(avctx->idct_algo==FF_IDCT_AUTO) + avctx->idct_algo=FF_IDCT_VP3; dsputil_init(&s->dsp, avctx); + ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); + /* initialize to an impossible value which will force a recalculation * in the first frame decode */ s->quality_index = -1; - s->superblock_width = (s->width + 31) / 32; - s->superblock_height = (s->height + 31) / 32; - s->superblock_count = s->superblock_width * s->superblock_height * 3 / 2; - s->u_superblock_start = s->superblock_width * s->superblock_height; - s->v_superblock_start = s->superblock_width * s->superblock_height * 5 / 4; + s->y_superblock_width = (s->width + 31) / 32; + s->y_superblock_height = (s->height + 31) / 32; + y_superblock_count = s->y_superblock_width * s->y_superblock_height; + + /* work out the dimensions for the C planes */ + c_width = s->width / 2; + c_height = s->height / 2; + s->c_superblock_width = (c_width + 31) / 32; + s->c_superblock_height = (c_height + 31) / 32; + c_superblock_count = s->c_superblock_width * s->c_superblock_height; + + s->superblock_count = y_superblock_count + (c_superblock_count * 2); + s->u_superblock_start = y_superblock_count; + s->v_superblock_start = s->u_superblock_start + c_superblock_count; s->superblock_coding = av_malloc(s->superblock_count); s->macroblock_width = (s->width + 15) / 16; @@ -2241,9 +2263,14 @@ static int vp3_decode_init(AVCodecContext *avctx) s->u_fragment_start = s->fragment_width * s->fragment_height; s->v_fragment_start = s->fragment_width * s->fragment_height * 5 / 4; - debug_init(" width: %d x %d\n", s->width, s->height); - debug_init(" superblocks: %d x %d, %d total\n", - s->superblock_width, s->superblock_height, s->superblock_count); + debug_init(" Y plane: %d x %d\n", s->width, s->height); + debug_init(" C plane: %d x %d\n", c_width, c_height); + debug_init(" Y superblocks: %d x %d, %d total\n", + s->y_superblock_width, s->y_superblock_height, y_superblock_count); + debug_init(" C superblocks: %d x %d, %d total\n", + s->c_superblock_width, s->c_superblock_height, c_superblock_count); + debug_init(" total superblocks = %d, U starts @ %d, V starts @ %d\n", + s->superblock_count, s->u_superblock_start, s->v_superblock_start); debug_init(" macroblocks: %d x %d, %d total\n", s->macroblock_width, s->macroblock_height, s->macroblock_count); debug_init(" %d fragments, %d x %d, u starts @ %d, v starts @ %d\n", @@ -2254,47 +2281,104 @@ static int vp3_decode_init(AVCodecContext *avctx) s->v_fragment_start); s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment)); + s->coeffs = av_malloc(s->fragment_count * sizeof(Coeff) * 65); s->coded_fragment_list = av_malloc(s->fragment_count * sizeof(int)); s->pixel_addresses_inited = 0; - /* init VLC tables */ - for (i = 0; i < 16; i++) { - - /* Dc histograms */ - init_vlc(&s->dc_vlc[i], 5, 32, - &dc_bias[i][0][1], 4, 2, - &dc_bias[i][0][0], 4, 2); - - /* group 1 AC histograms */ - init_vlc(&s->ac_vlc_1[i], 5, 32, - &ac_bias_0[i][0][1], 4, 2, - &ac_bias_0[i][0][0], 4, 2); - - /* group 2 AC histograms */ - init_vlc(&s->ac_vlc_2[i], 5, 32, - &ac_bias_1[i][0][1], 4, 2, - &ac_bias_1[i][0][0], 4, 2); - - /* group 3 AC histograms */ - init_vlc(&s->ac_vlc_3[i], 5, 32, - &ac_bias_2[i][0][1], 4, 2, - &ac_bias_2[i][0][0], 4, 2); - - /* group 4 AC histograms */ - init_vlc(&s->ac_vlc_4[i], 5, 32, - &ac_bias_3[i][0][1], 4, 2, - &ac_bias_3[i][0][0], 4, 2); + if (!s->theora_tables) + { + for (i = 0; i < 64; i++) + s->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i]; + for (i = 0; i < 64; i++) + s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i]; + for (i = 0; i < 64; i++) + s->coded_intra_y_dequant[i] = vp31_intra_y_dequant[i]; + for (i = 0; i < 64; i++) + s->coded_intra_c_dequant[i] = vp31_intra_c_dequant[i]; + for (i = 0; i < 64; i++) + s->coded_inter_dequant[i] = vp31_inter_dequant[i]; + for (i = 0; i < 64; i++) + s->filter_limit_values[i] = vp31_filter_limit_values[i]; + + /* init VLC tables */ + for (i = 0; i < 16; i++) { + + /* DC histograms */ + init_vlc(&s->dc_vlc[i], 5, 32, + &dc_bias[i][0][1], 4, 2, + &dc_bias[i][0][0], 4, 2, 0); + + /* group 1 AC histograms */ + init_vlc(&s->ac_vlc_1[i], 5, 32, + &ac_bias_0[i][0][1], 4, 2, + &ac_bias_0[i][0][0], 4, 2, 0); + + /* group 2 AC histograms */ + init_vlc(&s->ac_vlc_2[i], 5, 32, + &ac_bias_1[i][0][1], 4, 2, + &ac_bias_1[i][0][0], 4, 2, 0); + + /* group 3 AC histograms */ + init_vlc(&s->ac_vlc_3[i], 5, 32, + &ac_bias_2[i][0][1], 4, 2, + &ac_bias_2[i][0][0], 4, 2, 0); + + /* group 4 AC histograms */ + init_vlc(&s->ac_vlc_4[i], 5, 32, + &ac_bias_3[i][0][1], 4, 2, + &ac_bias_3[i][0][0], 4, 2, 0); + } + } else { + for (i = 0; i < 16; i++) { + + /* DC histograms */ + init_vlc(&s->dc_vlc[i], 5, 32, + &s->huffman_table[i][0][1], 4, 2, + &s->huffman_table[i][0][0], 4, 2, 0); + + /* group 1 AC histograms */ + init_vlc(&s->ac_vlc_1[i], 5, 32, + &s->huffman_table[i+16][0][1], 4, 2, + &s->huffman_table[i+16][0][0], 4, 2, 0); + + /* group 2 AC histograms */ + init_vlc(&s->ac_vlc_2[i], 5, 32, + &s->huffman_table[i+16*2][0][1], 4, 2, + &s->huffman_table[i+16*2][0][0], 4, 2, 0); + + /* group 3 AC histograms */ + init_vlc(&s->ac_vlc_3[i], 5, 32, + &s->huffman_table[i+16*3][0][1], 4, 2, + &s->huffman_table[i+16*3][0][0], 4, 2, 0); + + /* group 4 AC histograms */ + init_vlc(&s->ac_vlc_4[i], 5, 32, + &s->huffman_table[i+16*4][0][1], 4, 2, + &s->huffman_table[i+16*4][0][0], 4, 2, 0); + } } - /* build quantization table */ - for (i = 0; i < 64; i++) - quant_index[dequant_index[i]] = i; + init_vlc(&s->superblock_run_length_vlc, 6, 34, + &superblock_run_length_vlc_table[0][1], 4, 2, + &superblock_run_length_vlc_table[0][0], 4, 2, 0); + + init_vlc(&s->fragment_run_length_vlc, 5, 30, + &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)); s->macroblock_fragments = av_malloc(s->macroblock_count * 6 * sizeof(int)); - s->macroblock_coded = av_malloc(s->macroblock_count + 1); + s->macroblock_coding = av_malloc(s->macroblock_count + 1); init_block_mapping(s); for (i = 0; i < 3; i++) { @@ -2309,41 +2393,94 @@ static int vp3_decode_init(AVCodecContext *avctx) /* * This is the ffmpeg/libavcodec API frame decode function. */ -static int vp3_decode_frame(AVCodecContext *avctx, +static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; static int counter = 0; - - *data_size = 0; + int i; init_get_bits(&gb, buf, buf_size * 8); - s->keyframe = get_bits(&gb, 1); - s->keyframe ^= 1; - skip_bits(&gb, 1); + if (s->theora && get_bits1(&gb)) + { +#if 1 + av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n"); + return -1; +#else + int ptype = get_bits(&gb, 7); + + skip_bits(&gb, 6*8); /* "theora" */ + + switch(ptype) + { + case 1: + theora_decode_comments(avctx, gb); + break; + case 2: + theora_decode_tables(avctx, gb); + init_dequantizer(s); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype); + } + return buf_size; +#endif + } + + s->keyframe = !get_bits1(&gb); + if (!s->theora) + skip_bits(&gb, 1); s->last_quality_index = s->quality_index; s->quality_index = get_bits(&gb, 6); - if (s->quality_index != s->last_quality_index) - init_dequantizer(s); + if (s->theora >= 0x030200) + skip_bits1(&gb); - debug_vp3(" VP3 frame #%d: Q index = %d", counter, s->quality_index); + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n", + s->keyframe?"key":"", counter, s->quality_index); counter++; + if (s->quality_index != s->last_quality_index) { + init_dequantizer(s); + init_loop_filter(s); + } + if (s->keyframe) { - /* release the previous golden frame and get a new one */ - if (s->golden_frame.data[0]) - avctx->release_buffer(avctx, &s->golden_frame); + if (!s->theora) + { + skip_bits(&gb, 4); /* width code */ + skip_bits(&gb, 4); /* height code */ + if (s->version) + { + s->version = get_bits(&gb, 5); + if (counter == 1) + av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version); + } + } + if (s->version || s->theora) + { + if (get_bits1(&gb)) + av_log(s->avctx, AV_LOG_ERROR, "Warning, unsupported keyframe coding type?!\n"); + skip_bits(&gb, 2); /* reserved? */ + } - /* last frame, if allocated, is hereby invalidated */ - if (s->last_frame.data[0]) - avctx->release_buffer(avctx, &s->last_frame); + if (s->last_frame.data[0] == s->golden_frame.data[0]) { + if (s->golden_frame.data[0]) + avctx->release_buffer(avctx, &s->golden_frame); + s->last_frame= s->golden_frame; /* ensure that we catch any access to this released frame */ + } else { + if (s->golden_frame.data[0]) + avctx->release_buffer(avctx, &s->golden_frame); + if (s->last_frame.data[0]) + avctx->release_buffer(avctx, &s->last_frame); + } - s->golden_frame.reference = 0; + s->golden_frame.reference = 3; if(avctx->get_buffer(avctx, &s->golden_frame) < 0) { - printf("vp3: get_buffer() failed\n"); + av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n"); return -1; } @@ -2352,42 +2489,87 @@ static int vp3_decode_frame(AVCodecContext *avctx, /* time to figure out pixel addresses? */ if (!s->pixel_addresses_inited) - vp3_calculate_pixel_addresses(s); - + { + if (!s->flipped_image) + vp3_calculate_pixel_addresses(s); + else + theora_calculate_pixel_addresses(s); + } } else { - /* allocate a new current frame */ - s->current_frame.reference = 0; + s->current_frame.reference = 3; if(avctx->get_buffer(avctx, &s->current_frame) < 0) { - printf("vp3: get_buffer() failed\n"); + av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n"); return -1; } - } - if (s->keyframe) { - debug_vp3(", keyframe\n"); - /* skip the other 2 header bytes for now */ - skip_bits(&gb, 16); - } else - debug_vp3("\n"); + s->current_frame.qscale_table= s->qscale_table; //FIXME allocate individual tables per AVFrame + s->current_frame.qstride= 0; + {START_TIMER init_frame(s, &gb); + STOP_TIMER("init_frame")} + +#if KEYFRAMES_ONLY +if (!s->keyframe) { + + memcpy(s->current_frame.data[0], s->golden_frame.data[0], + s->current_frame.linesize[0] * s->height); + memcpy(s->current_frame.data[1], s->golden_frame.data[1], + s->current_frame.linesize[1] * s->height / 2); + memcpy(s->current_frame.data[2], s->golden_frame.data[2], + s->current_frame.linesize[2] * s->height / 2); + +} else { +#endif - unpack_superblocks(s, &gb); - unpack_modes(s, &gb); - unpack_vectors(s, &gb); - unpack_dct_coeffs(s, &gb); + {START_TIMER + if (unpack_superblocks(s, &gb)){ + av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n"); + return -1; + } + STOP_TIMER("unpack_superblocks")} + {START_TIMER + if (unpack_modes(s, &gb)){ + av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n"); + return -1; + } + STOP_TIMER("unpack_modes")} + {START_TIMER + if (unpack_vectors(s, &gb)){ + av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n"); + return -1; + } + STOP_TIMER("unpack_vectors")} + {START_TIMER + if (unpack_dct_coeffs(s, &gb)){ + av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n"); + return -1; + } + STOP_TIMER("unpack_dct_coeffs")} + {START_TIMER reverse_dc_prediction(s, 0, s->fragment_width, s->fragment_height); - reverse_dc_prediction(s, s->u_fragment_start, - s->fragment_width / 2, s->fragment_height / 2); - reverse_dc_prediction(s, s->v_fragment_start, - s->fragment_width / 2, s->fragment_height / 2); + if ((avctx->flags & CODEC_FLAG_GRAY) == 0) { + reverse_dc_prediction(s, s->u_fragment_start, + s->fragment_width / 2, s->fragment_height / 2); + reverse_dc_prediction(s, s->v_fragment_start, + s->fragment_width / 2, s->fragment_height / 2); + } + STOP_TIMER("reverse_dc_prediction")} + {START_TIMER - render_fragments(s, 0, s->width, s->height, 0); - render_fragments(s, s->u_fragment_start, s->width / 2, s->height / 2, 1); - render_fragments(s, s->v_fragment_start, s->width / 2, s->height / 2, 2); + for (i = 0; i < s->macroblock_height; i++) + render_slice(s, i); + STOP_TIMER("render_fragments")} + + {START_TIMER + apply_loop_filter(s); + STOP_TIMER("apply_loop_filter")} +#if KEYFRAMES_ONLY +} +#endif *data_size=sizeof(AVFrame); *(AVFrame*)data= s->current_frame; @@ -2400,6 +2582,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, /* shuffle frames (last = current) */ memcpy(&s->last_frame, &s->current_frame, sizeof(AVFrame)); + s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */ return buf_size; } @@ -2412,20 +2595,301 @@ static int vp3_decode_end(AVCodecContext *avctx) Vp3DecodeContext *s = avctx->priv_data; av_free(s->all_fragments); + av_free(s->coeffs); av_free(s->coded_fragment_list); av_free(s->superblock_fragments); av_free(s->superblock_macroblocks); av_free(s->macroblock_fragments); - av_free(s->macroblock_coded); + av_free(s->macroblock_coding); /* release all frames */ - avctx->release_buffer(avctx, &s->golden_frame); - avctx->release_buffer(avctx, &s->last_frame); - avctx->release_buffer(avctx, &s->current_frame); + if (s->golden_frame.data[0] && s->golden_frame.data[0] != s->last_frame.data[0]) + avctx->release_buffer(avctx, &s->golden_frame); + if (s->last_frame.data[0]) + avctx->release_buffer(avctx, &s->last_frame); + /* no need to release the current_frame since it will always be pointing + * to the same frame as either the golden or last frame */ + + return 0; +} + +static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) +{ + Vp3DecodeContext *s = avctx->priv_data; + + if (get_bits(gb, 1)) { + int token; + if (s->entries >= 32) { /* overflow */ + av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); + return -1; + } + token = get_bits(gb, 5); + //av_log(avctx, AV_LOG_DEBUG, "hti %d hbits %x token %d entry : %d size %d\n", s->hti, s->hbits, token, s->entries, s->huff_code_size); + s->huffman_table[s->hti][token][0] = s->hbits; + s->huffman_table[s->hti][token][1] = s->huff_code_size; + s->entries++; + } + else { + if (s->huff_code_size >= 32) {/* overflow */ + av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); + return -1; + } + s->huff_code_size++; + s->hbits <<= 1; + read_huffman_tree(avctx, gb); + s->hbits |= 1; + read_huffman_tree(avctx, gb); + s->hbits >>= 1; + s->huff_code_size--; + } + return 0; +} + +static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb) +{ + Vp3DecodeContext *s = avctx->priv_data; + int major, minor, micro; + + major = get_bits(&gb, 8); /* version major */ + minor = get_bits(&gb, 8); /* version minor */ + micro = get_bits(&gb, 8); /* version micro */ + av_log(avctx, AV_LOG_INFO, "Theora bitstream version %d.%d.%d\n", + major, minor, micro); + + /* FIXME: endianess? */ + s->theora = (major << 16) | (minor << 8) | micro; + + /* 3.2.0 aka alpha3 has the same frame orientation as original vp3 */ + /* but previous versions have the image flipped relative to vp3 */ + if (s->theora < 0x030200) + { + s->flipped_image = 1; + av_log(avctx, AV_LOG_DEBUG, "Old (width = get_bits(&gb, 16) << 4; + s->height = get_bits(&gb, 16) << 4; + + if(avcodec_check_dimensions(avctx, s->width, s->height)){ + av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", s->width, s->height); + s->width= s->height= 0; + return -1; + } + + if (s->theora >= 0x030400) + { + skip_bits(&gb, 32); /* total number of superblocks in a frame */ + // fixme, the next field is 36bits long + skip_bits(&gb, 32); /* total number of blocks in a frame */ + skip_bits(&gb, 4); /* total number of blocks in a frame */ + skip_bits(&gb, 32); /* total number of macroblocks in a frame */ + + skip_bits(&gb, 24); /* frame width */ + skip_bits(&gb, 24); /* frame height */ + } + else + { + skip_bits(&gb, 24); /* frame width */ + skip_bits(&gb, 24); /* frame height */ + } + + skip_bits(&gb, 8); /* offset x */ + skip_bits(&gb, 8); /* offset y */ + + skip_bits(&gb, 32); /* fps numerator */ + skip_bits(&gb, 32); /* fps denumerator */ + skip_bits(&gb, 24); /* aspect numerator */ + skip_bits(&gb, 24); /* aspect denumerator */ + + if (s->theora < 0x030200) + skip_bits(&gb, 5); /* keyframe frequency force */ + skip_bits(&gb, 8); /* colorspace */ + if (s->theora >= 0x030400) + skip_bits(&gb, 2); /* pixel format: 420,res,422,444 */ + skip_bits(&gb, 24); /* bitrate */ + + skip_bits(&gb, 6); /* quality hint */ + + if (s->theora >= 0x030200) + { + skip_bits(&gb, 5); /* keyframe frequency force */ + + if (s->theora < 0x030400) + skip_bits(&gb, 5); /* spare bits */ + } + +// align_get_bits(&gb); + + avctx->width = s->width; + avctx->height = s->height; return 0; } +static inline int theora_get_32bit(GetBitContext gb) +{ + int ret = get_bits(&gb, 8); + ret += get_bits(&gb, 8) << 8; + ret += get_bits(&gb, 8) << 16; + ret += get_bits(&gb, 8) << 24; + + return ret; +} + +static int theora_decode_tables(AVCodecContext *avctx, GetBitContext gb) +{ + Vp3DecodeContext *s = avctx->priv_data; + int i, n, matrices; + + if (s->theora >= 0x030200) { + n = get_bits(&gb, 3); + /* loop filter limit values table */ + for (i = 0; i < 64; i++) + s->filter_limit_values[i] = get_bits(&gb, n); + } + + if (s->theora >= 0x030200) + n = get_bits(&gb, 4) + 1; + else + n = 16; + /* quality threshold table */ + for (i = 0; i < 64; i++) + s->coded_ac_scale_factor[i] = get_bits(&gb, n); + + if (s->theora >= 0x030200) + n = get_bits(&gb, 4) + 1; + else + n = 16; + /* dc scale factor table */ + for (i = 0; i < 64; i++) + s->coded_dc_scale_factor[i] = get_bits(&gb, n); + + if (s->theora >= 0x030200) + matrices = get_bits(&gb, 9) + 1; + else + matrices = 3; + if (matrices != 3) { + av_log(avctx,AV_LOG_ERROR, "unsupported matrices: %d\n", matrices); +// return -1; + } + /* y coeffs */ + for (i = 0; i < 64; i++) + s->coded_intra_y_dequant[i] = get_bits(&gb, 8); + + /* uv coeffs */ + for (i = 0; i < 64; i++) + s->coded_intra_c_dequant[i] = get_bits(&gb, 8); + + /* inter coeffs */ + for (i = 0; i < 64; i++) + s->coded_inter_dequant[i] = get_bits(&gb, 8); + + /* skip unknown matrices */ + n = matrices - 3; + while(n--) + for (i = 0; i < 64; i++) + skip_bits(&gb, 8); + + for (i = 0; i <= 1; i++) { + for (n = 0; n <= 2; n++) { + int newqr; + if (i > 0 || n > 0) + newqr = get_bits(&gb, 1); + else + newqr = 1; + if (!newqr) { + if (i > 0) + get_bits(&gb, 1); + } + else { + int qi = 0; + skip_bits(&gb, av_log2(matrices-1)+1); + while (qi < 63) { + qi += get_bits(&gb, av_log2(63-qi)+1) + 1; + skip_bits(&gb, av_log2(matrices-1)+1); + } + if (qi > 63) { + av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi); + return -1; + } + } + } + } + + /* Huffman tables */ + for (s->hti = 0; s->hti < 80; s->hti++) { + s->entries = 0; + s->huff_code_size = 1; + if (!get_bits(&gb, 1)) { + s->hbits = 0; + read_huffman_tree(avctx, &gb); + s->hbits = 1; + read_huffman_tree(avctx, &gb); + } + } + + s->theora_tables = 1; + + return 0; +} + +static int theora_decode_init(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + GetBitContext gb; + int ptype; + uint8_t *p= avctx->extradata; + int op_bytes, i; + + s->theora = 1; + + if (!avctx->extradata_size) + { + av_log(avctx, AV_LOG_ERROR, "Missing extradata!\n"); + return -1; + } + + for(i=0;i<3;i++) { + op_bytes = *(p++)<<8; + op_bytes += *(p++); + + init_get_bits(&gb, p, op_bytes); + p += op_bytes; + + ptype = get_bits(&gb, 8); + debug_vp3("Theora headerpacket type: %x\n", ptype); + + if (!(ptype & 0x80)) + { + av_log(avctx, AV_LOG_ERROR, "Invalid extradata!\n"); + return -1; + } + + // FIXME: check for this aswell + skip_bits(&gb, 6*8); /* "theora" */ + + switch(ptype) + { + case 0x80: + theora_decode_header(avctx, gb); + break; + case 0x81: +// FIXME: is this needed? it breaks sometimes +// theora_decode_comments(avctx, gb); + break; + case 0x82: + theora_decode_tables(avctx, gb); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype&~0x80); + break; + } + } + + vp3_decode_init(avctx); + return 0; +} + AVCodec vp3_decoder = { "vp3", CODEC_TYPE_VIDEO, @@ -2438,3 +2902,18 @@ AVCodec vp3_decoder = { 0, NULL }; + +#ifndef CONFIG_LIBTHEORA +AVCodec theora_decoder = { + "theora", + CODEC_TYPE_VIDEO, + CODEC_ID_THEORA, + sizeof(Vp3DecodeContext), + theora_decode_init, + NULL, + vp3_decode_end, + vp3_decode_frame, + 0, + NULL +}; +#endif