X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp3.c;h=a5b97adb9e3a0fcbb50d99faf7464f3b0197e9eb;hb=cb377ec55e975119312c3cc72b9e8924cbbcfc6e;hp=5c5c6f28a18b4004e8540508c34b183219b82bd0;hpb=6f6a3e2acba7e7a6e35a925289fb06bcb01db99d;p=ffmpeg diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 5c5c6f28a18..a5b97adb9e3 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * */ /** @@ -25,7 +24,7 @@ * * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx) * For more information about the VP3 coding process, visit: - * http://multimedia.cx/ + * http://wiki.multimedia.cx/index.php?title=On2_VP3 * * Theora decoder by Alex Beregszaszi */ @@ -35,108 +34,15 @@ #include #include -#include "common.h" #include "avcodec.h" #include "dsputil.h" -#include "mpegvideo.h" +#include "bitstream.h" #include "vp3data.h" #include "xiph.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 - * DEBUG_BLOCK_CODING: unpacking the superblock/macroblock/fragment coding - * DEBUG_MODES: unpacking the coding modes for individual fragments - * DEBUG_VECTORS: display the motion vectors - * DEBUG_TOKEN: display exhaustive information about each DCT token - * DEBUG_VLC: display the VLCs as they are extracted from the stream - * DEBUG_DC_PRED: display the process of reversing DC prediction - * 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 -#define DEBUG_BLOCK_CODING 0 -#define DEBUG_MODES 0 -#define DEBUG_VECTORS 0 -#define DEBUG_TOKEN 0 -#define DEBUG_VLC 0 -#define DEBUG_DC_PRED 0 -#define DEBUG_IDCT 0 - -#if DEBUG_VP3 -#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(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_init(const char *format, ...) { } -#endif - -#if DEBUG_DEQUANTIZERS -#define debug_dequantizers(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_dequantizers(const char *format, ...) { } -#endif - -#if DEBUG_BLOCK_CODING -#define debug_block_coding(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_block_coding(const char *format, ...) { } -#endif - -#if DEBUG_MODES -#define debug_modes(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_modes(const char *format, ...) { } -#endif - -#if DEBUG_VECTORS -#define debug_vectors(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_vectors(const char *format, ...) { } -#endif - -#if DEBUG_TOKEN -#define debug_token(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_token(const char *format, ...) { } -#endif - -#if DEBUG_VLC -#define debug_vlc(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_vlc(const char *format, ...) { } -#endif - -#if DEBUG_DC_PRED -#define debug_dc_pred(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_dc_pred(const char *format, ...) { } -#endif - -#if DEBUG_IDCT -#define debug_idct(args...) av_log(NULL, AV_LOG_DEBUG, ## args) -#else -static inline void debug_idct(const char *format, ...) { } -#endif - typedef struct Coeff { struct Coeff *next; DCTELEM coeff; @@ -152,7 +58,6 @@ typedef struct Vp3Fragment { /* this is the macroblock that the fragment belongs to */ uint16_t macroblock; uint8_t coding_method; - uint8_t coeff_count; int8_t motion_x; int8_t motion_y; } Vp3Fragment; @@ -175,11 +80,8 @@ typedef struct Vp3Fragment { #define MODE_COPY 8 /* There are 6 preset schemes, plus a free-form scheme */ -static int ModeAlphabet[7][CODING_MODE_COUNT] = +static const int ModeAlphabet[6][CODING_MODE_COUNT] = { - /* this is the custom scheme */ - { 0, 0, 0, 0, 0, 0, 0, 0 }, - /* scheme 1: Last motion vector dominates */ { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, @@ -238,8 +140,6 @@ typedef struct Vp3DecodeContext { int last_quality_index; int superblock_count; - int superblock_width; - int superblock_height; int y_superblock_width; int y_superblock_height; int c_superblock_width; @@ -257,6 +157,7 @@ typedef struct Vp3DecodeContext { int fragment_height; Vp3Fragment *all_fragments; + uint8_t *coeff_counts; Coeff *coeffs; Coeff *next_coeff; int fragment_start[3]; @@ -271,11 +172,11 @@ typedef struct Vp3DecodeContext { uint8_t qr_size [2][3][64]; uint16_t qr_base[2][3][64]; - /* this is a list of indices into the all_fragments array indicating + /* this is a list of indexes into the all_fragments array indicating * which of the fragments are coded */ int *coded_fragment_list; int coded_fragment_list_index; - int pixel_addresses_inited; + int pixel_addresses_initialized; VLC dc_vlc[16]; VLC ac_vlc_1[16]; @@ -293,19 +194,19 @@ typedef struct Vp3DecodeContext { DECLARE_ALIGNED_16(int16_t, qmat[2][4][64]); //macroblock_width; hilbert_walk_mb[2] = 1; @@ -390,9 +289,6 @@ static int init_block_mapping(Vp3DecodeContext *s) /* iterate through each superblock (all planes) and map the fragments */ for (i = 0; i < s->superblock_count; i++) { - debug_init(" superblock %d (u starts @ %d, v starts @ %d)\n", - i, s->u_superblock_start, s->v_superblock_start); - /* time to re-assign the limits? */ if (i == 0) { @@ -454,14 +350,8 @@ static int init_block_mapping(Vp3DecodeContext *s) 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 (%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 (%d/%d x %d/%d)\n", - i, j, - current_width, right_edge, current_height, bottom_edge); } mapping_index++; @@ -475,7 +365,7 @@ static int init_block_mapping(Vp3DecodeContext *s) current_width = -1; current_height = 0; superblock_row_inc = s->macroblock_width - - (s->y_superblock_width * 2 - s->macroblock_width);; + (s->y_superblock_width * 2 - s->macroblock_width); hilbert = hilbert_walk_mb; mapping_index = 0; current_macroblock = -1; @@ -500,14 +390,8 @@ static int init_block_mapping(Vp3DecodeContext *s) 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 (%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 (%d/%d x %d/%d)\n", - i, j, - current_width, right_edge, current_height, bottom_edge); } mapping_index++; @@ -522,15 +406,12 @@ static int init_block_mapping(Vp3DecodeContext *s) for (j = 0; j < s->fragment_width; j += 2) { - debug_init(" macroblock %d contains fragments: ", current_macroblock); s->all_fragments[current_fragment].macroblock = current_macroblock; s->macroblock_fragments[mapping_index++] = current_fragment; - debug_init("%d ", current_fragment); if (j + 1 < s->fragment_width) { s->all_fragments[current_fragment + 1].macroblock = current_macroblock; s->macroblock_fragments[mapping_index++] = current_fragment + 1; - debug_init("%d ", current_fragment + 1); } else s->macroblock_fragments[mapping_index++] = -1; @@ -539,7 +420,6 @@ static int init_block_mapping(Vp3DecodeContext *s) current_macroblock; 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; @@ -548,7 +428,6 @@ static int init_block_mapping(Vp3DecodeContext *s) current_macroblock; 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; @@ -557,15 +436,11 @@ static int init_block_mapping(Vp3DecodeContext *s) (i * s->fragment_width / 4) + (j / 2); s->all_fragments[c_fragment].macroblock = s->macroblock_count; s->macroblock_fragments[mapping_index++] = c_fragment; - debug_init("%d ", c_fragment); c_fragment = s->fragment_start[2] + (i * s->fragment_width / 4) + (j / 2); s->all_fragments[c_fragment].macroblock = s->macroblock_count; s->macroblock_fragments[mapping_index++] = c_fragment; - debug_init("%d ", c_fragment); - - debug_init("\n"); if (j + 2 <= s->fragment_width) current_fragment += 2; @@ -590,7 +465,7 @@ 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++) { - s->all_fragments[i].coeff_count = 0; + s->coeff_counts[i] = 0; s->all_fragments[i].motion_x = 127; s->all_fragments[i].motion_y = 127; s->all_fragments[i].next_coeff= NULL; @@ -610,8 +485,6 @@ static void init_dequantizer(Vp3DecodeContext *s) int dc_scale_factor = s->coded_dc_scale_factor[s->quality_index]; int i, plane, inter, qri, bmi, bmj, qistart; - debug_vp3(" vp3: initializing dequantization tables\n"); - for(inter=0; inter<2; inter++){ for(plane=0; plane<3; plane++){ int sum=0; @@ -632,7 +505,7 @@ static void init_dequantizer(Vp3DecodeContext *s) int qmin= 8<<(inter + !i); int qscale= i ? ac_scale_factor : dc_scale_factor; - s->qmat[inter][plane][i]= av_clip((qscale * coeff)/100 * 4, qmin, 4096); + s->qmat[inter][plane][s->dsp.idct_permutation[i]]= av_clip((qscale * coeff)/100 * 4, qmin, 4096); } } } @@ -660,6 +533,7 @@ static void init_loop_filter(Vp3DecodeContext *s) bounding_values[x] = x; bounding_values[x + filter_limit] = filter_limit - x; } + bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202; } /* @@ -678,17 +552,13 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) int i, j; int current_fragment; - debug_vp3(" vp3: unpacking superblock coding\n"); - if (s->keyframe) { - - debug_vp3(" keyframe-- all superblocks are fully coded\n"); memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count); } else { /* unpack the list of partially-coded superblocks */ - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -699,10 +569,6 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *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, - (bit) ? "partially coded" : "not coded"); /* if any of the superblocks are not partially coded, flag * a boolean to decode the list of fully-coded superblocks */ @@ -724,7 +590,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) current_superblock = 0; current_run = 0; - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -740,10 +606,6 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) 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] = 2*bit; } current_superblock++; @@ -755,7 +617,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) if (decode_partial_blocks) { current_run = 0; - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -816,14 +678,10 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) } s->coded_fragment_list_index++; 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 { /* not coded; copy this fragment from the prior frame */ s->all_fragments[current_fragment].coding_method = MODE_COPY; - debug_block_coding(" superblock %d is partially coded, fragment %d is not coded\n", - i, current_fragment); } } else { @@ -844,8 +702,6 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) } s->coded_fragment_list_index++; 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); } } } @@ -858,13 +714,6 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) /* 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; } @@ -879,12 +728,9 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) int current_macroblock; int current_fragment; int coding_mode; - - debug_vp3(" vp3: unpacking encoding modes\n"); + int custom_mode_alphabet[CODING_MODE_COUNT]; if (s->keyframe) { - debug_vp3(" keyframe-- all blocks are coded as INTRA\n"); - for (i = 0; i < s->fragment_count; i++) s->all_fragments[i].coding_method = MODE_INTRA; @@ -892,19 +738,13 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) /* fetch the mode coding scheme for this frame */ scheme = get_bits(gb, 3); - debug_modes(" using mode alphabet %d\n", scheme); /* is it a custom coding scheme? */ if (scheme == 0) { - debug_modes(" custom mode alphabet ahead:\n"); for (i = 0; i < 8; i++) - ModeAlphabet[scheme][get_bits(gb, 3)] = i; + custom_mode_alphabet[get_bits(gb, 3)] = i; } - for (i = 0; i < 8; i++) - debug_modes(" mode[%d][%d] = %d\n", scheme, i, - ModeAlphabet[scheme][i]); - /* iterate through all of the macroblocks that contain 1 or more * coded fragments */ for (i = 0; i < s->u_superblock_start; i++) { @@ -923,8 +763,11 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) /* mode 7 means get 3 bits for each coding mode */ if (scheme == 7) coding_mode = get_bits(gb, 3); + else if(scheme == 0) + coding_mode = custom_mode_alphabet + [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; else - coding_mode = ModeAlphabet[scheme] + coding_mode = ModeAlphabet[scheme-1] [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; s->macroblock_coding[current_macroblock] = coding_mode; @@ -943,9 +786,6 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) s->all_fragments[current_fragment].coding_method = coding_mode; } - - debug_modes(" coding method for macroblock starting @ fragment %d = %d\n", - s->macroblock_fragments[current_macroblock * 6], coding_mode); } } } @@ -959,7 +799,7 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) */ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) { - int i, j, k; + int i, j, k, l; int coding_mode; int motion_x[6]; int motion_y[6]; @@ -970,75 +810,77 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) int current_macroblock; int current_fragment; - debug_vp3(" vp3: unpacking motion vectors\n"); - if (s->keyframe) { - - debug_vp3(" keyframe-- there are no motion vectors\n"); + if (s->keyframe) + return 0; - } else { + memset(motion_x, 0, 6 * sizeof(int)); + memset(motion_y, 0, 6 * sizeof(int)); - memset(motion_x, 0, 6 * sizeof(int)); - memset(motion_y, 0, 6 * sizeof(int)); + /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */ + coding_mode = get_bits1(gb); - /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */ - coding_mode = get_bits(gb, 1); - debug_vectors(" using %s scheme for unpacking motion vectors\n", - (coding_mode == 0) ? "VLC" : "fixed-length"); + /* iterate through all of the macroblocks that contain 1 or more + * coded fragments */ + for (i = 0; i < s->u_superblock_start; i++) { - /* iterate through all of the macroblocks that contain 1 or more - * coded fragments */ - for (i = 0; i < s->u_superblock_start; i++) { + for (j = 0; j < 4; j++) { + current_macroblock = s->superblock_macroblocks[i * 4 + j]; + if ((current_macroblock == -1) || + (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; + } - for (j = 0; j < 4; j++) { - current_macroblock = s->superblock_macroblocks[i * 4 + j]; - if ((current_macroblock == -1) || - (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]; + 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] = 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] = fixed_motion_vector_table[get_bits(gb, 6)]; + motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)]; } - current_fragment = s->macroblock_fragments[current_macroblock * 6]; - 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; + for (k = 1; k < 6; k++) { + motion_x[k] = motion_x[0]; + motion_y[k] = motion_y[0]; } - 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] = 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] = 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->macroblock_coding[current_macroblock] == - MODE_INTER_PLUS_MV) { - prior_last_motion_x = last_motion_x; - prior_last_motion_y = last_motion_y; - last_motion_x = motion_x[0]; - last_motion_y = motion_y[0]; - } - break; + /* vector maintenance, only on MODE_INTER_PLUS_MV */ + if (s->macroblock_coding[current_macroblock] == + MODE_INTER_PLUS_MV) { + prior_last_motion_x = last_motion_x; + prior_last_motion_y = last_motion_y; + last_motion_x = motion_x[0]; + last_motion_y = motion_y[0]; + } + break; - case MODE_INTER_FOURMV: - /* fetch 4 vectors from the bitstream, one for each - * Y fragment, then average for the C fragment vectors */ - motion_x[4] = motion_y[4] = 0; - for (k = 0; k < 4; k++) { + case MODE_INTER_FOURMV: + /* vector maintenance */ + prior_last_motion_x = last_motion_x; + prior_last_motion_y = last_motion_y; + + /* fetch 4 vectors from the bitstream, one for each + * Y fragment, then average for the C fragment vectors */ + motion_x[4] = motion_y[4] = 0; + for (k = 0; k < 4; k++) { + for (l = 0; l < s->coded_fragment_list_index; l++) + if (s->coded_fragment_list[l] == s->macroblock_fragments[6*current_macroblock + k]) + break; + if (l < s->coded_fragment_list_index) { if (coding_mode == 0) { 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)]; @@ -1046,81 +888,74 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *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]; + last_motion_x = motion_x[k]; + last_motion_y = motion_y[k]; + } else { + motion_x[k] = 0; + motion_y[k] = 0; } + motion_x[4] += motion_x[k]; + motion_y[4] += motion_y[k]; + } - motion_x[5]= - motion_x[4]= RSHIFT(motion_x[4], 2); - motion_y[5]= - motion_y[4]= RSHIFT(motion_y[4], 2); - - /* vector maintenance; vector[3] is treated as the - * last vector in this case */ - prior_last_motion_x = last_motion_x; - prior_last_motion_y = last_motion_y; - last_motion_x = motion_x[3]; - last_motion_y = motion_y[3]; - break; + motion_x[5]= + motion_x[4]= RSHIFT(motion_x[4], 2); + motion_y[5]= + motion_y[4]= RSHIFT(motion_y[4], 2); + break; - case MODE_INTER_LAST_MV: - /* all 6 fragments use the last motion vector */ - motion_x[0] = last_motion_x; - motion_y[0] = last_motion_y; - for (k = 1; k < 6; k++) { - motion_x[k] = motion_x[0]; - motion_y[k] = motion_y[0]; - } + case MODE_INTER_LAST_MV: + /* all 6 fragments use the last motion vector */ + motion_x[0] = last_motion_x; + motion_y[0] = last_motion_y; + for (k = 1; k < 6; k++) { + motion_x[k] = motion_x[0]; + motion_y[k] = motion_y[0]; + } - /* no vector maintenance (last vector remains the - * last vector) */ - break; + /* no vector maintenance (last vector remains the + * last vector) */ + break; - case MODE_INTER_PRIOR_LAST: - /* all 6 fragments use the motion vector prior to the - * last motion vector */ - motion_x[0] = prior_last_motion_x; - motion_y[0] = prior_last_motion_y; - for (k = 1; k < 6; k++) { - motion_x[k] = motion_x[0]; - motion_y[k] = motion_y[0]; - } + case MODE_INTER_PRIOR_LAST: + /* all 6 fragments use the motion vector prior to the + * last motion vector */ + motion_x[0] = prior_last_motion_x; + motion_y[0] = prior_last_motion_y; + for (k = 1; k < 6; k++) { + motion_x[k] = motion_x[0]; + motion_y[k] = motion_y[0]; + } - /* vector maintenance */ - prior_last_motion_x = last_motion_x; - prior_last_motion_y = last_motion_y; - last_motion_x = motion_x[0]; - last_motion_y = motion_y[0]; - break; + /* vector maintenance */ + prior_last_motion_x = last_motion_x; + prior_last_motion_y = last_motion_y; + last_motion_x = motion_x[0]; + last_motion_y = motion_y[0]; + break; - default: - /* covers intra, inter without MV, golden without MV */ - memset(motion_x, 0, 6 * sizeof(int)); - memset(motion_y, 0, 6 * sizeof(int)); + default: + /* covers intra, inter without MV, golden without MV */ + memset(motion_x, 0, 6 * sizeof(int)); + memset(motion_y, 0, 6 * sizeof(int)); - /* no vector maintenance */ - break; - } + /* no vector maintenance */ + break; + } - /* assign the motion vectors to the correct fragments */ - debug_vectors(" vectors for macroblock starting @ fragment %d (coding method %d):\n", - current_fragment, - s->macroblock_coding[current_macroblock]); - for (k = 0; k < 6; k++) { - current_fragment = - s->macroblock_fragments[current_macroblock * 6 + k]; - 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)\n", - k, current_fragment, motion_x[k], motion_y[k]); + /* assign the motion vectors to the correct fragments */ + for (k = 0; k < 6; k++) { + current_fragment = + s->macroblock_fragments[current_macroblock * 6 + k]; + 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]; } } } @@ -1162,15 +997,15 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, } for (i = first_fragment; i <= last_fragment; i++) { + int fragment_num = s->coded_fragment_list[i]; - fragment = &s->all_fragments[s->coded_fragment_list[i]]; - if (fragment->coeff_count > coeff_index) + if (s->coeff_counts[fragment_num] > coeff_index) continue; + fragment = &s->all_fragments[fragment_num]; if (!eob_run) { /* decode a VLC into a token */ 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 */ if (token <= 6) { eob_run = eob_run_base[token]; @@ -1191,20 +1026,16 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, } if (!eob_run) { - fragment->coeff_count += zero_run; - if (fragment->coeff_count < 64){ + s->coeff_counts[fragment_num] += zero_run; + if (s->coeff_counts[fragment_num] < 64){ fragment->next_coeff->coeff= coeff; - fragment->next_coeff->index= perm[fragment->coeff_count++]; //FIXME perm here already? + fragment->next_coeff->index= perm[s->coeff_counts[fragment_num]++]; //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->next_coeff[coeff_index]); } else { - fragment->coeff_count |= 128; - debug_vlc(" fragment %d eob with %d coefficients\n", - s->coded_fragment_list[i], fragment->coeff_count&127); + s->coeff_counts[fragment_num] |= 128; eob_run--; } } @@ -1225,78 +1056,54 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) int ac_c_table; int residual_eob_run = 0; - /* fetch the DC table indices */ + /* fetch the DC table indexes */ dc_y_table = get_bits(gb, 4); dc_c_table = get_bits(gb, 4); /* 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, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); /* unpack the C plane DC coefficients */ - debug_vp3(" vp3: unpacking C plane DC coefficients using table %d\n", - dc_c_table); residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); - /* fetch the AC table indices */ + /* fetch the AC table indexes */ ac_y_table = get_bits(gb, 4); ac_c_table = get_bits(gb, 4); /* unpack the group 1 AC coefficients (coeffs 1-5) */ for (i = 1; i <= 5; i++) { - - 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, 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, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } /* unpack the group 2 AC coefficients (coeffs 6-14) */ for (i = 6; i <= 14; i++) { - - 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, 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, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } /* unpack the group 3 AC coefficients (coeffs 15-27) */ for (i = 15; i <= 27; i++) { - - 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, 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, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } /* unpack the group 4 AC coefficients (coeffs 28-63) */ for (i = 28; i <= 63; i++) { - - 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, 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, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } @@ -1333,7 +1140,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, /* DC values for the left, up-left, up, and up-right fragments */ int vl, vul, vu, vur; - /* indices for the left, up-left, up, and up-right fragments */ + /* indexes for the left, up-left, up, and up-right fragments */ int l, ul, u, ur; /* @@ -1385,8 +1192,6 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, int transform = 0; - debug_vp3(" vp3: reversing DC prediction\n"); - vul = vu = vur = vl = 0; last_dc[0] = last_dc[1] = last_dc[2] = 0; @@ -1401,8 +1206,6 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, current_frame_type = compatible_frame[s->all_fragments[i].coding_method]; - debug_dc_pred(" frag %d: orig DC = %d, ", - i, DC_COEFF(i)); transform= 0; if(x){ @@ -1430,16 +1233,11 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, } } - debug_dc_pred("transform = %d, ", transform); - if (transform == 0) { /* if there were no fragments to predict from, use last * DC saved */ predicted_dc = last_dc[current_frame_type]; - debug_dc_pred("from last DC (%d) = %d\n", - current_frame_type, DC_COEFF(i)); - } else { /* apply the appropriate predictor transform */ @@ -1461,9 +1259,6 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, else if (FFABS(predicted_dc - vul) > 128) predicted_dc = vul; } - - debug_dc_pred("from pred DC = %d\n", - DC_COEFF(i)); } /* at long last, apply the predictor */ @@ -1476,8 +1271,8 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, s->coeffs[i].coeff += predicted_dc; /* save the DC */ 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; + if(DC_COEFF(i) && !(s->coeff_counts[i]&127)){ + s->coeff_counts[i]= 129; // s->all_fragments[i].next_coeff= s->next_coeff; s->coeffs[i].next= s->next_coeff; (s->next_coeff++)->next=NULL; @@ -1487,12 +1282,6 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, } } - -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); - /* * Perform the final rendering for a particular slice of data. * The slice number ranges from 0..(macroblock_height - 1). @@ -1500,7 +1289,6 @@ static void vertical_filter(unsigned char *first_pixel, int stride, static void render_slice(Vp3DecodeContext *s, int slice) { int x; - int m, n; int16_t *dequantizer; DECLARE_ALIGNED_16(DCTELEM, block[64]); int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef; @@ -1612,10 +1400,6 @@ static void render_slice(Vp3DecodeContext *s, int slice) } /* 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)); @@ -1647,19 +1431,6 @@ static void render_slice(Vp3DecodeContext *s, int slice) 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("\n"); - } - debug_idct("\n"); - } else { /* copy directly from the previous frame */ @@ -1717,39 +1488,6 @@ static void render_slice(Vp3DecodeContext *s, int slice) 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] = av_clip_uint8(first_pixel[-1] + filter_value); - first_pixel[ 0] = av_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] = av_clip_uint8(first_pixel[nstride] + filter_value); - first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value); - } -} - static void apply_loop_filter(Vp3DecodeContext *s) { int plane; @@ -1788,11 +1526,10 @@ static void apply_loop_filter(Vp3DecodeContext *s) 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( + s->dsp.vp3_h_loop_filter( plane_data + s->all_fragments[fragment].first_pixel, stride, bounding_values); } @@ -1800,7 +1537,7 @@ START_TIMER /* do not perform top edge filter for top row fragments */ if ((y > 0) && (s->all_fragments[fragment].coding_method != MODE_COPY)) { - vertical_filter( + s->dsp.vp3_v_loop_filter( plane_data + s->all_fragments[fragment].first_pixel, stride, bounding_values); } @@ -1811,7 +1548,7 @@ START_TIMER if ((x < width - 1) && (s->all_fragments[fragment].coding_method != MODE_COPY) && (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) { - horizontal_filter( + s->dsp.vp3_h_loop_filter( plane_data + s->all_fragments[fragment + 1].first_pixel, stride, bounding_values); } @@ -1822,13 +1559,12 @@ START_TIMER if ((y < height - 1) && (s->all_fragments[fragment].coding_method != MODE_COPY) && (s->all_fragments[fragment + width].coding_method == MODE_COPY)) { - vertical_filter( + s->dsp.vp3_v_loop_filter( plane_data + s->all_fragments[fragment + width].first_pixel, stride, bounding_values); } fragment++; -STOP_TIMER("loop filter") } } } @@ -1841,93 +1577,43 @@ STOP_TIMER("loop filter") */ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) { +#define Y_INITIAL(chroma_shift) s->flipped_image ? 1 : s->fragment_height >> chroma_shift +#define Y_FINISHED(chroma_shift) s->flipped_image ? y <= s->fragment_height >> chroma_shift : y > 0 int i, x, y; + const int y_inc = s->flipped_image ? 1 : -1; /* figure out the first pixel addresses for each of the fragments */ /* Y plane */ i = 0; - for (y = s->fragment_height; y > 0; y--) { + for (y = Y_INITIAL(0); Y_FINISHED(0); y += y_inc) { 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->fragment_start[1]; - for (y = s->fragment_height / 2; y > 0; y--) { + for (y = Y_INITIAL(1); Y_FINISHED(1); y += y_inc) { 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->fragment_start[2]; - for (y = s->fragment_height / 2; y > 0; y--) { + for (y = Y_INITIAL(1); Y_FINISHED(1); y += y_inc) { 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", - 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->fragment_start[1]; - 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->fragment_start[2]; - 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", - i-1, s->all_fragments[i-1].first_pixel); } } } @@ -1935,7 +1621,7 @@ static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) /* * This is the ffmpeg/libavcodec API init function. */ -static int vp3_decode_init(AVCodecContext *avctx) +static av_cold int vp3_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; int i, inter, plane; @@ -1991,27 +1677,11 @@ static int vp3_decode_init(AVCodecContext *avctx) s->fragment_start[1] = s->fragment_width * s->fragment_height; s->fragment_start[2] = s->fragment_width * s->fragment_height * 5 / 4; - 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", - s->fragment_count, - s->fragment_width, - s->fragment_height, - s->fragment_start[1], - s->fragment_start[2]); - s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment)); + s->coeff_counts = av_malloc(s->fragment_count * sizeof(*s->coeff_counts)); 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; + s->pixel_addresses_initialized = 0; if (!s->theora_tables) { @@ -2128,7 +1798,7 @@ static int vp3_decode_init(AVCodecContext *avctx) */ static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; @@ -2165,6 +1835,9 @@ static int vp3_decode_frame(AVCodecContext *avctx, init_loop_filter(s); } + if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe) + return buf_size; + if (s->keyframe) { if (!s->theora) { @@ -2205,18 +1878,15 @@ static int vp3_decode_frame(AVCodecContext *avctx, s->current_frame= s->golden_frame; /* time to figure out pixel addresses? */ - if (!s->pixel_addresses_inited) + if (!s->pixel_addresses_initialized) { - if (!s->flipped_image) - vp3_calculate_pixel_addresses(s); - else - theora_calculate_pixel_addresses(s); - s->pixel_addresses_inited = 1; + vp3_calculate_pixel_addresses(s); + s->pixel_addresses_initialized = 1; } } else { /* allocate a new current frame */ s->current_frame.reference = 3; - if (!s->pixel_addresses_inited) { + if (!s->pixel_addresses_initialized) { av_log(s->avctx, AV_LOG_ERROR, "vp3: first frame not a keyframe\n"); return -1; } @@ -2229,48 +1899,24 @@ static int vp3_decode_frame(AVCodecContext *avctx, 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 - - {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); if ((avctx->flags & CODEC_FLAG_GRAY) == 0) { @@ -2279,19 +1925,11 @@ if (!s->keyframe) { reverse_dc_prediction(s, s->fragment_start[2], s->fragment_width / 2, s->fragment_height / 2); } - STOP_TIMER("reverse_dc_prediction")} - {START_TIMER 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; @@ -2312,11 +1950,14 @@ if (!s->keyframe) { /* * This is the ffmpeg/libavcodec API module cleanup function. */ -static int vp3_decode_end(AVCodecContext *avctx) +static av_cold int vp3_decode_end(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; + int i; + av_free(s->superblock_coding); av_free(s->all_fragments); + av_free(s->coeff_counts); av_free(s->coeffs); av_free(s->coded_fragment_list); av_free(s->superblock_fragments); @@ -2324,6 +1965,19 @@ static int vp3_decode_end(AVCodecContext *avctx) av_free(s->macroblock_fragments); av_free(s->macroblock_coding); + for (i = 0; i < 16; i++) { + free_vlc(&s->dc_vlc[i]); + free_vlc(&s->ac_vlc_1[i]); + free_vlc(&s->ac_vlc_2[i]); + free_vlc(&s->ac_vlc_3[i]); + free_vlc(&s->ac_vlc_4[i]); + } + + free_vlc(&s->superblock_run_length_vlc); + free_vlc(&s->fragment_run_length_vlc); + free_vlc(&s->mode_code_vlc); + free_vlc(&s->motion_vector_vlc); + /* release all frames */ if (s->golden_frame.data[0] && s->golden_frame.data[0] != s->last_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); @@ -2339,7 +1993,7 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { int token; if (s->entries >= 32) { /* overflow */ av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); @@ -2367,12 +2021,14 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) return 0; } +#ifdef CONFIG_THEORA_DECODER static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; + int visible_width, visible_height; s->theora = get_bits_long(gb, 24); - av_log(avctx, AV_LOG_INFO, "Theora bitstream version %X\n", s->theora); + av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora); /* 3.2.0 aka alpha3 has the same frame orientation as original vp3 */ /* but previous versions have the image flipped relative to vp3 */ @@ -2382,8 +2038,8 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) av_log(avctx, AV_LOG_DEBUG, "Old (width = get_bits(gb, 16) << 4; - s->height = get_bits(gb, 16) << 4; + visible_width = s->width = get_bits(gb, 16) << 4; + visible_height = 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); @@ -2398,20 +2054,15 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) 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 */ } - if (s->theora >= 0x030200) { - skip_bits(gb, 8); /* offset x */ - skip_bits(gb, 8); /* offset y */ - } + if (s->theora >= 0x030200) { + visible_width = get_bits_long(gb, 24); + visible_height = get_bits_long(gb, 24); + + skip_bits(gb, 8); /* offset x */ + skip_bits(gb, 8); /* offset y */ + } skip_bits(gb, 32); /* fps numerator */ skip_bits(gb, 32); /* fps denumerator */ @@ -2437,8 +2088,11 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) // align_get_bits(gb); - avctx->width = s->width; - avctx->height = s->height; + if ( visible_width <= s->width && visible_width > s->width-16 + && visible_height <= s->height && visible_height > s->height-16) + avcodec_set_dimensions(avctx, visible_width, visible_height); + else + avcodec_set_dimensions(avctx, s->width, s->height); return 0; } @@ -2490,10 +2144,10 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) for (plane = 0; plane <= 2; plane++) { int newqr= 1; if (inter || plane > 0) - newqr = get_bits(gb, 1); + newqr = get_bits1(gb); if (!newqr) { int qtj, plj; - if(inter && get_bits(gb, 1)){ + if(inter && get_bits1(gb)){ qtj = 0; plj = plane; }else{ @@ -2534,7 +2188,7 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) for (s->hti = 0; s->hti < 80; s->hti++) { s->entries = 0; s->huff_code_size = 1; - if (!get_bits(gb, 1)) { + if (!get_bits1(gb)) { s->hbits = 0; read_huffman_tree(avctx, gb); s->hbits = 1; @@ -2574,7 +2228,6 @@ static int theora_decode_init(AVCodecContext *avctx) init_get_bits(&gb, header_start[i], header_len[i]); ptype = get_bits(&gb, 8); - debug_vp3("Theora headerpacket type: %x\n", ptype); if (!(ptype & 0x80)) { @@ -2601,8 +2254,8 @@ static int theora_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype&~0x80); break; } - if(8*header_len[i] != get_bits_count(&gb)) - av_log(avctx, AV_LOG_ERROR, "%d bits left in packet %X\n", 8*header_len[i] - get_bits_count(&gb), ptype); + if(ptype != 0x81 && 8*header_len[i] != get_bits_count(&gb)) + av_log(avctx, AV_LOG_WARNING, "%d bits left in packet %X\n", 8*header_len[i] - get_bits_count(&gb), ptype); if (s->theora < 0x030200) break; } @@ -2611,7 +2264,6 @@ static int theora_decode_init(AVCodecContext *avctx) return 0; } -#ifdef CONFIG_THEORA_DECODER AVCodec theora_decoder = { "theora", CODEC_TYPE_VIDEO, @@ -2622,7 +2274,8 @@ AVCodec theora_decoder = { vp3_decode_end, vp3_decode_frame, 0, - NULL + NULL, + .long_name = NULL_IF_CONFIG_SMALL("Theora"), }; #endif @@ -2636,5 +2289,6 @@ AVCodec vp3_decoder = { vp3_decode_end, vp3_decode_frame, 0, - NULL + NULL, + .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), };