From dc7b2548052c5d96d836f6a691ade566e4e85e87 Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Wed, 26 Nov 2014 21:06:57 +0100 Subject: [PATCH] videoencoder: Add gst_video_encoder_set_min_pts() For streams with reordered frames this can be used to ensure that there is enough time to accomodate first DTS, which may be less than first PTS https://bugzilla.gnome.org/show_bug.cgi?id=740575 --- gst-libs/gst/video/gstvideoencoder.c | 50 ++++++++++++++++++++++++++++++++++++ gst-libs/gst/video/gstvideoencoder.h | 2 ++ win32/common/libgstvideo.def | 1 + 3 files changed, 53 insertions(+) diff --git a/gst-libs/gst/video/gstvideoencoder.c b/gst-libs/gst/video/gstvideoencoder.c index f7cc98b..fdecd4d 100644 --- a/gst-libs/gst/video/gstvideoencoder.c +++ b/gst-libs/gst/video/gstvideoencoder.c @@ -164,6 +164,11 @@ struct _GstVideoEncoderPrivate GstTagList *tags; gboolean tags_changed; + + GstClockTime min_pts; + /* adjustment needed on pts, dts, segment start and stop to accomodate + * min_pts */ + GstClockTime time_adjustment; }; typedef struct _ForcedKeyUnitEvent ForcedKeyUnitEvent; @@ -343,6 +348,8 @@ gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard) priv->bytes = 0; priv->time = 0; + priv->time_adjustment = GST_CLOCK_TIME_NONE; + if (hard) { gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME); gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME); @@ -455,6 +462,8 @@ gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass) priv->min_latency = 0; priv->max_latency = 0; + priv->min_pts = GST_CLOCK_TIME_NONE; + priv->time_adjustment = GST_CLOCK_TIME_NONE; gst_video_encoder_reset (encoder, TRUE); } @@ -885,8 +894,19 @@ gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event) break; } + if (encoder->priv->time_adjustment != GST_CLOCK_TIME_NONE) { + segment.start += encoder->priv->time_adjustment; + if (GST_CLOCK_TIME_IS_VALID (segment.stop)) { + segment.stop += encoder->priv->time_adjustment; + } + } + encoder->output_segment = segment; GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); + + gst_event_unref (event); + event = gst_event_new_segment (&encoder->output_segment); + break; } default: @@ -1323,6 +1343,17 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) else duration = GST_CLOCK_TIME_NONE; + if (priv->min_pts != GST_CLOCK_TIME_NONE + && priv->time_adjustment == GST_CLOCK_TIME_NONE) { + if (cstart < priv->min_pts) { + priv->time_adjustment = priv->min_pts - cstart; + } + } + + if (priv->time_adjustment != GST_CLOCK_TIME_NONE) { + cstart += priv->time_adjustment; + } + /* incoming DTS is not really relevant and does not make sense anyway, * so pass along _NONE and maybe come up with something better later on */ frame = gst_video_encoder_new_frame (encoder, buf, cstart, @@ -2297,3 +2328,22 @@ gst_video_encoder_get_allocator (GstVideoEncoder * encoder, if (params) *params = encoder->priv->params; } + +/** + * Request minimal value for PTS passed to handle_frame. + * + * For streams with reordered frames this can be used to ensure that there + * is enough time to accomodate first DTS, which may be less than first PTS + * + * @encoder: a #GstVideoEncoder + * @min_pts: minimal PTS that will be passed to handle_frame + * + * Since 1.6 + */ +void +gst_video_encoder_set_min_pts (GstVideoEncoder * encoder, GstClockTime min_pts) +{ + g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder)); + encoder->priv->min_pts = min_pts; + encoder->priv->time_adjustment = GST_CLOCK_TIME_NONE; +} diff --git a/gst-libs/gst/video/gstvideoencoder.h b/gst-libs/gst/video/gstvideoencoder.h index aea119d..5299062 100644 --- a/gst-libs/gst/video/gstvideoencoder.h +++ b/gst-libs/gst/video/gstvideoencoder.h @@ -333,6 +333,8 @@ void gst_video_encoder_get_allocator (GstVideoEncoder *encoder, GstAllocator **allocator, GstAllocationParams *params); +void gst_video_encoder_set_min_pts(GstVideoEncoder *encoder, GstClockTime min_pts); + G_END_DECLS #endif diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index 27254c9..425f9cf 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -148,6 +148,7 @@ EXPORTS gst_video_encoder_proxy_getcaps gst_video_encoder_set_headers gst_video_encoder_set_latency + gst_video_encoder_set_min_pts gst_video_encoder_set_output_state gst_video_event_is_force_key_unit gst_video_event_new_downstream_force_key_unit -- 2.7.4