summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/Jamfile1
-rw-r--r--contrib/patch-x264-idr.patch17
-rw-r--r--libhb/encx264.c31
3 files changed, 48 insertions, 1 deletions
diff --git a/contrib/Jamfile b/contrib/Jamfile
index f321d293d..1ece7d902 100644
--- a/contrib/Jamfile
+++ b/contrib/Jamfile
@@ -332,6 +332,7 @@ rule LibX264
LIBX264_PATCH += "patch -p1 < ../patch-x264-cygwin.patch && " ;
}
LIBX264_PATCH += "patch -p0 < ../patch-x264-aq.patch && " ;
+ LIBX264_PATCH += "patch -p0 < ../patch-x264-idr.patch && " ;
Depends $(<) : $(>) ;
Depends lib : $(<) ;
}
diff --git a/contrib/patch-x264-idr.patch b/contrib/patch-x264-idr.patch
new file mode 100644
index 000000000..df4294f12
--- /dev/null
+++ b/contrib/patch-x264-idr.patch
@@ -0,0 +1,17 @@
+Index: encoder/slicetype.c
+===================================================================
+--- encoder/slicetype.c (revision 665)
++++ encoder/slicetype.c (working copy)
+@@ -379,7 +379,12 @@
+ return;
+ frames[0] = h->frames.last_nonb;
+ for( j = 0; h->frames.next[j]; j++ )
++ {
++ // if the app wants an IDR, give it to them
++ if ( h->frames.next[j]->i_type == X264_TYPE_IDR )
++ return;
+ frames[j+1] = h->frames.next[j];
++ }
+ keyint_limit = h->param.i_keyint_max - frames[0]->i_frame + h->frames.i_last_idr - 1;
+ num_frames = X264_MIN( j, keyint_limit );
+ if( num_frames == 0 )
diff --git a/libhb/encx264.c b/libhb/encx264.c
index 98ede9704..95922d504 100644
--- a/libhb/encx264.c
+++ b/libhb/encx264.c
@@ -38,6 +38,7 @@ struct hb_work_private_s
int64_t dts_write_index;
int64_t dts_read_index;
+ int64_t next_chap;
char filename[1024];
};
@@ -232,6 +233,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
pv->dts_write_index = 0;
pv->dts_read_index = 0;
+ pv->next_chap = 0;
return 0;
}
@@ -276,7 +278,25 @@ int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
job->height / 4, job->width * job->height / 4 );
}
- pv->pic_in.i_type = X264_TYPE_AUTO;
+ if( in->new_chap && job->chapter_markers )
+ {
+ /* chapters have to start with an IDR frame so request that this
+ frame be coded as IDR. Since there may be up to 16 frames
+ currently buffered in the encoder remember the timestamp so
+ when this frame finally pops out of the encoder we'll mark
+ its buffer as the start of a chapter. */
+ pv->pic_in.i_type = X264_TYPE_IDR;
+ if( pv->next_chap == 0 )
+ {
+ pv->next_chap = in->start;
+ }
+ /* don't let 'work_loop' put a chapter mark on the wrong buffer */
+ in->new_chap = 0;
+ }
+ else
+ {
+ pv->pic_in.i_type = X264_TYPE_AUTO;
+ }
pv->pic_in.i_qpplus1 = 0;
// Remember current PTS value, use as DTS later
@@ -365,6 +385,15 @@ int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
/* Decide what type of frame we have. */
case X264_TYPE_IDR:
buf->frametype = HB_FRAME_IDR;
+ /* if we have a chapter marker pending and this
+ frame's presentation time stamp is at or after
+ the marker's time stamp, use this as the
+ chapter start. */
+ if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
+ {
+ pv->next_chap = 0;
+ buf->new_chap = 1;
+ }
break;
case X264_TYPE_I:
buf->frametype = HB_FRAME_I;