mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
videoencoder: make PTS and DTS handling more explicit
This commit is contained in:
parent
c68683c15f
commit
136a3fd37f
1 changed files with 26 additions and 14 deletions
|
@ -215,7 +215,8 @@ static gboolean gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
|
||||||
static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
|
static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
|
static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
|
||||||
encoder, GstBuffer * buf, GstClockTime timestamp, GstClockTime duration);
|
encoder, GstBuffer * buf, GstClockTime pts, GstClockTime dts,
|
||||||
|
GstClockTime duration);
|
||||||
|
|
||||||
static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
|
static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
@ -1066,7 +1067,7 @@ error:
|
||||||
|
|
||||||
static GstVideoCodecFrame *
|
static GstVideoCodecFrame *
|
||||||
gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
|
gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
|
||||||
GstClockTime timestamp, GstClockTime duration)
|
GstClockTime pts, GstClockTime dts, GstClockTime duration)
|
||||||
{
|
{
|
||||||
GstVideoEncoderPrivate *priv = encoder->priv;
|
GstVideoEncoderPrivate *priv = encoder->priv;
|
||||||
GstVideoCodecFrame *frame;
|
GstVideoCodecFrame *frame;
|
||||||
|
@ -1086,7 +1087,8 @@ gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
|
||||||
frame->events = priv->current_frame_events;
|
frame->events = priv->current_frame_events;
|
||||||
priv->current_frame_events = NULL;
|
priv->current_frame_events = NULL;
|
||||||
frame->input_buffer = buf;
|
frame->input_buffer = buf;
|
||||||
frame->pts = timestamp;
|
frame->pts = pts;
|
||||||
|
frame->dts = dts;
|
||||||
frame->duration = duration;
|
frame->duration = duration;
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
|
@ -1100,8 +1102,9 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
GstVideoEncoderPrivate *priv;
|
GstVideoEncoderPrivate *priv;
|
||||||
GstVideoEncoderClass *klass;
|
GstVideoEncoderClass *klass;
|
||||||
GstVideoCodecFrame *frame;
|
GstVideoCodecFrame *frame;
|
||||||
|
GstClockTime pts, dts, duration;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
guint64 start, stop = GST_CLOCK_TIME_NONE, cstart, cstop;
|
guint64 start, stop, cstart, cstop;
|
||||||
|
|
||||||
encoder = GST_VIDEO_ENCODER (parent);
|
encoder = GST_VIDEO_ENCODER (parent);
|
||||||
priv = encoder->priv;
|
priv = encoder->priv;
|
||||||
|
@ -1111,20 +1114,27 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||||||
|
|
||||||
start = GST_BUFFER_TIMESTAMP (buf);
|
pts = GST_BUFFER_PTS (buf);
|
||||||
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buf)))
|
dts = GST_BUFFER_DTS (buf);
|
||||||
stop = start + GST_BUFFER_DURATION (buf);
|
duration = GST_BUFFER_DURATION (buf);
|
||||||
|
|
||||||
GST_LOG_OBJECT (encoder,
|
GST_LOG_OBJECT (encoder,
|
||||||
"received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
|
"received buffer of size %" G_GSIZE_FORMAT " with PTS %" GST_TIME_FORMAT
|
||||||
", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
|
", PTS %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (start), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
gst_buffer_get_size (buf), GST_TIME_ARGS (pts), GST_TIME_ARGS (dts),
|
||||||
|
GST_TIME_ARGS (duration));
|
||||||
|
|
||||||
if (priv->at_eos) {
|
if (priv->at_eos) {
|
||||||
ret = GST_FLOW_EOS;
|
ret = GST_FLOW_EOS;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start = pts;
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (duration))
|
||||||
|
stop = start + duration;
|
||||||
|
else
|
||||||
|
stop = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
/* Drop buffers outside of segment */
|
/* Drop buffers outside of segment */
|
||||||
if (!gst_segment_clip (&encoder->output_segment,
|
if (!gst_segment_clip (&encoder->output_segment,
|
||||||
GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
|
GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
|
||||||
|
@ -1133,7 +1143,8 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = gst_video_encoder_new_frame (encoder, buf, cstart, cstop - cstart);
|
frame =
|
||||||
|
gst_video_encoder_new_frame (encoder, buf, cstart, dts, cstop - cstart);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (encoder);
|
GST_OBJECT_LOCK (encoder);
|
||||||
if (priv->force_key_unit) {
|
if (priv->force_key_unit) {
|
||||||
|
@ -1143,7 +1154,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
|
|
||||||
running_time =
|
running_time =
|
||||||
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
|
||||||
GST_BUFFER_TIMESTAMP (buf));
|
cstart);
|
||||||
|
|
||||||
for (l = priv->force_key_unit; l; l = l->next) {
|
for (l = priv->force_key_unit; l; l = l->next) {
|
||||||
ForcedKeyUnitEvent *tmp = l->data;
|
ForcedKeyUnitEvent *tmp = l->data;
|
||||||
|
@ -1177,6 +1188,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
|
gst_video_codec_frame_ref (frame);
|
||||||
priv->frames = g_list_append (priv->frames, frame);
|
priv->frames = g_list_append (priv->frames, frame);
|
||||||
|
|
||||||
/* new data, more finish needed */
|
/* new data, more finish needed */
|
||||||
|
@ -1185,7 +1197,6 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
|
GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
|
||||||
frame->presentation_frame_number);
|
frame->presentation_frame_number);
|
||||||
|
|
||||||
gst_video_codec_frame_ref (frame);
|
|
||||||
ret = klass->handle_frame (encoder, frame);
|
ret = klass->handle_frame (encoder, frame);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -1439,7 +1450,8 @@ gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
|
||||||
frame->distance_from_sync = priv->distance_from_sync;
|
frame->distance_from_sync = priv->distance_from_sync;
|
||||||
priv->distance_from_sync++;
|
priv->distance_from_sync++;
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (frame->output_buffer) = frame->pts;
|
GST_BUFFER_PTS (frame->output_buffer) = frame->pts;
|
||||||
|
GST_BUFFER_DTS (frame->output_buffer) = frame->dts;
|
||||||
GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;
|
GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;
|
||||||
|
|
||||||
/* update rate estimate */
|
/* update rate estimate */
|
||||||
|
|
Loading…
Reference in a new issue