mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
codectimestamper: Implement QUERY_CAPS support
This is required to ensure that downstream restrcitions are also propagated upstream. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4341>
This commit is contained in:
parent
dbc6afd874
commit
5797fa09af
5 changed files with 102 additions and 5 deletions
|
@ -76,13 +76,16 @@ static GstFlowReturn gst_codec_timestamper_chain (GstPad * pad,
|
|||
GstObject * parent, GstBuffer * buffer);
|
||||
static gboolean gst_codec_timestamper_sink_event (GstPad * pad,
|
||||
GstObject * parent, GstEvent * event);
|
||||
static gboolean gst_codec_timestamper_sink_query (GstPad * pad,
|
||||
GstObject * parent, GstQuery * query);
|
||||
static gboolean gst_codec_timestamper_src_query (GstPad * pad,
|
||||
GstObject * parent, GstQuery * query);
|
||||
static GstStateChangeReturn
|
||||
gst_codec_timestamper_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
static void
|
||||
gst_codec_timestamper_clear_frame (GstCodecTimestamperFrame * frame);
|
||||
static GstCaps *gst_timestamper_get_caps (GstCodecTimestamper * self,
|
||||
GstCaps * filter);
|
||||
static GstStateChangeReturn gst_codec_timestamper_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
static void gst_codec_timestamper_clear_frame (GstCodecTimestamperFrame *
|
||||
frame);
|
||||
static void gst_codec_timestamper_reset (GstCodecTimestamper * self);
|
||||
static void gst_codec_timestamper_drain (GstCodecTimestamper * self);
|
||||
|
||||
|
@ -142,6 +145,9 @@ gst_codec_timestamper_class_init (GstCodecTimestamperClass * klass)
|
|||
element_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_codec_timestamper_change_state);
|
||||
|
||||
/* Default implementation is correct for both H264 and H265 */
|
||||
klass->get_sink_caps = gst_timestamper_get_caps;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_codec_timestamper_debug, "codectimestamper", 0,
|
||||
"codectimestamper");
|
||||
|
||||
|
@ -169,6 +175,9 @@ gst_codec_timestamper_init (GstCodecTimestamper * self,
|
|||
GST_DEBUG_FUNCPTR (gst_codec_timestamper_chain));
|
||||
gst_pad_set_event_function (self->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_codec_timestamper_sink_event));
|
||||
gst_pad_set_query_function (self->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_codec_timestamper_sink_query));
|
||||
|
||||
GST_PAD_SET_PROXY_SCHEDULING (self->sinkpad);
|
||||
GST_PAD_SET_ACCEPT_INTERSECT (self->sinkpad);
|
||||
GST_PAD_SET_ACCEPT_TEMPLATE (self->sinkpad);
|
||||
|
@ -582,6 +591,76 @@ gst_codec_timestamper_chain (GstPad * pad, GstObject * parent,
|
|||
return gst_codec_timestamper_process_output_frame (self);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_timestamper_get_caps (GstCodecTimestamper * self, GstCaps * filter)
|
||||
{
|
||||
GstCaps *peercaps, *templ;
|
||||
GstCaps *res, *tmp, *pcopy;
|
||||
|
||||
templ = gst_pad_get_pad_template_caps (self->sinkpad);
|
||||
if (filter) {
|
||||
GstCaps *fcopy = gst_caps_copy (filter);
|
||||
|
||||
peercaps = gst_pad_peer_query_caps (self->srcpad, fcopy);
|
||||
gst_caps_unref (fcopy);
|
||||
} else {
|
||||
peercaps = gst_pad_peer_query_caps (self->srcpad, NULL);
|
||||
}
|
||||
|
||||
pcopy = gst_caps_copy (peercaps);
|
||||
|
||||
res = gst_caps_intersect_full (pcopy, templ, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (pcopy);
|
||||
gst_caps_unref (templ);
|
||||
|
||||
if (filter) {
|
||||
GstCaps *tmp = gst_caps_intersect_full (res, filter,
|
||||
GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (res);
|
||||
res = tmp;
|
||||
}
|
||||
|
||||
/* Try if we can put the downstream caps first */
|
||||
pcopy = gst_caps_copy (peercaps);
|
||||
tmp = gst_caps_intersect_full (pcopy, res, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (pcopy);
|
||||
if (!gst_caps_is_empty (tmp))
|
||||
res = gst_caps_merge (tmp, res);
|
||||
else
|
||||
gst_caps_unref (tmp);
|
||||
|
||||
gst_caps_unref (peercaps);
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_codec_timestamper_sink_query (GstPad * pad, GstObject * parent,
|
||||
GstQuery * query)
|
||||
{
|
||||
GstCodecTimestamper *self = GST_CODEC_TIMESTAMPER (parent);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CAPS:{
|
||||
GstCaps *caps, *filter;
|
||||
GstCodecTimestamperClass *klass = GST_CODEC_TIMESTAMPER_GET_CLASS (self);
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
g_assert (klass->get_sink_caps);
|
||||
caps = klass->get_sink_caps (self, filter);
|
||||
GST_LOG_OBJECT (self, "sink getcaps returning caps %" GST_PTR_FORMAT,
|
||||
caps);
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return gst_pad_query_default (pad, parent, query);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_codec_timestamper_src_query (GstPad * pad, GstObject * parent,
|
||||
GstQuery * query)
|
||||
|
|
|
@ -54,6 +54,9 @@ struct _GstCodecTimestamperClass
|
|||
gboolean (*set_caps) (GstCodecTimestamper * timestamper,
|
||||
GstCaps * caps);
|
||||
|
||||
GstCaps * (*get_sink_caps) (GstCodecTimestamper * timestamper,
|
||||
GstCaps * filter);
|
||||
|
||||
GstFlowReturn (*handle_buffer) (GstCodecTimestamper * timestamper,
|
||||
GstBuffer * buffer);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
meta,
|
||||
args = {
|
||||
"videotestsrc num-buffers=1 ! video/x-raw,width=1920,height=1080,format=I420 ! videoscale ! x264enc tune=zerolatency ! h264timestamper ! video/x-h264,width=50,height=50 ! fakesink name=sink",
|
||||
},
|
||||
configs = {
|
||||
"$(validateflow), pad=sink:sink, buffers-checksum=as-id, caps-properties={width, height}, ignored-event-types={tag}",
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-h264, height=(int)50, width=(int)50;
|
||||
event segment: format=TIME, start=1000:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=1000:00:00.000000000
|
||||
buffer: content-id=0, dts=1000:00:00.000000000, pts=1000:00:00.000000000, dur=0:00:00.033333333, flags=discont marker
|
||||
event eos: (no structure)
|
|
@ -6,6 +6,7 @@ endif
|
|||
tests = [
|
||||
{'path': 'opencv/cvtracker'},
|
||||
{'path': 'testsrcbin/caps_spec'},
|
||||
{'path': 'codectimestamper/h264_propagate_caps'},
|
||||
{'path': 'wpe/load_bytes_first', 'skip': not building_wpe},
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in a new issue