[x264-devel] Enhance mb_info: add mb_info_update
Jason Garrett-Glaser
git at videolan.org
Wed Sep 5 21:07:22 CEST 2012
x264 | branch: master | Jason Garrett-Glaser <jason at x264.com> | Thu Aug 16 13:40:32 2012 -0700| [198a7ea13ccb727d4ea24b29f5da9b0292387309] | committer: Jason Garrett-Glaser
Enhance mb_info: add mb_info_update
This feature lets the callee know which decoded macroblocks have changed.
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=198a7ea13ccb727d4ea24b29f5da9b0292387309
---
encoder/analyse.c | 70 +++++++++++++++++++++++++++++------------------------
x264.h | 20 ++++++++++++---
2 files changed, 55 insertions(+), 35 deletions(-)
diff --git a/encoder/analyse.c b/encoder/analyse.c
index d396cc4..0577b7a 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -3047,43 +3047,49 @@ intra_analysis:
else
{
/* Special fast-skip logic using information from mb_info. */
- if( h->fdec->mb_info && !SLICE_MBAFF && (h->fdec->mb_info[h->mb.i_mb_xy]&X264_MBINFO_CONSTANT) &&
- (h->fdec->i_frame - h->fref[0][0]->i_frame) == 1 && !h->sh.b_weighted_pred &&
- h->fref[0][0]->effective_qp[h->mb.i_mb_xy] <= h->mb.i_qp )
- {
- /* Use the P-SKIP MV if we can... */
- if( !M32(h->mb.cache.pskip_mv) )
- b_skip = 1;
- /* Otherwise, just force a 16x16 block. */
- else
+ if( h->fdec->mb_info && (h->fdec->mb_info[h->mb.i_mb_xy]&X264_MBINFO_CONSTANT) )
+ {
+ if( !SLICE_MBAFF && (h->fdec->i_frame - h->fref[0][0]->i_frame) == 1 && !h->sh.b_weighted_pred &&
+ h->fref[0][0]->effective_qp[h->mb.i_mb_xy] <= h->mb.i_qp )
{
- h->mb.i_type = P_L0;
h->mb.i_partition = D_16x16;
- analysis.l0.me16x16.i_ref = 0;
- M32( analysis.l0.me16x16.mv ) = 0;
+ /* Use the P-SKIP MV if we can... */
+ if( !M32(h->mb.cache.pskip_mv) )
+ {
+ b_skip = 1;
+ h->mb.i_type = P_SKIP;
+ }
+ /* Otherwise, just force a 16x16 block. */
+ else
+ {
+ h->mb.i_type = P_L0;
+ analysis.l0.me16x16.i_ref = 0;
+ M32( analysis.l0.me16x16.mv ) = 0;
+ }
goto skip_analysis;
}
+ /* Reset the information accordingly */
+ else if( h->param.analyse.b_mb_info_update )
+ h->fdec->mb_info[h->mb.i_mb_xy] &= ~X264_MBINFO_CONSTANT;
}
- else
- {
- int skip_invalid = h->i_thread_frames > 1 && h->mb.cache.pskip_mv[1] > h->mb.mv_max_spel[1];
- /* If the current macroblock is off the frame, just skip it. */
- if( HAVE_INTERLACED && !MB_INTERLACED && h->mb.i_mb_y * 16 >= h->param.i_height && !skip_invalid )
- b_skip = 1;
- /* Fast P_SKIP detection */
- else if( h->param.analyse.b_fast_pskip )
- {
- if( skip_invalid )
- // FIXME don't need to check this if the reference frame is done
- {}
- else if( h->param.analyse.i_subpel_refine >= 3 )
- analysis.b_try_skip = 1;
- else if( h->mb.i_mb_type_left[0] == P_SKIP ||
- h->mb.i_mb_type_top == P_SKIP ||
- h->mb.i_mb_type_topleft == P_SKIP ||
- h->mb.i_mb_type_topright == P_SKIP )
- b_skip = x264_macroblock_probe_pskip( h );
- }
+
+ int skip_invalid = h->i_thread_frames > 1 && h->mb.cache.pskip_mv[1] > h->mb.mv_max_spel[1];
+ /* If the current macroblock is off the frame, just skip it. */
+ if( HAVE_INTERLACED && !MB_INTERLACED && h->mb.i_mb_y * 16 >= h->param.i_height && !skip_invalid )
+ b_skip = 1;
+ /* Fast P_SKIP detection */
+ else if( h->param.analyse.b_fast_pskip )
+ {
+ if( skip_invalid )
+ // FIXME don't need to check this if the reference frame is done
+ {}
+ else if( h->param.analyse.i_subpel_refine >= 3 )
+ analysis.b_try_skip = 1;
+ else if( h->mb.i_mb_type_left[0] == P_SKIP ||
+ h->mb.i_mb_type_top == P_SKIP ||
+ h->mb.i_mb_type_topleft == P_SKIP ||
+ h->mb.i_mb_type_topright == P_SKIP )
+ b_skip = x264_macroblock_probe_pskip( h );
}
}
diff --git a/x264.h b/x264.h
index 7648c96..8e96b7c 100644
--- a/x264.h
+++ b/x264.h
@@ -41,7 +41,7 @@
#include "x264_config.h"
-#define X264_BUILD 127
+#define X264_BUILD 128
/* Application developers planning to link against a shared library version of
* libx264 from a Microsoft Visual Studio or similar development environment
@@ -365,7 +365,8 @@ typedef struct x264_param_t
float f_psy_trellis; /* Psy trellis strength */
int b_psy; /* Toggle all psy optimizations */
- int b_mb_info; /* Use input mb_info data in x264_picture_t */
+ int b_mb_info; /* Use input mb_info data in x264_picture_t */
+ int b_mb_info_update; /* Update the values in mb_info according to the results of encoding. */
/* the deadzone size that will be used in luma quantization */
int i_luma_deadzone[2]; /* {inter, intra} */
@@ -718,7 +719,20 @@ typedef struct
* Allows specifying additional information for the encoder such as which macroblocks
* remain unchanged. Usable flags are listed below.
* x264_param_t.analyse.b_mb_info must be set to use this, since x264 needs to track
- * extra data internally to make full use of this information. */
+ * extra data internally to make full use of this information.
+ *
+ * Out: if b_mb_info_update is set, x264 will update this array as a result of encoding.
+ *
+ * For "MBINFO_CONSTANT", it will remove this flag on any macroblock whose decoded
+ * pixels have changed. This can be useful for e.g. noting which areas of the
+ * frame need to actually be blitted. Note: this intentionally ignores the effects
+ * of deblocking for the current frame, which should be fine unless one needs exact
+ * pixel-perfect accuracy.
+ *
+ * Results for MBINFO_CONSTANT are currently only set for P-frames, and are not
+ * guaranteed to enumerate all blocks which haven't changed. (There may be false
+ * negatives, but no false positives.)
+ */
uint8_t *mb_info;
/* In: optional callback to free mb_info when used. */
void (*mb_info_free)( void* );
More information about the x264-devel
mailing list