[x264-devel] Re: [PATCH] set a valid value in direct_8x8_inference_flag
Loïc Le Loarer
lll+vlc at m4x.org
Sat May 20 02:45:58 CEST 2006
Hi,
Here is patch which implement the following proposal.
I also contains the previous direct_8x8_inference_flag patch I sent.
Best regards.
--
Loïc
Le Saturday 20 May 2006 à 00:24:02 +0200, Loïc Le Loarer a écrit:
> Le Friday 19 May 2006 à 13:13:29 -0700, Loren Merritt a écrit:
> > On Fri, 19 May 2006, Loïc Le Loarer wrote:
> > >Le Thursday 11 May 2006 à 19:44:55 +0200, Loïc Le Loarer a écrit:
> > >>This patch avoids to produce invalid streams by enforcing the level
> > >>restrictions on direct_8x8_inference_flag value. It also allows the
> > >>application to ask for a given value of direct_8x8_inference_flag.
>
> Thank you for taking time to take at look and answer.
>
> > The option is ok, but the default value needs quality testing. If 8x8
> > inference measurably reduces quality, then I will leave it off by
> > default, even if that violates levels.
>
> Ok, I see your point of view, but the respect of the level contraints
> are essential in my point of view, because they are used by decoders to
> compute worst case senarii in term of memory, bandwidth, computing
> ressources... and so be sure that they can decode any stream respecting
> a given profile and level in real time. Producing invalid streams breaks
> interoperability and should be avoided. I propose that the default
> options always produce a valid stream and that some levels constraints
> can be ignored only with a special option and a big fat warning.
>
> More precisely, I propose that only the constraints which cannot be
> removed by using a higher level _and_ can improve encoding quality, can
> be violated (if explicitly asked only, not by default). If I read the
> spec correctly, the candidates are: MaxMvsPer2Mb (not checked yet but
> not relevant), direct_8x8_inference_flag, frame_mbs_only_flag (not
> relevant yet), MinLumaBiPredSize (not relevant yet) and SliceRate (not
> checked yet but not really a problem given the usage of slices). So only
> direct_8x8_inference_flag needs to be evaluated for the moment and
> you are working on it.
>
> All the other constraints (MB rate, MaxFS, DPB size, MaxBR, MaxCPB,
> MaxVmvR, MinCR (not yet checked, may be a problem for lossless mode))
> should be enforced and the CHECK macro in x264_validate_levels should
> return an error in such a condition, asking for a bigger level.
>
> This way:
> - someone using the default values (level=5.1) will still be nearly
> unconstrainted and produce a valid bitstream
> - someone who cares about interoperability and sets a level (and other
> parameters like direct_8x8_inference_flag) will be confident that x264
> will respect the level contraints and produce a valid bitstream or
> refuse to encode at the given level
> - and someone who knows what he does, control the decoder which will be
> used to decode his stream (and so can break interoperability) and
> really want to break the limits to increase quality will be able to
> do it too.
>
> I will try to give a patch which explain more clearly this.
>
> > The mv range thing is probably ok, I'll review it sometime.
> Thank you.
>
> Best regards.
>
> --
> Loïc
>
> "heaven is not a place, it's a feeling"
-------------- next part --------------
Index: encoder/set.h
===================================================================
--- encoder/set.h (révision 525)
+++ encoder/set.h (copie de travail)
@@ -29,6 +29,6 @@
void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *sps );
void x264_pps_write( bs_t *s, x264_pps_t *pps );
void x264_sei_version_write( x264_t *h, bs_t *s );
-void x264_validate_levels( x264_t *h );
+int x264_validate_levels( x264_t *h );
#endif
Index: encoder/encoder.c
===================================================================
--- encoder/encoder.c (révision 525)
+++ encoder/encoder.c (copie de travail)
@@ -431,6 +431,26 @@
h->param.analyse.i_mv_range = l->mv_range;
else
h->param.analyse.i_mv_range = x264_clip3(h->param.analyse.i_mv_range, 32, 2048);
+ /* Validate direct_8x8_inference_flag: */
+ if( h->param.i_direct_8x8_inference_flag < 0 )
+ {
+ /* The flag isn't forced, set it to 0 if the level doesn't
+ * limit it to 1 and it it possible to generate P macroblocks
+ * with partitions smaller than 8x8 */
+ h->param.i_direct_8x8_inference_flag = l->direct8x8 ? 1 : !(h->param.analyse.inter & X264_ANALYSE_PSUB8x8);
+ }
+ else
+ {
+ h->param.i_direct_8x8_inference_flag = x264_clip3( h->param.i_direct_8x8_inference_flag, 0, 1 );
+ /* if the level limits this flag to 1, check it isn't forced to 0 */
+ if (h->param.i_direct_8x8_inference_flag < l->direct8x8)
+ {
+ x264_log( h, X264_LOG_ERROR, "invalid direct_8x8_inference_flag %d for level %d\n", h->param.i_direct_8x8_inference_flag, h->param.i_level_idc );
+ if (!h->param.b_allow_invalid_bitstreams) {
+ return -1;
+ }
+ }
+ }
}
if( h->param.rc.f_qblur < 0 )
@@ -536,7 +556,11 @@
h->pps = &h->pps_array[0];
x264_pps_init( h->pps, h->param.i_sps_id, &h->param, h->sps);
- x264_validate_levels( h );
+ if (x264_validate_levels( h ) < 0)
+ {
+ x264_free( h );
+ return NULL;
+ }
x264_cqm_init( h );
Index: encoder/set.c
===================================================================
--- encoder/set.c (révision 525)
+++ encoder/set.c (copie de travail)
@@ -130,13 +130,7 @@
sps->i_mb_height= ( param->i_height + 15 )/ 16;
sps->b_frame_mbs_only = 1;
sps->b_mb_adaptive_frame_field = 0;
- sps->b_direct8x8_inference = 0;
- if( sps->b_frame_mbs_only == 0 ||
- !(param->analyse.inter & X264_ANALYSE_PSUB8x8) )
- {
- sps->b_direct8x8_inference = 1;
- }
-
+ sps->b_direct8x8_inference = param->i_direct_8x8_inference_flag;
sps->crop.i_left = 0;
sps->crop.i_top = 0;
sps->crop.i_right = (- param->i_width) & 15;
@@ -518,7 +512,7 @@
{ 0 }
};
-void x264_validate_levels( x264_t *h )
+int x264_validate_levels( x264_t *h )
{
int mbs;
@@ -530,12 +524,20 @@
if( l->frame_size < mbs
|| l->frame_size*8 < h->sps->i_mb_width * h->sps->i_mb_width
|| l->frame_size*8 < h->sps->i_mb_height * h->sps->i_mb_height )
- x264_log( h, X264_LOG_WARNING, "frame MB size (%dx%d) > level limit (%d)\n",
+ {
+ x264_log( h, X264_LOG_ERROR, "frame MB size (%dx%d) > level limit (%d)\n",
h->sps->i_mb_width, h->sps->i_mb_height, l->frame_size );
+ if (!h->param.b_allow_invalid_bitstreams)
+ return -1;
+ }
#define CHECK( name, limit, val ) \
if( (val) > (limit) ) \
- x264_log( h, X264_LOG_WARNING, name " (%d) > level limit (%d)\n", (int)(val), (limit) );
+ { \
+ x264_log( h, X264_LOG_ERROR, name " (%d) > level limit (%d), try increase level\n", (int)(val), (limit) ); \
+ if (!h->param.b_allow_invalid_bitstreams) \
+ return -1; \
+ }
CHECK( "DPB size", l->dpb, mbs * 384 * h->sps->i_num_ref_frames );
CHECK( "VBV bitrate", l->bitrate, h->param.rc.i_vbv_max_bitrate );
Index: x264.c
===================================================================
--- x264.c (révision 525)
+++ x264.c (copie de travail)
@@ -202,6 +202,10 @@
" (p4x4 requires p8x8. i8x8 requires --8x8dct.)\n"
" --direct <string> Direct MV prediction mode [\"%s\"]\n"
" - none, spatial, temporal, auto\n"
+ " --direct_8x8 <-1|0|1> Direct prediction size [%d]\n"
+ " - 0: 4x4\n"
+ " - 1: 8x8\n"
+ " - -1: smallest possible according to level\n"
" -w, --weightb Weighted prediction for B-frames\n"
" --me <string> Integer pixel motion estimation method [\"%s\"]\n"
" - dia: diamond search, radius 1 (fast)\n"
@@ -314,6 +318,7 @@
defaults->rc.f_complexity_blur,
defaults->rc.f_qblur,
strtable_lookup( x264_direct_pred_names, defaults->analyse.i_direct_mv_pred ),
+ defaults->i_direct_8x8_inference_flag,
strtable_lookup( x264_motion_est_names, defaults->analyse.i_me_method ),
defaults->analyse.i_me_range,
defaults->analyse.i_subpel_refine,
@@ -452,6 +457,7 @@
#define OPT_THREAD_INPUT 320
#define OPT_NO_DCT_DECIMATE 321
#define OPT_SPS_ID 322
+#define OPT_DIRECT_8X8 323
static struct option long_options[] =
{
@@ -481,6 +487,7 @@
{ "output", required_argument, NULL, 'o' },
{ "analyse", required_argument, NULL, 'A' },
{ "direct", required_argument, NULL, OPT_DIRECT },
+ { "direct_8x8", required_argument, NULL, OPT_DIRECT_8X8 },
{ "weightb", no_argument, NULL, 'w' },
{ "me", required_argument, NULL, OPT_ME },
{ "merange", required_argument, NULL, OPT_MERANGE },
@@ -703,6 +710,9 @@
case OPT_DIRECT:
b_error |= parse_enum( optarg, x264_direct_pred_names, ¶m->analyse.i_direct_mv_pred );
break;
+ case OPT_DIRECT_8X8:
+ param->i_direct_8x8_inference_flag = atoi(optarg);
+ break;
case 'w':
param->analyse.b_weighted_bipred = 1;
break;
Index: common/common.c
===================================================================
--- common/common.c (révision 525)
+++ common/common.c (copie de travail)
@@ -72,6 +72,7 @@
param->b_bframe_adaptive = 1;
param->i_bframe_bias = 0;
param->b_bframe_pyramid = 0;
+ param->i_direct_8x8_inference_flag = -1;
param->b_deblocking_filter = 1;
param->i_deblocking_filter_alphac0 = 0;
@@ -132,6 +133,7 @@
memset( param->cqm_8iy, 16, 64 );
memset( param->cqm_8py, 16, 64 );
+ param->b_allow_invalid_bitstreams = 0;
param->b_repeat_headers = 1;
param->b_aud = 0;
}
@@ -485,10 +487,10 @@
s += sprintf( s, " bframes=%d", p->i_bframe );
if( p->i_bframe )
{
- s += sprintf( s, " b_pyramid=%d b_adapt=%d b_bias=%d direct=%d wpredb=%d bime=%d",
+ s += sprintf( s, " b_pyramid=%d b_adapt=%d b_bias=%d direct=%d d8x8=%d wpredb=%d bime=%d",
p->b_bframe_pyramid, p->b_bframe_adaptive, p->i_bframe_bias,
- p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred,
- p->analyse.b_bidir_me );
+ p->analyse.i_direct_mv_pred, p->i_direct_8x8_inference_flag,
+ p->analyse.b_weighted_bipred, p->analyse.b_bidir_me );
}
s += sprintf( s, " keyint=%d keyint_min=%d scenecut=%d",
Index: x264.h
===================================================================
--- x264.h (révision 525)
+++ x264.h (copie de travail)
@@ -159,6 +159,7 @@
int b_bframe_adaptive;
int i_bframe_bias;
int b_bframe_pyramid; /* Keep some B-frames as references */
+ int i_direct_8x8_inference_flag; /* Use direct_8x8_inference_flag in SPS: (-1: 0 if possible according to level and partition mode) */
int b_deblocking_filter;
int i_deblocking_filter_alphac0; /* [-6, 6] -6 light filter, 6 strong */
@@ -243,6 +244,15 @@
char *psz_zones; /* alternate method of specifying zones */
} rc;
+ /* b_allow_invalid_bitstreams allow produce invalid bitstream by violating
+ * certains level contraints.
+ *
+ * this breaks interoperability so it should never be set except if you
+ * know in advance which decoder will decode the produced streams and you
+ * know that this decoder support the constraints which are not respected.
+ * */
+ int b_allow_invalid_bitstreams;
+
/* Muxing parameters */
int b_aud; /* generate access unit delimiters */
int b_repeat_headers; /* put SPS/PPS before each keyframe */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mailman.videolan.org/pipermail/x264-devel/attachments/20060520/36b7181b/attachment.pgp
More information about the x264-devel
mailing list