rendered paste bodydiff -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