summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/vp3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/vp3.c')
-rw-r--r--src/libffmpeg/libavcodec/vp3.c171
1 files changed, 162 insertions, 9 deletions
diff --git a/src/libffmpeg/libavcodec/vp3.c b/src/libffmpeg/libavcodec/vp3.c
index 5b3f1b926..659d6913b 100644
--- a/src/libffmpeg/libavcodec/vp3.c
+++ b/src/libffmpeg/libavcodec/vp3.c
@@ -2093,6 +2093,9 @@ static void render_fragments(Vp3DecodeContext *s,
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
/* for each fragment row... */
for (y = 0; y < height; y += 8) {
@@ -2216,7 +2219,143 @@ av_log(s->avctx, AV_LOG_ERROR, " help! got beefy vector! (%X, %X)\n", motion_x,
}
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;
+ 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);
+ 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);
+ }
+}
+
+static void vertical_filter(unsigned char *first_pixel, int stride,
+ int *bounding_values)
+{
+ int i;
+ int filter_value;
+
+ 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);
+ 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);
+ }
+}
+
+static void apply_loop_filter(Vp3DecodeContext *s)
+{
+ int x, y, plane;
+ int width, height;
+ int fragment;
+ int stride;
+ unsigned char *plane_data;
+ int bounding_values[256];
+ int filter_limit;
+
+ /* find the right loop limit value */
+ for (x = 63; x >= 0; x--) {
+ if (vp31_ac_scale_factor[x] >= s->quality_index)
+ break;
+ }
+ filter_limit = vp31_filter_limit_values[x];
+
+ /* set up the bounding values */
+ memset(bounding_values, 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;
+ }
+
+ for (plane = 0; plane < 3; plane++) {
+
+ if (plane == 0) {
+ /* Y plane parameters */
+ fragment = 0;
+ width = s->fragment_width;
+ height = s->fragment_height;
+ stride = s->current_frame.linesize[0];
+ plane_data = s->current_frame.data[0];
+ } else if (plane == 1) {
+ /* U plane parameters */
+ fragment = s->u_fragment_start;
+ width = s->fragment_width / 2;
+ height = s->fragment_height / 2;
+ stride = s->current_frame.linesize[1];
+ plane_data = s->current_frame.data[1];
+ } else {
+ /* V plane parameters */
+ fragment = s->v_fragment_start;
+ width = s->fragment_width / 2;
+ height = s->fragment_height / 2;
+ stride = s->current_frame.linesize[2];
+ plane_data = s->current_frame.data[2];
+ }
+
+ for (y = 0; y < height; y++) {
+
+ for (x = 0; x < width; x++) {
+
+ /* do not perform left edge filter for left columns frags */
+ if ((x > 0) &&
+ (s->all_fragments[fragment].coding_method != MODE_COPY)) {
+ horizontal_filter(
+ plane_data + s->all_fragments[fragment].first_pixel,
+ stride, bounding_values);
+ }
+
+ /* do not perform top edge filter for top row fragments */
+ if ((y > 0) &&
+ (s->all_fragments[fragment].coding_method != MODE_COPY)) {
+ vertical_filter(
+ plane_data + s->all_fragments[fragment].first_pixel,
+ stride, bounding_values);
+ }
+
+ /* do not perform right edge filter for right column
+ * fragments or if right fragment neighbor is also coded
+ * in this frame (it will be filtered in next iteration) */
+ if ((x < width - 1) &&
+ (s->all_fragments[fragment].coding_method != MODE_COPY) &&
+ (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) {
+ horizontal_filter(
+ plane_data + s->all_fragments[fragment + 1].first_pixel,
+ stride, bounding_values);
+ }
+ /* do not perform bottom edge filter for bottom row
+ * fragments or if bottom fragment neighbor is also coded
+ * in this frame (it will be filtered in the next row) */
+ if ((y < height - 1) &&
+ (s->all_fragments[fragment].coding_method != MODE_COPY) &&
+ (s->all_fragments[fragment + width].coding_method == MODE_COPY)) {
+ vertical_filter(
+ plane_data + s->all_fragments[fragment + width].first_pixel,
+ stride, bounding_values);
+ }
+
+ fragment++;
+ }
+ }
+ }
}
/*
@@ -2420,27 +2559,27 @@ static int vp3_decode_init(AVCodecContext *avctx)
/* DC histograms */
init_vlc(&s->dc_vlc[i], 5, 32,
&dc_bias[i][0][1], 4, 2,
- &dc_bias[i][0][0], 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);
+ &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);
+ &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);
+ &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);
+ &ac_bias_3[i][0][0], 4, 2, 0);
}
/* build quantization zigzag table */
@@ -2598,6 +2737,7 @@ if (!s->keyframe) {
reverse_dc_prediction(s, 0, s->fragment_width, s->fragment_height);
render_fragments(s, 0, s->width, s->height, 0);
+// apply_loop_filter(s);
if ((avctx->flags & CODEC_FLAG_GRAY) == 0) {
reverse_dc_prediction(s, s->u_fragment_start,
@@ -2681,6 +2821,11 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb)
s->width = get_bits(&gb, 16) << 4;
s->height = get_bits(&gb, 16) << 4;
+ if(avcodec_check_dimensions(avctx, s->width, s->height)){
+ s->width= s->height= 0;
+ return -1;
+ }
+
skip_bits(&gb, 24); /* frame width */
skip_bits(&gb, 24); /* frame height */
@@ -2719,16 +2864,16 @@ static int theora_decode_comments(AVCodecContext *avctx, GetBitContext gb)
{
int nb_comments, i, tmp;
- tmp = get_bits(&gb, 32);
+ tmp = get_bits_long(&gb, 32);
tmp = be2me_32(tmp);
while(tmp--)
skip_bits(&gb, 8);
- nb_comments = get_bits(&gb, 32);
+ nb_comments = get_bits_long(&gb, 32);
nb_comments = be2me_32(nb_comments);
for (i = 0; i < nb_comments; i++)
{
- tmp = get_bits(&gb, 32);
+ tmp = get_bits_long(&gb, 32);
tmp = be2me_32(tmp);
while(tmp--)
skip_bits(&gb, 8);
@@ -2774,13 +2919,20 @@ static int theora_decode_init(AVCodecContext *avctx)
Vp3DecodeContext *s = avctx->priv_data;
GetBitContext gb;
int ptype;
+ uint8_t *p= avctx->extradata;
+ int op_bytes, i;
s->theora = 1;
if (!avctx->extradata_size)
return -1;
- init_get_bits(&gb, avctx->extradata, avctx->extradata_size);
+ for(i=0;i<3;i++) {
+ op_bytes = *(p++)<<8;
+ op_bytes += *(p++);
+
+ init_get_bits(&gb, p, op_bytes);
+ p += op_bytes;
ptype = get_bits(&gb, 8);
debug_vp3("Theora headerpacket type: %x\n", ptype);
@@ -2803,6 +2955,7 @@ static int theora_decode_init(AVCodecContext *avctx)
theora_decode_tables(avctx, gb);
break;
}
+ }
return 0;
}