From b324fc6adddefe2749bc40f6116a755553ba22bf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 17 Dec 2013 18:46:07 +0100 Subject: [PATCH] plugins: factor out pad caps. --- gst-libs/gst/vaapi/gstcompat.h | 2 ++ gst/vaapi/gstvaapidecode.c | 40 +++++++++++++----------- gst/vaapi/gstvaapidecode.h | 4 --- gst/vaapi/gstvaapidownload.c | 3 ++ gst/vaapi/gstvaapipluginbase.c | 56 +++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapipluginbase.h | 34 +++++++++++++++++++++ gst/vaapi/gstvaapipostproc.c | 12 ++++---- gst/vaapi/gstvaapipostproc.h | 2 -- gst/vaapi/gstvaapisink.c | 4 +++ gst/vaapi/gstvaapiupload.c | 3 ++ 10 files changed, 129 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index efb5c568c4..9abc2fd37f 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -314,6 +314,8 @@ gst_compat_pad_start_task(GstPad *pad, GstTaskFunction func, gpointer user_data, gst_compat_pad_start_task(pad, func, user_data, notify) /* GstElement */ +#undef GST_ELEMENT_FLAG_SINK +#define GST_ELEMENT_FLAG_SINK GST_ELEMENT_IS_SINK #undef gst_element_class_set_static_metadata #define gst_element_class_set_static_metadata(klass, name, path, desc, author) \ gst_compat_element_class_set_static_metadata(klass, name, path, desc, author) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9cc5f78f20..8a6b31d212 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -399,7 +399,7 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) /* Suspend the task if an error occurred */ if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA) - gst_pad_pause_task(decode->srcpad); + gst_pad_pause_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); } static gboolean @@ -444,7 +444,7 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) decode->decoder_finish = TRUE; g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); g_mutex_unlock(&decode->decoder_mutex); - gst_pad_stop_task(decode->srcpad); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); GST_VIDEO_DECODER_STREAM_LOCK(vdec); return ret; } @@ -591,14 +591,14 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) gst_vaapi_decoder_state_changed, decode); decode->decoder_caps = gst_caps_ref(caps); - return gst_pad_start_task(decode->srcpad, + return gst_pad_start_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode), (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL); } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - gst_pad_stop_task(decode->srcpad); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); gst_vaapi_decoder_replace(&decode->decoder, NULL); gst_caps_replace(&decode->decoder_caps, NULL); gst_vaapidecode_release(decode); @@ -621,7 +621,7 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) gst_vaapi_decoder_flush(decode->decoder); GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - gst_pad_stop_task(decode->srcpad); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); GST_VIDEO_DECODER_STREAM_LOCK(vdec); decode->decoder_loop_status = GST_FLOW_OK; @@ -709,12 +709,16 @@ gst_vaapidecode_reset(GstVideoDecoder *vdec, gboolean hard) static gboolean gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); if (!gst_vaapidecode_update_sink_caps(decode, state->caps)) return FALSE; if (!gst_vaapidecode_update_src_caps(decode, state)) return FALSE; + if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, + decode->srcpad_caps)) + return FALSE; if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) return FALSE; return TRUE; @@ -881,12 +885,13 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) { GstVaapiDecode * const decode = GST_VAAPIDECODE(gst_pad_get_parent_element(pad)); + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(decode); gboolean res; GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(decode))) { - GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); + if (gst_vaapi_reply_to_query(query, plugin->display)) { + GST_DEBUG("sharing display %p", plugin->display); res = TRUE; } else if (GST_PAD_IS_SINK(pad)) { @@ -901,14 +906,14 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) } #endif default: - res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, - decode->sinkpad, parent, query); + res = GST_PAD_QUERY_FUNCTION_CALL(plugin->sinkpad_query, pad, + parent, query); break; } } else - res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query, - decode->srcpad, parent, query); + res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad, + parent, query); gst_object_unref(decode); return res; @@ -918,6 +923,7 @@ static void gst_vaapidecode_init(GstVaapiDecode *decode) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstPad *pad; gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT); @@ -933,15 +939,13 @@ gst_vaapidecode_init(GstVaapiDecode *decode) gst_video_decoder_set_packetized(vdec, FALSE); /* Pad through which data comes in to the element */ - decode->sinkpad = GST_VIDEO_DECODER_SINK_PAD(vdec); - decode->sinkpad_query = GST_PAD_QUERYFUNC(decode->sinkpad); - gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query); + pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD(decode); + gst_pad_set_query_function(pad, gst_vaapidecode_query); #if !GST_CHECK_VERSION(1,0,0) - gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); + gst_pad_set_getcaps_function(pad, gst_vaapidecode_get_caps); #endif /* Pad through which data goes out of the element */ - decode->srcpad = GST_VIDEO_DECODER_SRC_PAD(vdec); - decode->srcpad_query = GST_PAD_QUERYFUNC(decode->srcpad); - gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query); + pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode); + gst_pad_set_query_function(pad, gst_vaapidecode_query); } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index ed1e9bfa99..7128709deb 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -61,12 +61,8 @@ struct _GstVaapiDecode { /*< private >*/ GstVaapiPluginBase parent_instance; - GstPad *sinkpad; GstCaps *sinkpad_caps; - GstPadQueryFunction sinkpad_query; - GstPad *srcpad; GstCaps *srcpad_caps; - GstPadQueryFunction srcpad_query; GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index ff2a25a79e..40df273c44 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -499,8 +499,11 @@ gst_vaapidownload_set_caps( GstCaps *outcaps ) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + if (!gst_vaapi_plugin_base_set_caps(plugin, incaps, outcaps)) + return FALSE; if (!gst_vaapidownload_negotiate_buffers(download, incaps, outcaps)) return FALSE; return TRUE; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 09e6b4b42a..733921037c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -124,13 +124,28 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, plugin->debug_category = debug_category; plugin->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; plugin->display_type_req = GST_VAAPI_DISPLAY_TYPE_ANY; + + /* sink pad */ + plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink"); + plugin->sinkpad_query = GST_PAD_QUERYFUNC (plugin->sinkpad); + gst_video_info_init (&plugin->sinkpad_info); + + /* src pad */ + if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) { + plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); + plugin->srcpad_query = GST_PAD_QUERYFUNC (plugin->srcpad); + } + gst_video_info_init (&plugin->srcpad_info); } void gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) { gst_vaapi_plugin_base_close (plugin); - + if (plugin->sinkpad) + gst_object_unref (plugin->sinkpad); + if (plugin->srcpad) + gst_object_unref (plugin->srcpad); gst_debug_category_free (plugin->debug_category); } @@ -160,6 +175,14 @@ void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { gst_vaapi_display_replace (&plugin->display, NULL); + + gst_caps_replace (&plugin->sinkpad_caps, NULL); + plugin->sinkpad_caps_changed = FALSE; + gst_video_info_init (&plugin->sinkpad_info); + + gst_caps_replace (&plugin->srcpad_caps, NULL); + plugin->srcpad_caps_changed = FALSE; + gst_video_info_init (&plugin->srcpad_info); } /** @@ -203,3 +226,34 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) GST_VAAPI_PLUGIN_BASE_GET_CLASS (plugin)->display_changed (plugin); return TRUE; } + +/** + * gst_vaapi_plugin_base_set_caps: + * @plugin: a #GstVaapiPluginBase + * @incaps: the sink pad (input) caps + * @outcaps: the src pad (output) caps + * + * Notifies the base plugin object of the new input and output caps, + * obtained from the subclass. + * + * Returns: %TRUE if the update of caps was successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, + GstCaps * outcaps) +{ + if (incaps && incaps != plugin->sinkpad_caps) { + gst_caps_replace (&plugin->sinkpad_caps, incaps); + if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) + return FALSE; + plugin->sinkpad_caps_changed = TRUE; + } + + if (outcaps && outcaps != plugin->srcpad_caps) { + gst_caps_replace (&plugin->srcpad_caps, outcaps); + if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) + return FALSE; + plugin->srcpad_caps_changed = TRUE; + } + return TRUE; +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 0f80ea60d6..68ed6c83f6 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -71,6 +71,23 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; #define GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES \ gst_vaapi_plugin_base_init_interfaces(g_define_type_id); +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_caps) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(plugin) \ + (&GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_info) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_QUERYFUNC(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_query) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_caps) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \ + (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_QUERYFYNC(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_query) + #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) #define GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(plugin) \ @@ -93,6 +110,18 @@ struct _GstVaapiPluginBase GstDebugCategory *debug_category; + GstPad *sinkpad; + GstCaps *sinkpad_caps; + gboolean sinkpad_caps_changed; + GstVideoInfo sinkpad_info; + GstPadQueryFunction sinkpad_query; + + GstPad *srcpad; + GstCaps *srcpad_caps; + gboolean srcpad_caps_changed; + GstVideoInfo srcpad_info; + GstPadQueryFunction srcpad_query; + GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; @@ -148,6 +177,11 @@ G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, + GstCaps * outcaps); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 700c55e54e..fb61a0c55a 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -230,8 +230,9 @@ static gboolean gst_vaapipostproc_ensure_uploader_caps(GstVaapiPostproc *postproc) { #if !GST_CHECK_VERSION(1,0,0) + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(postproc); if (postproc->is_raw_yuv && !gst_vaapi_uploader_ensure_caps( - postproc->uploader, postproc->sinkpad_caps, NULL)) + postproc->uploader, plugin->sinkpad_caps, NULL)) return FALSE; #endif return TRUE; @@ -312,9 +313,7 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) gst_vaapipostproc_destroy_filter(postproc); gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); - gst_caps_replace(&postproc->sinkpad_caps, NULL); gst_caps_replace(&postproc->allowed_srcpad_caps, NULL); - gst_caps_replace(&postproc->srcpad_caps, NULL); gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); } @@ -375,7 +374,7 @@ create_output_buffer(GstVaapiPostproc *postproc) goto error_create_buffer; #if !GST_CHECK_VERSION(1,0,0) - gst_buffer_set_caps(outbuf, postproc->srcpad_caps); + gst_buffer_set_caps(outbuf, GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(postproc)); #endif return outbuf; @@ -1379,8 +1378,9 @@ gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, if (caps_changed) { gst_vaapipostproc_destroy(postproc); - gst_caps_replace(&postproc->sinkpad_caps, caps); - gst_caps_replace(&postproc->srcpad_caps, out_caps); + if (!gst_vaapi_plugin_base_set_caps(GST_VAAPI_PLUGIN_BASE(trans), + caps, out_caps)) + return FALSE; if (!gst_vaapipostproc_create(postproc)) return FALSE; } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 55dabae82a..fe04947852 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -148,14 +148,12 @@ struct _GstVaapiPostproc { guint flags; GstCaps *allowed_sinkpad_caps; - GstCaps *sinkpad_caps; GstVideoInfo sinkpad_info; #if GST_CHECK_VERSION(1,0,0) GstBufferPool *sinkpad_buffer_pool; #endif guint sinkpad_buffer_size; GstCaps *allowed_srcpad_caps; - GstCaps *srcpad_caps; GstVideoInfo srcpad_info; /* Deinterlacing */ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2f081dff2c..e219753a27 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -743,6 +743,7 @@ gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVideoInfo * const vip = &sink->video_info; GstVaapiDisplay *display; @@ -757,6 +758,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return TRUE; #endif + if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL)) + return FALSE; + if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) return FALSE; diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index d4b52b7f25..e90ef3034d 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -320,8 +320,11 @@ gst_vaapiupload_set_caps( GstCaps *outcaps ) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); + if (!gst_vaapi_plugin_base_set_caps(plugin, incaps, outcaps)) + return FALSE; if (!gst_vaapi_uploader_ensure_caps(upload->uploader, incaps, outcaps)) return FALSE; return TRUE;