Merge "Improve MV prediction accuracy to achieve performance gain"
diff --git a/build/make/configure.sh b/build/make/configure.sh
index d25d640..c5885da 100755
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -547,6 +547,10 @@
tgt_isa=universal
tgt_os=darwin9
;;
+ *darwin10*)
+ tgt_isa=x86_64
+ tgt_os=darwin10
+ ;;
*mingw32*|*cygwin*)
[ -z "$tgt_isa" ] && tgt_isa=x86
tgt_os=win32
@@ -606,6 +610,12 @@
add_ldflags "-isysroot /Developer/SDKs/MacOSX10.5.sdk"
add_ldflags "-mmacosx-version-min=10.5"
;;
+ *-darwin10-*)
+ add_cflags "-isysroot /Developer/SDKs/MacOSX10.6.sdk"
+ add_cflags "-mmacosx-version-min=10.6"
+ add_ldflags "-isysroot /Developer/SDKs/MacOSX10.6.sdk"
+ add_ldflags "-mmacosx-version-min=10.6"
+ ;;
esac
# Handle Solaris variants. Solaris 10 needs -lposix4
diff --git a/configure b/configure
index 11e086e..5a502ae 100755
--- a/configure
+++ b/configure
@@ -41,6 +41,7 @@
${toggle_shared} shared library support
${toggle_small} favor smaller size over speed
${toggle_arm_asm_detok} assembly version of the detokenizer (ARM platforms only)
+ ${toggle_postproc_visualizer} macro block / block level visualizers
Codecs:
Codecs can be selectively enabled or disabled individually, or by family:
@@ -114,6 +115,7 @@
all_platforms="${all_platforms} x86-win32-vs8"
all_platforms="${all_platforms} x86-win32-vs9"
all_platforms="${all_platforms} x86_64-darwin9-gcc"
+all_platforms="${all_platforms} x86_64-darwin10-gcc"
all_platforms="${all_platforms} x86_64-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc"
all_platforms="${all_platforms} x86_64-solaris-gcc"
@@ -250,6 +252,7 @@
shared
small
arm_asm_detok
+ postproc_visualizer
"
CMDLINE_SELECT="
extra_warnings
@@ -289,6 +292,7 @@
shared
small
arm_asm_detok
+ postproc_visualizer
"
process_cmdline() {
@@ -325,8 +329,6 @@
for c in ${CODECS}; do
enabled ${c} && enable ${c##*_}s
done
-
-
}
@@ -536,6 +538,10 @@
# Other toolchain specific defaults
case $toolchain in x86*|ppc*|universal*) soft_enable postproc;; esac
+
+ if enabled postproc_visualizer; then
+ enabled postproc || die "postproc_visualizer requires postproc to be enabled"
+ fi
}
diff --git a/examples/vp8_set_maps.txt b/examples/vp8_set_maps.txt
index 94554ba..ad9ef61 100644
--- a/examples/vp8_set_maps.txt
+++ b/examples/vp8_set_maps.txt
@@ -78,8 +78,8 @@
} else if(frame_cnt + 1 == 44) {
vpx_active_map_t active;
- active.rows = 240/16;
- active.cols = 320/16;
+ active.rows = cfg.g_h/16;
+ active.cols = cfg.g_w/16;
/* pass in null map to disable active_map*/
active.active_map = NULL;
diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h
index 0685cd0..70e2ae6 100644
--- a/vp8/common/entropy.h
+++ b/vp8/common/entropy.h
@@ -24,10 +24,10 @@
#define FOUR_TOKEN 4 /* 4 Extra Bits 0+1 */
#define DCT_VAL_CATEGORY1 5 /* 5-6 Extra Bits 1+1 */
#define DCT_VAL_CATEGORY2 6 /* 7-10 Extra Bits 2+1 */
-#define DCT_VAL_CATEGORY3 7 /* 11-26 Extra Bits 4+1 */
-#define DCT_VAL_CATEGORY4 8 /* 11-26 Extra Bits 5+1 */
-#define DCT_VAL_CATEGORY5 9 /* 27-58 Extra Bits 5+1 */
-#define DCT_VAL_CATEGORY6 10 /* 59+ Extra Bits 11+1 */
+#define DCT_VAL_CATEGORY3 7 /* 11-18 Extra Bits 3+1 */
+#define DCT_VAL_CATEGORY4 8 /* 19-34 Extra Bits 4+1 */
+#define DCT_VAL_CATEGORY5 9 /* 35-66 Extra Bits 5+1 */
+#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 11+1 */
#define DCT_EOB_TOKEN 11 /* EOB Extra Bits 0+0 */
#define vp8_coef_tokens 12
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
index 7b1a84b..b3eadaf 100644
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -65,11 +65,13 @@
rtcd->loopfilter.simple_b_h = vp8_loop_filter_bhs_c;
#if CONFIG_POSTPROC || (CONFIG_VP8_ENCODER && CONFIG_PSNR)
- rtcd->postproc.down = vp8_mbpost_proc_down_c;
- rtcd->postproc.across = vp8_mbpost_proc_across_ip_c;
- rtcd->postproc.downacross = vp8_post_proc_down_and_across_c;
- rtcd->postproc.addnoise = vp8_plane_add_noise_c;
- rtcd->postproc.blend_mb = vp8_blend_mb_c;
+ rtcd->postproc.down = vp8_mbpost_proc_down_c;
+ rtcd->postproc.across = vp8_mbpost_proc_across_ip_c;
+ rtcd->postproc.downacross = vp8_post_proc_down_and_across_c;
+ rtcd->postproc.addnoise = vp8_plane_add_noise_c;
+ rtcd->postproc.blend_mb_inner = vp8_blend_mb_inner_c;
+ rtcd->postproc.blend_mb_outer = vp8_blend_mb_outer_c;
+ rtcd->postproc.blend_b = vp8_blend_b_c;
#endif
#endif
diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h
index a006306..3c199d1 100644
--- a/vp8/common/onyx.h
+++ b/vp8/common/onyx.h
@@ -204,7 +204,7 @@
// and not just a copy of the pointer..
int vp8_receive_raw_frame(VP8_PTR comp, unsigned int frame_flags, YV12_BUFFER_CONFIG *sd, INT64 time_stamp, INT64 end_time_stamp);
int vp8_get_compressed_data(VP8_PTR comp, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, INT64 *time_stamp, INT64 *time_end, int flush);
- int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags);
+ int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t *flags);
int vp8_use_as_reference(VP8_PTR comp, int ref_frame_flags);
int vp8_update_reference(VP8_PTR comp, int ref_frame_flags);
diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h
index 00a97d9..e53bc31 100644
--- a/vp8/common/onyxd.h
+++ b/vp8/common/onyxd.h
@@ -51,7 +51,7 @@
int vp8dx_get_setting(VP8D_PTR comp, VP8D_SETTING oxst);
int vp8dx_receive_compressed_data(VP8D_PTR comp, unsigned long size, const unsigned char *dest, INT64 time_stamp);
- int vp8dx_get_raw_frame(VP8D_PTR comp, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level, int noise_level, int flags);
+ int vp8dx_get_raw_frame(VP8D_PTR comp, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags);
int vp8dx_get_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
int vp8dx_set_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
diff --git a/vp8/common/postproc.c b/vp8/common/postproc.c
index 453cb47..15b1c2c 100644
--- a/vp8/common/postproc.c
+++ b/vp8/common/postproc.c
@@ -26,7 +26,7 @@
( (0.439*(float)(t>>16)) - (0.368*(float)(t>>8&0xff)) - (0.071*(float)(t&0xff)) + 128)
/* global constants */
-
+#if CONFIG_POSTPROC_VISUALIZER
static const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] =
{
{ RGB_TO_YUV(0x98FB98) }, /* PaleGreen */
@@ -41,13 +41,32 @@
{ RGB_TO_YUV(0xFF0000) } /* Red */
};
-static const unsigned char MV_REFERENCE_FRAME_colors[MB_MODE_COUNT][3] =
+static const unsigned char B_PREDICTION_MODE_colors[B_MODE_COUNT][3] =
+{
+ { RGB_TO_YUV(0x6633ff) }, /* Purple */
+ { RGB_TO_YUV(0xcc33ff) }, /* Magenta */
+ { RGB_TO_YUV(0xff33cc) }, /* Pink */
+ { RGB_TO_YUV(0xff3366) }, /* Coral */
+ { RGB_TO_YUV(0x3366ff) }, /* Blue */
+ { RGB_TO_YUV(0xed00f5) }, /* Dark Blue */
+ { RGB_TO_YUV(0x2e00b8) }, /* Dark Purple */
+ { RGB_TO_YUV(0xff6633) }, /* Orange */
+ { RGB_TO_YUV(0x33ccff) }, /* Light Blue */
+ { RGB_TO_YUV(0x8ab800) }, /* Green */
+ { RGB_TO_YUV(0xffcc33) }, /* Light Orange */
+ { RGB_TO_YUV(0x33ffcc) }, /* Aqua */
+ { RGB_TO_YUV(0x66ff33) }, /* Light Green */
+ { RGB_TO_YUV(0xccff33) }, /* Yellow */
+};
+
+static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] =
{
{ RGB_TO_YUV(0x00ff00) }, /* Blue */
{ RGB_TO_YUV(0x0000ff) }, /* Green */
{ RGB_TO_YUV(0xffff00) }, /* Yellow */
{ RGB_TO_YUV(0xff0000) }, /* Red */
};
+#endif
static const short kernel5[] =
{
@@ -476,7 +495,7 @@
* edges unblended to give distinction to macro blocks in areas
* filled with the same color block.
*/
-void vp8_blend_mb_c (unsigned char *y, unsigned char *u, unsigned char *v,
+void vp8_blend_mb_inner_c (unsigned char *y, unsigned char *u, unsigned char *v,
int y1, int u1, int v1, int alpha, int stride)
{
int i, j;
@@ -484,10 +503,10 @@
int u1_const = u1*((1<<16)-alpha);
int v1_const = v1*((1<<16)-alpha);
- y += stride + 1;
- for (i = 0; i < 14; i++)
+ y += 2*stride + 2;
+ for (i = 0; i < 12; i++)
{
- for (j = 0; j < 14; j++)
+ for (j = 0; j < 12; j++)
{
y[j] = (y[j]*alpha + y1_const)>>16;
}
@@ -511,6 +530,104 @@
}
}
+/* Blend only the edge of the macro block. Leave center
+ * unblended to allow for other visualizations to be layered.
+ */
+void vp8_blend_mb_outer_c (unsigned char *y, unsigned char *u, unsigned char *v,
+ int y1, int u1, int v1, int alpha, int stride)
+{
+ int i, j;
+ int y1_const = y1*((1<<16)-alpha);
+ int u1_const = u1*((1<<16)-alpha);
+ int v1_const = v1*((1<<16)-alpha);
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ y[j] = (y[j]*alpha + y1_const)>>16;
+ }
+ y += stride;
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ y[0] = (y[0]*alpha + y1_const)>>16;
+ y[1] = (y[1]*alpha + y1_const)>>16;
+ y[14] = (y[14]*alpha + y1_const)>>16;
+ y[15] = (y[15]*alpha + y1_const)>>16;
+ y += stride;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ y[j] = (y[j]*alpha + y1_const)>>16;
+ }
+ y += stride;
+ }
+
+ stride >>= 1;
+
+ for (j = 0; j < 8; j++)
+ {
+ u[j] = (u[j]*alpha + u1_const)>>16;
+ v[j] = (v[j]*alpha + v1_const)>>16;
+ }
+ u += stride;
+ v += stride;
+
+ for (i = 0; i < 6; i++)
+ {
+ u[0] = (u[0]*alpha + u1_const)>>16;
+ v[0] = (v[0]*alpha + v1_const)>>16;
+
+ u[7] = (u[7]*alpha + u1_const)>>16;
+ v[7] = (v[7]*alpha + v1_const)>>16;
+
+ u += stride;
+ v += stride;
+ }
+
+ for (j = 0; j < 8; j++)
+ {
+ u[j] = (u[j]*alpha + u1_const)>>16;
+ v[j] = (v[j]*alpha + v1_const)>>16;
+ }
+}
+
+void vp8_blend_b_c (unsigned char *y, unsigned char *u, unsigned char *v,
+ int y1, int u1, int v1, int alpha, int stride)
+{
+ int i, j;
+ int y1_const = y1*((1<<16)-alpha);
+ int u1_const = u1*((1<<16)-alpha);
+ int v1_const = v1*((1<<16)-alpha);
+
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ y[j] = (y[j]*alpha + y1_const)>>16;
+ }
+ y += stride;
+ }
+
+ stride >>= 1;
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ u[j] = (u[j]*alpha + u1_const)>>16;
+ v[j] = (v[j]*alpha + v1_const)>>16;
+ }
+ u += stride;
+ v += stride;
+ }
+}
+
static void constrain_line (int x0, int *x1, int y0, int *y1, int width, int height)
{
int dx;
@@ -561,10 +678,13 @@
#define RTCD_VTABLE(oci) NULL
#endif
-int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags)
+int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t *ppflags)
{
char message[512];
int q = oci->filter_level * 10 / 6;
+ int flags = ppflags->post_proc_flag;
+ int deblock_level = ppflags->deblocking_level;
+ int noise_level = ppflags->noise_level;
if (!oci->frame_to_show)
return -1;
@@ -621,7 +741,8 @@
oci->post_proc_buffer.y_stride);
}
- if (flags & VP8D_DEBUG_LEVEL1)
+#if CONFIG_POSTPROC_VISUALIZER
+ if (flags & VP8D_DEBUG_TXT_FRAME_INFO)
{
sprintf(message, "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
(oci->frame_type == KEY_FRAME),
@@ -633,7 +754,7 @@
vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride);
}
- if (flags & VP8D_DEBUG_LEVEL2)
+ if (flags & VP8D_DEBUG_TXT_MBLK_MODES)
{
int i, j;
unsigned char *y_ptr;
@@ -665,7 +786,7 @@
}
}
- if (flags & VP8D_DEBUG_LEVEL3)
+ if (flags & VP8D_DEBUG_TXT_DC_DIFF)
{
int i, j;
unsigned char *y_ptr;
@@ -700,45 +821,14 @@
}
}
- if (flags & VP8D_DEBUG_LEVEL4)
+ if (flags & VP8D_DEBUG_TXT_RATE_INFO)
{
sprintf(message, "Bitrate: %10.2f frame_rate: %10.2f ", oci->bitrate, oci->framerate);
vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride);
-#if 0
- int i, j;
- unsigned char *y_ptr;
- YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
- int mb_rows = post->y_height >> 4;
- int mb_cols = post->y_width >> 4;
- int mb_index = 0;
- MODE_INFO *mi = oci->mi;
-
- y_ptr = post->y_buffer + 4 * post->y_stride + 4;
-
- /* vp8_filter each macro block */
- for (i = 0; i < mb_rows; i++)
- {
- for (j = 0; j < mb_cols; j++)
- {
- char zz[4];
-
- sprintf(zz, "%c", mi[mb_index].mbmi.dc_diff + '0');
- vp8_blit_text(zz, y_ptr, post->y_stride);
- mb_index ++;
- y_ptr += 16;
- }
-
- mb_index ++; /* border */
- y_ptr += post->y_stride * 16 - post->y_width;
-
- }
-
-#endif
-
}
/* Draw motion vectors */
- if (flags & VP8D_DEBUG_LEVEL5)
+ if ((flags & VP8D_DEBUG_DRAW_MV) && ppflags->display_mv_flag)
{
YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
int width = post->y_width;
@@ -755,6 +845,12 @@
{
int x1, y1;
+ if (!(ppflags->display_mv_flag & (1<<mi->mbmi.mode)))
+ {
+ mi++;
+ continue;
+ }
+
if (mi->mbmi.mode == SPLITMV)
{
switch (mi->mbmi.partitioning)
@@ -880,6 +976,7 @@
else
vp8_blit_line (lx0, x1, ly0, y1, y_buffer, y_stride);
}
+
mi++;
}
mi++;
@@ -887,9 +984,10 @@
}
/* Color in block modes */
- if (flags & VP8D_DEBUG_LEVEL6)
+ if ((flags & VP8D_DEBUG_CLR_BLK_MODES)
+ && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag))
{
- int i, j;
+ int y, x;
YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
int width = post->y_width;
int height = post->y_height;
@@ -899,18 +997,54 @@
int y_stride = oci->post_proc_buffer.y_stride;
MODE_INFO *mi = oci->mi;
- for (i = 0; i < height; i += 16)
+ for (y = 0; y < height; y += 16)
{
- for (j = 0; j < width; j += 16)
+ for (x = 0; x < width; x += 16)
{
int Y = 0, U = 0, V = 0;
- Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
- U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
- V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
+ if (mi->mbmi.mode == B_PRED &&
+ ((ppflags->display_mb_modes_flag & B_PRED) || ppflags->display_b_modes_flag))
+ {
+ int by, bx;
+ unsigned char *yl, *ul, *vl;
+ B_MODE_INFO *bmi = mi->bmi;
- POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_mb)
- (&y_ptr[j], &u_ptr[j>>1], &v_ptr[j>>1], Y, U, V, 0xc000, y_stride);
+ yl = y_ptr + x;
+ ul = u_ptr + (x>>1);
+ vl = v_ptr + (x>>1);
+
+ for (by = 0; by < 16; by += 4)
+ {
+ for (bx = 0; bx < 16; bx += 4)
+ {
+ if ((ppflags->display_b_modes_flag & (1<<mi->mbmi.mode))
+ || (ppflags->display_mb_modes_flag & B_PRED))
+ {
+ Y = B_PREDICTION_MODE_colors[bmi->mode][0];
+ U = B_PREDICTION_MODE_colors[bmi->mode][1];
+ V = B_PREDICTION_MODE_colors[bmi->mode][2];
+
+ POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_b)
+ (yl+bx, ul+(bx>>1), vl+(bx>>1), Y, U, V, 0xc000, y_stride);
+ }
+ bmi++;
+ }
+
+ yl += y_stride*4;
+ ul += y_stride*1;
+ vl += y_stride*1;
+ }
+ }
+ else if (ppflags->display_mb_modes_flag & (1<<mi->mbmi.mode))
+ {
+ Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
+ U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
+ V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
+
+ POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_mb_inner)
+ (y_ptr+x, u_ptr+(x>>1), v_ptr+(x>>1), Y, U, V, 0xc000, y_stride);
+ }
mi++;
}
@@ -923,9 +1057,9 @@
}
/* Color in frame reference blocks */
- if (flags & VP8D_DEBUG_LEVEL7)
+ if ((flags & VP8D_DEBUG_CLR_FRM_REF_BLKS) && ppflags->display_ref_frame_flag)
{
- int i, j;
+ int y, x;
YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
int width = post->y_width;
int height = post->y_height;
@@ -935,18 +1069,21 @@
int y_stride = oci->post_proc_buffer.y_stride;
MODE_INFO *mi = oci->mi;
- for (i = 0; i < height; i += 16)
+ for (y = 0; y < height; y += 16)
{
- for (j = 0; j < width; j +=16)
+ for (x = 0; x < width; x +=16)
{
int Y = 0, U = 0, V = 0;
- Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
- U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
- V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
+ if (ppflags->display_ref_frame_flag & (1<<mi->mbmi.ref_frame))
+ {
+ Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
+ U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
+ V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
- POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_mb)
- (&y_ptr[j], &u_ptr[j>>1], &v_ptr[j>>1], Y, U, V, 0xc000, y_stride);
+ POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_mb_outer)
+ (y_ptr+x, u_ptr+(x>>1), v_ptr+(x>>1), Y, U, V, 0xc000, y_stride);
+ }
mi++;
}
@@ -957,6 +1094,7 @@
mi++;
}
}
+#endif
*dest = oci->post_proc_buffer;
diff --git a/vp8/common/postproc.h b/vp8/common/postproc.h
index 4a44938..c641b9c 100644
--- a/vp8/common/postproc.h
+++ b/vp8/common/postproc.h
@@ -24,7 +24,15 @@
char whiteclamp[16], char bothclamp[16],\
unsigned int w, unsigned int h, int pitch)
-#define prototype_postproc_blend_mb(sym)\
+#define prototype_postproc_blend_mb_inner(sym)\
+ void sym (unsigned char *y, unsigned char *u, unsigned char *v,\
+ int y1, int u1, int v1, int alpha, int stride)
+
+#define prototype_postproc_blend_mb_outer(sym)\
+ void sym (unsigned char *y, unsigned char *u, unsigned char *v,\
+ int y1, int u1, int v1, int alpha, int stride)
+
+#define prototype_postproc_blend_b(sym)\
void sym (unsigned char *y, unsigned char *u, unsigned char *v,\
int y1, int u1, int v1, int alpha, int stride)
@@ -52,22 +60,36 @@
#endif
extern prototype_postproc_addnoise(vp8_postproc_addnoise);
-#ifndef vp8_postproc_blend_mb
-#define vp8_postproc_blend_mb vp8_blend_mb_c
+#ifndef vp8_postproc_blend_mb_inner
+#define vp8_postproc_blend_mb_inner vp8_blend_mb_inner_c
#endif
-extern prototype_postproc_blend_mb(vp8_postproc_blend_mb);
+extern prototype_postproc_blend_mb_inner(vp8_postproc_blend_mb_inner);
+
+#ifndef vp8_postproc_blend_mb_outer
+#define vp8_postproc_blend_mb_outer vp8_blend_mb_outer_c
+#endif
+extern prototype_postproc_blend_mb_outer(vp8_postproc_blend_mb_outer);
+
+#ifndef vp8_postproc_blend_b
+#define vp8_postproc_blend_b vp8_blend_b_c
+#endif
+extern prototype_postproc_blend_b(vp8_postproc_blend_b);
typedef prototype_postproc((*vp8_postproc_fn_t));
typedef prototype_postproc_inplace((*vp8_postproc_inplace_fn_t));
typedef prototype_postproc_addnoise((*vp8_postproc_addnoise_fn_t));
-typedef prototype_postproc_blend_mb((*vp8_postproc_blend_mb_fn_t));
+typedef prototype_postproc_blend_mb_inner((*vp8_postproc_blend_mb_inner_fn_t));
+typedef prototype_postproc_blend_mb_outer((*vp8_postproc_blend_mb_outer_fn_t));
+typedef prototype_postproc_blend_b((*vp8_postproc_blend_b_fn_t));
typedef struct
{
- vp8_postproc_inplace_fn_t down;
- vp8_postproc_inplace_fn_t across;
- vp8_postproc_fn_t downacross;
- vp8_postproc_addnoise_fn_t addnoise;
- vp8_postproc_blend_mb_fn_t blend_mb;
+ vp8_postproc_inplace_fn_t down;
+ vp8_postproc_inplace_fn_t across;
+ vp8_postproc_fn_t downacross;
+ vp8_postproc_addnoise_fn_t addnoise;
+ vp8_postproc_blend_mb_inner_fn_t blend_mb_inner;
+ vp8_postproc_blend_mb_outer_fn_t blend_mb_outer;
+ vp8_postproc_blend_b_fn_t blend_b;
} vp8_postproc_rtcd_vtable_t;
#if CONFIG_RUNTIME_CPU_DETECT
@@ -89,7 +111,7 @@
#include "onyxc_int.h"
#include "ppflags.h"
int vp8_post_proc_frame(struct VP8Common *oci, YV12_BUFFER_CONFIG *dest,
- int deblock_level, int noise_level, int flags);
+ vp8_ppflags_t *flags);
void vp8_de_noise(YV12_BUFFER_CONFIG *source,
diff --git a/vp8/common/ppflags.h b/vp8/common/ppflags.h
index 6a51d2c..65b0cab 100644
--- a/vp8/common/ppflags.h
+++ b/vp8/common/ppflags.h
@@ -13,17 +13,28 @@
#define __INC_PPFLAGS_H
enum
{
- VP8D_NOFILTERING = 0,
- VP8D_DEBLOCK = 1<<0,
- VP8D_DEMACROBLOCK = 1<<1,
- VP8D_ADDNOISE = 1<<2,
- VP8D_DEBUG_LEVEL1 = 1<<3,
- VP8D_DEBUG_LEVEL2 = 1<<4,
- VP8D_DEBUG_LEVEL3 = 1<<5,
- VP8D_DEBUG_LEVEL4 = 1<<6,
- VP8D_DEBUG_LEVEL5 = 1<<7,
- VP8D_DEBUG_LEVEL6 = 1<<8,
- VP8D_DEBUG_LEVEL7 = 1<<9
+ VP8D_NOFILTERING = 0,
+ VP8D_DEBLOCK = 1<<0,
+ VP8D_DEMACROBLOCK = 1<<1,
+ VP8D_ADDNOISE = 1<<2,
+ VP8D_DEBUG_TXT_FRAME_INFO = 1<<3,
+ VP8D_DEBUG_TXT_MBLK_MODES = 1<<4,
+ VP8D_DEBUG_TXT_DC_DIFF = 1<<5,
+ VP8D_DEBUG_TXT_RATE_INFO = 1<<6,
+ VP8D_DEBUG_DRAW_MV = 1<<7,
+ VP8D_DEBUG_CLR_BLK_MODES = 1<<8,
+ VP8D_DEBUG_CLR_FRM_REF_BLKS = 1<<9
};
+typedef struct
+{
+ int post_proc_flag;
+ int deblocking_level;
+ int noise_level;
+ int display_ref_frame_flag;
+ int display_mb_modes_flag;
+ int display_b_modes_flag;
+ int display_mv_flag;
+} vp8_ppflags_t;
+
#endif
diff --git a/vp8/decoder/decoderthreading.h b/vp8/decoder/decoderthreading.h
index 25dee8f..60c39d1 100644
--- a/vp8/decoder/decoderthreading.h
+++ b/vp8/decoder/decoderthreading.h
@@ -19,7 +19,7 @@
extern void vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd);
extern void vp8_decoder_remove_threads(VP8D_COMP *pbi);
extern void vp8_decoder_create_threads(VP8D_COMP *pbi);
-extern int vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows);
+extern void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows);
extern void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows);
#endif
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 1bdc3d9..4702fae 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -461,7 +461,8 @@
partition_size = user_data_end - partition;
}
- if (user_data_end - partition < partition_size)
+ if (partition + partition_size > user_data_end
+ || partition + partition_size < partition)
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt partition "
"%d length", i + 1);
@@ -580,7 +581,8 @@
(data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
data += 3;
- if (data_end - data < first_partition_length_in_bytes)
+ if (data + first_partition_length_in_bytes > data_end
+ || data + first_partition_length_in_bytes < data)
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt partition 0 length");
vp8_setup_version(pc);
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 6eda45e..aa2709f 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -506,7 +506,7 @@
pbi->common.error.setjmp = 0;
return retcode;
}
-int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level, int noise_level, int flags)
+int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags)
{
int ret = -1;
VP8D_COMP *pbi = (VP8D_COMP *) ptr;
@@ -524,7 +524,7 @@
sd->clrtype = pbi->common.clr_type;
#if CONFIG_POSTPROC
- ret = vp8_post_proc_frame(&pbi->common, sd, deblock_level, noise_level, flags);
+ ret = vp8_post_proc_frame(&pbi->common, sd, flags);
#else
if (pbi->common.frame_to_show)
diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c
index fc2fad5..fea4e1c 100644
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -596,7 +596,7 @@
}
-int vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
+void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
{
#if CONFIG_MULTITHREAD
VP8_COMMON *const pc = & pbi->common;
@@ -647,7 +647,6 @@
for (i=0; i< pc->mb_rows; i++)
CHECK_MEM_ERROR(pbi->mt_vleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
}
- return 0;
#else
(void) pbi;
(void) width;
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index e94e549..90b42c3 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -81,6 +81,7 @@
int errthresh;
int rddiv;
int rdmult;
+ INT64 activity_sum;
int mvcosts[2][MVvals+1];
int *mvcost[2];
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 85e121b..2002735 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -62,7 +62,6 @@
static const int qrounding_factors[129] =
{
- 56, 56, 56, 56, 48, 48, 56, 56,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
@@ -78,12 +77,18 @@
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
- 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48
};
static const int qzbin_factors[129] =
{
- 72, 72, 72, 72, 80, 80, 72, 72,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
@@ -94,17 +99,11 @@
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80,
+ 80
};
static const int qrounding_factors_y2[129] =
{
- 56, 56, 56, 56, 48, 48, 56, 56,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
@@ -120,12 +119,18 @@
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
- 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48
};
static const int qzbin_factors_y2[129] =
{
- 72, 72, 72, 72, 80, 80, 72, 72,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
@@ -136,26 +141,30 @@
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80,
+ 80
};
-//#define EXACT_QUANT
+#define EXACT_QUANT
#ifdef EXACT_QUANT
-static void vp8cx_invert_quant(short *quant, short *shift, short d)
+static void vp8cx_invert_quant(int improved_quant, short *quant,
+ short *shift, short d)
{
- unsigned t;
- int l;
- t = d;
- for(l = 0; t > 1; l++)
- t>>=1;
- t = 1 + (1<<(16+l))/d;
- *quant = (short)(t - (1<<16));
- *shift = l;
+ if(improved_quant)
+ {
+ unsigned t;
+ int l;
+ t = d;
+ for(l = 0; t > 1; l++)
+ t>>=1;
+ t = 1 + (1<<(16+l))/d;
+ *quant = (short)(t - (1<<16));
+ *shift = l;
+ }
+ else
+ {
+ *quant = (1 << 16) / d;
+ *shift = 0;
+ }
}
void vp8cx_init_quantizer(VP8_COMP *cpi)
@@ -170,7 +179,7 @@
{
// dc values
quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
- vp8cx_invert_quant(cpi->Y1quant[Q] + 0,
+ vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
cpi->Y1quant_shift[Q] + 0, quant_val);
cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
@@ -178,7 +187,7 @@
cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
- vp8cx_invert_quant(cpi->Y2quant[Q] + 0,
+ vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
cpi->Y2quant_shift[Q] + 0, quant_val);
cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
@@ -186,7 +195,7 @@
cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
- vp8cx_invert_quant(cpi->UVquant[Q] + 0,
+ vp8cx_invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
cpi->UVquant_shift[Q] + 0, quant_val);
cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
@@ -199,7 +208,7 @@
int rc = vp8_default_zig_zag1d[i];
quant_val = vp8_ac_yquant(Q);
- vp8cx_invert_quant(cpi->Y1quant[Q] + rc,
+ vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + rc,
cpi->Y1quant_shift[Q] + rc, quant_val);
cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
@@ -207,7 +216,7 @@
cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
- vp8cx_invert_quant(cpi->Y2quant[Q] + rc,
+ vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + rc,
cpi->Y2quant_shift[Q] + rc, quant_val);
cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7;
@@ -215,7 +224,7 @@
cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
- vp8cx_invert_quant(cpi->UVquant[Q] + rc,
+ vp8cx_invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + rc,
cpi->UVquant_shift[Q] + rc, quant_val);
cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
@@ -351,6 +360,9 @@
void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
{
+ // Clear Zbin mode boost for default case
+ cpi->zbin_mode_boost = 0;
+
// vp8cx_init_quantizer() is first called in vp8_create_compressor(). A check is added here so that vp8cx_init_quantizer() is only called
// when these values are not all zero.
if (cpi->common.y1dc_delta_q | cpi->common.y2dc_delta_q | cpi->common.uvdc_delta_q | cpi->common.y2ac_delta_q | cpi->common.uvac_delta_q)
@@ -363,6 +375,62 @@
}
+/* activity_avg must be positive, or flat regions could get a zero weight
+ * (infinite lambda), which confounds analysis.
+ * This also avoids the need for divide by zero checks in
+ * vp8_activity_masking().
+ */
+#define VP8_ACTIVITY_AVG_MIN (64)
+
+/* This is used as a reference when computing the source variance for the
+ * purposes of activity masking.
+ * Eventually this should be replaced by custom no-reference routines,
+ * which will be faster.
+ */
+static const unsigned char VP8_VAR_OFFS[16]=
+{
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
+};
+
+unsigned int vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x)
+{
+ unsigned int act;
+ unsigned int sse;
+ int sum;
+ unsigned int a;
+ unsigned int b;
+ unsigned int d;
+ /* TODO: This could also be done over smaller areas (8x8), but that would
+ * require extensive changes elsewhere, as lambda is assumed to be fixed
+ * over an entire MB in most of the code.
+ * Another option is to compute four 8x8 variances, and pick a single
+ * lambda using a non-linear combination (e.g., the smallest, or second
+ * smallest, etc.).
+ */
+ VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16var)(x->src.y_buffer,
+ x->src.y_stride, VP8_VAR_OFFS, 0, &sse, &sum);
+ /* This requires a full 32 bits of precision. */
+ act = (sse<<8) - sum*sum;
+ /* Drop 4 to give us some headroom to work with. */
+ act = (act + 8) >> 4;
+ /* If the region is flat, lower the activity some more. */
+ if (act < 8<<12)
+ act = act < 5<<12 ? act : 5<<12;
+ /* TODO: For non-flat regions, edge regions should receive less masking
+ * than textured regions, but identifying edge regions quickly and
+ * reliably enough is still a subject of experimentation.
+ * This will be most noticable near edges with a complex shape (e.g.,
+ * text), but the 4x4 transform size should make this less of a problem
+ * than it would be for an 8x8 transform.
+ */
+ /* Apply the masking to the RD multiplier. */
+ a = act + 4*cpi->activity_avg;
+ b = 4*act + cpi->activity_avg;
+ x->rdmult = (unsigned int)(((INT64)x->rdmult*b + (a>>1))/a);
+ return act;
+}
+
+
static
void encode_mb_row(VP8_COMP *cpi,
@@ -374,6 +442,7 @@
int *segment_counts,
int *totalrate)
{
+ INT64 activity_sum = 0;
int i;
int recon_yoffset, recon_uvoffset;
int mb_col;
@@ -402,14 +471,14 @@
// Set up limit values for vertical motion vector components
// to prevent them extending beyond the UMV borders
x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
- x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
+ x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
+ (VP8BORDERINPIXELS - 16);
// for each macroblock col in image
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
{
- // Distance of Mb to the left & right edges, specified in
- // 1/8th pel units as they are always compared to values
+ // Distance of Mb to the left & right edges, specified in
+ // 1/8th pel units as they are always compared to values
// that are in 1/8th pel units
xd->mb_to_left_edge = -((mb_col * 16) << 3);
xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
@@ -417,7 +486,7 @@
// Set up limit values for horizontal motion vector components
// to prevent them extending beyond the UMV borders
x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
- x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16)
+ x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16)
+ (VP8BORDERINPIXELS - 16);
xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
@@ -425,6 +494,11 @@
xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
xd->left_available = (mb_col != 0);
+ x->rddiv = cpi->RDDIV;
+ x->rdmult = cpi->RDMULT;
+
+ activity_sum += vp8_activity_masking(cpi, x);
+
// Is segmentation enabled
// MB level adjutment to quantizer
if (xd->segmentation_enabled)
@@ -531,6 +605,7 @@
// this is to account for the border
xd->mode_info_context++;
x->partition_info++;
+ x->activity_sum += activity_sum;
}
@@ -647,8 +722,7 @@
vp8_setup_block_ptrs(x);
- x->rddiv = cpi->RDDIV;
- x->rdmult = cpi->RDMULT;
+ x->activity_sum = 0;
#if 0
// Experimental rd code
@@ -703,11 +777,12 @@
else
{
#if CONFIG_MULTITHREAD
+ int i;
+
vp8cx_init_mbrthread_data(cpi, x, cpi->mb_row_ei, 1, cpi->encoding_thread_count);
for (mb_row = 0; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
{
- int i;
cpi->current_mb_col_main = -1;
for (i = 0; i < cpi->encoding_thread_count; i++)
@@ -785,6 +860,11 @@
totalrate += cpi->mb_row_ei[i].totalrate;
}
+ for (i = 0; i < cpi->encoding_thread_count; i++)
+ {
+ x->activity_sum += cpi->mb_row_ei[i].mb.activity_sum;
+ }
+
#endif
}
@@ -920,6 +1000,14 @@
cpi->last_frame_distortion = cpi->frame_distortion;
#endif
+ /* Update the average activity for the next frame.
+ * This is feed-forward for now; it could also be saved in two-pass, or
+ * done during lookahead when that is eventually added.
+ */
+ cpi->activity_avg = (unsigned int )(x->activity_sum/cpi->common.MBs);
+ if (cpi->activity_avg < VP8_ACTIVITY_AVG_MIN)
+ cpi->activity_avg = VP8_ACTIVITY_AVG_MIN;
+
}
void vp8_setup_block_ptrs(MACROBLOCK *x)
{
@@ -1214,11 +1302,25 @@
// Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
if (cpi->zbin_mode_boost_enabled)
{
- if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME))
- cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
+ if ( xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME )
+ cpi->zbin_mode_boost = 0;
else
- cpi->zbin_mode_boost = 0;
+ {
+ if (xd->mode_info_context->mbmi.mode == ZEROMV)
+ {
+ if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
+ cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
+ else
+ cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
+ }
+ else if (xd->mode_info_context->mbmi.mode == SPLITMV)
+ cpi->zbin_mode_boost = 0;
+ else
+ cpi->zbin_mode_boost = MV_ZBIN_BOOST;
+ }
}
+ else
+ cpi->zbin_mode_boost = 0;
vp8cx_mb_init_quantizer(cpi, x);
}
diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c
index 1c72b90..0f327ce 100644
--- a/vp8/encoder/encodeintra.c
+++ b/vp8/encoder/encodeintra.c
@@ -105,7 +105,7 @@
#if !(CONFIG_REALTIME_ONLY)
#if 1
- if (x->optimize==2 ||(x->optimize && x->rddiv > 1))
+ if (x->optimize)
vp8_optimize_mby(x, rtcd);
#endif
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
index 043eac2..f7faaa1 100644
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -309,8 +309,10 @@
eob = d->eob;
/* Now set up a Viterbi trellis to evaluate alternative roundings. */
- /* TODO: These should vary with the block type, since the quantizer does. */
rdmult = (mb->rdmult << 2)*err_mult;
+ if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME)
+ rdmult = (rdmult * 9)>>4;
+
rddiv = mb->rddiv;
best_mask[0] = best_mask[1] = 0;
/* Initialize the sentinel node of the trellis. */
@@ -633,7 +635,7 @@
vp8_quantize_mb(x);
#if !(CONFIG_REALTIME_ONLY)
- if (x->optimize==2 ||(x->optimize && x->rddiv > 1))
+ if (x->optimize)
vp8_optimize_mb(x, rtcd);
#endif
diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c
index 962e741..3646375 100644
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -61,6 +61,7 @@
int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
volatile int *last_row_current_mb_col;
+ INT64 activity_sum = 0;
if (ithread > 0)
last_row_current_mb_col = &cpi->mb_row_ei[ithread-1].current_mb_col;
@@ -111,6 +112,11 @@
xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
xd->left_available = (mb_col != 0);
+ x->rddiv = cpi->RDDIV;
+ x->rdmult = cpi->RDMULT;
+
+ activity_sum += vp8_activity_masking(cpi, x);
+
// Is segmentation enabled
// MB level adjutment to quantizer
if (xd->segmentation_enabled)
@@ -197,6 +203,7 @@
// this is to account for the border
xd->mode_info_context++;
x->partition_info++;
+ x->activity_sum += activity_sum;
x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
x->src.u_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
@@ -240,8 +247,6 @@
z->sadperbit16 = x->sadperbit16;
z->sadperbit4 = x->sadperbit4;
z->errthresh = x->errthresh;
- z->rddiv = x->rddiv;
- z->rdmult = x->rdmult;
/*
z->mv_col_min = x->mv_col_min;
@@ -392,8 +397,7 @@
vp8_setup_block_ptrs(mb);
- mb->rddiv = cpi->RDDIV;
- mb->rdmult = cpi->RDMULT;
+ mb->activity_sum = 0;
mbd->left_context = &cm->left_context;
mb->mvc = cm->fc.mvc;
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 539a28f..5cb1fd9 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -1145,6 +1145,7 @@
cpi->output_frame_rate = cpi->oxcf.frame_rate;
cpi->bits_left = (long long)(cpi->total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
cpi->bits_left -= (long long)(cpi->total_stats->duration * two_pass_min_rate / 10000000.0);
+ cpi->clip_bits_total = cpi->bits_left;
vp8_avg_stats(cpi->total_stats);
@@ -1173,17 +1174,25 @@
{
start_pos = cpi->stats_in; // Note starting "file" position
- cpi->modified_total_error_left = 0.0;
+ cpi->modified_error_total = 0.0;
+ cpi->modified_error_used = 0.0;
while (vp8_input_stats(cpi, &this_frame) != EOF)
{
- cpi->modified_total_error_left += calculate_modified_err(cpi, &this_frame);
+ cpi->modified_error_total += calculate_modified_err(cpi, &this_frame);
}
+ cpi->modified_error_left = cpi->modified_error_total;
reset_fpf_position(cpi, start_pos); // Reset file position
}
+ // Calculate the clip target modified bits per error
+ // The observed bpe starts as the same number.
+ cpi->clip_bpe = cpi->bits_left /
+ DOUBLE_DIVIDE_CHECK(cpi->modified_error_total);
+ cpi->observed_bpe = cpi->clip_bpe;
+
cpi->fp_motion_map_stats = (unsigned char *)cpi->stats_in;
}
@@ -1439,7 +1448,7 @@
// Boost for arf frame
Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
- Boost += (cpi->baseline_gf_interval * 50);
+ Boost += (i * 50);
allocation_chunks = (i * 100) + Boost;
// Normalize Altboost and allocations chunck down to prevent overflow
@@ -1585,6 +1594,9 @@
// Reset the file position
reset_fpf_position(cpi, start_pos);
+ // Update the record of error used so far (only done once per gf group)
+ cpi->modified_error_used += gf_group_err;
+
// Assign bits to the arf or gf.
{
int Boost;
@@ -1738,16 +1750,6 @@
vp8_avg_stats(§ionstats);
- if (sectionstats.pcnt_motion < .17)
- cpi->section_is_low_motion = 1;
- else
- cpi->section_is_low_motion = 0;
-
- if (sectionstats.mvc_abs + sectionstats.mvr_abs > 45)
- cpi->section_is_fast_motion = 1;
- else
- cpi->section_is_fast_motion = 0;
-
cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
@@ -1892,6 +1894,16 @@
// Is this a GF / ARF (Note that a KF is always also a GF)
if (cpi->frames_till_gf_update_due == 0)
{
+ // Update monitor of the bits per error observed so far.
+ // Done once per gf group based on what has gone before
+ // so do nothing if this is the first frame.
+ if (cpi->common.current_video_frame > 0)
+ {
+ cpi->observed_bpe =
+ (double)(cpi->clip_bits_total - cpi->bits_left) /
+ cpi->modified_error_used;
+ }
+
// Define next gf group and assign bits to it
vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
define_gf_group(cpi, &this_frame_copy);
@@ -1980,7 +1992,14 @@
cpi->ni_av_qi = cpi->worst_quality;
}
}
- else
+ // The last few frames of a clip almost always have to few or too many
+ // bits and for the sake of over exact rate control we dont want to make
+ // radical adjustments to the allowed quantizer range just to use up a
+ // few surplus bits or get beneath the target rate.
+ else if ( (cpi->common.current_video_frame <
+ (((unsigned int)cpi->total_stats->count * 255)>>8)) &&
+ ((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
+ (unsigned int)cpi->total_stats->count) )
{
if (frames_left < 1)
frames_left = 1;
@@ -2199,7 +2218,7 @@
}
// Calculate the number of bits that should be assigned to the kf group.
- if ((cpi->bits_left > 0) && ((int)cpi->modified_total_error_left > 0))
+ if ((cpi->bits_left > 0) && ((int)cpi->modified_error_left > 0))
{
// Max for a single normal frame (not key frame)
int max_bits = frame_max_bits(cpi);
@@ -2211,7 +2230,7 @@
// complexity of the section
cpi->kf_group_bits = (long long)( cpi->bits_left *
( kf_group_err /
- cpi->modified_total_error_left ));
+ cpi->modified_error_left ));
// Clip based on maximum per frame rate defined by the user.
max_grp_bits = (long long)max_bits * (long long)cpi->frames_to_key;
@@ -2344,17 +2363,7 @@
vp8_avg_stats(§ionstats);
- if (sectionstats.pcnt_motion < .17)
- cpi->section_is_low_motion = 1;
- else
- cpi->section_is_low_motion = 0;
-
- if (sectionstats.mvc_abs + sectionstats.mvr_abs > 45)
- cpi->section_is_fast_motion = 1;
- else
- cpi->section_is_fast_motion = 0;
-
- cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
+ cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
// if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) )
@@ -2474,7 +2483,7 @@
double alt_kf_grp_bits =
((double)cpi->bits_left *
(kf_mod_err * (double)cpi->frames_to_key) /
- DOUBLE_DIVIDE_CHECK(cpi->modified_total_error_left));
+ DOUBLE_DIVIDE_CHECK(cpi->modified_error_left));
alt_kf_bits = (int)((double)kf_boost *
(alt_kf_grp_bits / (double)allocation_chunks));
@@ -2492,7 +2501,7 @@
alt_kf_bits =
(int)((double)cpi->bits_left *
(kf_mod_err /
- DOUBLE_DIVIDE_CHECK(cpi->modified_total_error_left)));
+ DOUBLE_DIVIDE_CHECK(cpi->modified_error_left)));
if (alt_kf_bits > cpi->kf_bits)
{
@@ -2512,7 +2521,7 @@
// Adjust the count of total modified error left.
// The count of bits left is adjusted elsewhere based on real coded frame sizes
- cpi->modified_total_error_left -= kf_group_err;
+ cpi->modified_error_left -= kf_group_err;
if (cpi->oxcf.allow_spatial_resampling)
{
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index fd7b566..7e9a0f0 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -174,17 +174,6 @@
27,27,28,28,29,29,30,30,31,31,32,32,33,33,34,34,
35,35,36,36,37,38,39,40,41,42,43,44,45,46,47,48,
};
-/*static const int kf_minq[QINDEX_RANGE] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10,10,11,11,12,12,13,13,14,14,
- 15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,
- 23,23,24,24,25,25,26,26,27,27,28,28,29,29,30,30,
- 31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38
-};*/
static const int gf_low_motion_minq[QINDEX_RANGE] =
{
0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,
@@ -218,27 +207,16 @@
41,41,42,42,43,44,45,46,47,48,49,50,51,52,53,54,
55,56,57,58,59,60,62,64,66,68,70,72,74,76,78,80,
};
-/*static const int gf_arf_minq[QINDEX_RANGE] =
-{
- 0,0,0,0,1,1,1,1,1,1,2,2,3,3,3,4,
- 4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,
- 9,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,
- 15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,
- 23,23,24,24,25,25,26,26,27,27,28,28,29,29,30,30,
- 31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,39,
- 39,40,40,41,41,42,42,43,43,44,45,46,47,48,49,50,
- 51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66
-};*/
static const int inter_minq[QINDEX_RANGE] =
{
- 0,0,0,0,1,1,2,3,3,4,4,5,6,6,7,7,
- 8,8,9,9,10,11,11,12,12,13,13,14,14,15,15,16,
- 16,17,17,17,18,18,19,19,20,20,21,21,22,22,22,23,
- 23,24,24,24,25,25,26,27,28,28,29,30,31,32,33,34,
- 35,35,36,37,38,39,39,40,41,42,43,43,44,45,46,47,
- 47,48,49,49,51,52,53,54,54,55,56,56,57,57,58,58,
- 59,59,60,61,61,62,62,63,64,64,65,66,67,67,68,69,
- 69,70,71,71,72,73,74,75,76,76,77,78,79,80,81,81,
+ 0,0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,
+ 9,10,11,11,12,13,13,14,15,15,16,17,17,18,19,20,
+ 20,21,22,22,23,24,24,25,26,27,27,28,29,30,30,31,
+ 32,33,33,34,35,36,36,37,38,39,39,40,41,42,42,43,
+ 44,45,46,46,47,48,49,50,50,51,52,53,54,55,55,56,
+ 57,58,59,60,60,61,62,63,64,65,66,67,67,68,69,70,
+ 71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85,
+ 86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
};
void vp8_initialize()
@@ -578,6 +556,7 @@
int Speed = cpi->Speed;
int i;
VP8_COMMON *cm = &cpi->common;
+ int last_improved_quant = sf->improved_quant;
// Initialise default mode frequency sampling variables
for (i = 0; i < MAX_MODES; i ++)
@@ -818,7 +797,8 @@
sf->thresh_mult[THR_SPLITA ] = 50000;
}
- // Only do recode loop on key frames and golden frames
+ // Only do recode loop on key frames, golden frames and
+ // alt ref frames
sf->recode_loop = 2;
sf->full_freq[0] = 31;
@@ -1277,6 +1257,8 @@
{
cpi->mb.quantize_b = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb);
}
+ if (cpi->sf.improved_quant != last_improved_quant)
+ vp8cx_init_quantizer(cpi);
#if CONFIG_RUNTIME_CPU_DETECT
cpi->mb.e_mbd.rtcd = &cpi->common.rtcd;
@@ -2219,6 +2201,8 @@
init_context_counters();
#endif
+ /*Initialize the feed-forward activity masking.*/
+ cpi->activity_avg = 90<<12;
cpi->frames_since_key = 8; // Give a sensible default for the first frame.
cpi->key_frame_frequency = cpi->oxcf.key_freq;
@@ -3450,6 +3434,37 @@
#endif
// return of 0 means drop frame
+// Function to test for conditions that indeicate we should loop
+// back and recode a frame.
+static BOOL recode_loop_test( VP8_COMP *cpi,
+ int high_limit, int low_limit,
+ int q, int maxq, int minq )
+{
+ BOOL force_recode = FALSE;
+ VP8_COMMON *cm = &cpi->common;
+
+ // Is frame recode allowed at all
+ // Yes if either recode mode 1 is selected or mode two is selcted
+ // and the frame is a key frame. golden frame or alt_ref_frame
+ if ( (cpi->sf.recode_loop == 1) ||
+ ( (cpi->sf.recode_loop == 2) &&
+ ( (cm->frame_type == KEY_FRAME) ||
+ cm->refresh_golden_frame ||
+ cm->refresh_alt_ref_frame ) ) )
+ {
+ // General over and under shoot tests
+ if ( ((cpi->projected_frame_size > high_limit) && (q < maxq)) ||
+ ((cpi->projected_frame_size < low_limit) && (q > minq)) )
+ {
+ force_recode = TRUE;
+ }
+ // Specific rate control mode related tests
+ // TBD
+ }
+
+ return force_recode;
+}
+
static void encode_frame_to_data_rate
(
VP8_COMP *cpi,
@@ -3512,8 +3527,18 @@
cpi->zbin_over_quant = 0;
cpi->zbin_mode_boost = 0;
- // Enable mode based tweaking of the zbin
+ // Enable or disable mode based tweaking of the zbin
+ // For 2 Pass Only used where GF/ARF prediction quality
+ // is above a threshold
+ cpi->zbin_mode_boost = 0;
cpi->zbin_mode_boost_enabled = TRUE;
+ if (cpi->pass == 2)
+ {
+ if ( cpi->gfu_boost <= 400 )
+ {
+ cpi->zbin_mode_boost_enabled = FALSE;
+ }
+ }
// Current default encoder behaviour for the altref sign bias
if (cpi->source_alt_ref_active)
@@ -4034,19 +4059,18 @@
#if !(CONFIG_REALTIME_ONLY)
// Is the projected frame size out of range and are we allowed to attempt to recode.
- if (((cpi->sf.recode_loop == 1) ||
- ((cpi->sf.recode_loop == 2) && (cm->refresh_golden_frame || (cm->frame_type == KEY_FRAME)))) &&
- (((cpi->projected_frame_size > frame_over_shoot_limit) && (Q < top_index)) ||
- //((cpi->projected_frame_size > frame_over_shoot_limit ) && (Q == top_index) && (cpi->zbin_over_quant < ZBIN_OQ_MAX)) ||
- ((cpi->projected_frame_size < frame_under_shoot_limit) && (Q > bottom_index)))
- )
+ if ( recode_loop_test( cpi,
+ frame_over_shoot_limit, frame_under_shoot_limit,
+ Q, top_index, bottom_index ) )
{
int last_q = Q;
int Retries = 0;
// Frame size out of permitted range:
// Update correction factor & compute new Q to try...
- if (cpi->projected_frame_size > frame_over_shoot_limit)
+
+ // Frame is too large
+ if (cpi->projected_frame_size > cpi->this_frame_target)
{
//if ( cpi->zbin_over_quant == 0 )
q_low = (Q < q_high) ? (Q + 1) : q_high; // Raise Qlow as to at least the current value
@@ -4090,6 +4114,7 @@
overshoot_seen = TRUE;
}
+ // Frame is too small
else
{
if (cpi->zbin_over_quant == 0)
@@ -4183,9 +4208,9 @@
}
#endif
-
-
-
+ // Update the GF useage maps.
+ // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
+ vp8_update_gf_useage_maps(cpi, cm, &cpi->mb);
////////////////////////////////
////////////////////////////////
// This frame's MVs are saved and will be used in next frame's MV prediction.
@@ -4610,7 +4635,7 @@
}
else
{
- if (cpi->oxcf.play_alternate && cpi->common.refresh_alt_ref_frame)
+ if (cpi->oxcf.play_alternate && cpi->common.refresh_alt_ref_frame && (cpi->common.frame_type != KEY_FRAME))
// Update the alternate reference frame and stats as appropriate.
update_alt_ref_frame_and_stats(cpi);
else
@@ -5044,17 +5069,16 @@
*frame_flags = cpi->source_frame_flags;
-#if CONFIG_PSNR
-
if (cpi->source_time_stamp < cpi->first_time_stamp_ever)
+ {
cpi->first_time_stamp_ever = cpi->source_time_stamp;
-
-#endif
+ cpi->last_end_time_stamp_seen = cpi->source_time_stamp;
+ }
// adjust frame rates based on timestamps given
if (!cm->refresh_alt_ref_frame)
{
- if (cpi->last_time_stamp_seen == 0)
+ if (cpi->source_time_stamp == cpi->first_time_stamp_ever)
{
double this_fps = 10000000.000 / (cpi->source_end_time_stamp - cpi->source_time_stamp);
@@ -5062,7 +5086,8 @@
}
else
{
- long long nanosecs = cpi->source_time_stamp - cpi->last_time_stamp_seen;
+ long long nanosecs = cpi->source_end_time_stamp
+ - cpi->last_end_time_stamp_seen;
double this_fps = 10000000.000 / nanosecs;
vp8_new_frame_rate(cpi, (7 * cpi->oxcf.frame_rate + this_fps) / 8);
@@ -5070,6 +5095,7 @@
}
cpi->last_time_stamp_seen = cpi->source_time_stamp;
+ cpi->last_end_time_stamp_seen = cpi->source_end_time_stamp;
}
if (cpi->compressor_speed == 2)
@@ -5285,7 +5311,7 @@
return 0;
}
-int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags)
+int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t *flags)
{
VP8_COMP *cpi = (VP8_COMP *) comp;
@@ -5295,7 +5321,7 @@
{
int ret;
#if CONFIG_POSTPROC
- ret = vp8_post_proc_frame(&cpi->common, dest, deblock_level, noise_level, flags);
+ ret = vp8_post_proc_frame(&cpi->common, dest, flags);
#else
if (cpi->common.frame_to_show)
@@ -5388,12 +5414,12 @@
{
VP8_COMP *cpi = (VP8_COMP *) comp;
- if (horiz_mode >= NORMAL && horiz_mode <= ONETWO)
+ if (horiz_mode <= ONETWO)
cpi->common.horiz_scale = horiz_mode;
else
return -1;
- if (vert_mode >= NORMAL && vert_mode <= ONETWO)
+ if (vert_mode <= ONETWO)
cpi->common.vert_scale = vert_mode;
else
return -1;
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 31e627b..63f17aa 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -46,6 +46,8 @@
#define MAX_THRESHMULT 512
#define GF_ZEROMV_ZBIN_BOOST 24
+#define LF_ZEROMV_ZBIN_BOOST 12
+#define MV_ZBIN_BOOST 4
#define ZBIN_OQ_MAX 192
#define VP8_TEMPORAL_ALT_REF 1
@@ -282,14 +284,14 @@
unsigned int source_frame_flags;
YV12_BUFFER_CONFIG scaled_source;
- int source_buffer_count;
- int source_encode_index;
- int source_alt_ref_pending;
- int source_alt_ref_active;
+ int source_buffer_count; // number of src_buffers in use for lagged encoding
+ int source_encode_index; // index of buffer in src_buffer to encode
+ int source_alt_ref_pending; // frame in src_buffers has been identified to be encoded as an alt ref
+ int source_alt_ref_active; // an alt ref frame has been encoded and is usable
- int last_alt_ref_sei;
- int is_src_frame_alt_ref;
- int is_next_src_alt_ref;
+ int last_alt_ref_sei; // index into src_buffers of frame used as alt reference
+ int is_src_frame_alt_ref; // source of frame to encode is an exact copy of an alt ref frame
+ int is_next_src_alt_ref; // source of next frame to encode is an exact copy of an alt ref frame
int gold_is_last; // golden frame same as last frame ( short circuit gold searches)
int alt_is_last; // Alt reference frame same as last ( short circuit altref search)
@@ -325,6 +327,7 @@
int mvcostmultiplier;
int subseqblockweight;
int errthresh;
+ unsigned int activity_avg;
int RDMULT;
int RDDIV ;
@@ -405,6 +408,7 @@
int inter_frame_target;
double output_frame_rate;
long long last_time_stamp_seen;
+ long long last_end_time_stamp_seen;
long long first_time_stamp_ever;
int ni_av_qi;
@@ -472,11 +476,17 @@
double start_tot_err_left;
double min_error;
- double modified_total_error_left;
+ double modified_error_total;
+ double modified_error_used;
+ double modified_error_left;
+ double clip_bpe;
+ double observed_bpe;
+
double avg_iiratio;
int target_bandwidth;
long long bits_left;
+ long long clip_bits_total;
FIRSTPASS_STATS *total_stats;
FIRSTPASS_STATS *this_frame_stats;
FIRSTPASS_STATS *stats_in, *stats_in_end;
@@ -617,9 +627,6 @@
unsigned int tempdata2;
int base_skip_false_prob[128];
- unsigned int section_is_low_motion;
- unsigned int section_benefits_from_aggresive_q;
- unsigned int section_is_fast_motion;
unsigned int section_intra_rating;
double section_max_qfactor;
@@ -680,6 +687,8 @@
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size);
+unsigned int vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x);
+
int rd_cost_intra_mb(MACROBLOCKD *x);
void vp8_tokenize_mb(VP8_COMP *, MACROBLOCKD *, TOKENEXTRA **);
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c
index 5e65fad..a1be661 100644
--- a/vp8/encoder/quantize.c
+++ b/vp8/encoder/quantize.c
@@ -16,8 +16,9 @@
#include "entropy.h"
#include "predictdc.h"
-//#define EXACT_QUANT
-#ifdef EXACT_QUANT
+#define EXACT_QUANT
+
+#ifdef EXACT_FASTQUANT
void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
{
int i, rc, eob;
@@ -64,6 +65,45 @@
d->eob = eob + 1;
}
+#else
+
+void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *coeff_ptr = b->coeff;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+
+ eob = -1;
+ for (i = 0; i < 16; i++)
+ {
+ rc = vp8_default_zig_zag1d[i];
+ z = coeff_ptr[rc];
+
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ }
+ }
+ d->eob = eob + 1;
+}
+
+#endif
+
+#ifdef EXACT_QUANT
void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
{
int i, rc, eob;
@@ -178,39 +218,6 @@
}
#else
-void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
-{
- int i, rc, eob;
- int zbin;
- int x, y, z, sz;
- short *coeff_ptr = b->coeff;
- short *round_ptr = b->round;
- short *quant_ptr = b->quant;
- short *qcoeff_ptr = d->qcoeff;
- short *dqcoeff_ptr = d->dqcoeff;
- short *dequant_ptr = d->dequant;
-
- eob = -1;
- for (i = 0; i < 16; i++)
- {
- rc = vp8_default_zig_zag1d[i];
- z = coeff_ptr[rc];
-
- sz = (z >> 31); // sign of z
- x = (z ^ sz) - sz; // x = abs(z)
-
- y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
- x = (y ^ sz) - sz; // get the sign back
- qcoeff_ptr[rc] = x; // write to destination
- dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
-
- if (y)
- {
- eob = i; // last nonzero coeffs
- }
- }
- d->eob = eob + 1;
-}
void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
{
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index dd324f4..8455b7b 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -45,46 +45,48 @@
// Bits Per MB at different Q (Multiplied by 512)
#define BPER_MB_NORMBITS 9
+// Work in progress recalibration of baseline rate tables based on
+// the assumption that bits per mb is inversely proportional to the
+// quantizer value.
const int vp8_bits_per_mb[2][QINDEX_RANGE] =
{
- // (Updated 19 March 08) Baseline estimate of INTRA-frame Bits Per MB at each Q:
+ // Intra case 450000/Qintra
{
- 674781, 606845, 553905, 524293, 500428, 452540, 435379, 414719,
- 390970, 371082, 359416, 341807, 336957, 317263, 303724, 298402,
- 285688, 275237, 268455, 262560, 256038, 248734, 241087, 237615,
- 229247, 225211, 219112, 213920, 211559, 202714, 198482, 193401,
- 187866, 183453, 179212, 175965, 171852, 167235, 163972, 160560,
- 156032, 154349, 151390, 148725, 145708, 142311, 139981, 137700,
- 134084, 131863, 129746, 128498, 126077, 123461, 121290, 117782,
- 114883, 112332, 108410, 105685, 103434, 101192, 98587, 95959,
- 94059, 92017, 89970, 87936, 86142, 84801, 82736, 81106,
- 79668, 78135, 76641, 75103, 73943, 72693, 71401, 70098,
- 69165, 67901, 67170, 65987, 64923, 63534, 62378, 61302,
- 59921, 58941, 57844, 56782, 55960, 54973, 54257, 53454,
- 52230, 50938, 49962, 49190, 48288, 47270, 46738, 46037,
- 45020, 44027, 43216, 42287, 41594, 40702, 40081, 39414,
- 38282, 37627, 36987, 36375, 35808, 35236, 34710, 34162,
- 33659, 33327, 32751, 32384, 31936, 31461, 30982, 30582,
+ 1125000,900000, 750000, 642857, 562500, 500000, 450000, 450000,
+ 409090, 375000, 346153, 321428, 300000, 281250, 264705, 264705,
+ 250000, 236842, 225000, 225000, 214285, 214285, 204545, 204545,
+ 195652, 195652, 187500, 180000, 180000, 173076, 166666, 160714,
+ 155172, 150000, 145161, 140625, 136363, 132352, 128571, 125000,
+ 121621, 121621, 118421, 115384, 112500, 109756, 107142, 104651,
+ 102272, 100000, 97826, 97826, 95744, 93750, 91836, 90000,
+ 88235, 86538, 84905, 83333, 81818, 80357, 78947, 77586,
+ 76271, 75000, 73770, 72580, 71428, 70312, 69230, 68181,
+ 67164, 66176, 65217, 64285, 63380, 62500, 61643, 60810,
+ 60000, 59210, 59210, 58441, 57692, 56962, 56250, 55555,
+ 54878, 54216, 53571, 52941, 52325, 51724, 51136, 50561,
+ 49450, 48387, 47368, 46875, 45918, 45000, 44554, 44117,
+ 43269, 42452, 41666, 40909, 40178, 39473, 38793, 38135,
+ 36885, 36290, 35714, 35156, 34615, 34090, 33582, 33088,
+ 32608, 32142, 31468, 31034, 30405, 29801, 29220, 28662,
},
-
- // (Updated 19 March 08) Baseline estimate of INTER-frame Bits Per MB at each Q:
+ // Inter case 285000/Qinter
{
- 497401, 426316, 372064, 352732, 335763, 283921, 273848, 253321,
- 233181, 217727, 210030, 196685, 194836, 178396, 167753, 164116,
- 154119, 146929, 142254, 138488, 133591, 127741, 123166, 120226,
- 114188, 111756, 107882, 104749, 102522, 96451, 94424, 90905,
- 87286, 84931, 82111, 80534, 77610, 74700, 73037, 70715,
- 68006, 67235, 65374, 64009, 62134, 60180, 59105, 57691,
- 55509, 54512, 53318, 52693, 51194, 49840, 48944, 46980,
- 45668, 44177, 42348, 40994, 39859, 38889, 37717, 36391,
- 35482, 34622, 33795, 32756, 32002, 31492, 30573, 29737,
- 29152, 28514, 27941, 27356, 26859, 26329, 25874, 25364,
- 24957, 24510, 24290, 23689, 23380, 22845, 22481, 22066,
- 21587, 21219, 20880, 20452, 20260, 19926, 19661, 19334,
- 18915, 18391, 18046, 17833, 17441, 17105, 16888, 16729,
- 16383, 16023, 15706, 15442, 15222, 14938, 14673, 14452,
- 14005, 13807, 13611, 13447, 13223, 13102, 12963, 12801,
- 12627, 12534, 12356, 12228, 12056, 11907, 11746, 11643,
+ 712500, 570000, 475000, 407142, 356250, 316666, 285000, 259090,
+ 237500, 219230, 203571, 190000, 178125, 167647, 158333, 150000,
+ 142500, 135714, 129545, 123913, 118750, 114000, 109615, 105555,
+ 101785, 98275, 95000, 91935, 89062, 86363, 83823, 81428,
+ 79166, 77027, 75000, 73076, 71250, 69512, 67857, 66279,
+ 64772, 63333, 61956, 60638, 59375, 58163, 57000, 55882,
+ 54807, 53773, 52777, 51818, 50892, 50000, 49137, 47500,
+ 45967, 44531, 43181, 41911, 40714, 39583, 38513, 37500,
+ 36538, 35625, 34756, 33928, 33139, 32386, 31666, 30978,
+ 30319, 29687, 29081, 28500, 27941, 27403, 26886, 26388,
+ 25909, 25446, 25000, 24568, 23949, 23360, 22800, 22265,
+ 21755, 21268, 20802, 20357, 19930, 19520, 19127, 18750,
+ 18387, 18037, 17701, 17378, 17065, 16764, 16473, 16101,
+ 15745, 15405, 15079, 14766, 14467, 14179, 13902, 13636,
+ 13380, 13133, 12895, 12666, 12445, 12179, 11924, 11632,
+ 11445, 11220, 11003, 10795, 10594, 10401, 10215, 10035,
}
};
@@ -324,6 +326,7 @@
cpi->frames_till_gf_update_due = cpi->goldfreq;
cpi->common.refresh_golden_frame = TRUE;
+ cpi->common.refresh_alt_ref_frame = TRUE;
}
void vp8_calc_auto_iframe_target_size(VP8_COMP *cpi)
@@ -1034,9 +1037,7 @@
gf_frame_useage = pct_gf_active;
// Is a fixed manual GF frequency being used
- if (!cpi->auto_gold)
- cpi->common.refresh_golden_frame = TRUE;
- else
+ if (cpi->auto_gold)
{
// For one pass throw a GF if recent frame intra useage is low or the GF useage is high
if ((cpi->pass == 0) && (cpi->this_frame_percent_intra < 15 || gf_frame_useage >= 5))
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 99129ac..74f7f46 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -477,67 +477,6 @@
return error;
}
-#if !(CONFIG_REALTIME_ONLY)
-static int macro_block_max_error(MACROBLOCK *mb)
-{
- int error = 0;
- int dc = 0;
- BLOCK *be;
- int i, j;
- int berror;
-
- dc = !(mb->e_mbd.mode_info_context->mbmi.mode == B_PRED || mb->e_mbd.mode_info_context->mbmi.mode == SPLITMV);
-
- for (i = 0; i < 16; i++)
- {
- be = &mb->block[i];
-
- berror = 0;
-
- for (j = dc; j < 16; j++)
- {
- int this_diff = be->coeff[j];
- berror += this_diff * this_diff;
- }
-
- error += berror;
- }
-
- for (i = 16; i < 24; i++)
- {
- be = &mb->block[i];
- berror = 0;
-
- for (j = 0; j < 16; j++)
- {
- int this_diff = be->coeff[j];
- berror += this_diff * this_diff;
- }
-
- error += berror;
- }
-
- error <<= 2;
-
- if (dc)
- {
- be = &mb->block[24];
- berror = 0;
-
- for (j = 0; j < 16; j++)
- {
- int this_diff = be->coeff[j];
- berror += this_diff * this_diff;
- }
-
- error += berror;
- }
-
- error >>= 4;
- return error;
-}
-#endif
-
int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd)
{
unsigned char *uptr, *vptr;
@@ -610,11 +549,10 @@
return cost;
}
-int vp8_rdcost_mby(MACROBLOCK *mb)
+static int vp8_rdcost_mby(MACROBLOCK *mb)
{
int cost = 0;
int b;
- int type = 0;
MACROBLOCKD *x = &mb->e_mbd;
ENTROPY_CONTEXT_PLANES t_above, t_left;
ENTROPY_CONTEXT *ta;
@@ -626,16 +564,12 @@
ta = (ENTROPY_CONTEXT *)&t_above;
tl = (ENTROPY_CONTEXT *)&t_left;
- if (x->mode_info_context->mbmi.mode == SPLITMV)
- type = 3;
-
for (b = 0; b < 16; b++)
- cost += cost_coeffs(mb, x->block + b, type,
+ cost += cost_coeffs(mb, x->block + b, 0,
ta + vp8_block2above[b], tl + vp8_block2left[b]);
- if (x->mode_info_context->mbmi.mode != SPLITMV)
- cost += cost_coeffs(mb, x->block + 24, 1,
- ta + vp8_block2above[24], tl + vp8_block2left[24]);
+ cost += cost_coeffs(mb, x->block + 24, 1,
+ ta + vp8_block2above[24], tl + vp8_block2left[24]);
return cost;
}
@@ -1062,10 +996,7 @@
}
// 2nd order fdct
- if (x->mode_info_context->mbmi.mode != SPLITMV)
- {
- mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8);
- }
+ mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8);
// Quantization
for (b = 0; b < 16; b++)
@@ -1074,22 +1005,11 @@
}
// DC predication and Quantization of 2nd Order block
- if (x->mode_info_context->mbmi.mode != SPLITMV)
- {
-
- {
- mb->quantize_b(mb_y2, x_y2);
- }
- }
+ mb->quantize_b(mb_y2, x_y2);
// Distortion
- if (x->mode_info_context->mbmi.mode == SPLITMV)
- d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 0) << 2;
- else
- {
- d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
- d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
- }
+ d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
+ d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
*Distortion = (d >> 4);
@@ -1965,10 +1885,22 @@
// Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
if (cpi->zbin_mode_boost_enabled)
{
- if ((vp8_mode_order[mode_index] == ZEROMV) && (vp8_ref_frame_order[mode_index] != LAST_FRAME))
- cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
- else
+ if ( vp8_ref_frame_order[mode_index] == INTRA_FRAME )
cpi->zbin_mode_boost = 0;
+ else
+ {
+ if (vp8_mode_order[mode_index] == ZEROMV)
+ {
+ if (vp8_ref_frame_order[mode_index] != LAST_FRAME)
+ cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
+ else
+ cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
+ }
+ else if (vp8_ref_frame_order[mode_index] == SPLITMV)
+ cpi->zbin_mode_boost = 0;
+ else
+ cpi->zbin_mode_boost = MV_ZBIN_BOOST;
+ }
vp8cx_mb_init_quantizer(cpi, x);
}
@@ -2363,40 +2295,6 @@
#endif
}
-#if 0
- else
- {
- int rateuseskip;
- int ratenotuseskip;
- int maxdistortion;
- int minrate;
- int skip_rd;
-
- // distortion when no coeff is encoded
- maxdistortion = macro_block_max_error(x);
-
- ratenotuseskip = rate_y + rate_uv + vp8_cost_bit(cpi->prob_skip_false, 0);
- rateuseskip = vp8_cost_bit(cpi->prob_skip_false, 1);
-
- minrate = rateuseskip - ratenotuseskip;
-
- skip_rd = RDFUNC(x->rdmult, x->rddiv, minrate, maxdistortion - distortion2, cpi->target_bits_per_mb);
-
- if (skip_rd + 50 < 0 && x->e_mbd.mbmi.ref_frame != INTRA_FRAME && rate_y + rate_uv < 4000)
- {
- force_no_skip = 1;
- rate2 = rate2 + rateuseskip - ratenotuseskip;
- distortion2 = maxdistortion;
- }
- else
- {
- force_no_skip = 0;
- }
-
- }
-
-#endif
-
}
// Calculate the final RD estimate for this mode
diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c
index 745dc31..e4d4746 100644
--- a/vp8/encoder/temporal_filter.c
+++ b/vp8/encoder/temporal_filter.c
@@ -292,7 +292,7 @@
bestsme = cpi->find_fractional_mv_step(x, b, d,
&d->bmi.mv.as_mv, &best_ref_mv1,
x->errorperbit, &cpi->fn_ptr[BLOCK_16X16],
- cpi->mb.mvcost);
+ mvcost);
}
#endif
diff --git a/vp8/encoder/x86/dct_mmx.asm b/vp8/encoder/x86/dct_mmx.asm
index 5acaca8..f07b030 100644
--- a/vp8/encoder/x86/dct_mmx.asm
+++ b/vp8/encoder/x86/dct_mmx.asm
@@ -11,511 +11,231 @@
%include "vpx_ports/x86_abi_support.asm"
-section .text
- global sym(vp8_short_fdct4x4_mmx)
- global sym(vp8_short_fdct8x4_wmt)
-
-
-%define DCTCONSTANTSBITS (16)
-%define DCTROUNDINGVALUE (1<< (DCTCONSTANTSBITS-1))
-%define x_c1 (60547) ; cos(pi /8) * (1<<15)
-%define x_c2 (46341) ; cos(pi*2/8) * (1<<15)
-%define x_c3 (25080) ; cos(pi*3/8) * (1<<15)
-
-
;void vp8_short_fdct4x4_mmx(short *input, short *output, int pitch)
+global sym(vp8_short_fdct4x4_mmx)
sym(vp8_short_fdct4x4_mmx):
push rbp
- mov rbp, rsp
+ mov rbp, rsp
SHADOW_ARGS_TO_STACK 3
GET_GOT rbx
- push rsi
- push rdi
+ push rsi
+ push rdi
; end prolog
- mov rsi, arg(0) ;input
- mov rdi, arg(1) ;output
- lea rdx, [GLOBAL(dct_const_mmx)]
- movsxd rax, dword ptr arg(2) ;pitch
+ mov rsi, arg(0) ; input
+ mov rdi, arg(1) ; output
- lea rcx, [rsi + rax*2]
+ movsxd rax, dword ptr arg(2) ;pitch
+
+ lea rcx, [rsi + rax*2]
; read the input data
- movq mm0, [rsi]
- movq mm1, [rsi + rax ]
+ movq mm0, [rsi]
+ movq mm1, [rsi + rax]
- movq mm2, [rcx]
- movq mm3, [rcx + rax]
- ; get the constants
- ;shift to left by 1 for prescision
- psllw mm0, 3
- psllw mm1, 3
+ movq mm2, [rcx]
+ movq mm4, [rcx + rax]
- psllw mm2, 3
- psllw mm3, 3
+ ; transpose for the first stage
+ movq mm3, mm0 ; 00 01 02 03
+ movq mm5, mm2 ; 20 21 22 23
- ; transpose for the second stage
- movq mm4, mm0 ; 00 01 02 03
- movq mm5, mm2 ; 10 11 12 03
+ punpcklwd mm0, mm1 ; 00 10 01 11
+ punpckhwd mm3, mm1 ; 02 12 03 13
- punpcklwd mm0, mm1 ; 00 10 01 11
- punpckhwd mm4, mm1 ; 02 12 03 13
+ punpcklwd mm2, mm4 ; 20 30 21 31
+ punpckhwd mm5, mm4 ; 22 32 23 33
- punpcklwd mm2, mm3 ; 20 30 21 31
- punpckhwd mm5, mm3 ; 22 32 23 33
+ movq mm1, mm0 ; 00 10 01 11
+ punpckldq mm0, mm2 ; 00 10 20 30
+ punpckhdq mm1, mm2 ; 01 11 21 31
- movq mm1, mm0 ; 00 10 01 11
- punpckldq mm0, mm2 ; 00 10 20 30
+ movq mm2, mm3 ; 02 12 03 13
+ punpckldq mm2, mm5 ; 02 12 22 32
- punpckhdq mm1, mm2 ; 01 11 21 31
+ punpckhdq mm3, mm5 ; 03 13 23 33
- movq mm2, mm4 ; 02 12 03 13
- punpckldq mm2, mm5 ; 02 12 22 32
-
- punpckhdq mm4, mm5 ; 03 13 23 33
- movq mm3, mm4
-
+ ; mm0 0
+ ; mm1 1
+ ; mm2 2
+ ; mm3 3
; first stage
- movq mm5, mm0
- movq mm4, mm1
+ movq mm5, mm0
+ movq mm4, mm1
- paddw mm0, mm3 ; a = 0 + 3
- paddw mm1, mm2 ; b = 1 + 2
+ paddw mm0, mm3 ; a1 = 0 + 3
+ paddw mm1, mm2 ; b1 = 1 + 2
- psubw mm4, mm2 ; c = 1 - 2
- psubw mm5, mm3 ; d = 0 - 3
+ psubw mm4, mm2 ; c1 = 1 - 2
+ psubw mm5, mm3 ; d1 = 0 - 3
+ psllw mm5, 3
+ psllw mm4, 3
+
+ psllw mm0, 3
+ psllw mm1, 3
; output 0 and 2
- movq mm6, [rdx + 16] ; c2
- movq mm2, mm0 ; a
+ movq mm2, mm0 ; a1
- paddw mm0, mm1 ; a + b
- psubw mm2, mm1 ; a - b
-
- movq mm1, mm0 ; a + b
- pmulhw mm0, mm6 ; 00 01 02 03
-
- paddw mm0, mm1 ; output 00 01 02 03
- pmulhw mm6, mm2 ; 20 21 22 23
-
- paddw mm2, mm6 ; output 20 21 22 23
+ paddw mm0, mm1 ; op[0] = a1 + b1
+ psubw mm2, mm1 ; op[2] = a1 - b1
; output 1 and 3
- movq mm6, [rdx + 8] ; c1
- movq mm7, [rdx + 24] ; c3
+ ; interleave c1, d1
+ movq mm1, mm5 ; d1
+ punpcklwd mm1, mm4 ; c1 d1
+ punpckhwd mm5, mm4 ; c1 d1
- movq mm1, mm4 ; c
- movq mm3, mm5 ; d
+ movq mm3, mm1
+ movq mm4, mm5
- pmulhw mm1, mm7 ; c * c3
- pmulhw mm3, mm6 ; d * c1
+ pmaddwd mm1, MMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
+ pmaddwd mm4, MMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
- paddw mm3, mm5 ; d * c1 rounded
- paddw mm1, mm3 ; output 10 11 12 13
+ pmaddwd mm3, MMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
+ pmaddwd mm5, MMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
- movq mm3, mm4 ; c
- pmulhw mm5, mm7 ; d * c3
+ paddd mm1, MMWORD PTR[GLOBAL(_14500)]
+ paddd mm4, MMWORD PTR[GLOBAL(_14500)]
+ paddd mm3, MMWORD PTR[GLOBAL(_7500)]
+ paddd mm5, MMWORD PTR[GLOBAL(_7500)]
- pmulhw mm4, mm6 ; c * c1
- paddw mm3, mm4 ; round c* c1
+ psrad mm1, 12 ; (c1 * 2217 + d1 * 5352 + 14500)>>12
+ psrad mm4, 12 ; (c1 * 2217 + d1 * 5352 + 14500)>>12
+ psrad mm3, 12 ; (d1 * 2217 - c1 * 5352 + 7500)>>12
+ psrad mm5, 12 ; (d1 * 2217 - c1 * 5352 + 7500)>>12
- psubw mm5, mm3 ; output 30 31 32 33
- movq mm3, mm5
-
+ packssdw mm1, mm4 ; op[1]
+ packssdw mm3, mm5 ; op[3]
; done with vertical
; transpose for the second stage
- movq mm4, mm0 ; 00 01 02 03
- movq mm5, mm2 ; 10 11 12 03
+ movq mm4, mm0 ; 00 10 20 30
+ movq mm5, mm2 ; 02 12 22 32
- punpcklwd mm0, mm1 ; 00 10 01 11
- punpckhwd mm4, mm1 ; 02 12 03 13
+ punpcklwd mm0, mm1 ; 00 01 10 11
+ punpckhwd mm4, mm1 ; 20 21 30 31
- punpcklwd mm2, mm3 ; 20 30 21 31
- punpckhwd mm5, mm3 ; 22 32 23 33
+ punpcklwd mm2, mm3 ; 02 03 12 13
+ punpckhwd mm5, mm3 ; 22 23 32 33
+ movq mm1, mm0 ; 00 01 10 11
+ punpckldq mm0, mm2 ; 00 01 02 03
- movq mm1, mm0 ; 00 10 01 11
- punpckldq mm0, mm2 ; 00 10 20 30
+ punpckhdq mm1, mm2 ; 01 22 12 13
- punpckhdq mm1, mm2 ; 01 11 21 31
+ movq mm2, mm4 ; 20 31 30 31
+ punpckldq mm2, mm5 ; 20 21 22 23
- movq mm2, mm4 ; 02 12 03 13
- punpckldq mm2, mm5 ; 02 12 22 32
+ punpckhdq mm4, mm5 ; 30 31 32 33
- punpckhdq mm4, mm5 ; 03 13 23 33
- movq mm3, mm4
+ ; mm0 0
+ ; mm1 1
+ ; mm2 2
+ ; mm3 4
+ movq mm5, mm0
+ movq mm3, mm1
- ; first stage
- movq mm5, mm0
- movq mm4, mm1
+ paddw mm0, mm4 ; a1 = 0 + 3
+ paddw mm1, mm2 ; b1 = 1 + 2
- paddw mm0, mm3 ; a = 0 + 3
- paddw mm1, mm2 ; b = 1 + 2
+ psubw mm3, mm2 ; c1 = 1 - 2
+ psubw mm5, mm4 ; d1 = 0 - 3
- psubw mm4, mm2 ; c = 1 - 2
- psubw mm5, mm3 ; d = 0 - 3
+ pxor mm6, mm6 ; zero out for compare
+ pcmpeqw mm6, mm5 ; d1 != 0
+
+ pandn mm6, MMWORD PTR[GLOBAL(_cmp_mask)] ; clear upper,
+ ; and keep bit 0 of lower
; output 0 and 2
- movq mm6, [rdx + 16] ; c2
- movq mm2, mm0 ; a
- paddw mm0, mm1 ; a + b
+ movq mm2, mm0 ; a1
- psubw mm2, mm1 ; a - b
+ paddw mm0, mm1 ; a1 + b1
+ psubw mm2, mm1 ; a1 - b1
- movq mm1, mm0 ; a + b
- pmulhw mm0, mm6 ; 00 01 02 03
+ paddw mm0, MMWORD PTR[GLOBAL(_7w)]
+ paddw mm2, MMWORD PTR[GLOBAL(_7w)]
- paddw mm0, mm1 ; output 00 01 02 03
- pmulhw mm6, mm2 ; 20 21 22 23
+ psraw mm0, 4 ; op[0] = (a1 + b1 + 7)>>4
+ psraw mm2, 4 ; op[8] = (a1 - b1 + 7)>>4
- paddw mm2, mm6 ; output 20 21 22 23
-
+ movq MMWORD PTR[rdi + 0 ], mm0
+ movq MMWORD PTR[rdi + 16], mm2
; output 1 and 3
- movq mm6, [rdx + 8] ; c1
- movq mm7, [rdx + 24] ; c3
+ ; interleave c1, d1
+ movq mm1, mm5 ; d1
+ punpcklwd mm1, mm3 ; c1 d1
+ punpckhwd mm5, mm3 ; c1 d1
- movq mm1, mm4 ; c
- movq mm3, mm5 ; d
+ movq mm3, mm1
+ movq mm4, mm5
- pmulhw mm1, mm7 ; c * c3
- pmulhw mm3, mm6 ; d * c1
+ pmaddwd mm1, MMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
+ pmaddwd mm4, MMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
- paddw mm3, mm5 ; d * c1 rounded
- paddw mm1, mm3 ; output 10 11 12 13
+ pmaddwd mm3, MMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
+ pmaddwd mm5, MMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
- movq mm3, mm4 ; c
- pmulhw mm5, mm7 ; d * c3
+ paddd mm1, MMWORD PTR[GLOBAL(_12000)]
+ paddd mm4, MMWORD PTR[GLOBAL(_12000)]
+ paddd mm3, MMWORD PTR[GLOBAL(_51000)]
+ paddd mm5, MMWORD PTR[GLOBAL(_51000)]
- pmulhw mm4, mm6 ; c * c1
- paddw mm3, mm4 ; round c* c1
+ psrad mm1, 16 ; (c1 * 2217 + d1 * 5352 + 14500)>>16
+ psrad mm4, 16 ; (c1 * 2217 + d1 * 5352 + 14500)>>16
+ psrad mm3, 16 ; (d1 * 2217 - c1 * 5352 + 7500)>>16
+ psrad mm5, 16 ; (d1 * 2217 - c1 * 5352 + 7500)>>16
- psubw mm5, mm3 ; output 30 31 32 33
- movq mm3, mm5
- ; done with vertical
+ packssdw mm1, mm4 ; op[4]
+ packssdw mm3, mm5 ; op[12]
- pcmpeqw mm4, mm4
- pcmpeqw mm5, mm5
- psrlw mm4, 15
- psrlw mm5, 15
+ paddw mm1, mm6 ; op[4] += (d1!=0)
- psllw mm4, 2
- psllw mm5, 2
+ movq MMWORD PTR[rdi + 8 ], mm1
+ movq MMWORD PTR[rdi + 24], mm3
- paddw mm0, mm4
- paddw mm1, mm5
- paddw mm2, mm4
- paddw mm3, mm5
-
- psraw mm0, 3
- psraw mm1, 3
- psraw mm2, 3
- psraw mm3, 3
-
- movq [rdi ], mm0
- movq [rdi+ 8], mm1
- movq [rdi+16], mm2
- movq [rdi+24], mm3
-
- ; begin epilog
- pop rdi
- pop rsi
+ ; begin epilog
+ pop rdi
+ pop rsi
RESTORE_GOT
UNSHADOW_ARGS
pop rbp
ret
-
-;void vp8_short_fdct8x4_wmt(short *input, short *output, int pitch)
-sym(vp8_short_fdct8x4_wmt):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 3
- GET_GOT rbx
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;input
- mov rdi, arg(1) ;output
-
- lea rdx, [GLOBAL(dct_const_xmm)]
- movsxd rax, dword ptr arg(2) ;pitch
-
- lea rcx, [rsi + rax*2]
- ; read the input data
- movdqa xmm0, [rsi]
- movdqa xmm2, [rsi + rax]
-
- movdqa xmm4, [rcx]
- movdqa xmm3, [rcx + rax]
- ; get the constants
- ;shift to left by 1 for prescision
- psllw xmm0, 3
- psllw xmm2, 3
-
- psllw xmm4, 3
- psllw xmm3, 3
-
- ; transpose for the second stage
- movdqa xmm1, xmm0 ; 00 01 02 03 04 05 06 07
- movdqa xmm5, xmm4 ; 20 21 22 23 24 25 26 27
-
- punpcklwd xmm0, xmm2 ; 00 10 01 11 02 12 03 13
- punpckhwd xmm1, xmm2 ; 04 14 05 15 06 16 07 17
-
- punpcklwd xmm4, xmm3 ; 20 30 21 31 22 32 23 33
- punpckhwd xmm5, xmm3 ; 24 34 25 35 26 36 27 37
-
- movdqa xmm2, xmm0 ; 00 10 01 11 02 12 03 13
- punpckldq xmm0, xmm4 ; 00 10 20 30 01 11 21 31
-
- punpckhdq xmm2, xmm4 ; 02 12 22 32 03 13 23 33
-
-
- movdqa xmm4, xmm1 ; 04 14 05 15 06 16 07 17
- punpckldq xmm4, xmm5 ; 04 14 24 34 05 15 25 35
-
- punpckhdq xmm1, xmm5 ; 06 16 26 36 07 17 27 37
- movdqa xmm3, xmm2 ; 02 12 22 32 03 13 23 33
-
- punpckhqdq xmm3, xmm1 ; 03 13 23 33 07 17 27 37
- punpcklqdq xmm2, xmm1 ; 02 12 22 32 06 16 26 36
-
- movdqa xmm1, xmm0 ; 00 10 20 30 01 11 21 31
- punpcklqdq xmm0, xmm4 ; 00 10 20 30 04 14 24 34
-
- punpckhqdq xmm1, xmm4 ; 01 11 21 32 05 15 25 35
-
- ; xmm0 0
- ; xmm1 1
- ; xmm2 2
- ; xmm3 3
-
- ; first stage
- movdqa xmm5, xmm0
- movdqa xmm4, xmm1
-
- paddw xmm0, xmm3 ; a = 0 + 3
- paddw xmm1, xmm2 ; b = 1 + 2
-
- psubw xmm4, xmm2 ; c = 1 - 2
- psubw xmm5, xmm3 ; d = 0 - 3
-
-
- ; output 0 and 2
- movdqa xmm6, [rdx + 32] ; c2
- movdqa xmm2, xmm0 ; a
-
- paddw xmm0, xmm1 ; a + b
- psubw xmm2, xmm1 ; a - b
-
- movdqa xmm1, xmm0 ; a + b
- pmulhw xmm0, xmm6 ; 00 01 02 03
-
- paddw xmm0, xmm1 ; output 00 01 02 03
- pmulhw xmm6, xmm2 ; 20 21 22 23
-
- paddw xmm2, xmm6 ; output 20 21 22 23
-
- ; output 1 and 3
- movdqa xmm6, [rdx + 16] ; c1
- movdqa xmm7, [rdx + 48] ; c3
-
- movdqa xmm1, xmm4 ; c
- movdqa xmm3, xmm5 ; d
-
- pmulhw xmm1, xmm7 ; c * c3
- pmulhw xmm3, xmm6 ; d * c1
-
- paddw xmm3, xmm5 ; d * c1 rounded
- paddw xmm1, xmm3 ; output 10 11 12 13
-
- movdqa xmm3, xmm4 ; c
- pmulhw xmm5, xmm7 ; d * c3
-
- pmulhw xmm4, xmm6 ; c * c1
- paddw xmm3, xmm4 ; round c* c1
-
- psubw xmm5, xmm3 ; output 30 31 32 33
- movdqa xmm3, xmm5
-
-
- ; done with vertical
- ; transpose for the second stage
- movdqa xmm4, xmm2 ; 02 12 22 32 06 16 26 36
- movdqa xmm2, xmm1 ; 01 11 21 31 05 15 25 35
-
- movdqa xmm1, xmm0 ; 00 10 20 30 04 14 24 34
- movdqa xmm5, xmm4 ; 02 12 22 32 06 16 26 36
-
- punpcklwd xmm0, xmm2 ; 00 01 10 11 20 21 30 31
- punpckhwd xmm1, xmm2 ; 04 05 14 15 24 25 34 35
-
- punpcklwd xmm4, xmm3 ; 02 03 12 13 22 23 32 33
- punpckhwd xmm5, xmm3 ; 06 07 16 17 26 27 36 37
-
- movdqa xmm2, xmm0 ; 00 01 10 11 20 21 30 31
- punpckldq xmm0, xmm4 ; 00 01 02 03 10 11 12 13
-
- punpckhdq xmm2, xmm4 ; 20 21 22 23 30 31 32 33
-
-
- movdqa xmm4, xmm1 ; 04 05 14 15 24 25 34 35
- punpckldq xmm4, xmm5 ; 04 05 06 07 14 15 16 17
-
- punpckhdq xmm1, xmm5 ; 24 25 26 27 34 35 36 37
- movdqa xmm3, xmm2 ; 20 21 22 23 30 31 32 33
-
- punpckhqdq xmm3, xmm1 ; 30 31 32 33 34 35 36 37
- punpcklqdq xmm2, xmm1 ; 20 21 22 23 24 25 26 27
-
- movdqa xmm1, xmm0 ; 00 01 02 03 10 11 12 13
- punpcklqdq xmm0, xmm4 ; 00 01 02 03 04 05 06 07
-
- punpckhqdq xmm1, xmm4 ; 10 11 12 13 14 15 16 17
-
- ; first stage
- movdqa xmm5, xmm0
- movdqa xmm4, xmm1
-
- paddw xmm0, xmm3 ; a = 0 + 3
- paddw xmm1, xmm2 ; b = 1 + 2
-
- psubw xmm4, xmm2 ; c = 1 - 2
- psubw xmm5, xmm3 ; d = 0 - 3
-
-
- ; output 0 and 2
- movdqa xmm6, [rdx + 32] ; c2
- movdqa xmm2, xmm0 ; a
-
- paddw xmm0, xmm1 ; a + b
- psubw xmm2, xmm1 ; a - b
-
- movdqa xmm1, xmm0 ; a + b
- pmulhw xmm0, xmm6 ; 00 01 02 03
-
- paddw xmm0, xmm1 ; output 00 01 02 03
- pmulhw xmm6, xmm2 ; 20 21 22 23
-
- paddw xmm2, xmm6 ; output 20 21 22 23
-
- ; output 1 and 3
- movdqa xmm6, [rdx + 16] ; c1
- movdqa xmm7, [rdx + 48] ; c3
-
- movdqa xmm1, xmm4 ; c
- movdqa xmm3, xmm5 ; d
-
- pmulhw xmm1, xmm7 ; c * c3
- pmulhw xmm3, xmm6 ; d * c1
-
- paddw xmm3, xmm5 ; d * c1 rounded
- paddw xmm1, xmm3 ; output 10 11 12 13
-
- movdqa xmm3, xmm4 ; c
- pmulhw xmm5, xmm7 ; d * c3
-
- pmulhw xmm4, xmm6 ; c * c1
- paddw xmm3, xmm4 ; round c* c1
-
- psubw xmm5, xmm3 ; output 30 31 32 33
- movdqa xmm3, xmm5
- ; done with vertical
-
-
- pcmpeqw xmm4, xmm4
- pcmpeqw xmm5, xmm5;
- psrlw xmm4, 15
- psrlw xmm5, 15
-
- psllw xmm4, 2
- psllw xmm5, 2
-
- paddw xmm0, xmm4
- paddw xmm1, xmm5
- paddw xmm2, xmm4
- paddw xmm3, xmm5
-
- psraw xmm0, 3
- psraw xmm1, 3
- psraw xmm2, 3
- psraw xmm3, 3
-
- movq QWORD PTR[rdi ], xmm0
- movq QWORD PTR[rdi+ 8], xmm1
- movq QWORD PTR[rdi+16], xmm2
- movq QWORD PTR[rdi+24], xmm3
-
- psrldq xmm0, 8
- psrldq xmm1, 8
- psrldq xmm2, 8
- psrldq xmm3, 8
-
- movq QWORD PTR[rdi+32], xmm0
- movq QWORD PTR[rdi+40], xmm1
- movq QWORD PTR[rdi+48], xmm2
- movq QWORD PTR[rdi+56], xmm3
- ; begin epilog
- pop rdi
- pop rsi
- RESTORE_GOT
- UNSHADOW_ARGS
- pop rbp
- ret
-
-
SECTION_RODATA
-;static const unsigned int dct1st_stage_rounding_mmx[2] =
-align 16
-dct1st_stage_rounding_mmx:
- times 2 dd 8192
-
-
-;static const unsigned int dct2nd_stage_rounding_mmx[2] =
-align 16
-dct2nd_stage_rounding_mmx:
- times 2 dd 32768
-
-
-;static const short dct_matrix[4][4]=
-align 16
-dct_matrix:
- times 4 dw 23170
-
- dw 30274
- dw 12540
- dw -12540
- dw -30274
-
- dw 23170
- times 2 dw -23170
- dw 23170
-
- dw 12540
- dw -30274
- dw 30274
- dw -12540
-
-
-;static const unsigned short dct_const_mmx[4 * 4]=
-align 16
-dct_const_mmx:
- times 4 dw 0
- times 4 dw 60547
- times 4 dw 46341
- times 4 dw 25080
-
-
-;static const unsigned short dct_const_xmm[8 * 4]=
-align 16
-dct_const_xmm:
- times 8 dw 0
- times 8 dw 60547
- times 8 dw 46341
- times 8 dw 25080
+align 8
+_5352_2217:
+ dw 5352
+ dw 2217
+ dw 5352
+ dw 2217
+align 8
+_2217_neg5352:
+ dw 2217
+ dw -5352
+ dw 2217
+ dw -5352
+align 8
+_cmp_mask:
+ times 4 dw 1
+align 8
+_7w:
+ times 4 dw 7
+align 8
+_14500:
+ times 2 dd 14500
+align 8
+_7500:
+ times 2 dd 7500
+align 8
+_12000:
+ times 2 dd 12000
+align 8
+_51000:
+ times 2 dd 51000
diff --git a/vp8/encoder/x86/dct_sse2.asm b/vp8/encoder/x86/dct_sse2.asm
index 723a78d..652dd98 100644
--- a/vp8/encoder/x86/dct_sse2.asm
+++ b/vp8/encoder/x86/dct_sse2.asm
@@ -11,32 +11,68 @@
%include "vpx_ports/x86_abi_support.asm"
-;void vp8_short_fdct4x4_sse2(short *input, short *output, int pitch)
-global sym(vp8_short_fdct4x4_sse2)
-sym(vp8_short_fdct4x4_sse2):
+%macro STACK_FRAME_CREATE 0
+%if ABI_IS_32BIT
+ %define input rsi
+ %define output rdi
+ %define pitch rax
push rbp
mov rbp, rsp
- SHADOW_ARGS_TO_STACK 3
-;; SAVE_XMM
GET_GOT rbx
push rsi
push rdi
; end prolog
mov rsi, arg(0)
- movsxd rax, DWORD PTR arg(2)
- lea rdi, [rsi + rax*2]
+ mov rdi, arg(1)
- movq xmm0, MMWORD PTR[rsi ] ;03 02 01 00
- movq xmm2, MMWORD PTR[rsi + rax] ;13 12 11 10
- movq xmm1, MMWORD PTR[rsi + rax*2] ;23 22 21 20
- movq xmm3, MMWORD PTR[rdi + rax] ;33 32 31 30
+ movsxd rax, dword ptr arg(2)
+ lea rcx, [rsi + rax*2]
+%else
+ %ifidn __OUTPUT_FORMAT__,x64
+ %define input rcx
+ %define output rdx
+ %define pitch r8
+ %else
+ %define input rdi
+ %define output rsi
+ %define pitch rdx
+ %endif
+%endif
+%endmacro
+
+%macro STACK_FRAME_DESTROY 0
+ %define input
+ %define output
+ %define pitch
+
+%if ABI_IS_32BIT
+ pop rdi
+ pop rsi
+ RESTORE_GOT
+ pop rbp
+%else
+ %ifidn __OUTPUT_FORMAT__,x64
+ %endif
+%endif
+ ret
+%endmacro
+
+;void vp8_short_fdct4x4_sse2(short *input, short *output, int pitch)
+global sym(vp8_short_fdct4x4_sse2)
+sym(vp8_short_fdct4x4_sse2):
+
+ STACK_FRAME_CREATE
+
+ movq xmm0, MMWORD PTR[input ] ;03 02 01 00
+ movq xmm2, MMWORD PTR[input+ pitch] ;13 12 11 10
+ lea input, [input+2*pitch]
+ movq xmm1, MMWORD PTR[input ] ;23 22 21 20
+ movq xmm3, MMWORD PTR[input+ pitch] ;33 32 31 30
punpcklqdq xmm0, xmm2 ;13 12 11 10 03 02 01 00
punpcklqdq xmm1, xmm3 ;33 32 31 30 23 22 21 20
- mov rdi, arg(1)
-
movdqa xmm2, xmm0
punpckldq xmm0, xmm1 ;23 22 03 02 21 20 01 00
punpckhdq xmm2, xmm1 ;33 32 13 12 31 30 11 10
@@ -51,6 +87,7 @@
psubw xmm3, xmm1 ;c1 d1 c1 d1 c1 d1 c1 d1
psllw xmm0, 3 ;b1 <<= 3 a1 <<= 3
psllw xmm3, 3 ;c1 <<= 3 d1 <<= 3
+
movdqa xmm1, xmm0
pmaddwd xmm0, XMMWORD PTR[GLOBAL(_mult_add)] ;a1 + b1
pmaddwd xmm1, XMMWORD PTR[GLOBAL(_mult_sub)] ;a1 - b1
@@ -121,17 +158,216 @@
punpcklqdq xmm0, xmm3 ;op[4] op[0]
punpckhqdq xmm1, xmm3 ;op[12] op[8]
- movdqa XMMWORD PTR[rdi + 0], xmm0
- movdqa XMMWORD PTR[rdi + 16], xmm1
+ movdqa XMMWORD PTR[output + 0], xmm0
+ movdqa XMMWORD PTR[output + 16], xmm1
- ; begin epilog
- pop rdi
- pop rsi
- RESTORE_GOT
-;; RESTORE_XMM
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY
+
+;void vp8_short_fdct8x4_sse2(short *input, short *output, int pitch)
+global sym(vp8_short_fdct8x4_sse2)
+sym(vp8_short_fdct8x4_sse2):
+
+ STACK_FRAME_CREATE
+
+ ; read the input data
+ movdqa xmm0, [input ]
+ movdqa xmm2, [input+ pitch]
+ lea input, [input+2*pitch]
+ movdqa xmm4, [input ]
+ movdqa xmm3, [input+ pitch]
+
+ ; transpose for the first stage
+ movdqa xmm1, xmm0 ; 00 01 02 03 04 05 06 07
+ movdqa xmm5, xmm4 ; 20 21 22 23 24 25 26 27
+
+ punpcklwd xmm0, xmm2 ; 00 10 01 11 02 12 03 13
+ punpckhwd xmm1, xmm2 ; 04 14 05 15 06 16 07 17
+
+ punpcklwd xmm4, xmm3 ; 20 30 21 31 22 32 23 33
+ punpckhwd xmm5, xmm3 ; 24 34 25 35 26 36 27 37
+
+ movdqa xmm2, xmm0 ; 00 10 01 11 02 12 03 13
+ punpckldq xmm0, xmm4 ; 00 10 20 30 01 11 21 31
+
+ punpckhdq xmm2, xmm4 ; 02 12 22 32 03 13 23 33
+
+ movdqa xmm4, xmm1 ; 04 14 05 15 06 16 07 17
+ punpckldq xmm4, xmm5 ; 04 14 24 34 05 15 25 35
+
+ punpckhdq xmm1, xmm5 ; 06 16 26 36 07 17 27 37
+ movdqa xmm3, xmm2 ; 02 12 22 32 03 13 23 33
+
+ punpckhqdq xmm3, xmm1 ; 03 13 23 33 07 17 27 37
+ punpcklqdq xmm2, xmm1 ; 02 12 22 32 06 16 26 36
+
+ movdqa xmm1, xmm0 ; 00 10 20 30 01 11 21 31
+ punpcklqdq xmm0, xmm4 ; 00 10 20 30 04 14 24 34
+
+ punpckhqdq xmm1, xmm4 ; 01 11 21 32 05 15 25 35
+
+ ; xmm0 0
+ ; xmm1 1
+ ; xmm2 2
+ ; xmm3 3
+
+ ; first stage
+ movdqa xmm5, xmm0
+ movdqa xmm4, xmm1
+
+ paddw xmm0, xmm3 ; a1 = 0 + 3
+ paddw xmm1, xmm2 ; b1 = 1 + 2
+
+ psubw xmm4, xmm2 ; c1 = 1 - 2
+ psubw xmm5, xmm3 ; d1 = 0 - 3
+
+ psllw xmm5, 3
+ psllw xmm4, 3
+
+ psllw xmm0, 3
+ psllw xmm1, 3
+
+ ; output 0 and 2
+ movdqa xmm2, xmm0 ; a1
+
+ paddw xmm0, xmm1 ; op[0] = a1 + b1
+ psubw xmm2, xmm1 ; op[2] = a1 - b1
+
+ ; output 1 and 3
+ ; interleave c1, d1
+ movdqa xmm1, xmm5 ; d1
+ punpcklwd xmm1, xmm4 ; c1 d1
+ punpckhwd xmm5, xmm4 ; c1 d1
+
+ movdqa xmm3, xmm1
+ movdqa xmm4, xmm5
+
+ pmaddwd xmm1, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
+ pmaddwd xmm4, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
+
+ pmaddwd xmm3, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
+ pmaddwd xmm5, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
+
+ paddd xmm1, XMMWORD PTR[GLOBAL(_14500)]
+ paddd xmm4, XMMWORD PTR[GLOBAL(_14500)]
+ paddd xmm3, XMMWORD PTR[GLOBAL(_7500)]
+ paddd xmm5, XMMWORD PTR[GLOBAL(_7500)]
+
+ psrad xmm1, 12 ; (c1 * 2217 + d1 * 5352 + 14500)>>12
+ psrad xmm4, 12 ; (c1 * 2217 + d1 * 5352 + 14500)>>12
+ psrad xmm3, 12 ; (d1 * 2217 - c1 * 5352 + 7500)>>12
+ psrad xmm5, 12 ; (d1 * 2217 - c1 * 5352 + 7500)>>12
+
+ packssdw xmm1, xmm4 ; op[1]
+ packssdw xmm3, xmm5 ; op[3]
+
+ ; done with vertical
+ ; transpose for the second stage
+ movdqa xmm4, xmm0 ; 00 10 20 30 04 14 24 34
+ movdqa xmm5, xmm2 ; 02 12 22 32 06 16 26 36
+
+ punpcklwd xmm0, xmm1 ; 00 01 10 11 20 21 30 31
+ punpckhwd xmm4, xmm1 ; 04 05 14 15 24 25 34 35
+
+ punpcklwd xmm2, xmm3 ; 02 03 12 13 22 23 32 33
+ punpckhwd xmm5, xmm3 ; 06 07 16 17 26 27 36 37
+
+ movdqa xmm1, xmm0 ; 00 01 10 11 20 21 30 31
+ punpckldq xmm0, xmm2 ; 00 01 02 03 10 11 12 13
+
+ punpckhdq xmm1, xmm2 ; 20 21 22 23 30 31 32 33
+
+ movdqa xmm2, xmm4 ; 04 05 14 15 24 25 34 35
+ punpckldq xmm2, xmm5 ; 04 05 06 07 14 15 16 17
+
+ punpckhdq xmm4, xmm5 ; 24 25 26 27 34 35 36 37
+ movdqa xmm3, xmm1 ; 20 21 22 23 30 31 32 33
+
+ punpckhqdq xmm3, xmm4 ; 30 31 32 33 34 35 36 37
+ punpcklqdq xmm1, xmm4 ; 20 21 22 23 24 25 26 27
+
+ movdqa xmm4, xmm0 ; 00 01 02 03 10 11 12 13
+ punpcklqdq xmm0, xmm2 ; 00 01 02 03 04 05 06 07
+
+ punpckhqdq xmm4, xmm2 ; 10 11 12 13 14 15 16 17
+
+ ; xmm0 0
+ ; xmm1 4
+ ; xmm2 1
+ ; xmm3 3
+
+ movdqa xmm5, xmm0
+ movdqa xmm2, xmm1
+
+ paddw xmm0, xmm3 ; a1 = 0 + 3
+ paddw xmm1, xmm4 ; b1 = 1 + 2
+
+ psubw xmm4, xmm2 ; c1 = 1 - 2
+ psubw xmm5, xmm3 ; d1 = 0 - 3
+
+ pxor xmm6, xmm6 ; zero out for compare
+
+ pcmpeqw xmm6, xmm5 ; d1 != 0
+
+ pandn xmm6, XMMWORD PTR[GLOBAL(_cmp_mask8x4)] ; clear upper,
+ ; and keep bit 0 of lower
+
+ ; output 0 and 2
+ movdqa xmm2, xmm0 ; a1
+
+ paddw xmm0, xmm1 ; a1 + b1
+ psubw xmm2, xmm1 ; a1 - b1
+
+ paddw xmm0, XMMWORD PTR[GLOBAL(_7w)]
+ paddw xmm2, XMMWORD PTR[GLOBAL(_7w)]
+
+ psraw xmm0, 4 ; op[0] = (a1 + b1 + 7)>>4
+ psraw xmm2, 4 ; op[8] = (a1 - b1 + 7)>>4
+
+ ; output 1 and 3
+ ; interleave c1, d1
+ movdqa xmm1, xmm5 ; d1
+ punpcklwd xmm1, xmm4 ; c1 d1
+ punpckhwd xmm5, xmm4 ; c1 d1
+
+ movdqa xmm3, xmm1
+ movdqa xmm4, xmm5
+
+ pmaddwd xmm1, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
+ pmaddwd xmm4, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352
+
+ pmaddwd xmm3, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
+ pmaddwd xmm5, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352
+
+ paddd xmm1, XMMWORD PTR[GLOBAL(_12000)]
+ paddd xmm4, XMMWORD PTR[GLOBAL(_12000)]
+ paddd xmm3, XMMWORD PTR[GLOBAL(_51000)]
+ paddd xmm5, XMMWORD PTR[GLOBAL(_51000)]
+
+ psrad xmm1, 16 ; (c1 * 2217 + d1 * 5352 + 14500)>>16
+ psrad xmm4, 16 ; (c1 * 2217 + d1 * 5352 + 14500)>>16
+ psrad xmm3, 16 ; (d1 * 2217 - c1 * 5352 + 7500)>>16
+ psrad xmm5, 16 ; (d1 * 2217 - c1 * 5352 + 7500)>>16
+
+ packssdw xmm1, xmm4 ; op[4]
+ packssdw xmm3, xmm5 ; op[12]
+
+ paddw xmm1, xmm6 ; op[4] += (d1!=0)
+
+ movdqa xmm4, xmm0
+ movdqa xmm5, xmm2
+
+ punpcklqdq xmm0, xmm1
+ punpckhqdq xmm4, xmm1
+
+ punpcklqdq xmm2, xmm3
+ punpckhqdq xmm5, xmm3
+
+ movdqa XMMWORD PTR[output + 0 ], xmm0
+ movdqa XMMWORD PTR[output + 16], xmm2
+ movdqa XMMWORD PTR[output + 32], xmm4
+ movdqa XMMWORD PTR[output + 48], xmm5
+
+ STACK_FRAME_DESTROY
SECTION_RODATA
align 16
@@ -161,7 +397,9 @@
_cmp_mask:
times 4 dw 1
times 4 dw 0
-
+align 16
+_cmp_mask8x4:
+ times 8 dw 1
align 16
_mult_sub:
dw 1
@@ -176,6 +414,9 @@
_7:
times 4 dd 7
align 16
+_7w:
+ times 8 dw 7
+align 16
_14500:
times 4 dd 14500
align 16
diff --git a/vp8/encoder/x86/dct_x86.h b/vp8/encoder/x86/dct_x86.h
index 05824c6..59a5cb1 100644
--- a/vp8/encoder/x86/dct_x86.h
+++ b/vp8/encoder/x86/dct_x86.h
@@ -24,33 +24,31 @@
extern prototype_fdct(vp8_short_fdct8x4_mmx);
#if !CONFIG_RUNTIME_CPU_DETECT
-#if 0
+
#undef vp8_fdct_short4x4
#define vp8_fdct_short4x4 vp8_short_fdct4x4_mmx
#undef vp8_fdct_short8x4
#define vp8_fdct_short8x4 vp8_short_fdct8x4_mmx
-#endif
#endif
+
#endif
#if HAVE_SSE2
-extern prototype_fdct(vp8_short_fdct8x4_wmt);
+extern prototype_fdct(vp8_short_fdct8x4_sse2);
extern prototype_fdct(vp8_short_walsh4x4_sse2);
extern prototype_fdct(vp8_short_fdct4x4_sse2);
#if !CONFIG_RUNTIME_CPU_DETECT
-#if 1
-/* short SSE2 DCT currently disabled, does not match the MMX version */
+
#undef vp8_fdct_short4x4
#define vp8_fdct_short4x4 vp8_short_fdct4x4_sse2
#undef vp8_fdct_short8x4
#define vp8_fdct_short8x4 vp8_short_fdct8x4_sse2
-#endif
#undef vp8_fdct_fast4x4
#define vp8_fdct_fast4x4 vp8_short_fdct4x4_sse2
@@ -58,7 +56,7 @@
#undef vp8_fdct_fast8x4
#define vp8_fdct_fast8x4 vp8_short_fdct8x4_sse2
-#undef vp8_fdct_walsh_short4x4
+#undef vp8_fdct_walsh_short4x4
#define vp8_fdct_walsh_short4x4 vp8_short_walsh4x4_sse2
#endif
diff --git a/vp8/encoder/x86/sad_sse3.asm b/vp8/encoder/x86/sad_sse3.asm
index 1b7293c..5754175 100644
--- a/vp8/encoder/x86/sad_sse3.asm
+++ b/vp8/encoder/x86/sad_sse3.asm
@@ -8,24 +8,169 @@
; be found in the AUTHORS file in the root of the source tree.
;
-
%include "vpx_ports/x86_abi_support.asm"
-%macro PROCESS_16X2X3 1
-%if %1
- movdqa xmm0, XMMWORD PTR [rsi]
- lddqu xmm5, XMMWORD PTR [rdi]
- lddqu xmm6, XMMWORD PTR [rdi+1]
- lddqu xmm7, XMMWORD PTR [rdi+2]
+%macro STACK_FRAME_CREATE_X3 0
+%if ABI_IS_32BIT
+ %define src_ptr rsi
+ %define src_stride rax
+ %define ref_ptr rdi
+ %define ref_stride rdx
+ %define end_ptr rcx
+ %define ret_var rbx
+ %define result_ptr arg(4)
+ %define max_err arg(4)
+ push rbp
+ mov rbp, rsp
+ push rsi
+ push rdi
+ push rbx
+
+ mov rsi, arg(0) ; src_ptr
+ mov rdi, arg(2) ; ref_ptr
+
+ movsxd rax, dword ptr arg(1) ; src_stride
+ movsxd rdx, dword ptr arg(3) ; ref_stride
+%else
+ %ifidn __OUTPUT_FORMAT__,x64
+ %define src_ptr rcx
+ %define src_stride rdx
+ %define ref_ptr r8
+ %define ref_stride r9
+ %define end_ptr r10
+ %define ret_var r11
+ %define result_ptr [rsp+8+4*8]
+ %define max_err [rsp+8+4*8]
+ %else
+ %define src_ptr rdi
+ %define src_stride rsi
+ %define ref_ptr rdx
+ %define ref_stride rcx
+ %define end_ptr r9
+ %define ret_var r10
+ %define result_ptr r8
+ %define max_err r8
+ %endif
+%endif
+
+%endmacro
+
+%macro STACK_FRAME_DESTROY_X3 0
+ %define src_ptr
+ %define src_stride
+ %define ref_ptr
+ %define ref_stride
+ %define end_ptr
+ %define ret_var
+ %define result_ptr
+ %define max_err
+
+%if ABI_IS_32BIT
+ pop rbx
+ pop rdi
+ pop rsi
+ pop rbp
+%else
+ %ifidn __OUTPUT_FORMAT__,x64
+ %endif
+%endif
+ ret
+%endmacro
+
+%macro STACK_FRAME_CREATE_X4 0
+%if ABI_IS_32BIT
+ %define src_ptr rsi
+ %define src_stride rax
+ %define r0_ptr rcx
+ %define r1_ptr rdx
+ %define r2_ptr rbx
+ %define r3_ptr rdi
+ %define ref_stride rbp
+ %define result_ptr arg(4)
+ push rbp
+ mov rbp, rsp
+ push rsi
+ push rdi
+ push rbx
+
+ push rbp
+ mov rdi, arg(2) ; ref_ptr_base
+
+ LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+
+ mov rsi, arg(0) ; src_ptr
+
+ movsxd rbx, dword ptr arg(1) ; src_stride
+ movsxd rbp, dword ptr arg(3) ; ref_stride
+
+ xchg rbx, rax
+%else
+ %ifidn __OUTPUT_FORMAT__,x64
+ %define src_ptr rcx
+ %define src_stride rdx
+ %define r0_ptr rsi
+ %define r1_ptr r10
+ %define r2_ptr r11
+ %define r3_ptr r8
+ %define ref_stride r9
+ %define result_ptr [rsp+16+4*8]
+ push rsi
+
+ LOAD_X4_ADDRESSES r8, r0_ptr, r1_ptr, r2_ptr, r3_ptr
+ %else
+ %define src_ptr rdi
+ %define src_stride rsi
+ %define r0_ptr r9
+ %define r1_ptr r10
+ %define r2_ptr r11
+ %define r3_ptr rdx
+ %define ref_stride rcx
+ %define result_ptr r8
+
+ LOAD_X4_ADDRESSES rdx, r0_ptr, r1_ptr, r2_ptr, r3_ptr
+
+ %endif
+%endif
+%endmacro
+
+%macro STACK_FRAME_DESTROY_X4 0
+ %define src_ptr
+ %define src_stride
+ %define r0_ptr
+ %define r1_ptr
+ %define r2_ptr
+ %define r3_ptr
+ %define ref_stride
+ %define result_ptr
+
+%if ABI_IS_32BIT
+ pop rbx
+ pop rdi
+ pop rsi
+ pop rbp
+%else
+ %ifidn __OUTPUT_FORMAT__,x64
+ pop rsi
+ %endif
+%endif
+ ret
+%endmacro
+
+%macro PROCESS_16X2X3 5
+%if %1==0
+ movdqa xmm0, XMMWORD PTR [%2]
+ lddqu xmm5, XMMWORD PTR [%3]
+ lddqu xmm6, XMMWORD PTR [%3+1]
+ lddqu xmm7, XMMWORD PTR [%3+2]
psadbw xmm5, xmm0
psadbw xmm6, xmm0
psadbw xmm7, xmm0
%else
- movdqa xmm0, XMMWORD PTR [rsi]
- lddqu xmm1, XMMWORD PTR [rdi]
- lddqu xmm2, XMMWORD PTR [rdi+1]
- lddqu xmm3, XMMWORD PTR [rdi+2]
+ movdqa xmm0, XMMWORD PTR [%2]
+ lddqu xmm1, XMMWORD PTR [%3]
+ lddqu xmm2, XMMWORD PTR [%3+1]
+ lddqu xmm3, XMMWORD PTR [%3+2]
psadbw xmm1, xmm0
psadbw xmm2, xmm0
@@ -35,13 +180,15 @@
paddw xmm6, xmm2
paddw xmm7, xmm3
%endif
- movdqa xmm0, XMMWORD PTR [rsi+rax]
- lddqu xmm1, XMMWORD PTR [rdi+rdx]
- lddqu xmm2, XMMWORD PTR [rdi+rdx+1]
- lddqu xmm3, XMMWORD PTR [rdi+rdx+2]
+ movdqa xmm0, XMMWORD PTR [%2+%4]
+ lddqu xmm1, XMMWORD PTR [%3+%5]
+ lddqu xmm2, XMMWORD PTR [%3+%5+1]
+ lddqu xmm3, XMMWORD PTR [%3+%5+2]
- lea rsi, [rsi+rax*2]
- lea rdi, [rdi+rdx*2]
+%if %1==0 || %1==1
+ lea %2, [%2+%4*2]
+ lea %3, [%3+%5*2]
+%endif
psadbw xmm1, xmm0
psadbw xmm2, xmm0
@@ -52,21 +199,21 @@
paddw xmm7, xmm3
%endmacro
-%macro PROCESS_8X2X3 1
-%if %1
- movq mm0, QWORD PTR [rsi]
- movq mm5, QWORD PTR [rdi]
- movq mm6, QWORD PTR [rdi+1]
- movq mm7, QWORD PTR [rdi+2]
+%macro PROCESS_8X2X3 5
+%if %1==0
+ movq mm0, QWORD PTR [%2]
+ movq mm5, QWORD PTR [%3]
+ movq mm6, QWORD PTR [%3+1]
+ movq mm7, QWORD PTR [%3+2]
psadbw mm5, mm0
psadbw mm6, mm0
psadbw mm7, mm0
%else
- movq mm0, QWORD PTR [rsi]
- movq mm1, QWORD PTR [rdi]
- movq mm2, QWORD PTR [rdi+1]
- movq mm3, QWORD PTR [rdi+2]
+ movq mm0, QWORD PTR [%2]
+ movq mm1, QWORD PTR [%3]
+ movq mm2, QWORD PTR [%3+1]
+ movq mm3, QWORD PTR [%3+2]
psadbw mm1, mm0
psadbw mm2, mm0
@@ -76,13 +223,15 @@
paddw mm6, mm2
paddw mm7, mm3
%endif
- movq mm0, QWORD PTR [rsi+rax]
- movq mm1, QWORD PTR [rdi+rdx]
- movq mm2, QWORD PTR [rdi+rdx+1]
- movq mm3, QWORD PTR [rdi+rdx+2]
+ movq mm0, QWORD PTR [%2+%4]
+ movq mm1, QWORD PTR [%3+%5]
+ movq mm2, QWORD PTR [%3+%5+1]
+ movq mm3, QWORD PTR [%3+%5+2]
- lea rsi, [rsi+rax*2]
- lea rdi, [rdi+rdx*2]
+%if %1==0 || %1==1
+ lea %2, [%2+%4*2]
+ lea %3, [%3+%5*2]
+%endif
psadbw mm1, mm0
psadbw mm2, mm0
@@ -101,115 +250,117 @@
mov %5, [%1+REG_SZ_BYTES*3]
%endmacro
-%macro PROCESS_16X2X4 1
-%if %1
- movdqa xmm0, XMMWORD PTR [rsi]
- lddqu xmm4, XMMWORD PTR [rcx]
- lddqu xmm5, XMMWORD PTR [rdx]
- lddqu xmm6, XMMWORD PTR [rbx]
- lddqu xmm7, XMMWORD PTR [rdi]
+%macro PROCESS_16X2X4 8
+%if %1==0
+ movdqa xmm0, XMMWORD PTR [%2]
+ lddqu xmm4, XMMWORD PTR [%3]
+ lddqu xmm5, XMMWORD PTR [%4]
+ lddqu xmm6, XMMWORD PTR [%5]
+ lddqu xmm7, XMMWORD PTR [%6]
psadbw xmm4, xmm0
psadbw xmm5, xmm0
psadbw xmm6, xmm0
psadbw xmm7, xmm0
%else
- movdqa xmm0, XMMWORD PTR [rsi]
- lddqu xmm1, XMMWORD PTR [rcx]
- lddqu xmm2, XMMWORD PTR [rdx]
- lddqu xmm3, XMMWORD PTR [rbx]
+ movdqa xmm0, XMMWORD PTR [%2]
+ lddqu xmm1, XMMWORD PTR [%3]
+ lddqu xmm2, XMMWORD PTR [%4]
+ lddqu xmm3, XMMWORD PTR [%5]
psadbw xmm1, xmm0
psadbw xmm2, xmm0
psadbw xmm3, xmm0
paddw xmm4, xmm1
- lddqu xmm1, XMMWORD PTR [rdi]
+ lddqu xmm1, XMMWORD PTR [%6]
paddw xmm5, xmm2
paddw xmm6, xmm3
psadbw xmm1, xmm0
paddw xmm7, xmm1
%endif
- movdqa xmm0, XMMWORD PTR [rsi+rax]
- lddqu xmm1, XMMWORD PTR [rcx+rbp]
- lddqu xmm2, XMMWORD PTR [rdx+rbp]
- lddqu xmm3, XMMWORD PTR [rbx+rbp]
+ movdqa xmm0, XMMWORD PTR [%2+%7]
+ lddqu xmm1, XMMWORD PTR [%3+%8]
+ lddqu xmm2, XMMWORD PTR [%4+%8]
+ lddqu xmm3, XMMWORD PTR [%5+%8]
psadbw xmm1, xmm0
psadbw xmm2, xmm0
psadbw xmm3, xmm0
paddw xmm4, xmm1
- lddqu xmm1, XMMWORD PTR [rdi+rbp]
+ lddqu xmm1, XMMWORD PTR [%6+%8]
paddw xmm5, xmm2
paddw xmm6, xmm3
- lea rsi, [rsi+rax*2]
- lea rcx, [rcx+rbp*2]
+%if %1==0 || %1==1
+ lea %2, [%2+%7*2]
+ lea %3, [%3+%8*2]
- lea rdx, [rdx+rbp*2]
- lea rbx, [rbx+rbp*2]
+ lea %4, [%4+%8*2]
+ lea %5, [%5+%8*2]
- lea rdi, [rdi+rbp*2]
-
+ lea %6, [%6+%8*2]
+%endif
psadbw xmm1, xmm0
paddw xmm7, xmm1
%endmacro
-%macro PROCESS_8X2X4 1
-%if %1
- movq mm0, QWORD PTR [rsi]
- movq mm4, QWORD PTR [rcx]
- movq mm5, QWORD PTR [rdx]
- movq mm6, QWORD PTR [rbx]
- movq mm7, QWORD PTR [rdi]
+%macro PROCESS_8X2X4 8
+%if %1==0
+ movq mm0, QWORD PTR [%2]
+ movq mm4, QWORD PTR [%3]
+ movq mm5, QWORD PTR [%4]
+ movq mm6, QWORD PTR [%5]
+ movq mm7, QWORD PTR [%6]
psadbw mm4, mm0
psadbw mm5, mm0
psadbw mm6, mm0
psadbw mm7, mm0
%else
- movq mm0, QWORD PTR [rsi]
- movq mm1, QWORD PTR [rcx]
- movq mm2, QWORD PTR [rdx]
- movq mm3, QWORD PTR [rbx]
+ movq mm0, QWORD PTR [%2]
+ movq mm1, QWORD PTR [%3]
+ movq mm2, QWORD PTR [%4]
+ movq mm3, QWORD PTR [%5]
psadbw mm1, mm0
psadbw mm2, mm0
psadbw mm3, mm0
paddw mm4, mm1
- movq mm1, QWORD PTR [rdi]
+ movq mm1, QWORD PTR [%6]
paddw mm5, mm2
paddw mm6, mm3
psadbw mm1, mm0
paddw mm7, mm1
%endif
- movq mm0, QWORD PTR [rsi+rax]
- movq mm1, QWORD PTR [rcx+rbp]
- movq mm2, QWORD PTR [rdx+rbp]
- movq mm3, QWORD PTR [rbx+rbp]
+ movq mm0, QWORD PTR [%2+%7]
+ movq mm1, QWORD PTR [%3+%8]
+ movq mm2, QWORD PTR [%4+%8]
+ movq mm3, QWORD PTR [%5+%8]
psadbw mm1, mm0
psadbw mm2, mm0
psadbw mm3, mm0
paddw mm4, mm1
- movq mm1, QWORD PTR [rdi+rbp]
+ movq mm1, QWORD PTR [%6+%8]
paddw mm5, mm2
paddw mm6, mm3
- lea rsi, [rsi+rax*2]
- lea rcx, [rcx+rbp*2]
+%if %1==0 || %1==1
+ lea %2, [%2+%7*2]
+ lea %3, [%3+%8*2]
- lea rdx, [rdx+rbp*2]
- lea rbx, [rbx+rbp*2]
+ lea %4, [%4+%8*2]
+ lea %5, [%5+%8*2]
- lea rdi, [rdi+rbp*2]
-
+ lea %6, [%6+%8*2]
+%endif
psadbw mm1, mm0
paddw mm7, mm1
@@ -223,54 +374,39 @@
; int *results)
global sym(vp8_sad16x16x3_sse3)
sym(vp8_sad16x16x3_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;src_ptr
- mov rdi, arg(2) ;ref_ptr
+ STACK_FRAME_CREATE_X3
- movsxd rax, dword ptr arg(1) ;src_stride
- movsxd rdx, dword ptr arg(3) ;ref_stride
+ PROCESS_16X2X3 0, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 2, src_ptr, ref_ptr, src_stride, ref_stride
- PROCESS_16X2X3 1
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
-
- mov rdi, arg(4) ;Results
+ mov rcx, result_ptr
movq xmm0, xmm5
psrldq xmm5, 8
paddw xmm0, xmm5
- movd [rdi], xmm0
+ movd [rcx], xmm0
;-
movq xmm0, xmm6
psrldq xmm6, 8
paddw xmm0, xmm6
- movd [rdi+4], xmm0
+ movd [rcx+4], xmm0
;-
movq xmm0, xmm7
psrldq xmm7, 8
paddw xmm0, xmm7
- movd [rdi+8], xmm0
+ movd [rcx+8], xmm0
- ; begin epilog
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X3
;void int vp8_sad16x8x3_sse3(
; unsigned char *src_ptr,
@@ -280,50 +416,35 @@
; int *results)
global sym(vp8_sad16x8x3_sse3)
sym(vp8_sad16x8x3_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;src_ptr
- mov rdi, arg(2) ;ref_ptr
+ STACK_FRAME_CREATE_X3
- movsxd rax, dword ptr arg(1) ;src_stride
- movsxd rdx, dword ptr arg(3) ;ref_stride
+ PROCESS_16X2X3 0, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_16X2X3 2, src_ptr, ref_ptr, src_stride, ref_stride
- PROCESS_16X2X3 1
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
- PROCESS_16X2X3 0
-
- mov rdi, arg(4) ;Results
+ mov rcx, result_ptr
movq xmm0, xmm5
psrldq xmm5, 8
paddw xmm0, xmm5
- movd [rdi], xmm0
+ movd [rcx], xmm0
;-
movq xmm0, xmm6
psrldq xmm6, 8
paddw xmm0, xmm6
- movd [rdi+4], xmm0
+ movd [rcx+4], xmm0
;-
movq xmm0, xmm7
psrldq xmm7, 8
paddw xmm0, xmm7
- movd [rdi+8], xmm0
+ movd [rcx+8], xmm0
- ; begin epilog
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X3
;void int vp8_sad8x16x3_sse3(
; unsigned char *src_ptr,
@@ -333,40 +454,26 @@
; int *results)
global sym(vp8_sad8x16x3_sse3)
sym(vp8_sad8x16x3_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;src_ptr
- mov rdi, arg(2) ;ref_ptr
+ STACK_FRAME_CREATE_X3
- movsxd rax, dword ptr arg(1) ;src_stride
- movsxd rdx, dword ptr arg(3) ;ref_stride
+ PROCESS_8X2X3 0, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 2, src_ptr, ref_ptr, src_stride, ref_stride
- PROCESS_8X2X3 1
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
+ mov rcx, result_ptr
- mov rdi, arg(4) ;Results
+ punpckldq mm5, mm6
- movd [rdi], mm5
- movd [rdi+4], mm6
- movd [rdi+8], mm7
+ movq [rcx], mm5
+ movd [rcx+8], mm7
- ; begin epilog
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X3
;void int vp8_sad8x8x3_sse3(
; unsigned char *src_ptr,
@@ -376,36 +483,22 @@
; int *results)
global sym(vp8_sad8x8x3_sse3)
sym(vp8_sad8x8x3_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;src_ptr
- mov rdi, arg(2) ;ref_ptr
+ STACK_FRAME_CREATE_X3
- movsxd rax, dword ptr arg(1) ;src_stride
- movsxd rdx, dword ptr arg(3) ;ref_stride
+ PROCESS_8X2X3 0, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 1, src_ptr, ref_ptr, src_stride, ref_stride
+ PROCESS_8X2X3 2, src_ptr, ref_ptr, src_stride, ref_stride
- PROCESS_8X2X3 1
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
- PROCESS_8X2X3 0
+ mov rcx, result_ptr
- mov rdi, arg(4) ;Results
+ punpckldq mm5, mm6
- movd [rdi], mm5
- movd [rdi+4], mm6
- movd [rdi+8], mm7
+ movq [rcx], mm5
+ movd [rcx+8], mm7
- ; begin epilog
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X3
;void int vp8_sad4x4x3_sse3(
; unsigned char *src_ptr,
@@ -415,33 +508,23 @@
; int *results)
global sym(vp8_sad4x4x3_sse3)
sym(vp8_sad4x4x3_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;src_ptr
- mov rdi, arg(2) ;ref_ptr
+ STACK_FRAME_CREATE_X3
- movsxd rax, dword ptr arg(1) ;src_stride
- movsxd rdx, dword ptr arg(3) ;ref_stride
+ movd mm0, DWORD PTR [src_ptr]
+ movd mm1, DWORD PTR [ref_ptr]
- movd mm0, DWORD PTR [rsi]
- movd mm1, DWORD PTR [rdi]
-
- movd mm2, DWORD PTR [rsi+rax]
- movd mm3, DWORD PTR [rdi+rdx]
+ movd mm2, DWORD PTR [src_ptr+src_stride]
+ movd mm3, DWORD PTR [ref_ptr+ref_stride]
punpcklbw mm0, mm2
punpcklbw mm1, mm3
- movd mm4, DWORD PTR [rdi+1]
- movd mm5, DWORD PTR [rdi+2]
+ movd mm4, DWORD PTR [ref_ptr+1]
+ movd mm5, DWORD PTR [ref_ptr+2]
- movd mm2, DWORD PTR [rdi+rdx+1]
- movd mm3, DWORD PTR [rdi+rdx+2]
+ movd mm2, DWORD PTR [ref_ptr+ref_stride+1]
+ movd mm3, DWORD PTR [ref_ptr+ref_stride+2]
psadbw mm1, mm0
@@ -451,29 +534,27 @@
psadbw mm4, mm0
psadbw mm5, mm0
+ lea src_ptr, [src_ptr+src_stride*2]
+ lea ref_ptr, [ref_ptr+ref_stride*2]
+ movd mm0, DWORD PTR [src_ptr]
+ movd mm2, DWORD PTR [ref_ptr]
- lea rsi, [rsi+rax*2]
- lea rdi, [rdi+rdx*2]
-
- movd mm0, DWORD PTR [rsi]
- movd mm2, DWORD PTR [rdi]
-
- movd mm3, DWORD PTR [rsi+rax]
- movd mm6, DWORD PTR [rdi+rdx]
+ movd mm3, DWORD PTR [src_ptr+src_stride]
+ movd mm6, DWORD PTR [ref_ptr+ref_stride]
punpcklbw mm0, mm3
punpcklbw mm2, mm6
- movd mm3, DWORD PTR [rdi+1]
- movd mm7, DWORD PTR [rdi+2]
+ movd mm3, DWORD PTR [ref_ptr+1]
+ movd mm7, DWORD PTR [ref_ptr+2]
psadbw mm2, mm0
paddw mm1, mm2
- movd mm2, DWORD PTR [rdi+rdx+1]
- movd mm6, DWORD PTR [rdi+rdx+2]
+ movd mm2, DWORD PTR [ref_ptr+ref_stride+1]
+ movd mm6, DWORD PTR [ref_ptr+ref_stride+2]
punpcklbw mm3, mm2
punpcklbw mm7, mm6
@@ -484,19 +565,14 @@
paddw mm3, mm4
paddw mm7, mm5
- mov rdi, arg(4) ;Results
- movd [rdi], mm1
+ mov rcx, result_ptr
- movd [rdi+4], mm3
- movd [rdi+8], mm7
+ punpckldq mm1, mm3
+ movq [rcx], mm1
+ movd [rcx+8], mm7
- ; begin epilog
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X3
;unsigned int vp8_sad16x16_sse3(
; unsigned char *src_ptr,
@@ -507,51 +583,40 @@
;%define lddqu movdqu
global sym(vp8_sad16x16_sse3)
sym(vp8_sad16x16_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rbx
- push rsi
- push rdi
- ; end prolog
- mov rsi, arg(0) ;src_ptr
- mov rdi, arg(2) ;ref_ptr
+ STACK_FRAME_CREATE_X3
- movsxd rbx, dword ptr arg(1) ;src_stride
- movsxd rdx, dword ptr arg(3) ;ref_stride
+ lea end_ptr, [src_ptr+src_stride*8]
- lea rcx, [rsi+rbx*8]
-
- lea rcx, [rcx+rbx*8]
+ lea end_ptr, [end_ptr+src_stride*8]
pxor mm7, mm7
-vp8_sad16x16_sse3_loop:
+.vp8_sad16x16_sse3_loop:
- movq rax, mm7
- cmp rax, arg(4)
- jg vp8_sad16x16_early_exit
+ movq ret_var, mm7
+ cmp ret_var, max_err
+ jg .vp8_sad16x16_early_exit
- movq mm0, QWORD PTR [rsi]
- movq mm2, QWORD PTR [rsi+8]
+ movq mm0, QWORD PTR [src_ptr]
+ movq mm2, QWORD PTR [src_ptr+8]
- movq mm1, QWORD PTR [rdi]
- movq mm3, QWORD PTR [rdi+8]
+ movq mm1, QWORD PTR [ref_ptr]
+ movq mm3, QWORD PTR [ref_ptr+8]
- movq mm4, QWORD PTR [rsi+rbx]
- movq mm5, QWORD PTR [rdi+rdx]
+ movq mm4, QWORD PTR [src_ptr+src_stride]
+ movq mm5, QWORD PTR [ref_ptr+ref_stride]
psadbw mm0, mm1
psadbw mm2, mm3
- movq mm1, QWORD PTR [rsi+rbx+8]
- movq mm3, QWORD PTR [rdi+rdx+8]
+ movq mm1, QWORD PTR [src_ptr+src_stride+8]
+ movq mm3, QWORD PTR [ref_ptr+ref_stride+8]
psadbw mm4, mm5
psadbw mm1, mm3
- lea rsi, [rsi+rbx*2]
- lea rdi, [rdi+rdx*2]
+ lea src_ptr, [src_ptr+src_stride*2]
+ lea ref_ptr, [ref_ptr+ref_stride*2]
paddw mm0, mm2
paddw mm4, mm1
@@ -559,20 +624,16 @@
paddw mm7, mm0
paddw mm7, mm4
- cmp rsi, rcx
- jne vp8_sad16x16_sse3_loop
+ cmp src_ptr, end_ptr
+ jne .vp8_sad16x16_sse3_loop
- movq rax, mm7
+ movq ret_var, mm7
-vp8_sad16x16_early_exit:
+.vp8_sad16x16_early_exit:
- ; begin epilog
- pop rdi
- pop rsi
- pop rbx
- UNSHADOW_ARGS
- pop rbp
- ret
+ mov rax, ret_var
+
+ STACK_FRAME_DESTROY_X3
;void vp8_sad16x16x4d_sse3(
; unsigned char *src_ptr,
@@ -582,69 +643,48 @@
; int *results)
global sym(vp8_sad16x16x4d_sse3)
sym(vp8_sad16x16x4d_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- push rbx
- ; end prolog
- push rbp
- mov rdi, arg(2) ; ref_ptr_base
+ STACK_FRAME_CREATE_X4
- LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+ PROCESS_16X2X4 0, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 2, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
- mov rsi, arg(0) ;src_ptr
-
- movsxd rbx, dword ptr arg(1) ;src_stride
- movsxd rbp, dword ptr arg(3) ;ref_stride
-
- xchg rbx, rax
-
- PROCESS_16X2X4 1
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
-
+%if ABI_IS_32BIT
pop rbp
- mov rdi, arg(4) ;Results
+%endif
+ mov rcx, result_ptr
movq xmm0, xmm4
psrldq xmm4, 8
paddw xmm0, xmm4
- movd [rdi], xmm0
+ movd [rcx], xmm0
;-
movq xmm0, xmm5
psrldq xmm5, 8
paddw xmm0, xmm5
- movd [rdi+4], xmm0
+ movd [rcx+4], xmm0
;-
movq xmm0, xmm6
psrldq xmm6, 8
paddw xmm0, xmm6
- movd [rdi+8], xmm0
+ movd [rcx+8], xmm0
;-
movq xmm0, xmm7
psrldq xmm7, 8
paddw xmm0, xmm7
- movd [rdi+12], xmm0
+ movd [rcx+12], xmm0
- ; begin epilog
- pop rbx
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X4
;void vp8_sad16x8x4d_sse3(
; unsigned char *src_ptr,
@@ -654,65 +694,44 @@
; int *results)
global sym(vp8_sad16x8x4d_sse3)
sym(vp8_sad16x8x4d_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- push rbx
- ; end prolog
- push rbp
- mov rdi, arg(2) ; ref_ptr_base
+ STACK_FRAME_CREATE_X4
- LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+ PROCESS_16X2X4 0, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_16X2X4 2, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
- mov rsi, arg(0) ;src_ptr
-
- movsxd rbx, dword ptr arg(1) ;src_stride
- movsxd rbp, dword ptr arg(3) ;ref_stride
-
- xchg rbx, rax
-
- PROCESS_16X2X4 1
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
- PROCESS_16X2X4 0
-
+%if ABI_IS_32BIT
pop rbp
- mov rdi, arg(4) ;Results
+%endif
+ mov rcx, result_ptr
movq xmm0, xmm4
psrldq xmm4, 8
paddw xmm0, xmm4
- movd [rdi], xmm0
+ movd [rcx], xmm0
;-
movq xmm0, xmm5
psrldq xmm5, 8
paddw xmm0, xmm5
- movd [rdi+4], xmm0
+ movd [rcx+4], xmm0
;-
movq xmm0, xmm6
psrldq xmm6, 8
paddw xmm0, xmm6
- movd [rdi+8], xmm0
+ movd [rcx+8], xmm0
;-
movq xmm0, xmm7
psrldq xmm7, 8
paddw xmm0, xmm7
- movd [rdi+12], xmm0
+ movd [rcx+12], xmm0
- ; begin epilog
- pop rbx
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X4
;void int vp8_sad8x16x4d_sse3(
; unsigned char *src_ptr,
@@ -722,50 +741,30 @@
; int *results)
global sym(vp8_sad8x16x4d_sse3)
sym(vp8_sad8x16x4d_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- push rbx
- ; end prolog
- push rbp
- mov rdi, arg(2) ; ref_ptr_base
+ STACK_FRAME_CREATE_X4
- LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+ PROCESS_8X2X4 0, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 2, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
- mov rsi, arg(0) ;src_ptr
-
- movsxd rbx, dword ptr arg(1) ;src_stride
- movsxd rbp, dword ptr arg(3) ;ref_stride
-
- xchg rbx, rax
-
- PROCESS_8X2X4 1
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
-
+%if ABI_IS_32BIT
pop rbp
- mov rdi, arg(4) ;Results
+%endif
+ mov rcx, result_ptr
- movd [rdi], mm4
- movd [rdi+4], mm5
- movd [rdi+8], mm6
- movd [rdi+12], mm7
+ punpckldq mm4, mm5
+ punpckldq mm6, mm7
- ; begin epilog
- pop rbx
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ movq [rcx], mm4
+ movq [rcx+8], mm6
+
+ STACK_FRAME_DESTROY_X4
;void int vp8_sad8x8x4d_sse3(
; unsigned char *src_ptr,
@@ -775,46 +774,26 @@
; int *results)
global sym(vp8_sad8x8x4d_sse3)
sym(vp8_sad8x8x4d_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- push rbx
- ; end prolog
- push rbp
- mov rdi, arg(2) ; ref_ptr_base
+ STACK_FRAME_CREATE_X4
- LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+ PROCESS_8X2X4 0, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 1, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
+ PROCESS_8X2X4 2, src_ptr, r0_ptr, r1_ptr, r2_ptr, r3_ptr, src_stride, ref_stride
- mov rsi, arg(0) ;src_ptr
-
- movsxd rbx, dword ptr arg(1) ;src_stride
- movsxd rbp, dword ptr arg(3) ;ref_stride
-
- xchg rbx, rax
-
- PROCESS_8X2X4 1
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
- PROCESS_8X2X4 0
-
+%if ABI_IS_32BIT
pop rbp
- mov rdi, arg(4) ;Results
+%endif
+ mov rcx, result_ptr
- movd [rdi], mm4
- movd [rdi+4], mm5
- movd [rdi+8], mm6
- movd [rdi+12], mm7
+ punpckldq mm4, mm5
+ punpckldq mm6, mm7
- ; begin epilog
- pop rbx
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ movq [rcx], mm4
+ movq [rcx+8], mm6
+
+ STACK_FRAME_DESTROY_X4
;void int vp8_sad4x4x4d_sse3(
; unsigned char *src_ptr,
@@ -824,43 +803,26 @@
; int *results)
global sym(vp8_sad4x4x4d_sse3)
sym(vp8_sad4x4x4d_sse3):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- push rsi
- push rdi
- push rbx
- ; end prolog
- push rbp
- mov rdi, arg(2) ; ref_ptr_base
+ STACK_FRAME_CREATE_X4
- LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+ movd mm0, DWORD PTR [src_ptr]
+ movd mm1, DWORD PTR [r0_ptr]
- mov rsi, arg(0) ;src_ptr
-
- movsxd rbx, dword ptr arg(1) ;src_stride
- movsxd rbp, dword ptr arg(3) ;ref_stride
-
- xchg rbx, rax
-
- movd mm0, DWORD PTR [rsi]
- movd mm1, DWORD PTR [rcx]
-
- movd mm2, DWORD PTR [rsi+rax]
- movd mm3, DWORD PTR [rcx+rbp]
+ movd mm2, DWORD PTR [src_ptr+src_stride]
+ movd mm3, DWORD PTR [r0_ptr+ref_stride]
punpcklbw mm0, mm2
punpcklbw mm1, mm3
- movd mm4, DWORD PTR [rdx]
- movd mm5, DWORD PTR [rbx]
+ movd mm4, DWORD PTR [r1_ptr]
+ movd mm5, DWORD PTR [r2_ptr]
- movd mm6, DWORD PTR [rdi]
- movd mm2, DWORD PTR [rdx+rbp]
+ movd mm6, DWORD PTR [r3_ptr]
+ movd mm2, DWORD PTR [r1_ptr+ref_stride]
- movd mm3, DWORD PTR [rbx+rbp]
- movd mm7, DWORD PTR [rdi+rbp]
+ movd mm3, DWORD PTR [r2_ptr+ref_stride]
+ movd mm7, DWORD PTR [r3_ptr+ref_stride]
psadbw mm1, mm0
@@ -875,37 +837,40 @@
- lea rsi, [rsi+rax*2]
- lea rcx, [rcx+rbp*2]
+ lea src_ptr, [src_ptr+src_stride*2]
+ lea r0_ptr, [r0_ptr+ref_stride*2]
- lea rdx, [rdx+rbp*2]
- lea rbx, [rbx+rbp*2]
+ lea r1_ptr, [r1_ptr+ref_stride*2]
+ lea r2_ptr, [r2_ptr+ref_stride*2]
- lea rdi, [rdi+rbp*2]
+ lea r3_ptr, [r3_ptr+ref_stride*2]
- movd mm0, DWORD PTR [rsi]
- movd mm2, DWORD PTR [rcx]
+ movd mm0, DWORD PTR [src_ptr]
+ movd mm2, DWORD PTR [r0_ptr]
- movd mm3, DWORD PTR [rsi+rax]
- movd mm7, DWORD PTR [rcx+rbp]
+ movd mm3, DWORD PTR [src_ptr+src_stride]
+ movd mm7, DWORD PTR [r0_ptr+ref_stride]
punpcklbw mm0, mm3
punpcklbw mm2, mm7
- movd mm3, DWORD PTR [rdx]
- movd mm7, DWORD PTR [rbx]
+ movd mm3, DWORD PTR [r1_ptr]
+ movd mm7, DWORD PTR [r2_ptr]
psadbw mm2, mm0
+%if ABI_IS_32BIT
mov rax, rbp
pop rbp
- mov rsi, arg(4) ;Results
+%define ref_stride rax
+%endif
+ mov rsi, result_ptr
paddw mm1, mm2
movd [rsi], mm1
- movd mm2, DWORD PTR [rdx+rax]
- movd mm1, DWORD PTR [rbx+rax]
+ movd mm2, DWORD PTR [r1_ptr+ref_stride]
+ movd mm1, DWORD PTR [r2_ptr+ref_stride]
punpcklbw mm3, mm2
punpcklbw mm7, mm1
@@ -913,8 +878,8 @@
psadbw mm3, mm0
psadbw mm7, mm0
- movd mm2, DWORD PTR [rdi]
- movd mm1, DWORD PTR [rdi+rax]
+ movd mm2, DWORD PTR [r3_ptr]
+ movd mm1, DWORD PTR [r3_ptr+ref_stride]
paddw mm3, mm4
paddw mm7, mm5
@@ -929,10 +894,4 @@
movd [rsi+12], mm2
- ; begin epilog
- pop rbx
- pop rdi
- pop rsi
- UNSHADOW_ARGS
- pop rbp
- ret
+ STACK_FRAME_DESTROY_X4
diff --git a/vp8/encoder/x86/x86_csystemdependent.c b/vp8/encoder/x86/x86_csystemdependent.c
index fb1b37c..7810798 100644
--- a/vp8/encoder/x86/x86_csystemdependent.c
+++ b/vp8/encoder/x86/x86_csystemdependent.c
@@ -18,11 +18,10 @@
#if HAVE_MMX
void vp8_short_fdct8x4_mmx(short *input, short *output, int pitch)
{
- vp8_short_fdct4x4_c(input, output, pitch);
- vp8_short_fdct4x4_c(input + 4, output + 16, pitch);
+ vp8_short_fdct4x4_mmx(input, output, pitch);
+ vp8_short_fdct4x4_mmx(input + 4, output + 16, pitch);
}
-
int vp8_fast_quantize_b_impl_mmx(short *coeff_ptr, short *zbin_ptr,
short *qcoeff_ptr, short *dequant_ptr,
short *scan_mask, short *round_ptr,
@@ -82,12 +81,6 @@
#endif
#if HAVE_SSE2
-void vp8_short_fdct8x4_sse2(short *input, short *output, int pitch)
-{
- vp8_short_fdct4x4_sse2(input, output, pitch);
- vp8_short_fdct4x4_sse2(input + 4, output + 16, pitch);
-}
-
int vp8_fast_quantize_b_impl_sse2(short *coeff_ptr,
short *qcoeff_ptr, short *dequant_ptr,
short *scan_mask, short *round_ptr,
@@ -249,18 +242,11 @@
cpi->rtcd.variance.get8x8var = vp8_get8x8var_mmx;
cpi->rtcd.variance.get16x16var = vp8_get16x16var_mmx;
cpi->rtcd.variance.get4x4sse_cs = vp8_get4x4sse_cs_mmx;
-#if 0 // new fdct
+
cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_mmx;
cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_mmx;
cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_mmx;
cpi->rtcd.fdct.fast8x4 = vp8_short_fdct8x4_mmx;
-#else
- cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_c;
- cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_c;
- cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_c;
- cpi->rtcd.fdct.fast8x4 = vp8_short_fdct8x4_c;
-
-#endif
cpi->rtcd.fdct.walsh_short4x4 = vp8_short_walsh4x4_c;
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 8e50b7f..ed830cc 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -104,6 +104,7 @@
}
+#undef ERROR
#define ERROR(str) do {\
ctx->base.err_detail = str;\
return VPX_CODEC_INVALID_PARAM;\
@@ -132,8 +133,8 @@
const vpx_codec_enc_cfg_t *cfg,
const struct vp8_extracfg *vp8_cfg)
{
- RANGE_CHECK(cfg, g_w, 2, 16384);
- RANGE_CHECK(cfg, g_h, 2, 16384);
+ RANGE_CHECK(cfg, g_w, 1, 16384);
+ RANGE_CHECK(cfg, g_h, 1, 16384);
RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
RANGE_CHECK_HI(cfg, g_profile, 3);
@@ -860,8 +861,16 @@
{
YV12_BUFFER_CONFIG sd;
+ vp8_ppflags_t flags = {0};
- if (0 == vp8_get_preview_raw_frame(ctx->cpi, &sd, ctx->preview_ppcfg.deblocking_level, ctx->preview_ppcfg.noise_level, ctx->preview_ppcfg.post_proc_flag))
+ if (ctx->preview_ppcfg.post_proc_flag)
+ {
+ flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag;
+ flags.deblocking_level = ctx->preview_ppcfg.deblocking_level;
+ flags.noise_level = ctx->preview_ppcfg.noise_level;
+ }
+
+ if (0 == vp8_get_preview_raw_frame(ctx->cpi, &sd, &flags))
{
/*
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index a85cad1..9dd4922 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -65,12 +65,19 @@
vpx_codec_priv_t base;
vpx_codec_mmap_t mmaps[NELEMENTS(vp8_mem_req_segs)-1];
vpx_codec_dec_cfg_t cfg;
- vp8_stream_info_t si;
+ vp8_stream_info_t si;
int defer_alloc;
int decoder_init;
VP8D_PTR pbi;
int postproc_cfg_set;
vp8_postproc_cfg_t postproc_cfg;
+#if CONFIG_POSTPROC_VISUALIZER
+ unsigned int dbg_postproc_flag;
+ int dbg_color_ref_frame_flag;
+ int dbg_color_mb_modes_flag;
+ int dbg_color_b_modes_flag;
+ int dbg_display_mv_flag;
+#endif
vpx_image_t img;
int img_setup;
int img_avail;
@@ -253,8 +260,11 @@
unsigned int data_sz,
vpx_codec_stream_info_t *si)
{
-
vpx_codec_err_t res = VPX_CODEC_OK;
+
+ if(data + data_sz <= data)
+ res = VPX_CODEC_INVALID_PARAM;
+ else
{
/* Parse uncompresssed part of key frame header.
* 3 bytes:- including version, frame type and an offset
@@ -331,7 +341,10 @@
ctx->img_avail = 0;
- /* Determine the stream parameters */
+ /* Determine the stream parameters. Note that we rely on peek_si to
+ * validate that we have a buffer that does not wrap around the top
+ * of the heap.
+ */
if (!ctx->si.h)
res = ctx->base.iface->dec.peek_si(data, data_sz, &ctx->si);
@@ -410,15 +423,27 @@
{
YV12_BUFFER_CONFIG sd;
INT64 time_stamp = 0, time_end_stamp = 0;
- int ppflag = 0;
- int ppdeblocking = 0;
- int ppnoise = 0;
+ vp8_ppflags_t flags = {0};
if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
{
- ppflag = ctx->postproc_cfg.post_proc_flag;
- ppdeblocking = ctx->postproc_cfg.deblocking_level;
- ppnoise = ctx->postproc_cfg.noise_level;
+ flags.post_proc_flag= ctx->postproc_cfg.post_proc_flag
+#if CONFIG_POSTPROC_VISUALIZER
+
+ | ((ctx->dbg_color_ref_frame_flag != 0) ? VP8D_DEBUG_CLR_FRM_REF_BLKS : 0)
+ | ((ctx->dbg_color_mb_modes_flag != 0) ? VP8D_DEBUG_CLR_BLK_MODES : 0)
+ | ((ctx->dbg_color_b_modes_flag != 0) ? VP8D_DEBUG_CLR_BLK_MODES : 0)
+ | ((ctx->dbg_display_mv_flag != 0) ? VP8D_DEBUG_DRAW_MV : 0)
+#endif
+ ;
+ flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
+ flags.noise_level = ctx->postproc_cfg.noise_level;
+#if CONFIG_POSTPROC_VISUALIZER
+ flags.display_ref_frame_flag= ctx->dbg_color_ref_frame_flag;
+ flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
+ flags.display_b_modes_flag = ctx->dbg_color_b_modes_flag;
+ flags.display_mv_flag = ctx->dbg_display_mv_flag;
+#endif
}
if (vp8dx_receive_compressed_data(ctx->pbi, data_sz, data, deadline))
@@ -427,7 +452,7 @@
res = update_error_state(ctx, &pbi->common.error);
}
- if (!res && 0 == vp8dx_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, ppdeblocking, ppnoise, ppflag))
+ if (!res && 0 == vp8dx_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, &flags))
{
/* Align width/height */
unsigned int a_w = (sd.y_width + 15) & ~15;
@@ -640,12 +665,38 @@
#endif
}
+static vpx_codec_err_t vp8_set_dbg_options(vpx_codec_alg_priv_t *ctx,
+ int ctrl_id,
+ va_list args)
+{
+#if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
+ int data = va_arg(args, int);
+
+#define MAP(id, var) case id: var = data; break;
+
+ switch (ctrl_id)
+ {
+ MAP (VP8_SET_DBG_COLOR_REF_FRAME, ctx->dbg_color_ref_frame_flag);
+ MAP (VP8_SET_DBG_COLOR_MB_MODES, ctx->dbg_color_mb_modes_flag);
+ MAP (VP8_SET_DBG_COLOR_B_MODES, ctx->dbg_color_b_modes_flag);
+ MAP (VP8_SET_DBG_DISPLAY_MV, ctx->dbg_display_mv_flag);
+ }
+
+ return VPX_CODEC_OK;
+#else
+ return VPX_CODEC_INCAPABLE;
+#endif
+}
vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
{
- {VP8_SET_REFERENCE, vp8_set_reference},
- {VP8_COPY_REFERENCE, vp8_get_reference},
- {VP8_SET_POSTPROC, vp8_set_postproc},
+ {VP8_SET_REFERENCE, vp8_set_reference},
+ {VP8_COPY_REFERENCE, vp8_get_reference},
+ {VP8_SET_POSTPROC, vp8_set_postproc},
+ {VP8_SET_DBG_COLOR_REF_FRAME, vp8_set_dbg_options},
+ {VP8_SET_DBG_COLOR_MB_MODES, vp8_set_dbg_options},
+ {VP8_SET_DBG_COLOR_B_MODES, vp8_set_dbg_options},
+ {VP8_SET_DBG_DISPLAY_MV, vp8_set_dbg_options},
{ -1, NULL},
};
diff --git a/vpx/vp8.h b/vpx/vp8.h
index d7ed8d8..32c0132 100644
--- a/vpx/vp8.h
+++ b/vpx/vp8.h
@@ -38,9 +38,13 @@
*/
enum vp8_dec_control_id
{
- VP8_SET_REFERENCE = 1, /**< pass in an external frame into decoder to be used as reference frame */
- VP8_COPY_REFERENCE = 2, /**< get a copy of reference frame from the decoder */
- VP8_SET_POSTPROC = 3, /**< set decoder's the post processing settings */
+ VP8_SET_REFERENCE = 1, /**< pass in an external frame into decoder to be used as reference frame */
+ VP8_COPY_REFERENCE = 2, /**< get a copy of reference frame from the decoder */
+ VP8_SET_POSTPROC = 3, /**< set the decoder's post processing settings */
+ VP8_SET_DBG_COLOR_REF_FRAME = 4, /**< set the reference frames to color for each macroblock */
+ VP8_SET_DBG_COLOR_MB_MODES = 5, /**< set which macro block modes to color */
+ VP8_SET_DBG_COLOR_B_MODES = 6, /**< set which blocks modes to color */
+ VP8_SET_DBG_DISPLAY_MV = 7, /**< set which motion vector modes to draw */
VP8_COMMON_CTRL_ID_MAX
};
@@ -50,10 +54,14 @@
*/
enum vp8_postproc_level
{
- VP8_NOFILTERING = 0,
- VP8_DEBLOCK = 1,
- VP8_DEMACROBLOCK = 2,
- VP8_ADDNOISE = 4
+ VP8_NOFILTERING = 0,
+ VP8_DEBLOCK = 1<<0,
+ VP8_DEMACROBLOCK = 1<<1,
+ VP8_ADDNOISE = 1<<2,
+ VP8_DEBUG_TXT_FRAME_INFO = 1<<3, /**< print frame information */
+ VP8_DEBUG_TXT_MBLK_MODES = 1<<4, /**< print macro block modes over each macro block */
+ VP8_DEBUG_TXT_DC_DIFF = 1<<5, /**< print dc diff for each macro block */
+ VP8_DEBUG_TXT_RATE_INFO = 1<<6, /**< print video rate info (encoder only) */
};
/*!\brief post process flags
@@ -65,9 +73,9 @@
typedef struct vp8_postproc_cfg
{
- int post_proc_flag; /**< the types of post processing to be done, should be combination of "vp8_postproc_level" */
- int deblocking_level; /**< the strength of deblocking, valid range [0, 16] */
- int noise_level; /**< the strength of additive noise, valid range [0, 16] */
+ int post_proc_flag; /**< the types of post processing to be done, should be combination of "vp8_postproc_level" */
+ int deblocking_level; /**< the strength of deblocking, valid range [0, 16] */
+ int noise_level; /**< the strength of additive noise, valid range [0, 16] */
} vp8_postproc_cfg_t;
/*!\brief reference frame type
@@ -95,12 +103,16 @@
/*!\brief vp8 decoder control funciton parameter type
*
- * defines the data type for each of VP8 decoder control funciton requires
+ * defines the data type for each of VP8 decoder control function requires
*/
VPX_CTRL_USE_TYPE(VP8_SET_REFERENCE, vpx_ref_frame_t *)
VPX_CTRL_USE_TYPE(VP8_COPY_REFERENCE, vpx_ref_frame_t *)
VPX_CTRL_USE_TYPE(VP8_SET_POSTPROC, vp8_postproc_cfg_t *)
+VPX_CTRL_USE_TYPE(VP8_SET_DBG_COLOR_REF_FRAME, int)
+VPX_CTRL_USE_TYPE(VP8_SET_DBG_COLOR_MB_MODES, int)
+VPX_CTRL_USE_TYPE(VP8_SET_DBG_COLOR_B_MODES, int)
+VPX_CTRL_USE_TYPE(VP8_SET_DBG_DISPLAY_MV, int)
/*! @} - end defgroup vp8 */
diff --git a/vpxdec.c b/vpxdec.c
index 85ab206..dd17963 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -108,11 +108,19 @@
"Enable VP8 demacroblocking, w/ level");
static const arg_def_t pp_debug_info = ARG_DEF(NULL, "pp-debug-info", 1,
"Enable VP8 visible debug info");
-
+static const arg_def_t pp_disp_ref_frame = ARG_DEF(NULL, "pp-dbg-ref-frame", 1,
+ "Display only selected reference frame per macro block");
+static const arg_def_t pp_disp_mb_modes = ARG_DEF(NULL, "pp-dbg-mb-modes", 1,
+ "Display only selected macro block modes");
+static const arg_def_t pp_disp_b_modes = ARG_DEF(NULL, "pp-dbg-b-modes", 1,
+ "Display only selected block modes");
+static const arg_def_t pp_disp_mvs = ARG_DEF(NULL, "pp-dbg-mvs", 1,
+ "Draw only selected motion vectors");
static const arg_def_t *vp8_pp_args[] =
{
&addnoise_level, &deblock, &demacroblock_level, &pp_debug_info,
+ &pp_disp_ref_frame, &pp_disp_mb_modes, &pp_disp_b_modes, &pp_disp_mvs,
NULL
};
#endif
@@ -434,6 +442,8 @@
int is_raw = 0;
vpx_codec_stream_info_t si;
+ si.sz = sizeof(si);
+
if (fread(buf, 1, 32, infile) == 32)
{
int i;
@@ -542,6 +552,7 @@
*fps_den = tstamp / 1000;
return 0;
fail:
+ nestegg_destroy(input->nestegg_ctx);
input->nestegg_ctx = NULL;
rewind(input->infile);
return 1;
@@ -704,6 +715,10 @@
vpx_codec_dec_cfg_t cfg = {0};
#if CONFIG_VP8_DECODER
vp8_postproc_cfg_t vp8_pp_cfg = {0};
+ int vp8_dbg_color_ref_frame = 0;
+ int vp8_dbg_color_mb_modes = 0;
+ int vp8_dbg_color_b_modes = 0;
+ int vp8_dbg_display_mv = 0;
#endif
struct input_ctx input = {0};
@@ -789,6 +804,42 @@
if (level)
vp8_pp_cfg.post_proc_flag |= level;
}
+ else if (arg_match(&arg, &pp_disp_ref_frame, argi))
+ {
+ unsigned int flags = arg_parse_int(&arg);
+ if (flags)
+ {
+ postproc = 1;
+ vp8_dbg_color_ref_frame = flags;
+ }
+ }
+ else if (arg_match(&arg, &pp_disp_mb_modes, argi))
+ {
+ unsigned int flags = arg_parse_int(&arg);
+ if (flags)
+ {
+ postproc = 1;
+ vp8_dbg_color_mb_modes = flags;
+ }
+ }
+ else if (arg_match(&arg, &pp_disp_b_modes, argi))
+ {
+ unsigned int flags = arg_parse_int(&arg);
+ if (flags)
+ {
+ postproc = 1;
+ vp8_dbg_color_b_modes = flags;
+ }
+ }
+ else if (arg_match(&arg, &pp_disp_mvs, argi))
+ {
+ unsigned int flags = arg_parse_int(&arg);
+ if (flags)
+ {
+ postproc = 1;
+ vp8_dbg_display_mv = flags;
+ }
+ }
#endif
else
@@ -878,7 +929,13 @@
}
if(input.kind == WEBM_FILE)
- webm_guess_framerate(&input, &fps_den, &fps_num);
+ if(webm_guess_framerate(&input, &fps_den, &fps_num))
+ {
+ fprintf(stderr, "Failed to guess framerate -- error parsing "
+ "webm file?\n");
+ return EXIT_FAILURE;
+ }
+
/*Note: We can't output an aspect ratio here because IVF doesn't
store one, and neither does VP8.
@@ -922,6 +979,33 @@
return EXIT_FAILURE;
}
+ if (vp8_dbg_color_ref_frame
+ && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_REF_FRAME, vp8_dbg_color_ref_frame))
+ {
+ fprintf(stderr, "Failed to configure reference block visualizer: %s\n", vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+
+ if (vp8_dbg_color_mb_modes
+ && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_MB_MODES, vp8_dbg_color_mb_modes))
+ {
+ fprintf(stderr, "Failed to configure macro block visualizer: %s\n", vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+
+ if (vp8_dbg_color_b_modes
+ && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_B_MODES, vp8_dbg_color_b_modes))
+ {
+ fprintf(stderr, "Failed to configure block visualizer: %s\n", vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+
+ if (vp8_dbg_display_mv
+ && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv))
+ {
+ fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
#endif
/* Decode file */
diff --git a/vpxenc.c b/vpxenc.c
index 032e2e8..0ae391f 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -251,7 +251,8 @@
struct detect_buffer {
char buf[4];
- int valid;
+ size_t buf_read;
+ size_t position;
};
@@ -305,14 +306,21 @@
for (r = 0; r < h; r++)
{
- if (detect->valid)
+ size_t needed = w;
+ size_t buf_position = 0;
+ const size_t left = detect->buf_read - detect->position;
+ if (left > 0)
{
- memcpy(ptr, detect->buf, 4);
- shortread |= fread(ptr+4, 1, w-4, f) < w-4;
- detect->valid = 0;
+ const size_t more = (left < needed) ? left : needed;
+ memcpy(ptr, detect->buf + detect->position, more);
+ buf_position = more;
+ needed -= more;
+ detect->position += more;
}
- else
- shortread |= fread(ptr, 1, w, f) < w;
+ if (needed > 0)
+ {
+ shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
+ }
ptr += img->stride[plane];
}
@@ -435,7 +443,7 @@
int debug;
FILE *stream;
- uint64_t last_pts_ms;
+ int64_t last_pts_ms;
vpx_rational_t framerate;
/* These pointers are to the start of an element */
@@ -648,7 +656,7 @@
unsigned char track_number;
unsigned short block_timecode = 0;
unsigned char flags;
- uint64_t pts_ms;
+ int64_t pts_ms;
int start_cluster = 0, is_keyframe;
/* Calculate the PTS of this frame in milliseconds */
@@ -1074,6 +1082,7 @@
int psnr_count = 0;
exec_name = argv_[0];
+ ebml.last_pts_ms = -1;
if (argc < 3)
usage_exit();
@@ -1188,7 +1197,7 @@
/* Change the default timebase to a high enough value so that the encoder
* will always create strictly increasing timestamps.
*/
- cfg.g_timebase.den = 100000;
+ cfg.g_timebase.den = 1000;
/* Never use the library's default resolution, require it be parsed
* from the file or set on the command line.
@@ -1337,7 +1346,6 @@
{
int frames_in = 0, frames_out = 0;
unsigned long nbytes = 0;
- size_t detect_bytes;
struct detect_buffer detect;
/* Parse certain options from the input file, if possible */
@@ -1352,13 +1360,11 @@
/* For RAW input sources, these bytes will applied on the first frame
* in read_frame().
- * We can always read 4 bytes because the minimum supported frame size
- * is 2x2.
*/
- detect_bytes = fread(detect.buf, 1, 4, infile);
- detect.valid = 0;
+ detect.buf_read = fread(detect.buf, 1, 4, infile);
+ detect.position = 0;
- if (detect_bytes == 4 && file_is_y4m(infile, &y4m, detect.buf))
+ if (detect.buf_read == 4 && file_is_y4m(infile, &y4m, detect.buf))
{
if (y4m_input_open(&y4m, infile, detect.buf, 4) >= 0)
{
@@ -1383,7 +1389,7 @@
return EXIT_FAILURE;
}
}
- else if (detect_bytes == 4 &&
+ else if (detect.buf_read == 4 &&
file_is_ivf(infile, &fourcc, &cfg.g_w, &cfg.g_h, detect.buf))
{
file_type = FILE_TYPE_IVF;
@@ -1403,7 +1409,6 @@
else
{
file_type = FILE_TYPE_RAW;
- detect.valid = 1;
}
if(!cfg.g_w || !cfg.g_h)
@@ -1544,7 +1549,7 @@
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt;
struct vpx_usec_timer timer;
- int64_t frame_start;
+ int64_t frame_start, next_frame_start;
if (!arg_limit || frames_in < arg_limit)
{
@@ -1565,9 +1570,11 @@
frame_start = (cfg.g_timebase.den * (int64_t)(frames_in - 1)
* arg_framerate.den) / cfg.g_timebase.num / arg_framerate.num;
+ next_frame_start = (cfg.g_timebase.den * (int64_t)(frames_in)
+ * arg_framerate.den)
+ / cfg.g_timebase.num / arg_framerate.num;
vpx_codec_encode(&encoder, frame_avail ? &raw : NULL, frame_start,
- cfg.g_timebase.den * arg_framerate.den
- / cfg.g_timebase.num / arg_framerate.num,
+ next_frame_start - frame_start,
0, arg_deadline);
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);