All pastes #1535080 Raw Edit

x264_hrd_pulldown.15_interlace.f

public shellscript v1 · immutable
#1535080 ·published 2009-08-19 13:32 UTC
rendered paste body
diff -uNrp a/common/bs.h b/common/bs.h--- a/common/bs.h	2009-07-07 21:27:03 +0300+++ b/common/bs.h	2009-08-09 20:15:34 +0300@@ -169,6 +169,13 @@ static inline void bs_align_1( bs_t *s )     bs_flush( s ); } +static inline void bs_align_10( bs_t *s )+{+    if( s->i_left&7 )+        bs_write1( s, 1 );+    bs_flush( s );+}+ /* golomb functions */  static const uint8_t x264_ue_size_tab[256] =diff -uNrp a/common/common.c b/common/common.c--- a/common/common.c	2009-08-09 19:51:37 +0300+++ b/common/common.c	2009-08-09 20:15:34 +0300@@ -148,6 +148,8 @@ void    x264_param_default( x264_param_t      param->b_repeat_headers = 1;     param->b_aud = 0;+    param->b_nal_hrd = 0;+    param->i_pulldown = 0; }  static int parse_enum( const char *arg, const char * const *names, int *dst )@@ -375,7 +377,23 @@ int x264_param_parse( x264_param_t *p, c     OPT("cabac-idc")         p->i_cabac_init_idc = atoi(value);     OPT("interlaced")+    {+        p->b_interlaced = atobool(value);+        p->b_nal_hrd = atobool(value);  // this is only a bool+        p->b_tff = 1;+    }+    OPT("tff")+    {         p->b_interlaced = atobool(value);+        p->b_nal_hrd = atobool(value);  // this is only a bool+        p->b_tff = 1;+    }+    OPT("bff")+    {+        p->b_interlaced = atobool(value);+        p->b_nal_hrd = atobool(value);  // this is only a bool+        p->b_tff = 0;+    }     OPT("cqm")     {         if( strstr( value, "flat" ) )@@ -580,6 +598,10 @@ int x264_param_parse( x264_param_t *p, c         p->analyse.b_ssim = atobool(value);     OPT("aud")         p->b_aud = atobool(value);+    OPT2("pulldown","pd")+        p->i_pulldown = atoi(value);+    OPT("nal-hrd")+        p->b_nal_hrd = atobool(value);     OPT("sps-id")         p->i_sps_id = atoi(value);     OPT("global-header")diff -uNrp a/common/common.h b/common/common.h--- a/common/common.h	2009-08-09 19:51:37 +0300+++ b/common/common.h	2009-08-09 20:15:34 +0300@@ -333,7 +333,13 @@ struct x264_t     int             i_poc_msb;      /* decoding only */     int             i_poc_lsb;      /* decoding only */     int             i_poc;          /* decoding only */-+    int             i_dframe;+    int             i_cpb_delay;    /* Equal to number of fields preceding this field+                                     * since last buffering_period SEI */+    int64_t         i_dts_last_key;+    int64_t         i_prev_dts_dur;+    int64_t         i_prev_dts;+    int             i_pic_struct_prev;     int             i_thread_num;   /* threads only */     int             i_nal_type;     /* threads only */     int             i_nal_ref_idc;  /* threads only */diff -uNrp a/common/frame.c b/common/frame.c--- a/common/frame.c	2009-08-09 19:51:37 +0300+++ b/common/frame.c	2009-08-09 20:15:34 +0300@@ -115,6 +115,7 @@ x264_frame_t *x264_frame_new( x264_t *h      frame->i_type = X264_TYPE_AUTO;     frame->i_qpplus1 = 0;     frame->i_pts = -1;+    frame->i_dts = 0;     frame->i_frame = -1;     frame->i_frame_num = -1;     frame->i_lines_completed = -1;diff -uNrp a/common/frame.h b/common/frame.h--- a/common/frame.h	2009-08-09 19:51:37 +0300+++ b/common/frame.h	2009-08-09 20:15:34 +0300@@ -34,6 +34,7 @@ typedef struct     int     i_poc;     int     i_type;     int     i_qpplus1;+    int64_t i_dts;     int64_t i_pts;     int     i_frame;    /* Presentation frame number */     int     i_frame_num; /* Coded frame number */diff -uNrp a/common/set.h b/common/set.h--- a/common/set.h	2009-07-07 21:27:03 +0300+++ b/common/set.h	2009-08-09 20:15:34 +0300@@ -125,6 +125,18 @@ typedef struct         int i_num_reorder_frames;         int i_max_dec_frame_buffering; +        int b_nal_hrd_parameters_present;+        int i_pulldown_type;+        int b_pic_struct_present_flag;+        struct+        {+            int i_bit_rate;+            int i_cpb_size;+            int b_cbr;+            int i_initial_cpb_removal_delay_length;+            int i_cpb_removal_delay_length;+            int i_dpb_output_delay_length;+        } nal_hrd_parameters;         /* FIXME to complete */     } vui; diff -uNrp a/encoder/encoder.c b/encoder/encoder.c--- a/encoder/encoder.c	2009-08-09 19:51:37 +0300+++ b/encoder/encoder.c	2009-08-09 20:24:56 +0300@@ -409,6 +409,32 @@ static int x264_validate_parameters( x26         }     } +    if( h->param.b_nal_hrd )+    {+        if( h->param.rc.i_vbv_max_bitrate == 0 || h->param.rc.i_vbv_buffer_size == 0 )+        {+            x264_log( h, X264_LOG_WARNING, "NAL HRD parameters require VBV max bitrate and buffer size to be specified\n" );+            h->param.b_nal_hrd = 0;+        }+    }++    if( h->param.i_pulldown > 0 ) // 32 or 64+    {+        if( h->param.b_nal_hrd == 0 )+        {+            x264_log( h, X264_LOG_WARNING, "pulldown requires NAL HRD parameters setting\n" );+            h->param.i_pulldown = 0;+        }+        else+        {+            if( h->param.i_pulldown != 32 && h->param.i_pulldown != 64 )+            {+                x264_log( h, X264_LOG_WARNING, "32/64 only acceptable values for --pulldown. Forcing to 32 (3:2)" );+                h->param.i_pulldown = 32;+            }+        }+    }+     if( h->param.rc.i_rc_method < 0 || h->param.rc.i_rc_method > 2 )     {         x264_log( h, X264_LOG_ERROR, "no ratecontrol method specified\n" );@@ -728,6 +754,9 @@ x264_t *x264_encoder_open   ( x264_param     h->i_frame = 0;     h->i_frame_num = 0;     h->i_idr_pic_id = 0;+    h->i_cpb_delay = 0;+    h->i_dts_last_key = 0;+    h->i_dframe = -1;      h->sps = &h->sps_array[0];     x264_sps_init( h->sps, h->param.i_sps_id, &h->param );@@ -941,12 +970,6 @@ int x264_encoder_headers( x264_t *h, x26     /* Put SPS and PPS */     if( h->i_frame == 0 )     {-        /* identify ourself */-        x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );-        if( x264_sei_version_write( h, &h->out.bs ) )-            return -1;-        x264_nal_end( h );-         /* generate sequence parameters */         x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );         x264_sps_write( &h->out.bs, h->sps );@@ -956,6 +979,12 @@ int x264_encoder_headers( x264_t *h, x26         x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST );         x264_pps_write( &h->out.bs, h->pps );         x264_nal_end( h );++        /* identify ourself */+        x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );+        if( x264_sei_version_write( h, &h->out.bs ) )+            return -1;+        x264_nal_end( h );     }     /* now set output*/     *pi_nal = h->out.i_nal;@@ -1407,7 +1436,7 @@ static void *x264_slices_write( x264_t *      if( x264_stack_align( x264_slice_write, h ) )         return (void *)-1;-    i_frame_size = h->out.nal[h->out.i_nal-1].i_payload;+    i_frame_size = h->out.nal[h->out.i_nal-1].i_payload + ( NALU_OVERHEAD * (int)h->param.b_nal_hrd );  #if VISUALIZE     if( h->param.b_visualize )@@ -1417,7 +1446,7 @@ static void *x264_slices_write( x264_t *     } #endif -    h->out.i_frame_size = i_frame_size;+    h->out.i_frame_size += i_frame_size;     return (void *)0; } @@ -1439,11 +1468,14 @@ int     x264_encoder_encode( x264_t *h,                              x264_picture_t *pic_in,                              x264_picture_t *pic_out ) {+    static const int tbt_pattern[] = { 5, 4, 6, 3 };     x264_t *thread_current, *thread_prev, *thread_oldest;     int     i_nal_type;     int     i_nal_ref_idc;--    int   i_global_qp;+    int     i_global_qp;+    int     cpb_removal_delay;+    int64_t i_ptsoffset = 0;+    int64_t i_ptsreferenceoffset = 0;      if( h->param.i_threads > 1)     {@@ -1598,7 +1630,19 @@ int     x264_encoder_encode( x264_t *h,     h->fdec->i_frame = h->fenc->i_frame;     h->fenc->b_kept_as_ref =     h->fdec->b_kept_as_ref = i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE && h->param.i_keyint_max > 1;-+    h->i_dframe++;+    if( !h->sps->vui.i_pulldown_type )+        i_ptsreferenceoffset = h->sps->vui.i_num_units_in_tick *+                              (h->param.i_bframe ? ( h->param.b_bframe_pyramid ? 4 : 2 ) : 0 ) ;+    else+    {+        i_ptsreferenceoffset = h->sps->vui.i_num_reorder_frames * ( h->sps->vui.i_num_units_in_tick * 3 );+        i_ptsoffset = (h->fenc->i_frame&1) ? (h->sps->vui.i_num_units_in_tick*((h->fenc->i_frame/2)+1)) :+                      (h->sps->vui.i_num_units_in_tick*((int64_t)(h->fenc->i_frame/2)));+    }  // pulldown > 0+    h->fdec->i_dts = h->i_prev_dts + h->i_prev_dts_dur;+    h->i_prev_dts = h->fdec->i_dts;+    h->i_prev_dts_dur = h->sps->vui.i_num_units_in_tick * ( ((h->fenc->i_frame)&1) ? 2 : ( h->sps->vui.i_pulldown_type ? 3 : 2 ) );       /* ------------------- Init                ----------------------------- */@@ -1648,26 +1692,92 @@ int     x264_encoder_encode( x264_t *h,     h->i_nal_ref_idc = i_nal_ref_idc;      /* Write SPS and PPS */+    //clear payload tracking  -- start here so we can add non VCL-NAL payload size+    //to bring to type II conformance+    h->out.i_frame_size = (NALU_OVERHEAD + 1 ) * (int)h->param.b_aud * (int)h->param.b_nal_hrd;     if( i_nal_type == NAL_SLICE_IDR && h->param.b_repeat_headers )     {-        if( h->fenc->i_frame == 0 )-        {-            /* identify ourself */-            x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );-            if( x264_sei_version_write( h, &h->out.bs ) )-                return -1;-            x264_nal_end( h );-        }-         /* generate sequence parameters */         x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );         x264_sps_write( &h->out.bs, h->sps );         x264_nal_end( h );+        h->out.i_frame_size += (h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD ) * (int)h->param.b_nal_hrd ;          /* generate picture parameters */         x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST );         x264_pps_write( &h->out.bs, h->pps );         x264_nal_end( h );+        h->out.i_frame_size += ( h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD ) * (int)h->param.b_nal_hrd;++        if( h->fenc->i_frame == 0 )+        {+            if( !h->param.b_nal_hrd )+            {+                /* identify ourself */+                x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );+                x264_sei_version_write( h, &h->out.bs );+                bs_rbsp_trailing(&h->out.bs);+                x264_nal_end( h );+                h->out.i_frame_size += ( h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD )+                                     * (int)h->param.b_nal_hrd;+            }+        }+    }++    if( h->param.b_nal_hrd )+    {+        int dpb_output_delay = 0;+        int pic_struct = 0;++        x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );++        // write bp sei then close and reopen nal to create separate nal from pt sei+        if( i_nal_type == NAL_SLICE_IDR )+        {+            x264_sei_buffering_period_write( h, &h->param, &h->out.bs, h->sps );+            if( h->fenc->i_frame == 0 ) // write identifying data after bp in same nal+            {+                /* identify ourself */+                x264_sei_version_write( h, &h->out.bs );+            }+            bs_rbsp_trailing(&h->out.bs);+            x264_nal_end( h );+            h->out.i_frame_size += (h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD ) * (int)h->param.b_nal_hrd;+            x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );+        }+        if( !h->sh.b_field_pic )+        {+            //pic_struct+            dpb_output_delay = (int)( h->fenc->i_pts*2 + i_ptsoffset + i_ptsreferenceoffset+                             - h->fdec->i_dts ) / h->sps->vui.i_num_units_in_tick;+            cpb_removal_delay = (h->fdec->i_dts - h->i_dts_last_key) / h->sps->vui.i_num_units_in_tick;+            if( !h->param.b_interlaced )+            {+                if( h->sps->vui.i_pulldown_type == 32 )+                    pic_struct = tbt_pattern[(h->fenc->i_frame) & 3];+                else if( h->sps->vui.i_pulldown_type == 64 )+                {+                    pic_struct = (h->fenc->i_frame & 1) ? 7 : 8;+                    cpb_removal_delay *= 2;+                    dpb_output_delay *=2;+                }+            }+            else+            {+                // tff = 3, bff = 4+                pic_struct = h->param.b_tff ? 3 : 4;+            }+            x264_sei_picture_timing_write( &h->out.bs, h->sps, cpb_removal_delay, dpb_output_delay, pic_struct);+            bs_rbsp_trailing(&h->out.bs);+            cpb_removal_delay = h->i_cpb_delay;+            if( i_nal_type == NAL_SLICE_IDR )+            {+                cpb_removal_delay  = 0;+                h->i_dts_last_key = h->fdec->i_dts ;+            }+        }+        x264_nal_end( h );+        h->out.i_frame_size += ( h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD ) * (int)h->param.b_nal_hrd;     }      /* Write frame */@@ -1681,6 +1791,7 @@ int     x264_encoder_encode( x264_t *h,         if( (intptr_t)x264_slices_write( h ) )             return -1; +    h->i_cpb_delay = cpb_removal_delay;     return x264_encoder_frame_end( thread_oldest, thread_current, pp_nal, pi_nal, pic_out ); } @@ -1732,7 +1843,9 @@ static int x264_encoder_frame_end( x264_      /* update rc */     x264_emms();-    if( x264_ratecontrol_end( h, h->out.i_frame_size * 8 ) < 0 )++    int duration_this_frame = ((h->fenc->i_frame)&1) ? 2 : ( h->sps->vui.i_pulldown_type ? 3 : 2 );+    if( x264_ratecontrol_end( h, (h->out.i_frame_size ) * 8, duration_this_frame ) < 0 )         return -1;      /* restore CPU state (before using float again) */@@ -1745,7 +1858,7 @@ static int x264_encoder_frame_end( x264_      /* Slice stat */     h->stat.i_slice_count[h->sh.i_type]++;-    h->stat.i_slice_size[h->sh.i_type] += h->out.i_frame_size + NALU_OVERHEAD;+    h->stat.i_slice_size[h->sh.i_type] += h->out.i_frame_size + ( NALU_OVERHEAD * (int)!h->param.b_nal_hrd );     h->stat.f_slice_qp[h->sh.i_type] += h->fdec->f_qp_avg_aq;      for( i = 0; i < X264_MBTYPE_MAX; i++ )diff -uNrp a/encoder/ratecontrol.c b/encoder/ratecontrol.c--- a/encoder/ratecontrol.c	2009-08-09 19:51:37 +0300+++ b/encoder/ratecontrol.c	2009-08-09 20:15:41 +0300@@ -69,6 +69,8 @@ struct x264_ratecontrol_t     int b_vbv;     int b_vbv_min_rate;     double fps;+    double fps_vfr_low;+    double fps_vfr_high;        /* variable frame rate support (final side only)*/     double bitrate;     double rate_tolerance;     double qcompress;@@ -89,6 +91,8 @@ struct x264_ratecontrol_t     double buffer_fill_final;   /* real buffer as of the last finished frame */     double buffer_fill;         /* planned buffer, if all in-progress frames hit their bit budget */     double buffer_rate;         /* # of bits added to buffer_fill after each frame */+    double buffer_rate_vfr_low; /* # bits added to buffer on a long frame time */+    double buffer_rate_vfr_high;/* # bits added to buffer on a short frame time */     predictor_t *pred;          /* predict frame size from satd */      /* ABR stuff */@@ -143,7 +147,7 @@ struct x264_ratecontrol_t static int parse_zones( x264_t *h ); static int init_pass2(x264_t *); static float rate_estimate_qscale( x264_t *h );-static void update_vbv( x264_t *h, int bits );+static void update_vbv( x264_t *h, int bits, int vfrlowhigh ); //high = 3 static void update_vbv_plan( x264_t *h ); static double predict_size( predictor_t *p, double q, double var ); static void update_predictor( predictor_t *p, double q, double var, double bits );@@ -327,6 +331,29 @@ int x264_ratecontrol_new( x264_t *h )         rc->fps = (float) h->param.i_fps_num / h->param.i_fps_den;     else         rc->fps = 25.0;+    rc->fps_vfr_low =+    rc->fps_vfr_high =+    rc->fps;+    if( !h->param.b_interlaced )+    {+        if( h->sps->vui.i_pulldown_type > 0 && h->sps->vui.b_nal_hrd_parameters_present )+        {+            if( h->sps->vui.i_pulldown_type == 32 )+            {+                rc->fps_vfr_low = 19.98;+                rc->fps = 23.976; // fps average for prediction+                rc->fps_vfr_high = 29.97;+            }+            else+            {+                rc->fps_vfr_low = 19.98; // 39.96;+                rc->fps = 23.976; // fps average for prediction // 47.952;+                rc->fps_vfr_high = 29.97; // 59.94;+            }+        }+    }+    rc->buffer_rate_vfr_low = h->param.rc.i_vbv_max_bitrate * 1000 / rc->fps_vfr_low;+    rc->buffer_rate_vfr_high= h->param.rc.i_vbv_max_bitrate * 1000 / rc->fps_vfr_high;      if( h->param.rc.b_mb_tree )     {@@ -1166,7 +1193,7 @@ int x264_ratecontrol_slice_type( x264_t  }  /* After encoding one frame, save stats and update ratecontrol state */-int x264_ratecontrol_end( x264_t *h, int bits )+int x264_ratecontrol_end( x264_t *h, int bits, int vfrlowhigh ) {     x264_ratecontrol_t *rc = h->rc;     const int *mbs = h->stat.frame.i_mb_count;@@ -1256,7 +1283,7 @@ int x264_ratecontrol_end( x264_t *h, int         }     } -    update_vbv( h, bits );+    update_vbv( h, bits, vfrlowhigh );     return 0; fail:     x264_log(h, X264_LOG_ERROR, "ratecontrol_end: stats file could not be written to\n");@@ -1393,7 +1420,8 @@ static void update_predictor( predictor_ }  // update VBV after encoding a frame-static void update_vbv( x264_t *h, int bits )+// vfrlowhigh 2 == high  default == low  when non vfr stream low == avg+static void update_vbv( x264_t *h, int bits, int vfrlowhigh ) {     x264_ratecontrol_t *rcc = h->rc;     x264_ratecontrol_t *rct = h->thread[0]->rc;@@ -1404,10 +1432,13 @@ static void update_vbv( x264_t *h, int b     if( !rcc->b_vbv )         return; -    rct->buffer_fill_final += rct->buffer_rate - bits;+    // we will honor vfr (when applicable) for the final buffer while prediction routines+    // will continue to use the average frame rate+    rct->buffer_fill_final += ( vfrlowhigh == 3 ? rcc->buffer_rate_vfr_high : rcc->buffer_rate_vfr_low ) - bits;     if( rct->buffer_fill_final < 0 )         x264_log( h, X264_LOG_WARNING, "VBV underflow (%.0f bits)\n", rct->buffer_fill_final );     rct->buffer_fill_final = x264_clip3f( rct->buffer_fill_final, 0, rct->buffer_size );+    h->param.rc.i_buffer_fill_final = x264_clip3f( rct->buffer_fill_final, 0, rct->buffer_size - 1000 ); }  // provisionally update VBV according to the planned size of all frames currently in progressdiff -uNrp a/encoder/ratecontrol.h b/encoder/ratecontrol.h--- a/encoder/ratecontrol.h	2009-08-07 18:50:22 +0300+++ b/encoder/ratecontrol.h	2009-08-09 20:15:41 +0300@@ -35,7 +35,7 @@ void x264_ratecontrol_start( x264_t *, i int  x264_ratecontrol_slice_type( x264_t *, int i_frame ); void x264_ratecontrol_mb( x264_t *, int bits ); int  x264_ratecontrol_qp( x264_t * );-int  x264_ratecontrol_end( x264_t *, int bits );+int  x264_ratecontrol_end( x264_t *, int bits, int vfrlowhigh ); void x264_ratecontrol_summary( x264_t * ); void x264_ratecontrol_set_estimated_size( x264_t *, int bits ); int  x264_ratecontrol_get_estimated_size( x264_t const *);diff -uNrp a/encoder/set.c b/encoder/set.c--- a/encoder/set.c	2009-08-09 19:51:37 +0300+++ b/encoder/set.c	2009-08-09 20:28:45 +0300@@ -208,8 +208,47 @@ void x264_sps_init( x264_sps_t *sps, int         sps->vui.i_log2_max_mv_length_horizontal =         sps->vui.i_log2_max_mv_length_vertical = (int)(log(param->analyse.i_mv_range*4-1)/log(2)) + 1;     }-} +    sps->vui.b_nal_hrd_parameters_present = param->b_nal_hrd;+    if( sps->vui.b_nal_hrd_parameters_present )+    {+        sps->vui.nal_hrd_parameters.i_bit_rate = param->rc.i_vbv_max_bitrate * 1000;+        sps->vui.nal_hrd_parameters.i_cpb_size = param->rc.i_vbv_buffer_size * 1000;++        sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length = 0;+        while( (1 << ++sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length) <+               ( param->rc.i_vbv_buffer_size * 90000.0 / param->rc.i_vbv_max_bitrate ) );++        sps->vui.nal_hrd_parameters.i_cpb_removal_delay_length = 0;+        while( (1 << ++sps->vui.nal_hrd_parameters.i_cpb_removal_delay_length) <+               (2 * (param->i_keyint_max * ((param->i_pulldown/32)+1) )));++        sps->vui.nal_hrd_parameters.i_dpb_output_delay_length = 0;+        while( (1 << ++sps->vui.nal_hrd_parameters.i_dpb_output_delay_length) <+               ( ( 2 * (sps->i_num_ref_frames + X264_MAX(sps->vui.i_num_reorder_frames, param->i_bframe) ) *+               ( ( param->i_pulldown/32) + 1 ) ) ) );+    }++    sps->vui.b_pic_struct_present_flag = 0;+    sps->vui.i_pulldown_type = param->i_pulldown;+    if( !param->b_interlaced )+    {+        if( sps->vui.i_pulldown_type > 0 && sps->vui.b_nal_hrd_parameters_present )+        {  // pulldown and hrd go together+            sps->vui.b_pic_struct_present_flag = 1;+            sps->vui.i_num_units_in_tick = 1001;+            if( sps->vui.i_pulldown_type == 64 )+                sps->vui.i_time_scale = 60000*2;+            else+                sps->vui.i_time_scale = 30000*2;+        }+    }+    else+    {+        if( sps->vui.b_nal_hrd_parameters_present )+            sps->vui.b_pic_struct_present_flag = 1;+    }+}  void x264_sps_write( bs_t *s, x264_sps_t *sps ) {@@ -345,9 +384,45 @@ void x264_sps_write( bs_t *s, x264_sps_t             bs_write1( s, sps->vui.b_fixed_frame_rate );         } -        bs_write1( s, 0 );      /* nal_hrd_parameters_present_flag */+        bs_write1( s, sps->vui.b_nal_hrd_parameters_present );+        if( sps->vui.b_nal_hrd_parameters_present )+        {+            int bit_rate_scale = 0, cpb_size_scale = 0;+            unsigned int bit_rate_tmp, cpb_size_tmp;++            bs_write_ue( s, 0 );    /* cpb_cnt_minus1 */++            bit_rate_tmp = ( sps->vui.nal_hrd_parameters.i_bit_rate + (1 << 5) ) >> 6;+            while( ( bit_rate_tmp & 1) == 0 )+            {+                bit_rate_tmp >>= 1;+                bit_rate_scale++;+                if (bit_rate_scale == 15)+                    break;+            }+            cpb_size_tmp = ( sps->vui.nal_hrd_parameters.i_cpb_size + (1 << 3) ) >> 4;+            while( ( cpb_size_tmp & 1) == 0 )+            {+                cpb_size_tmp >>= 1;+                cpb_size_scale++;+                if (cpb_size_scale == 15)+                    break;+            }+            bs_write( s, 4, bit_rate_scale );+            bs_write( s, 4, cpb_size_scale );+            bs_write_ue_big( s, bit_rate_tmp - 1 );+            bs_write_ue_big( s, cpb_size_tmp - 1 );+            bs_write1( s, 0 );+            bs_write( s, 5, sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length - 1 );+            bs_write( s, 5, sps->vui.nal_hrd_parameters.i_cpb_removal_delay_length - 1 );+            bs_write( s, 5, sps->vui.nal_hrd_parameters.i_dpb_output_delay_length - 1 );+            bs_write( s, 5, 24 ); // time_offset_length+        }+         bs_write1( s, 0 );      /* vcl_hrd_parameters_present_flag */-        bs_write1( s, 0 );      /* pic_struct_present_flag */+        if( sps->vui.b_nal_hrd_parameters_present ) /* or VCL HRD */+            bs_write1( s, 0);   /* low_delay_hrd_flag */+        bs_write1( s, sps->vui.b_pic_struct_present_flag );      /* pic_struct_present_flag */         bs_write1( s, sps->vui.b_bitstream_restriction );         if( sps->vui.b_bitstream_restriction )         {@@ -502,7 +577,7 @@ int x264_sei_version_write( x264_t *h, b     for( i = 0; i < length-16; i++ )         bs_write( s, 8, version[i] ); -    bs_rbsp_trailing( s );+    bs_align_10( s ); // does nothing here.. but dangit it belongs      x264_free( opts );     x264_free( version );@@ -512,6 +587,83 @@ fail:     return -1; } +void x264_sei_buffering_period_write( x264_t *h, x264_param_t *param, bs_t *s, x264_sps_t *sps )+{+    int payload_size;++    bs_write( s, 8, 0x0 ); // payload_type = buffering_period+    payload_size = bs_size_ue( sps->i_id );+    if( sps->vui.b_nal_hrd_parameters_present )+        payload_size += sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length * 2;++    bs_write( s, 8, (payload_size + 7) / 8);+    bs_write_ue( s, sps->i_id );++    if ( sps->vui.b_nal_hrd_parameters_present )+    {+        /* NOTE: This should be a loop for each CPB, but we currently only support one */++        double buffer_rate = param->rc.i_vbv_max_bitrate;+        double buffer_size = param->rc.i_vbv_buffer_size;+        double buffer_fill_final;+        if( h->param.rc.i_buffer_fill_final > 0 )+            buffer_fill_final = h->param.rc.i_buffer_fill_final / 1000;+        else+            buffer_fill_final = buffer_size * param->rc.f_vbv_buffer_init;+        assert( ( buffer_fill_final * 90000. / ( buffer_rate ) ) <+                  pow( 2, sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length ) );+        bs_write( s, sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length,+                     buffer_fill_final * 90000. / ( buffer_rate ) );+        bs_write( s, sps->vui.nal_hrd_parameters.i_initial_cpb_removal_delay_length,+                   ( buffer_size - buffer_fill_final ) * 90000. / ( buffer_rate ) );+    }++    /* VCL HRD parameters should go here */+    bs_align_10( s );+}++void x264_sei_picture_timing_write( bs_t *s, x264_sps_t *sps, int cpb_removal_delay, int dpb_output_delay, int pic_struct )+{+    int payload_size;++    static const int num_clockts[] = { 1, 1, 1, 2, 2, 3, 3, 2, 3 };+    bs_write( s, 8, 0x1 ); // payload_type = pic_timing++    payload_size = 0;+    if( sps->vui.b_nal_hrd_parameters_present )+    {+        payload_size += sps->vui.nal_hrd_parameters.i_cpb_removal_delay_length+                      + sps->vui.nal_hrd_parameters.i_dpb_output_delay_length;+        if( sps->vui.b_pic_struct_present_flag )+        {+            payload_size += 4;+            payload_size += num_clockts[pic_struct]; // pad #num_clockts bytes for 0 (no time code)+        }+    }+    bs_write( s, 8, (payload_size + 7) / 8);++    if( sps->vui.b_nal_hrd_parameters_present )+    {+        /* NOTE: This should be a loop for each CPB, but we currently only support one */++        assert( cpb_removal_delay < pow( 2,  sps->vui.nal_hrd_parameters.i_cpb_removal_delay_length ) );+        bs_write( s, sps->vui.nal_hrd_parameters.i_cpb_removal_delay_length,+                     cpb_removal_delay);+        assert( dpb_output_delay < pow( 2, sps->vui.nal_hrd_parameters.i_dpb_output_delay_length ) );+        bs_write( s, sps->vui.nal_hrd_parameters.i_dpb_output_delay_length,+                     dpb_output_delay);+        if( sps->vui.b_pic_struct_present_flag )+        {+            bs_write( s, 4, pic_struct );+            bs_write( s, num_clockts[ pic_struct ], 0 );+        }+    }++    /* VCL HRD parameters should go here */+    //bs_rbsp_trailing( s );+    bs_align_10( s );+}+ const x264_level_t x264_levels[] = {     { 10,   1485,    99,   152064,     64,    175,  64, 64,  0, 0, 0, 1 },diff -uNrp a/encoder/set.h b/encoder/set.h--- a/encoder/set.h	2009-08-09 19:51:37 +0300+++ b/encoder/set.h	2009-08-09 20:29:12 +0300@@ -29,6 +29,8 @@ void x264_sps_write( bs_t *s, x264_sps_t 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 ); int  x264_sei_version_write( x264_t *h, bs_t *s );+void x264_sei_buffering_period_write( x264_t *h, x264_param_t *param, bs_t *s, x264_sps_t *sps );+void x264_sei_picture_timing_write( bs_t *s, x264_sps_t *sps, int cpb_removal_delay, int dpb_output_delay, int pic_struct ); int  x264_validate_levels( x264_t *h, int verbose );  #endifdiff -uNrp a/x264.c b/x264.c--- a/x264.c	2009-08-09 19:51:37 +0300+++ b/x264.c	2009-08-09 20:15:48 +0300@@ -196,7 +196,9 @@ static void Help( x264_param_t *defaults     H1( "      --no-deblock            Disable loop filter\n" );     H0( "  -f, --deblock <alpha:beta>  Loop filter AlphaC0 and Beta parameters [%d:%d]\n",                                        defaults->i_deblocking_filter_alphac0, defaults->i_deblocking_filter_beta );-    H0( "      --interlaced            Enable pure-interlaced mode\n" );+    H0( "      --interlaced            Enable pure-interlaced mode (tff)\n" );+    H0( "      --tff                   Alias for --interlaced\n" );+    H0( "      --bff                   Enable pure-interlaced mode (bff)\n" );     H0( "\n" );     H0( "Ratecontrol:\n" );     H0( "\n" );@@ -358,6 +360,10 @@ static void Help( x264_param_t *defaults     H1( "      --dump-yuv <string>     Save reconstructed frames\n" );     H1( "      --sps-id <integer>      Set SPS and PPS id numbers [%d]\n", defaults->i_sps_id );     H1( "      --aud                   Use access unit delimiters\n" );+    H1( "      --nal-hrd               Use NAL HRD parameters\n" );+    H1( "      --pulldown <integer>    Use 3:2 pulldown\n"+        "                                  - 32: TBT,BT,BTB,TB pattern\n"+        "                                  - 64: triple,double *recommended for 720p\n" );     H0( "\n" ); } @@ -399,6 +405,8 @@ static struct option long_options[] =     { "filter",      required_argument, NULL, 0 },     { "deblock",     required_argument, NULL, 'f' },     { "interlaced",        no_argument, NULL, 0 },+    { "tff",     no_argument,    NULL, 0 },+    { "bff",     no_argument,    NULL, 0 },     { "cabac",             no_argument, NULL, 0 },     { "no-cabac",          no_argument, NULL, 0 },     { "qp",          required_argument, NULL, 'q' },@@ -470,6 +478,9 @@ static struct option long_options[] =     { "dump-yuv",    required_argument, NULL, 0 },     { "sps-id",      required_argument, NULL, 0 },     { "aud",               no_argument, NULL, 0 },+    { "nal-hrd", no_argument,       NULL, 0 },+    { "pulldown", required_argument,NULL, 0 },+    { "pd",      required_argument, NULL, 0 },     { "nr",          required_argument, NULL, 0 },     { "cqm",         required_argument, NULL, 0 },     { "cqmfile",     required_argument, NULL, 0 },diff -uNrp a/x264.h b/x264.h--- a/x264.h	2009-08-09 19:51:37 +0300+++ b/x264.h	2009-08-09 20:15:48 +0300@@ -201,6 +201,7 @@ typedef struct x264_param_t     int         i_cabac_init_idc;      int         b_interlaced;+    int         b_tff;      int         i_cqm_preset;     char        *psz_cqm_file;      /* JM format */@@ -267,6 +268,7 @@ typedef struct x264_param_t         int         i_vbv_max_bitrate;         int         i_vbv_buffer_size;         float       f_vbv_buffer_init; /* <=1: fraction of buffer_size. >1: kbit */+        int64_t     i_buffer_fill_final;         float       f_ip_factor;         float       f_pb_factor; @@ -294,6 +296,8 @@ typedef struct x264_param_t     int b_aud;                  /* generate access unit delimiters */     int b_repeat_headers;       /* put SPS/PPS before each keyframe */     int i_sps_id;               /* SPS and PPS id number */+    int b_nal_hrd;              /* Add NAL HRD parameters to bitstream */+    int i_pulldown;                /* 3:2 pulldown */    /* Optional callback for freeing this x264_param_t when it is done being used.     * Only used when the x264_param_t sits in memory for an indefinite period of time,