mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 03:46:11 +00:00
vdpauvideopostprocess: implement basic qos handling
This commit is contained in:
parent
55b108f7ca
commit
51caa55d4e
2 changed files with 99 additions and 1 deletions
|
@ -626,6 +626,9 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp)
|
||||||
vpp->interlaced = FALSE;
|
vpp->interlaced = FALSE;
|
||||||
vpp->field_duration = GST_CLOCK_TIME_NONE;
|
vpp->field_duration = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
|
vpp->earliest_time = GST_CLOCK_TIME_NONE;
|
||||||
|
vpp->discont = FALSE;
|
||||||
|
|
||||||
vpp->mixer = VDP_INVALID_HANDLE;
|
vpp->mixer = VDP_INVALID_HANDLE;
|
||||||
vpp->device = NULL;
|
vpp->device = NULL;
|
||||||
|
|
||||||
|
@ -654,8 +657,9 @@ gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GstVdpVideoPostProcess *vpp =
|
GstVdpVideoPostProcess *vpp =
|
||||||
GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
|
GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstClockTime qostime;
|
||||||
|
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstVdpPicture current_pic;
|
GstVdpPicture current_pic;
|
||||||
|
|
||||||
guint32 video_surfaces_past_count;
|
guint32 video_surfaces_past_count;
|
||||||
|
@ -664,6 +668,47 @@ gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
guint32 video_surfaces_future_count;
|
guint32 video_surfaces_future_count;
|
||||||
VdpVideoSurface video_surfaces_future[MAX_PICTURES];
|
VdpVideoSurface video_surfaces_future[MAX_PICTURES];
|
||||||
|
|
||||||
|
/* can only do QoS if the segment is in TIME */
|
||||||
|
if (vpp->segment.format != GST_FORMAT_TIME)
|
||||||
|
goto no_qos;
|
||||||
|
|
||||||
|
/* QOS is done on the running time of the buffer, get it now */
|
||||||
|
qostime = gst_segment_to_running_time (&vpp->segment, GST_FORMAT_TIME,
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer));
|
||||||
|
|
||||||
|
if (qostime != -1) {
|
||||||
|
gboolean need_skip;
|
||||||
|
GstClockTime earliest_time;
|
||||||
|
|
||||||
|
/* lock for getting the QoS parameters that are set (in a different thread)
|
||||||
|
* with the QOS events */
|
||||||
|
GST_OBJECT_LOCK (vpp);
|
||||||
|
earliest_time = vpp->earliest_time;
|
||||||
|
/* check for QoS, don't perform conversion for buffers
|
||||||
|
* that are known to be late. */
|
||||||
|
need_skip = GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime != -1 &&
|
||||||
|
qostime <= earliest_time;
|
||||||
|
|
||||||
|
GST_OBJECT_UNLOCK (vpp);
|
||||||
|
|
||||||
|
if (need_skip) {
|
||||||
|
GST_DEBUG_OBJECT (vpp, "skipping transform: qostime %"
|
||||||
|
GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
|
||||||
|
/* mark discont for next buffer */
|
||||||
|
vpp->discont = TRUE;
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
no_qos:
|
||||||
|
|
||||||
|
if (vpp->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
vpp->discont = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
|
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
|
||||||
GST_DEBUG_OBJECT (vpp, "Received discont buffer");
|
GST_DEBUG_OBJECT (vpp, "Received discont buffer");
|
||||||
gst_vdp_vpp_flush (vpp);
|
gst_vdp_vpp_flush (vpp);
|
||||||
|
@ -902,6 +947,35 @@ video_buffer_error:
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vdp_vpp_src_event (GstPad * pad, GstEvent * event)
|
||||||
|
{
|
||||||
|
GstVdpVideoPostProcess *vpp =
|
||||||
|
GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_QOS:
|
||||||
|
{
|
||||||
|
gdouble proportion;
|
||||||
|
GstClockTimeDiff diff;
|
||||||
|
GstClockTime timestamp;
|
||||||
|
|
||||||
|
gst_event_parse_qos (event, &proportion, &diff, ×tamp);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (vpp);
|
||||||
|
vpp->earliest_time = timestamp + diff;
|
||||||
|
GST_OBJECT_UNLOCK (vpp);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = gst_pad_event_default (pad, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_unref (vpp);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vdp_vpp_sink_event (GstPad * pad, GstEvent * event)
|
gst_vdp_vpp_sink_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
@ -919,6 +993,23 @@ gst_vdp_vpp_sink_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GST_EVENT_NEWSEGMENT:
|
||||||
|
{
|
||||||
|
gboolean update;
|
||||||
|
gdouble rate, applied_rate;
|
||||||
|
GstFormat format;
|
||||||
|
gint64 start, stop, time;
|
||||||
|
|
||||||
|
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
|
||||||
|
&format, &start, &stop, &time);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (vpp);
|
||||||
|
gst_segment_set_newsegment_full (&vpp->segment, update, rate,
|
||||||
|
applied_rate, format, start, stop, time);
|
||||||
|
GST_OBJECT_UNLOCK (vpp);
|
||||||
|
|
||||||
|
res = gst_pad_push_event (vpp->srcpad, event);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = gst_pad_event_default (pad, event);
|
res = gst_pad_event_default (pad, event);
|
||||||
}
|
}
|
||||||
|
@ -1189,6 +1280,9 @@ gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp,
|
||||||
vpp->srcpad = gst_pad_new_from_static_template (&src_template, "src");
|
vpp->srcpad = gst_pad_new_from_static_template (&src_template, "src");
|
||||||
gst_element_add_pad (GST_ELEMENT (vpp), vpp->srcpad);
|
gst_element_add_pad (GST_ELEMENT (vpp), vpp->srcpad);
|
||||||
|
|
||||||
|
gst_pad_set_event_function (vpp->srcpad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_vdp_vpp_src_event));
|
||||||
|
|
||||||
/* SINK PAD */
|
/* SINK PAD */
|
||||||
sink_template =
|
sink_template =
|
||||||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (gclass), "sink");
|
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (gclass), "sink");
|
||||||
|
|
|
@ -77,6 +77,10 @@ struct _GstVdpVideoPostProcess
|
||||||
|
|
||||||
gboolean interlaced;
|
gboolean interlaced;
|
||||||
GstClockTime field_duration;
|
GstClockTime field_duration;
|
||||||
|
|
||||||
|
GstSegment segment;
|
||||||
|
GstClockTime earliest_time;
|
||||||
|
gboolean discont;
|
||||||
|
|
||||||
GstVdpDevice *device;
|
GstVdpDevice *device;
|
||||||
VdpVideoMixer mixer;
|
VdpVideoMixer mixer;
|
||||||
|
|
Loading…
Reference in a new issue