All pastes #1549828 Raw Edit

x264_open_gop.14.1243.test.diff

public diff v1 · immutable
#1549828 ·published 2009-09-01 00:51 UTC
rendered paste body
diff -NdurwBE x264-bluray/common/common.c x264-bluray3/common/common.c--- x264-bluray/common/common.c	2009-09-01 03:43:06 +0300+++ x264-bluray3/common/common.c	2009-09-01 03:23:02 +0300@@ -75,6 +75,7 @@     param->i_bframe_adaptive = X264_B_ADAPT_FAST;     param->i_bframe_bias = 0;     param->b_bframe_pyramid = 0;+    param->b_strictdpb = 0;      param->b_deblocking_filter = 1;     param->i_deblocking_filter_alphac0 = 0;@@ -358,6 +359,8 @@         p->i_bframe_bias = atoi(value);     OPT("b-pyramid")         p->b_bframe_pyramid = atobool(value);+    OPT("strict-dpb")+        p->b_strictdpb = atobool(value);     OPT("nf")         p->b_deblocking_filter = !atobool(value);     OPT2("filter", "deblock")@@ -381,6 +384,8 @@         p->i_slice_max_mbs = atoi(value);     OPT("slices")         p->i_slice_count = atoi(value);+    OPT("open-gop")+        p->b_open_gop = atobool(value);     OPT("cabac")         p->b_cabac = atobool(value);     OPT("cabac-idc")@@ -881,6 +886,7 @@     s += sprintf( s, " cqm=%d", p->i_cqm_preset );     s += sprintf( s, " deadzone=%d,%d", p->analyse.i_luma_deadzone[0], p->analyse.i_luma_deadzone[1] );     s += sprintf( s, " chroma_qp_offset=%d", p->analyse.i_chroma_qp_offset );+    s += sprintf( s, " opengop=%d", p->b_open_gop );     s += sprintf( s, " threads=%d", p->i_threads );     if( p->i_slice_count )         s += sprintf( s, " slices=%d", p->i_slice_count );@@ -895,8 +901,8 @@     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",-                      p->b_bframe_pyramid, p->i_bframe_adaptive, p->i_bframe_bias,+        s += sprintf( s, " b_pyramid=%d b_strict_dpb=%d b_adapt=%d b_bias=%d direct=%d wpredb=%d",+                      p->b_bframe_pyramid, p->b_strictdpb, p->i_bframe_adaptive, p->i_bframe_bias,                       p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred );     } diff -NdurwBE x264-bluray/common/common.h x264-bluray3/common/common.h--- x264-bluray/common/common.h	2009-09-01 03:43:06 +0300+++ x264-bluray3/common/common.h	2009-09-01 03:21:31 +0300@@ -224,6 +224,11 @@         int idc;         int arg;     } ref_pic_list_order[2][16];+    struct // for future expansion+    {+        int i_difference_of_pic_nums;+    } mmco[16];+    int i_mmco_idx;      int i_cabac_init_idc; @@ -366,7 +371,9 @@         /* frames used for reference + sentinels */         x264_frame_t *reference[16+2]; -        int i_last_idr; /* Frame number of the last IDR */+        int i_last_idr; /* Frame number of the last IDR or RP */+        int i_idr_opengop_offset; /* Offset of above to handle open gop */+        int b_leading_bframes; /* Place holder to know when to remove old references for soft gop*/          int i_input;    /* Number of input frames already accepted */ @@ -391,7 +398,11 @@     x264_frame_t    *fref1[16+3];     /* ref list 1 */     int             b_ref_reorder[2]; -+    int             i_mmco_idx;+    struct+    {+        int         i_difference_of_pic_nums;+    } mmco[16];      /* Current MB DCT coeffs */     structdiff -NdurwBE x264-bluray/common/frame.h x264-bluray3/common/frame.h--- x264-bluray/common/frame.h	2009-09-01 03:43:06 +0300+++ x264-bluray3/common/frame.h	2009-09-01 03:21:31 +0300@@ -41,6 +41,7 @@     int     i_frame;    /* Presentation frame number */     int     i_frame_num; /* Coded frame number */     int     b_kept_as_ref;+    int     b_keyframe;     float   f_qp_avg_rc; /* QPs as decided by ratecontrol */     float   f_qp_avg_aq; /* QPs as decided by AQ in addition to ratecontrol */ diff -NdurwBE x264-bluray/encoder/encoder.c x264-bluray3/encoder/encoder.c--- x264-bluray/encoder/encoder.c	2009-09-01 03:43:06 +0300+++ x264-bluray3/encoder/encoder.c	2009-09-01 03:28:06 +0300@@ -123,6 +123,16 @@     sh->b_ref_pic_list_reordering_l0 = h->b_ref_reorder[0];     sh->b_ref_pic_list_reordering_l1 = h->b_ref_reorder[1]; +    sh->i_mmco_idx = h->i_mmco_idx;+    if( h->i_mmco_idx )+    {+        int j = 0;+        for( ; j < h->i_mmco_idx; j++ )+        {+            sh->mmco[j].i_difference_of_pic_nums = h->mmco[j].i_difference_of_pic_nums;+        }+    }+     /* If the ref list isn't in the default order, construct reordering header */     /* List1 reordering isn't needed yet */     if( sh->b_ref_pic_list_reordering_l0 )@@ -175,7 +185,7 @@      bs_write_ue( s, sh->i_type + 5 );   /* same type things */     bs_write_ue( s, sh->i_pps_id );-    bs_write( s, sh->sps->i_log2_max_frame_num, sh->i_frame_num );+    bs_write( s, sh->sps->i_log2_max_frame_num, sh->i_frame_num & (1<<sh->sps->i_log2_max_frame_num)-1 );      if( !sh->sps->b_frame_mbs_only )     {@@ -191,7 +201,7 @@      if( sh->sps->i_poc_type == 0 )     {-        bs_write( s, sh->sps->i_log2_max_poc_lsb, sh->i_poc_lsb );+        bs_write( s, sh->sps->i_log2_max_poc_lsb, sh->i_poc_lsb & (1<<sh->sps->i_log2_max_poc_lsb)-1 );         if( sh->pps->b_pic_order && !sh->b_field_pic )         {             bs_write_se( s, sh->i_delta_poc_bottom );@@ -272,7 +282,17 @@         }         else         {-            bs_write1( s, 0 );  /* adaptive_ref_pic_marking_mode_flag */+            bs_write1( s, sh->i_mmco_idx > 0 ); /* adaptive_ref_pic_marking_mode_flag */+            if( sh->i_mmco_idx > 0 )+            {+                int i = 0;+                for( ; i < sh->i_mmco_idx; i++ )+                {+                    bs_write_ue( s, 1 ); /* mark short term ref as unused */+                    bs_write_ue( s, sh->mmco[i].i_difference_of_pic_nums - 1 );+                }+                bs_write_ue( s, 0 );+            }         }     } @@ -838,6 +858,7 @@     h->frames.b_have_sub8x8_esa = !!(h->param.analyse.inter & X264_ANALYSE_PSUB8x8);      h->frames.i_last_idr = - h->param.i_keyint_max;+    h->frames.i_idr_opengop_offset = 0; //will stay 0 if !open-gop     h->frames.i_input    = 0;     h->frames.last_nonb  = NULL; @@ -1120,6 +1141,8 @@                 h->b_ref_reorder[0] = 1;                 break;             }+        if( h->param.b_bframe_pyramid )+            h->b_ref_reorder[0] = 1;     }      h->i_ref1 = X264_MIN( h->i_ref1, h->frames.i_max_ref1 );@@ -1254,6 +1277,43 @@     h->fenc->i_poc = 0; } +static inline void x264_reference_partial_reset( x264_t *h, int leave_one_nonbref_only )+{+    int refs = 0;+    int lastnonbidx = -1;+    while( h->frames.reference[refs] )+    {+        if( h->frames.reference[refs]->i_type == X264_TYPE_I+         || h->frames.reference[refs]->i_type == X264_TYPE_IDR+       || ( h->frames.reference[refs]->i_type == X264_TYPE_P+         && !leave_one_nonbref_only) )+            lastnonbidx = refs;+        refs++;+    }+    assert( lastnonbidx > -1 );+    while( refs > lastnonbidx+1 )+    {+        int diff = h->i_frame_num - h->frames.reference[refs-1]->i_frame_num;+        h->mmco[ h->i_mmco_idx++ ].i_difference_of_pic_nums = diff;+        x264_frame_push_unused( h, x264_frame_pop( h->frames.reference ) );+        refs--;+    }+    // This makes room in the dpb for the delayed display time of the later b-frame's+    // Within a mini-gop . Specific to b-pyramid. Also can remove all but one ref as well depending on +    // leave_one_nonbref_only+    while( ( h->param.b_strictdpb && ( ( refs + 2 ) > X264_MAX( h->frames.i_max_dpb, 4 ) )+                                  && h->sh.i_type ==  SLICE_TYPE_B+                                  && !leave_one_nonbref_only )+                                  || ( lastnonbidx > 0 && leave_one_nonbref_only ) )+    {+        int diff = h->i_frame_num - h->frames.reference[0]->i_frame_num;+        h->mmco[ h->i_mmco_idx++ ].i_difference_of_pic_nums = diff;+        x264_frame_push_unused( h, x264_frame_shift( h->frames.reference ) );+        lastnonbidx--;+        refs--;+    }+}+ static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp ) {     /* ------------------------ Create slice header  ----------------------- */@@ -1662,6 +1722,7 @@             x264_frame_expand_border_mod16( h, fenc );          fenc->i_frame = h->frames.i_input++;+        h->i_mmco_idx = 0;          x264_frame_push( h->frames.next, fenc ); @@ -1731,11 +1792,27 @@         if( h->fenc->param->param_free )             h->fenc->param->param_free( h->fenc->param );     }+    int b_exceeds_min = (h->fenc->i_frame - h->frames.i_last_idr ) >= h->param.i_keyint_min;+    h->fdec->b_keyframe = 0;+    if( h->param.b_open_gop )+    {+        if( ( (h->fenc->i_type == X264_TYPE_I && b_exceeds_min) +            || h->fenc->i_type == X264_TYPE_IDR ) +            && h->fenc->i_frame != 0 )+        {+            h->frames.i_idr_opengop_offset += ( h->fenc->i_frame - h->frames.i_last_idr );+            h->fdec->b_keyframe = 1;+        }+        if( h->fenc->i_type == X264_TYPE_I && b_exceeds_min )+            h->frames.i_last_idr = h->fenc->i_frame;+    }      if( h->fenc->i_type == X264_TYPE_IDR )     {         h->frames.i_last_idr = h->fenc->i_frame;+        h->fdec->b_keyframe = 1;     }+    h->i_mmco_idx = 0;      /* ------------------- Setup frame context ----------------------------- */     /* 5: Init data dependent of frame type */@@ -1744,6 +1821,7 @@         /* reset ref pictures */         x264_reference_reset( h ); +        h->frames.i_idr_opengop_offset = 0;         i_nal_type    = NAL_SLICE_IDR;         i_nal_ref_idc = NAL_PRIORITY_HIGHEST;         h->sh.i_type = SLICE_TYPE_I;@@ -1753,18 +1831,29 @@         i_nal_type    = NAL_SLICE;         i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/         h->sh.i_type = SLICE_TYPE_I;+        if( ( h->fdec->b_keyframe && h->frames.b_leading_bframes ) || h->param.b_bframe_pyramid )+            x264_reference_partial_reset( h, h->frames.b_leading_bframes );+        if( h->param.b_open_gop )+        {+            h->frames.b_leading_bframes = (b_exceeds_min && h->frames.b_leading_bframes) ? 1 : !b_exceeds_min ? 0 : 1;+        }     }     else if( h->fenc->i_type == X264_TYPE_P )     {         i_nal_type    = NAL_SLICE;         i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/         h->sh.i_type = SLICE_TYPE_P;+        x264_reference_partial_reset( h, h->frames.b_leading_bframes );+        if( h->frames.b_leading_bframes ) +            h->frames.b_leading_bframes = 0;     }     else if( h->fenc->i_type == X264_TYPE_BREF )     {         i_nal_type    = NAL_SLICE;         i_nal_ref_idc = NAL_PRIORITY_HIGH; /* maybe add MMCO to forget it? -> low */         h->sh.i_type = SLICE_TYPE_B;+        if( h->param.b_strictdpb )+            x264_reference_partial_reset( h, 0 );     }     else    /* B frame */     {@@ -1774,7 +1863,7 @@     }      h->fdec->i_poc =-    h->fenc->i_poc = 2 * (h->fenc->i_frame - h->frames.i_last_idr);+    h->fenc->i_poc = 2 * (h->fenc->i_frame - ( h->frames.i_last_idr - h->frames.i_idr_opengop_offset ) );     h->fdec->i_type = h->fenc->i_type;     h->fdec->i_frame = h->fenc->i_frame;     h->fenc->b_kept_as_ref =@@ -1845,7 +1934,8 @@     //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( (i_nal_type == NAL_SLICE_IDR && h->param.b_repeat_headers)+                    || ( h->sh.i_type == SLICE_TYPE_I && h->fdec->b_keyframe ) )     {         /* generate sequence parameters */         x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );@@ -1860,6 +1950,13 @@         if( x264_nal_end( h ) )             return -1;         h->out.i_frame_size += ( h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD ) * (int)h->param.b_nal_hrd;+        /* recovery point */+        if( h->param.b_open_gop ) +        {+            x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );+            x264_sei_recovery_point_write( h, &h->out.bs );+            x264_nal_end( h );+        }          if( h->fenc->i_frame == 0 )         {@@ -1990,6 +2087,7 @@         pic_out->img.i_stride[i] = h->fdec->i_stride[i];         pic_out->img.plane[i] = h->fdec->plane[i];     }+    pic_out->b_keyframe = h->fdec->b_keyframe;      /* ---------------------- Update encoder state ------------------------- */ diff -NdurwBE x264-bluray/encoder/set.c x264-bluray3/encoder/set.c--- x264-bluray/encoder/set.c	2009-09-01 03:43:06 +0300+++ x264-bluray3/encoder/set.c	2009-09-01 03:21:31 +0300@@ -77,6 +77,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ) {     sps->i_id = i_id;+    int max_frame_num;      sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;     if( sps->b_qpprime_y_zero_transform_bypass )@@ -96,17 +97,26 @@     /* Never set constraint_set2, it is not necessary and not used in real world. */     sps->b_constraint_set2  = 0; -    sps->i_log2_max_frame_num = 4;  /* at least 4 */-    while( (1 << sps->i_log2_max_frame_num) <= param->i_keyint_max )-    {+    sps->vui.i_num_reorder_frames = param->b_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;+    /* extra slot with pyramid so that we don't have to override the+     * order of forgetting old pictures */+    sps->vui.i_max_dec_frame_buffering =+    sps->i_num_ref_frames = X264_MIN(16, X264_MAX(param->i_frame_reference, 1 + sps->vui.i_num_reorder_frames));++    /* number of refs + current frame */+    /* we MMCO away b-refs, so we have to count those too. */+    max_frame_num = sps->i_num_ref_frames * (param->b_bframe_pyramid?2:1) + 1;+    sps->i_log2_max_frame_num = 4;+    while( (1 << sps->i_log2_max_frame_num) < max_frame_num )         sps->i_log2_max_frame_num++;-    }-    sps->i_log2_max_frame_num++;    /* just in case */      sps->i_poc_type = 0;     if( sps->i_poc_type == 0 )     {-        sps->i_log2_max_poc_lsb = sps->i_log2_max_frame_num + 1;    /* max poc = 2*frame_num */+        int max_poc = (param->i_bframe+1)*(param->b_bframe_pyramid?3:2)*2;+        sps->i_log2_max_poc_lsb = 4;+        while( (1 << sps->i_log2_max_poc_lsb) < max_poc )+            sps->i_log2_max_poc_lsb++;     }     else if( sps->i_poc_type == 1 )     {@@ -193,12 +203,6 @@         sps->vui.b_fixed_frame_rate = 1;     } -    sps->vui.i_num_reorder_frames = param->b_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;-    /* extra slot with pyramid so that we don't have to override the-     * order of forgetting old pictures */-    sps->vui.i_max_dec_frame_buffering =-    sps->i_num_ref_frames = X264_MIN(16, X264_MAX(param->i_frame_reference, 1 + sps->vui.i_num_reorder_frames));-     sps->vui.b_bitstream_restriction = 1;     if( sps->vui.b_bitstream_restriction )     {@@ -545,6 +549,22 @@     bs_rbsp_trailing( s ); } +void x264_sei_recovery_point_write( x264_t *h, bs_t *s )+{+    int payload_size;++    bs_write( s, 8, 0x06 ); // payload_type = Recovery Point+    payload_size = 1 ;  // values as given below will never be > 1    ++    bs_write( s, 8, (payload_size + 7) / 8);+    bs_write_ue( s, 0 ); // recovery_frame_cnt 0+    bs_write( s, 1, 1 ); //exact_match_flag 1+    bs_write( s, 1, 0 ); //broken_link_flag 0+    bs_write( s, 2, 0 ); //changing_slice_group 0    ++    bs_align_10( s );+}+ int x264_sei_version_write( x264_t *h, bs_t *s ) {     int i;diff -NdurwBE x264-bluray/encoder/set.h x264-bluray3/encoder/set.h--- x264-bluray/encoder/set.h	2009-09-01 03:43:06 +0300+++ x264-bluray3/encoder/set.h	2009-09-01 03:21:31 +0300@@ -24,6 +24,7 @@ #ifndef X264_ENCODER_SET_H #define X264_ENCODER_SET_H +void x264_sei_recovery_point_write( x264_t *h, bs_t *s ); void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ); void x264_sps_write( bs_t *s, x264_sps_t *sps ); void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *sps );diff -NdurwBE x264-bluray/encoder/slicetype.c x264-bluray3/encoder/slicetype.c--- x264-bluray/encoder/slicetype.c	2009-09-01 03:42:50 +0300+++ x264-bluray3/encoder/slicetype.c	2009-09-01 03:30:26 +0300@@ -704,6 +704,7 @@ {     x264_mb_analysis_t a;     x264_frame_t *frames[X264_LOOKAHEAD_MAX+3] = { NULL, };+    int minigop_end_frame_type[X264_LOOKAHEAD_MAX+3];     int num_frames;     int keyint_limit;     int i,j;@@ -717,7 +718,11 @@         return;     frames[0] = h->frames.last_nonb;     for( j = 0; h->frames.next[j] && h->frames.next[j]->i_type == X264_TYPE_AUTO; j++ )+    {         frames[j+1] = h->frames.next[j];+        minigop_end_frame_type[j+1] = frames[j+1]->i_frame - h->frames.i_last_idr+                                   >= h->param.i_keyint_max ? X264_TYPE_I : X264_TYPE_P;+    }      if( !j )         return;@@ -726,7 +731,8 @@     num_frames = X264_MIN( j, keyint_limit );      x264_lowres_context_init( h, &a );-    idr_frame_type = frames[1]->i_frame - h->frames.i_last_idr >= h->param.i_keyint_min ? X264_TYPE_IDR : X264_TYPE_I;+    idr_frame_type = frames[1]->i_frame - h->frames.i_last_idr >= h->param.i_keyint_min ?+                   ( h->param.b_open_gop && h->frames.i_last_idr > -1 ? X264_TYPE_I : X264_TYPE_IDR ) : X264_TYPE_I;      /* This is important psy-wise: if we have a non-scenecut keyframe,      * there will be significant visual artifacts if the frames just before@@ -736,7 +742,7 @@         num_frames = j;     else if( num_frames == 1 )     {-        frames[1]->i_type = X264_TYPE_P;+        frames[1]->i_type = minigop_end_frame_type[1];         if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, 0, 1 ) )             frames[1]->i_type = idr_frame_type;         return;@@ -771,9 +777,9 @@                 num_bframes = strspn( best_paths[num_frames-2], "B" );                 /* Load the results of the analysis into the frame types. */                 for( j = 1; j < num_frames; j++ )-                    frames[j]->i_type = best_paths[num_frames-2][j-1] == 'B' ? X264_TYPE_B : X264_TYPE_P;+                    frames[j]->i_type = best_paths[num_frames-2][j-1] == 'B' ? X264_TYPE_B : minigop_end_frame_type[j];             }-            frames[num_frames]->i_type = X264_TYPE_P;+            frames[num_frames]->i_type = minigop_end_frame_type[num_frames];         }         else if( h->param.i_bframe_adaptive == X264_B_ADAPT_FAST )         {@@ -783,7 +789,7 @@                 if( frames[i+2]->i_intra_mbs[2] > i_mb_count / 2 )                 {                     frames[i+1]->i_type = X264_TYPE_P;-                    frames[i+2]->i_type = X264_TYPE_P;+                    frames[i+2]->i_type = minigop_end_frame_type[i+2];                     i += 2;                     continue;                 }@@ -795,7 +801,7 @@                 if( cost1p0 + cost2p0 < cost1b1 + cost2p1 )                 {                     frames[i+1]->i_type = X264_TYPE_P;-                    frames[i+2]->i_type = X264_TYPE_P;+                    frames[i+2]->i_type = minigop_end_frame_type[i+2];                     i += 2;                     continue;                 }@@ -804,7 +810,7 @@                 #define INTER_THRESH 300                 #define P_SENS_BIAS (50 - h->param.i_bframe_bias)                 frames[i+1]->i_type = X264_TYPE_B;-                frames[i+2]->i_type = X264_TYPE_P;+                frames[i+2]->i_type = minigop_end_frame_type[i+2];                  for( j = i+2; j <= X264_MIN( h->param.i_bframe, num_frames-1 ); j++ )                 {@@ -813,7 +819,7 @@                      if( pcost > pthresh*i_mb_count || frames[j+1]->i_intra_mbs[j-i+1] > i_mb_count/3 )                     {-                        frames[j]->i_type = X264_TYPE_P;+                        frames[j]->i_type = minigop_end_frame_type[j];                         break;                     }                     else@@ -821,7 +827,7 @@                 }                 i = j;             }-            frames[i+!i]->i_type = X264_TYPE_P;+            frames[i+!i]->i_type = minigop_end_frame_type[i+!i];             num_bframes = 0;             while( num_bframes < num_frames && frames[num_bframes+1]->i_type == X264_TYPE_B )                 num_bframes++;@@ -830,15 +836,15 @@         {             num_bframes = X264_MIN(num_frames-1, h->param.i_bframe);             for( j = 1; j < num_frames; j++ )-                frames[j]->i_type = (j%(num_bframes+1)) ? X264_TYPE_B : X264_TYPE_P;-            frames[num_frames]->i_type = X264_TYPE_P;+                frames[j]->i_type = (j%(num_bframes+1)) ? X264_TYPE_B : minigop_end_frame_type[j];+            frames[num_frames]->i_type = minigop_end_frame_type[num_frames];         }          /* Check scenecut on the first minigop. */         for( j = 1; j < num_bframes+1; j++ )             if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, j, j+1 ) )             {-                frames[j]->i_type = X264_TYPE_P;+                frames[j]->i_type = minigop_end_frame_type[j];                 num_analysed_frames = j;                 break;             }@@ -848,7 +854,7 @@     else     {         for( j = 1; j < num_frames; j++ )-            frames[j]->i_type = X264_TYPE_P;+            frames[j]->i_type = minigop_end_frame_type[j];         reset_start = !keyframe + 1;         num_bframes = 0;     }@@ -867,9 +873,9 @@     {         if( ((j-keyint_limit) % h->param.i_keyint_max) == 0 )         {-            if( j && h->param.i_keyint_max > 1 )-                frames[j]->i_type = X264_TYPE_P;-            frames[j+1]->i_type = X264_TYPE_IDR;+            //if( j && h->param.i_keyint_max > 1 )+            //    frames[j]->i_type = X264_TYPE_P;+            frames[j+1]->i_type = minigop_end_frame_type[j+1];             reset_start = X264_MIN( reset_start, j+2 );         }     }@@ -912,12 +917,15 @@         if( frm->i_frame - h->frames.i_last_idr >= h->param.i_keyint_max )         {             if( frm->i_type == X264_TYPE_AUTO )-                frm->i_type = X264_TYPE_IDR;-            if( frm->i_type != X264_TYPE_IDR )+                frm->i_type = h->param.b_open_gop && h->frames.i_last_idr > -1 ? X264_TYPE_I : X264_TYPE_IDR;+            if( frm->i_type != X264_TYPE_I && frm->i_type != X264_TYPE_IDR )                 x264_log( h, X264_LOG_WARNING, "specified frame type (%d) is not compatible with keyframe interval\n", frm->i_type );         }-        if( frm->i_type == X264_TYPE_IDR )+        if( ( frm->i_type == X264_TYPE_I || frm->i_type == X264_TYPE_IDR )+                          && !(frm->i_frame - h->frames.i_last_idr < h->param.i_keyint_min)+                          && !h->param.b_open_gop )         {+            frm->i_type = X264_TYPE_IDR;             /* Close GOP */             if( bframes > 0 )             {diff -NdurwBE x264-bluray/muxers.c x264-bluray3/muxers.c--- x264-bluray/muxers.c	2009-09-01 03:42:50 +0300+++ x264-bluray3/muxers.c	2009-09-01 03:21:31 +0300@@ -800,7 +800,7 @@     uint64_t pts = (uint64_t)p_picture->i_pts;     int32_t offset = p_mp4->i_init_delay + pts - dts; -    p_mp4->p_sample->IsRAP = p_picture->i_type == X264_TYPE_IDR ? 1 : 0;+    p_mp4->p_sample->IsRAP = p_picture->b_keyframe;     p_mp4->p_sample->DTS = dts;     p_mp4->p_sample->CTS_Offset = offset;     gf_isom_add_sample(p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx, p_mp4->p_sample);@@ -1016,8 +1016,7 @@      p_mkv->b_writing_frame = 0; -    return mk_setFrameFlags( p_mkv->w, i_stamp,-                             p_picture->i_type == X264_TYPE_IDR );+    return mk_setFrameFlags( p_mkv->w, i_stamp, p_picture->b_keyframe ); }  int close_file_mkv( hnd_t handle )diff -NdurwBE x264-bluray/x264.c x264-bluray3/x264.c--- x264-bluray/x264.c	2009-09-01 03:43:06 +0300+++ x264-bluray3/x264.c	2009-09-01 03:21:31 +0300@@ -191,6 +191,8 @@         "                                  - 2: Optimal (slow with high --bframes)\n", defaults->i_bframe_adaptive );     H1( "      --b-bias <integer>      Influences how often B-frames are used [%d]\n", defaults->i_bframe_bias );     H0( "      --b-pyramid             Keep some B-frames as references\n" );+    H0( "      --strict-dpb            Stricter usage of dpb when b-pyramid is active (ref 4+)\n" );+    H0( "      --open-gop              Use non IDR i-frames at max-keyint w/ recovery pt SEI\n" );     H0( "      --no-cabac              Disable CABAC\n" );     H0( "  -r, --ref <integer>         Number of reference frames [%d]\n", defaults->i_frame_reference );     H1( "      --no-deblock            Disable loop filter\n" );@@ -400,9 +402,11 @@     { "no-b-adapt",        no_argument, NULL, 0 },     { "b-bias",      required_argument, NULL, 0 },     { "b-pyramid",         no_argument, NULL, 0 },+    { "strict-dpb",        no_argument, NULL, 0 },     { "min-keyint",  required_argument, NULL, 'i' },     { "keyint",      required_argument, NULL, 'I' },     { "scenecut",    required_argument, NULL, 0 },+    { "open-gop",          no_argument, NULL, 0 },     { "no-scenecut",       no_argument, NULL, 0 },     { "nf",                no_argument, NULL, 0 },     { "no-deblock",        no_argument, NULL, 0 },diff -NdurwBE x264-bluray/x264.h x264-bluray3/x264.h--- x264-bluray/x264.h	2009-09-01 03:43:06 +0300+++ x264-bluray3/x264.h	2009-09-01 03:21:31 +0300@@ -195,6 +195,8 @@     int         i_bframe_adaptive;     int         i_bframe_bias;     int         b_bframe_pyramid;   /* Keep some B-frames as references */+    int         b_strictdpb;        /* Reserve a spot in dpb for delayed display time b frames */+    int         b_open_gop;      int         b_deblocking_filter;     int         i_deblocking_filter_alphac0;    /* [-6, 6] -6 light filter, 6 strong */@@ -370,6 +372,7 @@     int     i_type;     /* In: force quantizer for > 0 */     int     i_qpplus1;+    int     b_keyframe;     /* In: user pts, Out: pts of encoded picture (user)*/     int64_t i_pts;     /* In: custom encoding parameters to be set from this frame forwards