summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreddyg <[email protected]>2007-09-17 03:01:07 +0000
committereddyg <[email protected]>2007-09-17 03:01:07 +0000
commit7b0444d5945ab264fa3b7086dd44a3c6ae383ee4 (patch)
treea02302e038fe02d941319d421ce7217a2aed5824
parentb67ea5e9820f3ed2e969da3ae94205e4097c5da6 (diff)
Van's changes to the x264 lib and HB encoder to ensure that an IDR frame is used for each new chapter. Well done and lots of thanks to Van for this one.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@967 b64f7644-9d1e-0410-96f1-a4d463321fa5
-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;