diff options
-rw-r--r-- | contrib/libmp4v2/module.defs | 2 | ||||
-rw-r--r-- | libhb/encx264.c | 6 | ||||
-rw-r--r-- | libhb/muxmp4.c | 77 |
3 files changed, 73 insertions, 12 deletions
diff --git a/contrib/libmp4v2/module.defs b/contrib/libmp4v2/module.defs index 784fc16d4..a46769075 100644 --- a/contrib/libmp4v2/module.defs +++ b/contrib/libmp4v2/module.defs @@ -1,7 +1,7 @@ $(eval $(call import.MODULE.defs,LIBMP4V2,libmp4v2)) $(eval $(call import.CONTRIB.defs,LIBMP4V2)) -LIBMP4V2.FETCH.url = http://download.m0k.org/handbrake/contrib/libmp4v2-2.0-r286.tar.gz +LIBMP4V2.FETCH.url = http://download.m0k.org/handbrake/contrib/libmp4v2-2.0-r290.tar.gz LIBMP4V2.EXTRACT.tarbase = libmp4v2 ## propagate more flags diff --git a/libhb/encx264.c b/libhb/encx264.c index 360dc8448..374c92184 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -508,6 +508,12 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, (nal[i].i_ref_idc != NAL_PRIORITY_DISPOSABLE) ) buf->frametype = HB_FRAME_BREF; + /* Expose disposable bit to muxer. */ + if( nal[i].i_ref_idc == NAL_PRIORITY_DISPOSABLE ) + buf->flags &= ~HB_FRAME_REF; + else + buf->flags |= HB_FRAME_REF; + buf->size += size; } // make sure we found at least one video frame diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c index 7442532ca..29d08ca88 100644 --- a/libhb/muxmp4.c +++ b/libhb/muxmp4.c @@ -514,18 +514,73 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data, duration = MP4_INVALID_DURATION; } - // Here's where the sample actually gets muxed. - if( !MP4WriteSample( m->file, - mux_data->track, - buf->data, - buf->size, - duration, - offset, - ( job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data ) ? - ( buf->frametype == HB_FRAME_IDR ) : ( ( buf->frametype & HB_FRAME_KEY ) != 0 ) ) ) + /* Here's where the sample actually gets muxed. */ + if( job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data ) { - hb_error("Failed to write to output file, disk full?"); - *job->die = 1; + /* Compute dependency flags. + * + * This mechanism is (optionally) used by media players such as QuickTime + * to offer better scrubbing performance. The most influential bits are + * MP4_SDT_HAS_NO_DEPENDENTS and MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED. + * + * Other bits are possible but no example media using such bits have been + * found. + * + * It is acceptable to supply 0-bits for any samples which characteristics + * cannot be positively guaranteed. + */ + int sync = 0; + uint32_t dflags = 0; + + /* encoding layer signals if frame is referenced by other frames */ + if( buf->flags & HB_FRAME_REF ) + dflags |= MP4_SDT_HAS_DEPENDENTS; + else + dflags |= MP4_SDT_HAS_NO_DEPENDENTS; /* disposable */ + + switch( buf->frametype ) + { + case HB_FRAME_IDR: + sync = 1; + break; + case HB_FRAME_I: + dflags |= MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED; + break; + case HB_FRAME_P: + dflags |= MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED; + break; + case HB_FRAME_BREF: + case HB_FRAME_B: + default: + break; /* nothing to mark */ + } + + if( !MP4WriteSampleDependency( m->file, + mux_data->track, + buf->data, + buf->size, + duration, + offset, + sync, + dflags )) + { + hb_error("Failed to write to output file, disk full?"); + *job->die = 1; + } + } + else + { + if( !MP4WriteSample( m->file, + mux_data->track, + buf->data, + buf->size, + duration, + offset, + ( buf->frametype & HB_FRAME_KEY ) != 0 )) + { + hb_error("Failed to write to output file, disk full?"); + *job->die = 1; + } } return 0; |