From 148399720729d9440a87f13e3f69fc056c47cf71 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 24 Apr 2012 22:35:29 +0200 Subject: [PATCH] videodecoder: Add support for subclasses to configure the buffer pool --- gst-libs/gst/video/gstvideodecoder.c | 51 +++++++++++++++++++++------- gst-libs/gst/video/gstvideodecoder.h | 8 ++++- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c index f37fe22ad1..0916d92dd0 100644 --- a/gst-libs/gst/video/gstvideodecoder.c +++ b/gst-libs/gst/video/gstvideodecoder.c @@ -283,6 +283,8 @@ static gboolean gst_video_decoder_sink_event_default (GstVideoDecoder * decoder, GstEvent * event); static gboolean gst_video_decoder_src_event_default (GstVideoDecoder * decoder, GstEvent * event); +static gboolean gst_video_decoder_configure_buffer_pool_default (GstVideoDecoder + * decoder, GstQuery * query, GstBufferPool * pool); /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init * method to get to the padtemplates */ @@ -334,6 +336,8 @@ gst_video_decoder_class_init (GstVideoDecoderClass * klass) klass->sink_event = gst_video_decoder_sink_event_default; klass->src_event = gst_video_decoder_src_event_default; + klass->configure_buffer_pool = + gst_video_decoder_configure_buffer_pool_default; } static void @@ -1947,7 +1951,8 @@ gst_video_decoder_finish_frame (GstVideoDecoder * decoder, GST_LOG_OBJECT (decoder, "finish frame"); - if (G_UNLIKELY (priv->output_state_changed)) + if (G_UNLIKELY (priv->output_state_changed || (priv->output_state + && gst_pad_check_reconfigure (decoder->srcpad)))) gst_video_decoder_set_src_caps (decoder); GST_VIDEO_DECODER_STREAM_LOCK (decoder); @@ -2375,6 +2380,25 @@ gst_video_decoder_get_frame (GstVideoDecoder * decoder, int frame_number) return frame; } +static gboolean +gst_video_decoder_configure_buffer_pool_default (GstVideoDecoder * decoder, + GstQuery * query, GstBufferPool * pool) +{ + GstStructure *config; + + if (gst_query_has_allocation_meta (query, GST_VIDEO_META_API_TYPE)) { + config = gst_buffer_pool_get_config (pool); + /* just set the option, if the pool can support it we will transparently use + * it through the video info API. We could also see if the pool support this + * option and only activate it then. */ + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + gst_buffer_pool_set_config (pool, config); + } + + return TRUE; +} + /** * gst_video_decoder_set_src_caps: * @decoder: a #GstVideoDecoder @@ -2389,6 +2413,7 @@ static gboolean gst_video_decoder_set_src_caps (GstVideoDecoder * decoder) { GstVideoCodecState *state = decoder->priv->output_state; + GstVideoDecoderClass *klass; GstQuery *query; GstBufferPool *pool; GstStructure *config; @@ -2400,6 +2425,8 @@ gst_video_decoder_set_src_caps (GstVideoDecoder * decoder) GST_VIDEO_DECODER_STREAM_LOCK (decoder); + klass = GST_VIDEO_DECODER_GET_CLASS (decoder); + GST_DEBUG_OBJECT (decoder, "output_state par %d/%d fps %d/%d", state->info.par_n, state->info.par_d, state->info.fps_n, state->info.fps_d); @@ -2442,18 +2469,14 @@ gst_video_decoder_set_src_caps (GstVideoDecoder * decoder) config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, state->caps, size, min, max); + gst_buffer_pool_set_config (pool, config); - if (gst_query_has_allocation_meta (query, GST_VIDEO_META_API_TYPE)) { - /* just set the option, if the pool can support it we will transparently use - * it through the video info API. We could also see if the pool support this - * option and only activate it then. */ - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - } + if (klass->configure_buffer_pool) + ret = klass->configure_buffer_pool (decoder, query, pool); - gst_buffer_pool_set_config (pool, config); /* and activate */ - gst_buffer_pool_set_active (pool, TRUE); + if (ret) + gst_buffer_pool_set_active (pool, TRUE); gst_query_unref (query); @@ -2482,7 +2505,9 @@ gst_video_decoder_alloc_output_buffer (GstVideoDecoder * decoder) GST_DEBUG ("alloc src buffer"); GST_VIDEO_DECODER_STREAM_LOCK (decoder); - if (G_UNLIKELY (decoder->priv->output_state_changed)) + if (G_UNLIKELY (decoder->priv->output_state_changed + || (decoder->priv->output_state + && gst_pad_check_reconfigure (decoder->srcpad)))) gst_video_decoder_set_src_caps (decoder); gst_buffer_pool_acquire_buffer (decoder->priv->pool, &buffer, NULL); @@ -2516,7 +2541,9 @@ gst_video_decoder_alloc_output_frame (GstVideoDecoder * g_return_val_if_fail (num_bytes != 0, GST_FLOW_ERROR); - if (G_UNLIKELY (decoder->priv->output_state_changed)) + if (G_UNLIKELY (decoder->priv->output_state_changed + || (decoder->priv->output_state + && gst_pad_check_reconfigure (decoder->srcpad)))) gst_video_decoder_set_src_caps (decoder); GST_LOG_OBJECT (decoder, "alloc buffer size %d", num_bytes); diff --git a/gst-libs/gst/video/gstvideodecoder.h b/gst-libs/gst/video/gstvideodecoder.h index 66e3eb92a4..e7c0462b80 100644 --- a/gst-libs/gst/video/gstvideodecoder.h +++ b/gst-libs/gst/video/gstvideodecoder.h @@ -247,7 +247,11 @@ struct _GstVideoDecoder * Event handler on the source pad. This function should return * TRUE if the event was handled and should be discarded * (i.e. not unref'ed). - * + * @configure_buffer_pool: Optional. + * Configure the buffer that is used for allocation of output + * buffers. The passed query contains the result of the allocation + * query. The default implementation will add the VIDEO_META if + * supported by the buffer pool. * Subclasses can override any of the available virtual methods or not, as * needed. At minimum @handle_frame needs to be overridden, and @set_format * and likely as well. If non-packetized input is supported or expected, @@ -291,6 +295,8 @@ struct _GstVideoDecoderClass gboolean (*src_event) (GstVideoDecoder *decoder, GstEvent *event); + gboolean (*configure_buffer_pool) (GstVideoDecoder *decoder, GstQuery *query, GstBufferPool *pool); + /*< private >*/ /* FIXME before moving to base */ -- 2.34.1