X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp3.c;h=b47923ec6bbd7ed6a684f5d753cd47ca13040105;hb=7669899bdf2d1b416a13fa2ba763e28c1fbedafb;hp=04fa4d19d028fd44d774b24ff4d0cfe29b6e2097;hpb=ae1dd8e1258c81f385ce7b4efdf62193f17f0165;p=ffmpeg diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 04fa4d19d02..b47923ec6bb 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1,20 +1,21 @@ /* * 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 + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * */ /** @@ -33,12 +34,12 @@ #include #include -#include "common.h" #include "avcodec.h" #include "dsputil.h" -#include "mpegvideo.h" +#include "bitstream.h" #include "vp3data.h" +#include "xiph.h" #define FRAGMENT_PIXELS 8 @@ -229,6 +230,8 @@ typedef struct Vp3DecodeContext { DSPContext dsp; int flipped_image; + int qis[3]; + int nqis; int quality_index; int last_quality_index; @@ -254,8 +257,7 @@ typedef struct Vp3DecodeContext { Vp3Fragment *all_fragments; Coeff *coeffs; Coeff *next_coeff; - int u_fragment_start; - int v_fragment_start; + int fragment_start[3]; ScanTable scantable; @@ -271,7 +273,7 @@ typedef struct Vp3DecodeContext { * which of the fragments are coded */ int *coded_fragment_list; int coded_fragment_list_index; - int pixel_addresses_inited; + int pixel_addresses_initialized; VLC dc_vlc[16]; VLC ac_vlc_1[16]; @@ -314,7 +316,7 @@ typedef struct Vp3DecodeContext { int last_coded_c_fragment; uint8_t edge_emu_buffer[9*2048]; //FIXME dynamic alloc - uint8_t qscale_table[2048]; //FIXME dynamic alloc (width+15)/16 + int8_t qscale_table[2048]; //FIXME dynamic alloc (width+15)/16 /* Huffman decode */ int hti; @@ -327,8 +329,6 @@ typedef struct Vp3DecodeContext { int bounding_values_array[256]; } Vp3DecodeContext; -static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb); - /************************************************************************ * VP3 specific functions ************************************************************************/ @@ -343,8 +343,6 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb); static int init_block_mapping(Vp3DecodeContext *s) { int i, j; - signed int hilbert_walk_y[16]; - signed int hilbert_walk_c[16]; signed int hilbert_walk_mb[4]; int current_fragment = 0; @@ -383,41 +381,6 @@ static int init_block_mapping(Vp3DecodeContext *s) debug_vp3(" vp3: initialize block mapping tables\n"); - /* figure out hilbert pattern per these frame dimensions */ - hilbert_walk_y[0] = 1; - hilbert_walk_y[1] = 1; - hilbert_walk_y[2] = s->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; @@ -438,7 +401,6 @@ static int init_block_mapping(Vp3DecodeContext *s) current_height = 0; 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; @@ -452,10 +414,9 @@ static int init_block_mapping(Vp3DecodeContext *s) current_height = 0; 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) { @@ -466,10 +427,9 @@ static int init_block_mapping(Vp3DecodeContext *s) current_height = 0; 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; } @@ -484,7 +444,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]; @@ -513,7 +473,7 @@ static int init_block_mapping(Vp3DecodeContext *s) current_width = -1; current_height = 0; superblock_row_inc = s->macroblock_width - - (s->y_superblock_width * 2 - s->macroblock_width);; + (s->y_superblock_width * 2 - s->macroblock_width); hilbert = hilbert_walk_mb; mapping_index = 0; current_macroblock = -1; @@ -591,13 +551,13 @@ static int init_block_mapping(Vp3DecodeContext *s) 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; @@ -646,7 +606,7 @@ 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, plane, inter, qri, bmi, bmj, qistart; + int i, plane, inter, qri, bmi, bmj, qistart; debug_vp3(" vp3: initializing dequantization tables\n"); @@ -667,10 +627,10 @@ static void init_dequantizer(Vp3DecodeContext *s) + s->qr_size[inter][plane][qri]) / (2*s->qr_size[inter][plane][qri]); - int qmin= 8<<(inter + !plane); + 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); + s->qmat[inter][plane][i]= av_clip((qscale * coeff)/100 * 4, qmin, 4096); } } } @@ -726,7 +686,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) } else { /* unpack the list of partially-coded superblocks */ - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -762,7 +722,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) current_superblock = 0; current_run = 0; - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -793,7 +753,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) if (decode_partial_blocks) { current_run = 0; - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -845,7 +805,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) 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; @@ -873,7 +833,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) 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; @@ -1019,7 +979,7 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) memset(motion_y, 0, 6 * sizeof(int)); /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */ - coding_mode = get_bits(gb, 1); + coding_mode = get_bits1(gb); debug_vectors(" using %s scheme for unpacking motion vectors\n", (coding_mode == 0) ? "VLC" : "fixed-length"); @@ -1351,7 +1311,6 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type) #define FRAME_CODED(x) (s->all_fragments[x].coding_method != MODE_COPY) #define DC_COEFF(u) (s->coeffs[u].index ? 0 : s->coeffs[u].coeff) //FIXME do somethin to simplify this -static inline int iabs (int x) { return ((x < 0) ? -x : x); } static void reverse_dc_prediction(Vp3DecodeContext *s, int first_fragment, @@ -1367,23 +1326,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; @@ -1397,26 +1340,24 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, * 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 @@ -1458,113 +1399,33 @@ static void reverse_dc_prediction(Vp3DecodeContext *s, 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, DC_COEFF(i)); - - switch (predictor_group) { + debug_dc_pred(" frag %d: orig DC = %d, ", + i, DC_COEFF(i)); - 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 = DC_COEFF(ul); - vu = DC_COEFF(u); - vur = DC_COEFF(ur); + transform= 0; + if(x){ + l= i-1; vl = DC_COEFF(l); - - /* 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 = DC_COEFF(u); - vur = DC_COEFF(ur); - - /* 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 = DC_COEFF(l); - - /* 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 = DC_COEFF(ul); + if(FRAME_CODED(l) && COMPATIBLE_FRAME(l)) + transform |= PL; + } + if(y){ + u= i-fragment_width; vu = DC_COEFF(u); - vl = DC_COEFF(l); - - /* 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; - + 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); @@ -1586,22 +1447,16 @@ 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 (FFABS(predicted_dc - vu) > 128) predicted_dc = vu; - else if (iabs(predicted_dc - vl) > 128) + else if (FFABS(predicted_dc - vl) > 128) predicted_dc = vl; - else if (iabs(predicted_dc - vul) > 128) + else if (FFABS(predicted_dc - vul) > 128) predicted_dc = vul; } @@ -1642,75 +1497,34 @@ static void vertical_filter(unsigned char *first_pixel, int stride, */ static void render_slice(Vp3DecodeContext *s, int slice) { - int x, y; + int x; int m, n; - int i; /* indicates current fragment */ int16_t *dequantizer; DECLARE_ALIGNED_16(DCTELEM, block[64]); - unsigned char *output_plane; - unsigned char *last_plane; - unsigned char *golden_plane; - int stride; 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 plane_width; - int plane_height; - int slice_height; int current_macroblock_entry = slice * s->macroblock_width * 6; - int fragment_width; if (slice >= s->macroblock_height) return; 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]; - /* set up plane-specific parameters */ - if (plane == 0) { - output_plane = s->current_frame.data[0]; - last_plane = s->last_frame.data[0]; - golden_plane = s->golden_frame.data[0]; - stride = s->current_frame.linesize[0]; - if (!s->flipped_image) stride = -stride; - upper_motion_limit = 7 * s->current_frame.linesize[0]; - lower_motion_limit = s->height * s->current_frame.linesize[0] + s->width - 8; - y = slice * FRAGMENT_PIXELS * 2; - plane_width = s->width; - plane_height = s->height; - slice_height = y + FRAGMENT_PIXELS * 2; - i = s->macroblock_fragments[current_macroblock_entry + 0]; - } else if (plane == 1) { - output_plane = s->current_frame.data[1]; - last_plane = s->last_frame.data[1]; - golden_plane = s->golden_frame.data[1]; - stride = s->current_frame.linesize[1]; - if (!s->flipped_image) stride = -stride; - upper_motion_limit = 7 * s->current_frame.linesize[1]; - lower_motion_limit = (s->height / 2) * s->current_frame.linesize[1] + (s->width / 2) - 8; - y = slice * FRAGMENT_PIXELS; - plane_width = s->width / 2; - plane_height = s->height / 2; - slice_height = y + FRAGMENT_PIXELS; - i = s->macroblock_fragments[current_macroblock_entry + 4]; - } else { - output_plane = s->current_frame.data[2]; - last_plane = s->last_frame.data[2]; - golden_plane = s->golden_frame.data[2]; - stride = s->current_frame.linesize[2]; - if (!s->flipped_image) stride = -stride; - upper_motion_limit = 7 * s->current_frame.linesize[2]; - lower_motion_limit = (s->height / 2) * s->current_frame.linesize[2] + (s->width / 2) - 8; - y = slice * FRAGMENT_PIXELS; - plane_width = s->width / 2; - plane_height = s->height / 2; - slice_height = y + FRAGMENT_PIXELS; - i = s->macroblock_fragments[current_macroblock_entry + 5]; - } - fragment_width = plane_width / FRAGMENT_PIXELS; + if (!s->flipped_image) stride = -stride; - if(ABS(stride) > 2048) + + if(FFABS(stride) > 2048) return; //various tables are fixed size /* for each fragment row in the slice (both of them)... */ @@ -1867,7 +1681,7 @@ static void render_slice(Vp3DecodeContext *s, int slice) (s->all_fragments[i - 1].coding_method != MODE_COPY)) )) { horizontal_filter( output_plane + s->all_fragments[i].first_pixel + 7*stride, - -stride, bounding_values); + -stride, s->bounding_values_array + 127); } /* perform the top edge filter if: @@ -1883,7 +1697,7 @@ static void render_slice(Vp3DecodeContext *s, int slice) (s->all_fragments[i - fragment_width].coding_method != MODE_COPY)) )) { vertical_filter( output_plane + s->all_fragments[i].first_pixel - stride, - -stride, bounding_values); + -stride, s->bounding_values_array + 127); } #endif } @@ -1907,13 +1721,13 @@ static void horizontal_filter(unsigned char *first_pixel, int stride, unsigned char *end; int filter_value; - for (end= first_pixel + 8*stride; first_pixel < end; first_pixel += stride) { + for (end= first_pixel + 8*stride; first_pixel != end; first_pixel += stride) { filter_value = (first_pixel[-2] - first_pixel[ 1]) +3*(first_pixel[ 0] - first_pixel[-1]); filter_value = bounding_values[(filter_value + 4) >> 3]; - first_pixel[-1] = clip_uint8(first_pixel[-1] + filter_value); - first_pixel[ 0] = clip_uint8(first_pixel[ 0] - filter_value); + first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value); + first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value); } } @@ -1929,18 +1743,15 @@ static void vertical_filter(unsigned char *first_pixel, int stride, (first_pixel[2 * nstride] - first_pixel[ stride]) +3*(first_pixel[0 ] - first_pixel[nstride]); filter_value = bounding_values[(filter_value + 4) >> 3]; - first_pixel[nstride] = clip_uint8(first_pixel[nstride] + filter_value); - first_pixel[0] = clip_uint8(first_pixel[0] - filter_value); + first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value); + first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value); } } static void apply_loop_filter(Vp3DecodeContext *s) { - int 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 @@ -1965,29 +1776,12 @@ static void apply_loop_filter(Vp3DecodeContext *s) #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++) { @@ -1997,7 +1791,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); } @@ -2005,7 +1799,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); } @@ -2016,7 +1810,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); } @@ -2027,7 +1821,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); } @@ -2063,7 +1857,7 @@ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) } /* 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 = @@ -2076,7 +1870,7 @@ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s) } /* 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 = @@ -2110,7 +1904,7 @@ static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) } /* 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 = @@ -2123,7 +1917,7 @@ static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) } /* 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 = @@ -2139,7 +1933,7 @@ static void theora_calculate_pixel_addresses(Vp3DecodeContext *s) /* * This is the ffmpeg/libavcodec API init function. */ -static int vp3_decode_init(AVCodecContext *avctx) +static av_cold int vp3_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; int i, inter, plane; @@ -2157,7 +1951,6 @@ static int vp3_decode_init(AVCodecContext *avctx) s->width = (avctx->width + 15) & 0xFFFFFFF0; s->height = (avctx->height + 15) & 0xFFFFFFF0; avctx->pix_fmt = PIX_FMT_YUV420P; - avctx->has_b_frames = 0; if(avctx->idct_algo==FF_IDCT_AUTO) avctx->idct_algo=FF_IDCT_VP3; dsputil_init(&s->dsp, avctx); @@ -2193,8 +1986,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); @@ -2210,28 +2003,24 @@ 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(Coeff) * 65); s->coded_fragment_list = av_malloc(s->fragment_count * sizeof(int)); - s->pixel_addresses_inited = 0; + s->pixel_addresses_initialized = 0; if (!s->theora_tables) { - for (i = 0; i < 64; i++) + 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->base_matrix[0][i] = vp31_intra_y_dequant[i]; - for (i = 0; i < 64; i++) s->base_matrix[1][i] = vp31_intra_c_dequant[i]; - for (i = 0; i < 64; i++) s->base_matrix[2][i] = vp31_inter_dequant[i]; - for (i = 0; i < 64; i++) s->filter_limit_values[i] = vp31_filter_limit_values[i]; + } for(inter=0; inter<2; inter++){ for(plane=0; plane<3; plane++){ @@ -2337,7 +2126,7 @@ static int vp3_decode_init(AVCodecContext *avctx) */ static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; @@ -2348,37 +2137,21 @@ static int vp3_decode_frame(AVCodecContext *avctx, if (s->theora && get_bits1(&gb)) { -#if 1 av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n"); return -1; -#else - int ptype = get_bits(&gb, 7); - - skip_bits(&gb, 6*8); /* "theora" */ - - switch(ptype) - { - case 1: - theora_decode_comments(avctx, &gb); - break; - case 2: - theora_decode_tables(avctx, &gb); - init_dequantizer(s); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype); - } - return buf_size; -#endif } s->keyframe = !get_bits1(&gb); if (!s->theora) skip_bits(&gb, 1); s->last_quality_index = s->quality_index; - s->quality_index = get_bits(&gb, 6); - if (s->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", @@ -2430,16 +2203,21 @@ static int vp3_decode_frame(AVCodecContext *avctx, s->current_frame= s->golden_frame; /* time to figure out pixel addresses? */ - if (!s->pixel_addresses_inited) + if (!s->pixel_addresses_initialized) { if (!s->flipped_image) vp3_calculate_pixel_addresses(s); else theora_calculate_pixel_addresses(s); + s->pixel_addresses_initialized = 1; } } else { /* allocate a new current frame */ s->current_frame.reference = 3; + if (!s->pixel_addresses_initialized) { + 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; @@ -2494,9 +2272,9 @@ if (!s->keyframe) { reverse_dc_prediction(s, 0, s->fragment_width, s->fragment_height); 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); } STOP_TIMER("reverse_dc_prediction")} @@ -2532,10 +2310,12 @@ if (!s->keyframe) { /* * This is the ffmpeg/libavcodec API module cleanup function. */ -static int vp3_decode_end(AVCodecContext *avctx) +static av_cold int vp3_decode_end(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; + int i; + av_free(s->superblock_coding); av_free(s->all_fragments); av_free(s->coeffs); av_free(s->coded_fragment_list); @@ -2544,6 +2324,19 @@ static int vp3_decode_end(AVCodecContext *avctx) av_free(s->macroblock_fragments); av_free(s->macroblock_coding); + for (i = 0; i < 16; i++) { + free_vlc(&s->dc_vlc[i]); + free_vlc(&s->ac_vlc_1[i]); + free_vlc(&s->ac_vlc_2[i]); + free_vlc(&s->ac_vlc_3[i]); + free_vlc(&s->ac_vlc_4[i]); + } + + free_vlc(&s->superblock_run_length_vlc); + free_vlc(&s->fragment_run_length_vlc); + free_vlc(&s->mode_code_vlc); + free_vlc(&s->motion_vector_vlc); + /* release all frames */ if (s->golden_frame.data[0] && s->golden_frame.data[0] != s->last_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); @@ -2559,7 +2352,7 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { int token; if (s->entries >= 32) { /* overflow */ av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); @@ -2587,12 +2380,14 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) return 0; } +#ifdef CONFIG_THEORA_DECODER static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; + int visible_width, visible_height; s->theora = get_bits_long(gb, 24); - av_log(avctx, AV_LOG_INFO, "Theora bitstream version %X\n", s->theora); + av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora); /* 3.2.0 aka alpha3 has the same frame orientation as original vp3 */ /* but previous versions have the image flipped relative to vp3 */ @@ -2618,18 +2413,15 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) skip_bits(gb, 32); /* total number of blocks in a frame */ skip_bits(gb, 4); /* total number of blocks in a frame */ skip_bits(gb, 32); /* total number of macroblocks in a frame */ - - skip_bits(gb, 24); /* frame width */ - skip_bits(gb, 24); /* frame height */ - } - else - { - skip_bits(gb, 24); /* frame width */ - skip_bits(gb, 24); /* frame height */ } - skip_bits(gb, 8); /* offset x */ - skip_bits(gb, 8); /* offset y */ + visible_width = get_bits_long(gb, 24); + visible_height = get_bits_long(gb, 24); + + if (s->theora >= 0x030200) { + skip_bits(gb, 8); /* offset x */ + skip_bits(gb, 8); /* offset y */ + } skip_bits(gb, 32); /* fps numerator */ skip_bits(gb, 32); /* fps denumerator */ @@ -2655,8 +2447,11 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) // align_get_bits(gb); - avctx->width = s->width; - avctx->height = s->height; + if ( visible_width <= s->width && visible_width > s->width-16 + && visible_height <= s->height && visible_height > s->height-16) + avcodec_set_dimensions(avctx, visible_width, visible_height); + else + avcodec_set_dimensions(avctx, s->width, s->height); return 0; } @@ -2708,10 +2503,10 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) for (plane = 0; plane <= 2; plane++) { int newqr= 1; if (inter || plane > 0) - newqr = get_bits(gb, 1); + newqr = get_bits1(gb); if (!newqr) { int qtj, plj; - if(inter && get_bits(gb, 1)){ + if(inter && get_bits1(gb)){ qtj = 0; plj = plane; }else{ @@ -2752,7 +2547,7 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) for (s->hti = 0; s->hti < 80; s->hti++) { s->entries = 0; s->huff_code_size = 1; - if (!get_bits(gb, 1)) { + if (!get_bits1(gb)) { s->hbits = 0; read_huffman_tree(avctx, gb); s->hbits = 1; @@ -2770,8 +2565,9 @@ static int theora_decode_init(AVCodecContext *avctx) Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; int ptype; - uint8_t *p= avctx->extradata; - int op_bytes, i; + uint8_t *header_start[3]; + int header_len[3]; + int i; s->theora = 1; @@ -2781,12 +2577,14 @@ static int theora_decode_init(AVCodecContext *avctx) return -1; } - for(i=0;i<3;i++) { - op_bytes = *(p++)<<8; - op_bytes += *(p++); + if (ff_split_xiph_headers(avctx->extradata, avctx->extradata_size, + 42, header_start, header_len) < 0) { + av_log(avctx, AV_LOG_ERROR, "Corrupt extradata\n"); + return -1; + } - init_get_bits(&gb, p, op_bytes); - p += op_bytes; + for(i=0;i<3;i++) { + init_get_bits(&gb, header_start[i], header_len[i]); ptype = get_bits(&gb, 8); debug_vp3("Theora headerpacket type: %x\n", ptype); @@ -2797,7 +2595,7 @@ static int theora_decode_init(AVCodecContext *avctx) // return -1; } - // FIXME: check for this aswell + // FIXME: Check for this as well. skip_bits(&gb, 6*8); /* "theora" */ switch(ptype) @@ -2816,38 +2614,39 @@ static int theora_decode_init(AVCodecContext *avctx) 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(8*header_len[i] != get_bits_count(&gb)) + av_log(avctx, AV_LOG_ERROR, "%d bits left in packet %X\n", 8*header_len[i] - get_bits_count(&gb), ptype); + if (s->theora < 0x030200) + break; } vp3_decode_init(avctx); return 0; } -AVCodec vp3_decoder = { - "vp3", +AVCodec theora_decoder = { + "theora", CODEC_TYPE_VIDEO, - CODEC_ID_VP3, + CODEC_ID_THEORA, sizeof(Vp3DecodeContext), - vp3_decode_init, + theora_decode_init, NULL, vp3_decode_end, vp3_decode_frame, 0, NULL }; +#endif -#ifndef CONFIG_LIBTHEORA -AVCodec theora_decoder = { - "theora", +AVCodec vp3_decoder = { + "vp3", CODEC_TYPE_VIDEO, - CODEC_ID_THEORA, + CODEC_ID_VP3, sizeof(Vp3DecodeContext), - theora_decode_init, + vp3_decode_init, NULL, vp3_decode_end, vp3_decode_frame, 0, NULL }; -#endif