X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp3.c;h=b7c2dcd5f3038f01eb4e8b5106ba40230a8fc858;hb=d61c4e731e1b5475bc449a04d792bcadcd89d1df;hp=7923229dc13b7c9a4896ae931d4b764ae90fdfd5;hpb=ea191e08d6cefad09bfb1e6d9317874dfd4080be;p=ffmpeg diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 7923229dc13..b7c2dcd5f30 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1,31 +1,33 @@ /* * Copyright (C) 2003-2004 the ffmpeg project * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * VP3 Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the VP3 coding process, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * Theora decoder by Alex Beregszaszi + * License along with FFmpeg; if not, write to the Free Software + * 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 @@ -42,9 +44,9 @@ #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. * @@ -75,77 +77,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; - int coding_method; - int coeff_count; - int last_coeff; - int motion_x; - int motion_y; + 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 @@ -172,39 +180,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 }, }; @@ -223,6 +231,8 @@ typedef struct Vp3DecodeContext { DSPContext dsp; int flipped_image; + int qis[3]; + int nqis; int quality_index; int last_quality_index; @@ -246,16 +256,19 @@ typedef struct Vp3DecodeContext { int fragment_height; Vp3Fragment *all_fragments; - DCTELEM *coeffs; - int u_fragment_start; - int v_fragment_start; - + Coeff *coeffs; + Coeff *next_coeff; + int fragment_start[3]; + + 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]; + uint8_t base_matrix[384][64]; + uint8_t qr_count[2][3]; + 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 * which of the fragments are coded */ @@ -269,11 +282,14 @@ typedef struct Vp3DecodeContext { VLC ac_vlc_3[16]; VLC ac_vlc_4[16]; + VLC superblock_run_length_vlc; + VLC fragment_run_length_vlc; + VLC mode_code_vlc; + VLC motion_vector_vlc; + /* these arrays need to be on 16-byte boundaries since SSE2 operations * index into them */ - int16_t __align16 intra_y_dequant[64]; - int16_t __align16 intra_c_dequant[64]; - int16_t __align16 inter_dequant[64]; + DECLARE_ALIGNED_16(int16_t, qmat[2][4][64]); //fragment_width; - hilbert_walk_y[3] = -1; - hilbert_walk_y[4] = s->fragment_width; - hilbert_walk_y[5] = s->fragment_width; - hilbert_walk_y[6] = 1; - hilbert_walk_y[7] = -s->fragment_width; - hilbert_walk_y[8] = 1; - hilbert_walk_y[9] = s->fragment_width; - hilbert_walk_y[10] = 1; - hilbert_walk_y[11] = -s->fragment_width; - hilbert_walk_y[12] = -s->fragment_width; - hilbert_walk_y[13] = -1; - hilbert_walk_y[14] = -s->fragment_width; - hilbert_walk_y[15] = 1; - - hilbert_walk_c[0] = 1; - hilbert_walk_c[1] = 1; - hilbert_walk_c[2] = s->fragment_width / 2; - hilbert_walk_c[3] = -1; - hilbert_walk_c[4] = s->fragment_width / 2; - hilbert_walk_c[5] = s->fragment_width / 2; - hilbert_walk_c[6] = 1; - hilbert_walk_c[7] = -s->fragment_width / 2; - hilbert_walk_c[8] = 1; - hilbert_walk_c[9] = s->fragment_width / 2; - hilbert_walk_c[10] = 1; - hilbert_walk_c[11] = -s->fragment_width / 2; - hilbert_walk_c[12] = -s->fragment_width / 2; - hilbert_walk_c[13] = -1; - hilbert_walk_c[14] = -s->fragment_width / 2; - hilbert_walk_c[15] = 1; - hilbert_walk_mb[0] = 1; hilbert_walk_mb[1] = s->macroblock_width; hilbert_walk_mb[2] = 1; @@ -414,9 +402,8 @@ static int init_block_mapping(Vp3DecodeContext *s) bottom_edge = s->fragment_height; 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 */ current_fragment = -1; @@ -428,12 +415,11 @@ static int init_block_mapping(Vp3DecodeContext *s) bottom_edge = s->fragment_height / 2; 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 */ - current_fragment = s->u_fragment_start - 1; + current_fragment = s->fragment_start[1] - 1; } else if (i == s->v_superblock_start) { @@ -442,12 +428,11 @@ static int init_block_mapping(Vp3DecodeContext *s) bottom_edge = s->fragment_height / 2; 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 */ - current_fragment = s->v_fragment_start - 1; + current_fragment = s->fragment_start[2] - 1; } @@ -462,7 +447,7 @@ static int init_block_mapping(Vp3DecodeContext *s) /* iterate through all 16 fragments in a superblock */ for (j = 0; j < 16; j++) { - current_fragment += hilbert[j]; + current_fragment += travel_width[j] + right_edge * travel_height[j]; current_width += travel_width[j]; current_height += travel_height[j]; @@ -470,12 +455,12 @@ 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", + 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", + 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); } @@ -551,31 +536,31 @@ static int 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->fragment_start[1] + (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->v_fragment_start + + 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; @@ -585,7 +570,7 @@ static int init_block_mapping(Vp3DecodeContext *s) if (j + 2 <= s->fragment_width) current_fragment += 2; - else + else current_fragment++; current_macroblock++; } @@ -596,554 +581,90 @@ static int init_block_mapping(Vp3DecodeContext *s) return 0; /* successful path out */ } -/* - * 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: - av_log(NULL, AV_LOG_ERROR, " vp3: help! Got a bad token: %d > 31\n", token); - break; - - } -} - /* * This function wipes out all of the fragment data. */ static void init_frame(Vp3DecodeContext *s, GetBitContext *gb) { int i; - static const DCTELEM zero_block[64]; /* 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].coeffs = zero_block; s->all_fragments[i].coeff_count = 0; - s->all_fragments[i].last_coeff = -1; -s->all_fragments[i].motion_x = 0xbeef; -s->all_fragments[i].motion_y = 0xbeef; + 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 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; + int i, plane, inter, qri, bmi, bmj, qistart; debug_vp3(" vp3: initializing dequantization tables\n"); - /* - * Scale dequantizers: - * - * quantizer * sf - * -------------- - * 100 - * - * where sf = dc_scale_factor for DC quantizer - * or ac_scale_factor for AC quantizer - * - * Then, saturate the result to a lower limit of MIN_DEQUANT_VAL. - */ -#define SCALER 4 - - /* scale DC quantizers */ - 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] = 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] = 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; - - /* scale AC quantizers, zigzag at the same time in preparation for - * the dequantization phase */ - for (i = 1; i < 64; i++) { - - j = i; - - s->intra_y_dequant[j] = s->coded_intra_y_dequant[i] * 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] = s->coded_intra_c_dequant[i] * 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] = s->coded_inter_dequant[i] * 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++) { - for (j = i * 8; j < i * 8 + 8; j++) { - debug_dequantizers(" %4d,", s->intra_y_dequant[j]); - } - debug_dequantizers("\n"); - } - debug_dequantizers("\n"); - - debug_dequantizers("intra C dequantizers:\n"); - for (i = 0; i < 8; i++) { - for (j = i * 8; j < i * 8 + 8; j++) { - debug_dequantizers(" %4d,", s->intra_c_dequant[j]); - } - debug_dequantizers("\n"); - } - debug_dequantizers("\n"); - - debug_dequantizers("interframe dequantizers:\n"); - for (i = 0; i < 8; i++) { - for (j = i * 8; j < i * 8 + 8; j++) { - debug_dequantizers(" %4d,", s->inter_dequant[j]); - } - debug_dequantizers("\n"); + for(inter=0; inter<2; inter++){ + for(plane=0; plane<3; plane++){ + int sum=0; + for(qri=0; qriqr_count[inter][plane]; qri++){ + sum+= s->qr_size[inter][plane][qri]; + if(s->quality_index <= sum) + break; + } + qistart= sum - s->qr_size[inter][plane][qri]; + bmi= s->qr_base[inter][plane][qri ]; + bmj= s->qr_base[inter][plane][qri+1]; + for(i=0; i<64; i++){ + int coeff= ( 2*(sum -s->quality_index)*s->base_matrix[bmi][i] + - 2*(qistart-s->quality_index)*s->base_matrix[bmj][i] + + s->qr_size[inter][plane][qri]) + / (2*s->qr_size[inter][plane][qri]); + + int qmin= 8<<(inter + !i); + int qscale= i ? ac_scale_factor : dc_scale_factor; + + s->qmat[inter][plane][i]= clip((qscale * coeff)/100 * 4, qmin, 4096); + } + } } - debug_dequantizers("\n"); -} - -/* - * 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)); + memset(s->qscale_table, (FFMAX(s->qmat[0][0][1], s->qmat[0][1][1])+8)/16, 512); //FIXME finetune } /* - * 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 - * + * This function initializes the loop filter boundary limits if the frame's + * quality index is different from the previous frame's. */ -static int get_mode_code(GetBitContext *gb) +static void init_loop_filter(Vp3DecodeContext *s) { + int *bounding_values= s->bounding_values_array+127; + int filter_limit; + int x; - 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 - */ -static int get_motion_vector_vlc(GetBitContext *gb) -{ - 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; + 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 int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) @@ -1169,13 +690,16 @@ static int 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, @@ -1192,9 +716,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) 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 @@ -1204,7 +726,7 @@ static int 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) { @@ -1212,17 +734,18 @@ static int 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++; } @@ -1234,7 +757,7 @@ static int 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; } @@ -1243,6 +766,7 @@ static int 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; first_c_fragment_seen = 0; @@ -1263,27 +787,28 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) 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) { - /* default mode; actual mode will be decoded in + /* default mode; actual mode will be decoded in * the next phase */ - s->all_fragments[current_fragment].coding_method = + s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; - s->all_fragments[current_fragment].coeffs= s->coeffs + 64*s->coded_fragment_list_index; - 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) && + if ((current_fragment >= s->fragment_start[1]) && (s->last_coded_y_fragment == -1) && (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; @@ -1302,18 +827,16 @@ static int 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->all_fragments[current_fragment].coeffs= s->coeffs + 64*s->coded_fragment_list_index; - 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) && + if ((current_fragment >= s->fragment_start[1]) && (s->last_coded_y_fragment == -1) && (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; @@ -1332,7 +855,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) if (!first_c_fragment_seen) /* only Y fragments coded in this frame */ s->last_coded_y_fragment = s->coded_fragment_list_index - 1; - else + else /* end the list of coded C fragments */ s->last_coded_c_fragment = s->coded_fragment_list_index - 1; @@ -1380,7 +903,7 @@ static int 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 @@ -1402,11 +925,12 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) 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 (current_fragment == -1) continue; @@ -1415,7 +939,7 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) current_fragment, s->fragment_count); return 1; } - if (s->all_fragments[current_fragment].coding_method != + if (s->all_fragments[current_fragment].coding_method != MODE_COPY) s->all_fragments[current_fragment].coding_method = coding_mode; @@ -1489,12 +1013,13 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) case MODE_GOLDEN_MV: /* all 6 fragments use the same motion vector */ if (coding_mode == 0) { - 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]; @@ -1516,27 +1041,20 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) motion_x[4] = motion_y[4] = 0; for (k = 0; k < 4; k++) { if (coding_mode == 0) { - 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) - 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) - motion_y[4] = (motion_y[4] + 2) / 4; - else - motion_y[4] = (motion_y[4] - 2) / 4; - motion_y[5] = motion_y[4]; + 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 */ @@ -1590,7 +1108,7 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) current_fragment, s->macroblock_coding[current_macroblock]); for (k = 0; k < 6; k++) { - current_fragment = + current_fragment = s->macroblock_fragments[current_macroblock * 6 + k]; if (current_fragment == -1) continue; @@ -1611,7 +1129,7 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) 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 @@ -1630,9 +1148,11 @@ 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)) { @@ -1653,20 +1173,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[dezigzag_index[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--; } } @@ -1694,7 +1233,7 @@ static int 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 */ @@ -1712,12 +1251,12 @@ static int 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); } @@ -1726,12 +1265,12 @@ static int 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); } @@ -1740,12 +1279,12 @@ static int 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); } @@ -1754,12 +1293,12 @@ static int 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); } @@ -1768,18 +1307,18 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* * 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) -static inline int iabs (int x) { return ((x < 0) ? -x : x); } +#define DC_COEFF(u) (s->coeffs[u].index ? 0 : s->coeffs[u].coeff) //FIXME do somethin to simplify this static void reverse_dc_prediction(Vp3DecodeContext *s, int first_fragment, int fragment_width, - int fragment_height) + int fragment_height) { #define PUL 8 @@ -1790,23 +1329,7 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, int x, y; int i = first_fragment; - /* - * Fragment prediction groups: - * - * 32222222226 - * 10000000004 - * 10000000004 - * 10000000004 - * 10000000004 - * - * 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; - short predicted_dc; - - /* validity flags for the left, up-left, up, and up-right fragments */ - int fl, ful, fu, fur; + int predicted_dc; /* DC values for the left, up-left, up, and up-right fragments */ int vl, vul, vu, vur; @@ -1814,38 +1337,36 @@ 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 * 2: up-right multiplier * 3: left multiplier - * 4: mask - * 5: right bit shift divisor (e.g., 7 means >>=7, a.k.a. div by 128) */ - int predictor_transform[16][6] = { - { 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 1, 0, 0 }, // PL - { 0, 0, 1, 0, 0, 0 }, // PUR - { 0, 0, 53, 75, 127, 7 }, // PUR|PL - { 0, 1, 0, 0, 0, 0 }, // PU - { 0, 1, 0, 1, 1, 1 }, // PU|PL - { 0, 1, 0, 0, 0, 0 }, // PU|PUR - { 0, 0, 53, 75, 127, 7 }, // PU|PUR|PL - { 1, 0, 0, 0, 0, 0 }, // PUL - { 0, 0, 0, 1, 0, 0 }, // PUL|PL - { 1, 0, 1, 0, 1, 1 }, // PUL|PUR - { 0, 0, 53, 75, 127, 7 }, // PUL|PUR|PL - { 0, 1, 0, 0, 0, 0 }, // PUL|PU - {-26, 29, 0, 29, 31, 5 }, // PUL|PU|PL - { 3, 10, 3, 0, 15, 4 }, // PUL|PU|PUR - {-26, 29, 0, 29, 31, 5 } // PUL|PU|PUR|PL + int predictor_transform[16][4] = { + { 0, 0, 0, 0}, + { 0, 0, 0,128}, // PL + { 0, 0,128, 0}, // PUR + { 0, 0, 53, 75}, // PUR|PL + { 0,128, 0, 0}, // PU + { 0, 64, 0, 64}, // PU|PL + { 0,128, 0, 0}, // PU|PUR + { 0, 0, 53, 75}, // PU|PUR|PL + {128, 0, 0, 0}, // PUL + { 0, 0, 0,128}, // PUL|PL + { 64, 0, 64, 0}, // PUL|PUR + { 0, 0, 53, 75}, // PUL|PUR|PL + { 0,128, 0, 0}, // PUL|PU + {-104,116, 0,116}, // PUL|PU|PL + { 24, 80, 24, 0}, // PUL|PU|PUR + {-104,116, 0,116} // PUL|PU|PUR|PL }; /* 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] = { @@ -1879,115 +1400,35 @@ 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]); - - switch (predictor_group) { - - case 0: - /* main body of fragments; consider all 4 possible - * fragments for prediction */ - - /* calculate the indices of the predicting fragments */ - ul = i - fragment_width - 1; - u = i - fragment_width; - ur = i - fragment_width + 1; - 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]; - - /* figure out which fragments are valid */ - ful = FRAME_CODED(ul) && COMPATIBLE_FRAME(ul); - fu = FRAME_CODED(u) && COMPATIBLE_FRAME(u); - fur = FRAME_CODED(ur) && COMPATIBLE_FRAME(ur); - fl = FRAME_CODED(l) && COMPATIBLE_FRAME(l); - - /* decide which predictor transform to use */ - transform = (fl*PL) | (fu*PU) | (ful*PUL) | (fur*PUR); - - break; - - case 1: - /* left column of fragments, not including top corner; - * only consider up and up-right fragments */ - - /* calculate the indices of the predicting fragments */ - u = i - fragment_width; - 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]; - - /* figure out which fragments are valid */ - fur = FRAME_CODED(ur) && COMPATIBLE_FRAME(ur); - fu = FRAME_CODED(u) && COMPATIBLE_FRAME(u); - - /* decide which predictor transform to use */ - transform = (fu*PU) | (fur*PUR); - - break; - - case 2: - case 6: - /* top row of fragments, not including top-left frag; - * only consider the left fragment for prediction */ - - /* calculate the indices of the predicting fragments */ - l = i - 1; - - /* fetch the DC values for the predicting fragments */ - vl = s->all_fragments[l].coeffs[0]; - - /* figure out which fragments are valid */ - fl = FRAME_CODED(l) && COMPATIBLE_FRAME(l); - - /* decide which predictor transform to use */ - transform = (fl*PL); - - break; - - case 3: - /* top-left fragment */ - - /* nothing to predict from in this case */ - transform = 0; - - break; - - case 4: - /* right column of fragments, not including top corner; - * consider up-left, up, and left fragments for - * prediction */ - - /* calculate the indices of the predicting fragments */ - ul = i - fragment_width - 1; - u = i - fragment_width; - 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]; - - /* figure out which fragments are valid */ - ful = FRAME_CODED(ul) && COMPATIBLE_FRAME(ul); - fu = FRAME_CODED(u) && COMPATIBLE_FRAME(u); - fl = FRAME_CODED(l) && COMPATIBLE_FRAME(l); - - /* decide which predictor transform to use */ - transform = (fl*PL) | (fu*PU) | (ful*PUL); - - break; - + debug_dc_pred(" frag %d: orig DC = %d, ", + i, DC_COEFF(i)); + + transform= 0; + if(x){ + l= i-1; + vl = DC_COEFF(l); + if(FRAME_CODED(l) && COMPATIBLE_FRAME(l)) + transform |= PL; + } + if(y){ + u= i-fragment_width; + vu = DC_COEFF(u); + if(FRAME_CODED(u) && COMPATIBLE_FRAME(u)) + transform |= PU; + if(x){ + ul= i-fragment_width-1; + vul = DC_COEFF(ul); + if(FRAME_CODED(ul) && COMPATIBLE_FRAME(ul)) + transform |= PUL; + } + if(x + 1 < fragment_width){ + ur= i-fragment_width+1; + vur = DC_COEFF(ur); + if(FRAME_CODED(ur) && COMPATIBLE_FRAME(ur)) + transform |= PUR; + } } debug_dc_pred("transform = %d, ", transform); @@ -1996,9 +1437,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 { @@ -2009,276 +1450,315 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, (predictor_transform[transform][2] * vur) + (predictor_transform[transform][3] * vl); - /* 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) & - predictor_transform[transform][4]); - predicted_dc >>= predictor_transform[transform][5]; - } + predicted_dc /= 128; /* check for outranging on the [ul u l] and * [ul u ur l] predictors */ if ((transform == 13) || (transform == 15)) { - if (iabs(predicted_dc - vu) > 128) + if (ABS(predicted_dc - vu) > 128) predicted_dc = vu; - else if (iabs(predicted_dc - vl) > 128) + else if (ABS(predicted_dc - vl) > 128) predicted_dc = vl; - else if (iabs(predicted_dc - vul) > 128) + else if (ABS(predicted_dc - vul) > 128) 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]; - if(s->all_fragments[i].coeffs[0] && s->all_fragments[i].last_coeff<0) - s->all_fragments[i].last_coeff= 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 x; int m, n; - int i = first_fragment; int16_t *dequantizer; - DCTELEM __align16 output_samples[64]; - unsigned char *output_plane; - unsigned char *last_plane; - unsigned char *golden_plane; - int stride; + DECLARE_ALIGNED_16(DCTELEM, block[64]); int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef; - int upper_motion_limit, lower_motion_limit; int motion_halfpel_index; uint8_t *motion_source; + int plane; + int current_macroblock_entry = slice * s->macroblock_width * 6; - 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) { - 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 = height * s->current_frame.linesize[0] + width - 8; - } 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 = height * s->current_frame.linesize[1] + width - 8; - } 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 = height * s->current_frame.linesize[2] + width - 8; - } - - if(ABS(stride) > 2048) - return; //various tables are fixed size + if (slice >= s->macroblock_height) + return; - /* for each fragment row... */ - for (y = 0; y < height; y += 8) { + for (plane = 0; plane < 3; plane++) { + uint8_t *output_plane = s->current_frame.data [plane]; + uint8_t * last_plane = s-> last_frame.data [plane]; + uint8_t *golden_plane = s-> golden_frame.data [plane]; + int stride = s->current_frame.linesize[plane]; + int plane_width = s->width >> !!plane; + int plane_height = s->height >> !!plane; + int y = slice * FRAGMENT_PIXELS << !plane ; + int slice_height = y + (FRAGMENT_PIXELS << !plane); + int i = s->macroblock_fragments[current_macroblock_entry + plane + 3*!!plane]; - /* for each fragment in a row... */ - for (x = 0; x < width; x += 8, i++) { + if (!s->flipped_image) stride = -stride; - if ((i < 0) || (i >= s->fragment_count)) { - av_log(s->avctx, AV_LOG_ERROR, " vp3:render_fragments(): bad fragment number (%d)\n", i); - return; - } - /* transform if this block was coded */ - if ((s->all_fragments[i].coding_method != MODE_COPY) && - !((s->avctx->flags & CODEC_FLAG_GRAY) && plane)) { - - 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); - } + if(ABS(stride) > 2048) + return; //various tables are fixed size + + /* for each fragment row in the slice (both of them)... */ + for (; y < slice_height; y += 8) { - src_x= (motion_x>>1) + x; - src_y= (motion_y>>1) + y; -if ((motion_x == 0xbeef) || (motion_y == 0xbeef)) -av_log(s->avctx, AV_LOG_ERROR, " help! got beefy vector! (%X, %X)\n", motion_x, motion_y); + /* for each fragment in a row... */ + for (x = 0; x < plane_width; x += 8, i++) { - motion_halfpel_index = motion_x & 0x01; - motion_source += (motion_x >> 1); + if ((i < 0) || (i >= s->fragment_count)) { + av_log(s->avctx, AV_LOG_ERROR, " vp3:render_slice(): bad fragment number (%d)\n", i); + return; + } -// motion_y = -motion_y; - motion_halfpel_index |= (motion_y & 0x01) << 1; - motion_source += ((motion_y >> 1) * stride); + /* transform if this block was coded */ + if ((s->all_fragments[i].coding_method != MODE_COPY) && + !((s->avctx->flags & CODEC_FLAG_GRAY) && plane)) { - if(src_x<0 || src_y<0 || src_x + 9 >= width || src_y + 9 >= height){ - uint8_t *temp= s->edge_emu_buffer; - if(stride<0) temp -= 9*stride; - else temp += 9*stride; + 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); + } - ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, width, height); - motion_source= temp; + 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); + + motion_halfpel_index = motion_x & 0x01; + motion_source += (motion_x >> 1); + + 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; + } } - } - - - /* 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); + + + /* 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->qmat[1][plane]; }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->qmat[0][plane]; } - 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, - s->all_fragments[i].coeffs[0], dequantizer[0]); - - /* invert DCT and place (or add) in final output */ - s->dsp.vp3_idct(s->all_fragments[i].coeffs, - dequantizer, - s->all_fragments[i].coeff_count, - output_samples); - memset(s->all_fragments[i].coeffs, 0, 64*sizeof(DCTELEM)); - if (s->all_fragments[i].coding_method == MODE_INTRA) { - s->dsp.put_signed_pixels_clamped(output_samples, - output_plane + s->all_fragments[i].first_pixel, - stride); - } else { - s->dsp.add_pixels_clamped(output_samples, - output_plane + s->all_fragments[i].first_pixel, - stride); - } + /* 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; + } + } - 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))); + /* 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("\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, s->bounding_values_array + 127); + } + /* 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, s->bounding_values_array + 127); + } +#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(); } -#define SATURATE_U8(x) ((x) < 0) ? 0 : ((x) > 255) ? 255 : x - static void horizontal_filter(unsigned char *first_pixel, int stride, int *bounding_values) { - int i; + unsigned char *end; int filter_value; - for (i = 0; i < 8; i++, first_pixel += stride) { - filter_value = - (first_pixel[-2] * 1) - - (first_pixel[-1] * 3) + - (first_pixel[ 0] * 3) - - (first_pixel[ 1] * 1); + 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] = SATURATE_U8(first_pixel[-1] + filter_value); - first_pixel[ 0] = SATURATE_U8(first_pixel[ 0] - filter_value); + 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) { - int i; + unsigned char *end; int filter_value; + const int nstride= -stride; - for (i = 0; i < 8; i++, first_pixel++) { - filter_value = - (first_pixel[-(2 * stride)] * 1) - - (first_pixel[-(1 * stride)] * 3) + - (first_pixel[ (0 )] * 3) - - (first_pixel[ (1 * stride)] * 1); + 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[-(1 * stride)] = SATURATE_U8(first_pixel[-(1 * stride)] + filter_value); - first_pixel[0] = SATURATE_U8(first_pixel[0] - filter_value); + 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 plane; + int x, y; + int *bounding_values= s->bounding_values_array+127; +#if 0 int bounding_values_array[256]; - int *bounding_values= bounding_values_array+127; int filter_limit; /* find the right loop limit value */ @@ -2296,31 +1776,15 @@ static void apply_loop_filter(Vp3DecodeContext *s) 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]; - } + int width = s->fragment_width >> !!plane; + int height = s->fragment_height >> !!plane; + int fragment = s->fragment_start [plane]; + int stride = s->current_frame.linesize[plane]; + uint8_t *plane_data = s->current_frame.data [plane]; + if (!s->flipped_image) stride = -stride; for (y = 0; y < height; y++) { @@ -2330,7 +1794,7 @@ START_TIMER if ((x > 0) && (s->all_fragments[fragment].coding_method != MODE_COPY)) { horizontal_filter( - plane_data + s->all_fragments[fragment].first_pixel - 7*stride, + plane_data + s->all_fragments[fragment].first_pixel, stride, bounding_values); } @@ -2338,7 +1802,7 @@ START_TIMER if ((y > 0) && (s->all_fragments[fragment].coding_method != MODE_COPY)) { vertical_filter( - plane_data + s->all_fragments[fragment].first_pixel + stride, + plane_data + s->all_fragments[fragment].first_pixel, stride, bounding_values); } @@ -2349,7 +1813,7 @@ START_TIMER (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, + plane_data + s->all_fragments[fragment + 1].first_pixel, stride, bounding_values); } @@ -2360,7 +1824,7 @@ START_TIMER (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, + plane_data + s->all_fragments[fragment + width].first_pixel, stride, bounding_values); } @@ -2371,12 +1835,12 @@ 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; @@ -2386,44 +1850,44 @@ 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); } } /* U plane */ - i = s->u_fragment_start; + i = s->fragment_start[1]; 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); } } /* V plane */ - i = s->v_fragment_start; + i = s->fragment_start[2]; 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", + 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) +static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) { int i, x, y; @@ -2433,37 +1897,37 @@ static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) 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->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); } } /* U plane */ - i = s->u_fragment_start; + 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->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); } } /* V plane */ - i = s->v_fragment_start; + 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->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); } } @@ -2475,29 +1939,27 @@ static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) static int vp3_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; - int i; + int i, inter, plane; 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; + s->version = 0; else - s->version = 1; + s->version = 1; s->avctx = avctx; -#if 0 - s->width = avctx->width; - s->height = avctx->height; -#else s->width = (avctx->width + 15) & 0xFFFFFFF0; s->height = (avctx->height + 15) & 0xFFFFFFF0; -#endif avctx->pix_fmt = PIX_FMT_YUV420P; avctx->has_b_frames = 0; + if(avctx->idct_algo==FF_IDCT_AUTO) + avctx->idct_algo=FF_IDCT_VP3; dsputil_init(&s->dsp, avctx); - s->dsp.vp3_dsp_init(); + + 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 */ @@ -2528,8 +1990,8 @@ static int vp3_decode_init(AVCodecContext *avctx) /* fragment count covers all 8x8 blocks for all 3 planes */ s->fragment_count = s->fragment_width * s->fragment_height * 3 / 2; - s->u_fragment_start = s->fragment_width * s->fragment_height; - s->v_fragment_start = s->fragment_width * s->fragment_height * 5 / 4; + 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); @@ -2537,7 +1999,7 @@ static int vp3_decode_init(AVCodecContext *avctx) 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", + 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); @@ -2545,60 +2007,107 @@ static int vp3_decode_init(AVCodecContext *avctx) s->fragment_count, s->fragment_width, s->fragment_height, - s->u_fragment_start, - s->v_fragment_start); + s->fragment_start[1], + s->fragment_start[2]); s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment)); - s->coeffs = av_malloc(s->fragment_count * sizeof(DCTELEM) * 64); + 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; 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->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i]; + s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i]; + s->base_matrix[0][i] = vp31_intra_y_dequant[i]; + s->base_matrix[1][i] = vp31_intra_c_dequant[i]; + s->base_matrix[2][i] = vp31_inter_dequant[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); + for(inter=0; inter<2; inter++){ + for(plane=0; plane<3; plane++){ + s->qr_count[inter][plane]= 1; + s->qr_size [inter][plane][0]= 63; + s->qr_base [inter][plane][0]= + s->qr_base [inter][plane][1]= 2*inter + (!!plane)*!inter; + } + } + + /* 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 zigzag table */ - for (i = 0; i < 64; i++) - zigzag_index[dezigzag_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)); @@ -2619,71 +2128,83 @@ 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; + int i; init_get_bits(&gb, buf, buf_size * 8); - + if (s->theora && get_bits1(&gb)) { - 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; +#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); + skip_bits(&gb, 1); s->last_quality_index = s->quality_index; - s->quality_index = get_bits(&gb, 6); - if (s->theora >= 0x030200) - skip_bits1(&gb); + + s->nqis=0; + do{ + s->qis[s->nqis++]= get_bits(&gb, 6); + } while(s->theora >= 0x030200 && s->nqis<3 && get_bits1(&gb)); + + s->quality_index= s->qis[0]; 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); + 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) + if (s->quality_index != s->last_quality_index) { init_dequantizer(s); + init_loop_filter(s); + } if (s->keyframe) { - 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? */ - } + 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? */ + } if (s->last_frame.data[0] == s->golden_frame.data[0]) { if (s->golden_frame.data[0]) @@ -2703,19 +2224,24 @@ static int vp3_decode_frame(AVCodecContext *avctx, } /* golden frame is also the current frame */ - memcpy(&s->current_frame, &s->golden_frame, sizeof(AVFrame)); + s->current_frame= s->golden_frame; /* time to figure out pixel addresses? */ if (!s->pixel_addresses_inited) - { - if (!s->flipped_image) - vp3_calculate_pixel_addresses(s); - else - theora_calculate_pixel_addresses(s); - } + { + if (!s->flipped_image) + vp3_calculate_pixel_addresses(s); + else + theora_calculate_pixel_addresses(s); + s->pixel_addresses_inited = 1; + } } else { /* allocate a new current frame */ s->current_frame.reference = 3; + if (!s->pixel_addresses_inited) { + av_log(s->avctx, AV_LOG_ERROR, "vp3: first frame not a keyframe\n"); + return -1; + } if(avctx->get_buffer(avctx, &s->current_frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n"); return -1; @@ -2769,22 +2295,18 @@ if (!s->keyframe) { {START_TIMER reverse_dc_prediction(s, 0, s->fragment_width, s->fragment_height); - STOP_TIMER("reverse_dc_prediction")} - {START_TIMER - render_fragments(s, 0, s->width, s->height, 0); - STOP_TIMER("render_fragments")} - if ((avctx->flags & CODEC_FLAG_GRAY) == 0) { - reverse_dc_prediction(s, s->u_fragment_start, + reverse_dc_prediction(s, s->fragment_start[1], s->fragment_width / 2, s->fragment_height / 2); - reverse_dc_prediction(s, s->v_fragment_start, + reverse_dc_prediction(s, s->fragment_start[2], s->fragment_width / 2, s->fragment_height / 2); - 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); - } else { - memset(s->current_frame.data[1], 0x80, s->width * s->height / 4); - memset(s->current_frame.data[2], 0x80, s->width * s->height / 4); } + 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); @@ -2803,7 +2325,7 @@ if (!s->keyframe) { avctx->release_buffer(avctx, &s->last_frame); /* shuffle frames (last = current) */ - memcpy(&s->last_frame, &s->current_frame, sizeof(AVFrame)); + s->last_frame= s->current_frame; s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */ return buf_size; @@ -2823,7 +2345,7 @@ static int vp3_decode_end(AVCodecContext *avctx) av_free(s->superblock_macroblocks); av_free(s->macroblock_fragments); av_free(s->macroblock_coding); - + /* 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); @@ -2835,142 +2357,215 @@ static int vp3_decode_end(AVCodecContext *avctx) return 0; } -static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb) +static int read_huffman_tree(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); + 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; - /* FIXME: endianess? */ - s->theora = (major << 16) | (minor << 8) | micro; + s->theora = get_bits_long(gb, 24); + av_log(avctx, AV_LOG_INFO, "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 */ if (s->theora < 0x030200) { - s->flipped_image = 1; + s->flipped_image = 1; av_log(avctx, AV_LOG_DEBUG, "Old (width = get_bits(&gb, 16) << 4; - s->height = get_bits(&gb, 16) << 4; - + s->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; } - - 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 */ - skip_bits(&gb, 24); /* bitrate */ - skip_bits(&gb, 6); /* last(?) quality index */ - - if (s->theora >= 0x030200) + if (s->theora >= 0x030400) { - skip_bits(&gb, 5); /* keyframe frequency force */ - skip_bits(&gb, 5); /* spare bits */ + 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 */ } - -// align_get_bits(&gb); - - avctx->width = s->width; - avctx->height = s->height; - return 0; -} + if (s->theora >= 0x030200) { + skip_bits(gb, 8); /* offset x */ + skip_bits(gb, 8); /* offset y */ + } -static int theora_decode_comments(AVCodecContext *avctx, GetBitContext gb) -{ - int nb_comments, i, tmp; + 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 */ - tmp = get_bits_long(&gb, 32); - tmp = be2me_32(tmp); - while(tmp--) - skip_bits(&gb, 8); + skip_bits(gb, 6); /* quality hint */ - nb_comments = get_bits_long(&gb, 32); - nb_comments = be2me_32(nb_comments); - for (i = 0; i < nb_comments; i++) + if (s->theora >= 0x030200) { - tmp = get_bits_long(&gb, 32); - tmp = be2me_32(tmp); - while(tmp--) - skip_bits(&gb, 8); + 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 int theora_decode_tables(AVCodecContext *avctx, GetBitContext gb) +static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; - int i, n; + int i, n, matrices, inter, plane; if (s->theora >= 0x030200) { - n = get_bits(&gb, 3); - /* loop filter table */ + n = get_bits(gb, 3); + /* loop filter limit values table */ for (i = 0; i < 64; i++) - skip_bits(&gb, n); + s->filter_limit_values[i] = get_bits(gb, n); } - + if (s->theora >= 0x030200) - n = get_bits(&gb, 4) + 1; + 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); + s->coded_ac_scale_factor[i] = get_bits(gb, n); if (s->theora >= 0x030200) - n = get_bits(&gb, 4) + 1; + 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); + s->coded_dc_scale_factor[i] = get_bits(gb, n); if (s->theora >= 0x030200) - n = get_bits(&gb, 9) + 1; + matrices = get_bits(gb, 9) + 1; else - n = 3; - if (n != 3) { - av_log(NULL,AV_LOG_ERROR, "unsupported nbms : %d\n", n); + matrices = 3; + + if(matrices > 384){ + av_log(avctx, AV_LOG_ERROR, "invalid number of base matrixes\n"); 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); + for(n=0; nbase_matrix[n][i]= get_bits(gb, 8); + } - /* inter coeffs */ - for (i = 0; i < 64; i++) - s->coded_inter_dequant[i] = get_bits(&gb, 8); + for (inter = 0; inter <= 1; inter++) { + for (plane = 0; plane <= 2; plane++) { + int newqr= 1; + if (inter || plane > 0) + newqr = get_bits(gb, 1); + if (!newqr) { + int qtj, plj; + if(inter && get_bits(gb, 1)){ + qtj = 0; + plj = plane; + }else{ + qtj= (3*inter + plane - 1) / 3; + plj= (plane + 2) % 3; + } + s->qr_count[inter][plane]= s->qr_count[qtj][plj]; + memcpy(s->qr_size[inter][plane], s->qr_size[qtj][plj], sizeof(s->qr_size[0][0])); + memcpy(s->qr_base[inter][plane], s->qr_base[qtj][plj], sizeof(s->qr_base[0][0])); + } else { + int qri= 0; + int qi = 0; + + for(;;){ + i= get_bits(gb, av_log2(matrices-1)+1); + if(i>= matrices){ + av_log(avctx, AV_LOG_ERROR, "invalid base matrix index\n"); + return -1; + } + s->qr_base[inter][plane][qri]= i; + if(qi >= 63) + break; + i = get_bits(gb, av_log2(63-qi)+1) + 1; + s->qr_size[inter][plane][qri++]= i; + qi += i; + } + + if (qi > 63) { + av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi); + return -1; + } + s->qr_count[inter][plane]= qri; + } + } + } + + /* 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); + } + } - /* FIXME: read huffmann tree.. */ - s->theora_tables = 1; - + return 0; } @@ -2981,11 +2576,14 @@ static int theora_decode_init(AVCodecContext *avctx) int ptype; uint8_t *p= avctx->extradata; int op_bytes, i; - + s->theora = 1; if (!avctx->extradata_size) - return -1; + { + av_log(avctx, AV_LOG_ERROR, "Missing extradata!\n"); + return -1; + } for(i=0;i<3;i++) { op_bytes = *(p++)<<8; @@ -2996,24 +2594,36 @@ static int theora_decode_init(AVCodecContext *avctx) ptype = get_bits(&gb, 8); debug_vp3("Theora headerpacket type: %x\n", ptype); - - if (!(ptype & 0x80)) - return -1; - + + 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: - theora_decode_comments(avctx, gb); - break; - case 0x82: - theora_decode_tables(avctx, gb); - break; + 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; } + if(8*op_bytes != get_bits_count(&gb)) + av_log(avctx, AV_LOG_ERROR, "%d bits left in packet %X\n", 8*op_bytes - get_bits_count(&gb), ptype); + if (s->theora < 0x030200) + break; } vp3_decode_init(avctx);