diff options
author | Nicolas Dufresne <nicolas.dufresne@collabora.co.uk> | 2014-06-06 20:23:15 -0400 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.co.uk> | 2014-07-19 12:59:05 -0400 |
commit | 698714fc9781c614ea5d65744508d5db73f16066 (patch) | |
tree | 7ab9cfa57c799fbcb564da62c96cf716f9ffca43 /ext | |
parent | caee6eb21d8ee5eb50600f373809c737fab7dbec (diff) |
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
Diffstat (limited to 'ext')
-rw-r--r-- | ext/x264/gstx264enc.c | 26 | ||||
-rw-r--r-- | ext/x264/gstx264enc.h | 2 |
2 files changed, 10 insertions, 18 deletions
diff --git a/ext/x264/gstx264enc.c b/ext/x264/gstx264enc.c index 3d81d962..aa1e481e 100644 --- a/ext/x264/gstx264enc.c +++ b/ext/x264/gstx264enc.c @@ -1470,7 +1470,7 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder) encoder->reconfig = FALSE; /* good start, will be corrected if needed */ - encoder->dts_offset = 0; + encoder->ts_offset = 0; 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_pts = frame->pts; - pic_in.i_dts = frame->dts; pic_in.opaque = GINT_TO_POINTER (frame->system_frame_number); 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 */ 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) { - /* should be ok now, surprise if not */ - GST_WARNING_OBJECT (encoder, "negative dts after offset compensation"); - frame->dts = GST_CLOCK_TIME_NONE; - } else - frame->dts = pic_out.i_dts + encoder->dts_offset; + /* As upstream often starts with PTS set to zero, in presence of b-frames, + * x264 will have to use negative DTS. As this is not supported by + * GStreamer, we shift both DTS and PTS forward to make it positive. It's + * important to shift both in order to ensure PTS remains >= to DTS. */ + if (pic_out.i_dts < encoder->ts_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) { GST_DEBUG_OBJECT (encoder, "Output keyframe"); diff --git a/ext/x264/gstx264enc.h b/ext/x264/gstx264enc.h index e2349379..acf309d9 100644 --- a/ext/x264/gstx264enc.h +++ b/ext/x264/gstx264enc.h @@ -51,7 +51,7 @@ struct _GstX264Enc x264_t *x264enc; x264_param_t x264param; gint current_byte_stream; - GstClockTime dts_offset; + gint64 ts_offset; /* List of frame/buffer mapping structs for * pending frames */ |