mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
x264enc: Shift both PTS and DTS to ensure positive timestamp
Currently we only shift DTS to compensate that we don't support negative timestamp. This cause a problem that PTS is no longer >= DTS and may make muxers live much harder. Instead, shift both PTS/DTS forward. Also remove all the hack to handle this which seems the result of thinking libx264 is bugged. https://bugzilla.gnome.org/show_bug.cgi?id=731351
This commit is contained in:
parent
caee6eb21d
commit
698714fc97
2 changed files with 10 additions and 18 deletions
|
@ -1470,7 +1470,7 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
|
||||||
|
|
||||||
encoder->reconfig = FALSE;
|
encoder->reconfig = FALSE;
|
||||||
/* good start, will be corrected if needed */
|
/* good start, will be corrected if needed */
|
||||||
encoder->dts_offset = 0;
|
encoder->ts_offset = 0;
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
|
@ -1964,7 +1964,6 @@ gst_x264_enc_handle_frame (GstVideoEncoder * video_enc,
|
||||||
|
|
||||||
pic_in.i_type = X264_TYPE_AUTO;
|
pic_in.i_type = X264_TYPE_AUTO;
|
||||||
pic_in.i_pts = frame->pts;
|
pic_in.i_pts = frame->pts;
|
||||||
pic_in.i_dts = frame->dts;
|
|
||||||
pic_in.opaque = GINT_TO_POINTER (frame->system_frame_number);
|
pic_in.opaque = GINT_TO_POINTER (frame->system_frame_number);
|
||||||
|
|
||||||
ret = gst_x264_enc_encode_frame (encoder, &pic_in, frame, &i_nal, TRUE);
|
ret = gst_x264_enc_encode_frame (encoder, &pic_in, frame, &i_nal, TRUE);
|
||||||
|
@ -2070,23 +2069,16 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
|
||||||
|
|
||||||
/* we want to know if x264 is messing around with this */
|
/* we want to know if x264 is messing around with this */
|
||||||
g_assert (frame->pts == pic_out.i_pts);
|
g_assert (frame->pts == pic_out.i_pts);
|
||||||
if (pic_out.b_keyframe) {
|
|
||||||
/* expect dts == pts, and also positive ts,
|
|
||||||
* so arrange for an offset if needed */
|
|
||||||
if (pic_out.i_dts + encoder->dts_offset != pic_out.i_pts) {
|
|
||||||
encoder->dts_offset = pic_out.i_pts - pic_out.i_dts;
|
|
||||||
GST_DEBUG_OBJECT (encoder, "determined dts offset %" G_GINT64_FORMAT,
|
|
||||||
encoder->dts_offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pic_out.i_dts + (gint64) encoder->dts_offset < 0) {
|
/* As upstream often starts with PTS set to zero, in presence of b-frames,
|
||||||
/* should be ok now, surprise if not */
|
* x264 will have to use negative DTS. As this is not supported by
|
||||||
GST_WARNING_OBJECT (encoder, "negative dts after offset compensation");
|
* GStreamer, we shift both DTS and PTS forward to make it positive. It's
|
||||||
frame->dts = GST_CLOCK_TIME_NONE;
|
* important to shift both in order to ensure PTS remains >= to DTS. */
|
||||||
} else
|
if (pic_out.i_dts < encoder->ts_offset)
|
||||||
frame->dts = pic_out.i_dts + encoder->dts_offset;
|
encoder->ts_offset = pic_out.i_dts;
|
||||||
|
|
||||||
|
frame->dts = pic_out.i_dts - encoder->ts_offset;
|
||||||
|
frame->pts = pic_out.i_pts - encoder->ts_offset;
|
||||||
|
|
||||||
if (pic_out.b_keyframe) {
|
if (pic_out.b_keyframe) {
|
||||||
GST_DEBUG_OBJECT (encoder, "Output keyframe");
|
GST_DEBUG_OBJECT (encoder, "Output keyframe");
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct _GstX264Enc
|
||||||
x264_t *x264enc;
|
x264_t *x264enc;
|
||||||
x264_param_t x264param;
|
x264_param_t x264param;
|
||||||
gint current_byte_stream;
|
gint current_byte_stream;
|
||||||
GstClockTime dts_offset;
|
gint64 ts_offset;
|
||||||
|
|
||||||
/* List of frame/buffer mapping structs for
|
/* List of frame/buffer mapping structs for
|
||||||
* pending frames */
|
* pending frames */
|
||||||
|
|
Loading…
Reference in a new issue