[Ffmpeg-cvslog] CVS: ffmpeg/libavcodec vp3.c,1.63,1.64
Mike Melanson CVS
melanson
Sat May 21 07:20:54 CEST 2005
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec
In directory mail:/var2/tmp/cvs-serv25323/libavcodec
Modified Files:
vp3.c
Log Message:
apply the loop filter to fragments as they are rendered into the final
output
Index: vp3.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/vp3.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- vp3.c 21 May 2005 04:43:36 -0000 1.63
+++ vp3.c 21 May 2005 05:20:52 -0000 1.64
@@ -317,12 +317,15 @@
uint8_t edge_emu_buffer[9*2048]; //FIXME dynamic alloc
uint8_t qscale_table[2048]; //FIXME dynamic alloc (width+15)/16
- /* Huffman decode */
- int hti;
- unsigned int hbits;
- int entries;
- int huff_code_size;
- uint16_t huffman_table[80][32][2];
+ /* Huffman decode */
+ int hti;
+ unsigned int hbits;
+ int entries;
+ int huff_code_size;
+ uint16_t huffman_table[80][32][2];
+
+ uint32_t filter_limit_values[64];
+ int bounding_values_array[256];
} Vp3DecodeContext;
static int theora_decode_comments(AVCodecContext *avctx, GetBitContext gb);
@@ -862,7 +865,7 @@
}
/*
- * 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)
@@ -958,6 +961,28 @@
}
/*
+ * This function initializes the loop filter boundary limits if the frame's
+ * quality index is different from the previous frame's.
+ */
+static void init_loop_filter(Vp3DecodeContext *s)
+{
+ int *bounding_values= s->bounding_values_array+127;
+ int filter_limit;
+ int x;
+
+ filter_limit = s->filter_limit_values[s->quality_index];
+
+ /* set up the bounding values */
+ memset(s->bounding_values_array, 0, 256 * sizeof(int));
+ for (x = 0; x < filter_limit; x++) {
+ bounding_values[-x - filter_limit] = -filter_limit + x;
+ bounding_values[-x] = -x;
+ bounding_values[x] = x;
+ bounding_values[x + filter_limit] = filter_limit - x;
+ }
+}
+
+/*
* 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.
*
@@ -2143,6 +2168,12 @@
}
}
+
+static void horizontal_filter(unsigned char *first_pixel, int stride,
+ int *bounding_values);
+static void vertical_filter(unsigned char *first_pixel, int stride,
+ int *bounding_values);
+
/*
* Perform the final rendering for a particular slice of data.
* The slice number ranges from 0..(macroblock_height - 1).
@@ -2167,6 +2198,8 @@
int plane_height;
int slice_height;
int current_macroblock_entry = slice * s->macroblock_width * 6;
+ int *bounding_values= s->bounding_values_array+127;
+ int fragment_width;
if (slice >= s->macroblock_height)
return;
@@ -2214,6 +2247,7 @@
slice_height = y + FRAGMENT_PIXELS;
i = s->macroblock_fragments[current_macroblock_entry + 5];
}
+ fragment_width = plane_width / 2;
if(ABS(stride) > 2048)
return; //various tables are fixed size
@@ -2361,25 +2395,54 @@
stride, 8);
}
+
+ /* do not perform left edge filter for left columns frags */
+ if ((x > 0) &&
+ (s->all_fragments[i].coding_method != MODE_COPY)) {
+ horizontal_filter(
+ output_plane + s->all_fragments[i].first_pixel - 7*stride,
+ stride, bounding_values);
+ }
+
+ /* do not perform top edge filter for top row fragments */
+ if ((y > 0) &&
+ (s->all_fragments[i].coding_method != MODE_COPY)) {
+ vertical_filter(
+ output_plane + s->all_fragments[i].first_pixel + stride,
+ stride, bounding_values);
+ }
+
+ /* do not perform right edge filter for right column
+ * fragments or if right fragment neighbor is also coded
+ * in this frame (it will be filtered for next fragment) */
+ if ((x < plane_width - 1) &&
+ (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 + 1].first_pixel - 7*stride,
+ stride, bounding_values);
+ }
+
+ /* do not perform bottom edge filter for bottom row
+ * fragments or if bottom fragment neighbor is also coded
+ * in this frame (it will be filtered in the next row) */
+ if ((y < plane_height - 1) &&
+ (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 + fragment_width].first_pixel + stride,
+ stride, bounding_values);
+ }
}
}
}
- /* future loop filter logic goes here... */
- /* algorithm:
- * if (slice != 0)
- * run filter on 1st row of Y slice
- * run filter on U slice
- * run filter on V slice
- * run filter on 2nd row of Y slice
- */
-
/* this looks like a good place for slice dispatch... */
/* algorithm:
- * if (slice > 0)
- * dispatch (slice - 1);
* if (slice == s->macroblock_height - 1)
- * dispatch (slice); // handle last slice
+ * dispatch (both last slice & 2nd-to-last slice);
+ * else if (slice > 0)
+ * dispatch (slice - 1);
*/
emms_c();
@@ -2628,9 +2691,10 @@
int fragment;
int stride;
unsigned char *plane_data;
+ 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 */
@@ -2648,6 +2712,7 @@
bounding_values[x] = x;
bounding_values[x + filter_limit] = filter_limit - x;
}
+#endif
for (plane = 0; plane < 3; plane++) {
@@ -2915,6 +2980,8 @@
s->coded_intra_c_dequant[i] = vp31_intra_c_dequant[i];
for (i = 0; i < 64; i++)
s->coded_inter_dequant[i] = vp31_inter_dequant[i];
+ for (i = 0; i < 64; i++)
+ s->filter_limit_values[i] = vp31_filter_limit_values[i];
/* init VLC tables */
for (i = 0; i < 16; i++) {
@@ -3054,8 +3121,10 @@
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)
@@ -3185,7 +3254,7 @@
STOP_TIMER("render_fragments")}
{START_TIMER
- apply_loop_filter(s);
+// apply_loop_filter(s);
STOP_TIMER("apply_loop_filter")}
#if KEYFRAMES_ONLY
}
@@ -3433,6 +3502,10 @@
}
}
+ /* XXX FIXME: these limit values need to come from the Theora header */
+ for (i = 0; i < 64; i++)
+ s->filter_limit_values[i] = vp31_filter_limit_values[i];
+
s->theora_tables = 1;
return 0;
More information about the ffmpeg-cvslog
mailing list