From b945c015497386efd6197f5bb5dd63f171082288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 24 Apr 2012 20:04:48 +0200 Subject: [PATCH] videodecoder: Add minimal support for buffer pools --- gst-libs/gst/video/gstvideodecoder.c | 68 +++++++++++++++++++++++++--- gst-libs/gst/video/gstvideodecoder.h | 2 - 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c index 881e443e1d..5f1a702497 100644 --- a/gst-libs/gst/video/gstvideodecoder.c +++ b/gst-libs/gst/video/gstvideodecoder.c @@ -146,6 +146,8 @@ #include "gstvideodecoder.h" #include "gstvideoutils.h" +#include +#include #include GST_DEBUG_CATEGORY (videodecoder_debug); @@ -159,6 +161,8 @@ struct _GstVideoDecoderPrivate { /* FIXME introduce a context ? */ + GstBufferPool *pool; + /* parse tracking */ /* input data */ GstAdapter *input_adapter; @@ -635,6 +639,11 @@ gst_video_decoder_finalize (GObject * object) if (decoder->priv->output_state) gst_video_codec_state_unref (decoder->priv->output_state); + if (decoder->priv->pool) { + g_object_unref (decoder->priv->pool); + decoder->priv->pool = NULL; + } + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -2379,6 +2388,10 @@ static gboolean gst_video_decoder_set_src_caps (GstVideoDecoder * decoder) { GstVideoCodecState *state = decoder->priv->output_state; + GstQuery *query; + GstBufferPool *pool; + GstStructure *config; + guint size, min, max; gboolean ret; g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (&state->info) != 0, FALSE); @@ -2398,6 +2411,51 @@ gst_video_decoder_set_src_caps (GstVideoDecoder * decoder) ret = gst_pad_set_caps (decoder->srcpad, state->caps); decoder->priv->output_state_changed = FALSE; + /* Negotiate pool */ + query = gst_query_new_allocation (state->caps, TRUE); + + if (!gst_pad_peer_query (decoder->srcpad, query)) { + GST_DEBUG_OBJECT (decoder, "didn't get downstream ALLOCATION hints"); + } + + if (gst_query_get_n_allocation_pools (query) > 0) { + /* we got configuration from our peer, parse them */ + gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); + size = MAX (size, state->info.size); + } else { + pool = NULL; + size = state->info.size; + min = max = 0; + } + + if (pool == NULL) { + /* we did not get a pool, make one ourselves then */ + pool = gst_video_buffer_pool_new (); + } + + if (decoder->priv->pool) { + gst_buffer_pool_set_active (decoder->priv->pool, FALSE); + gst_object_unref (decoder->priv->pool); + } + decoder->priv->pool = pool; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, state->caps, size, min, max); + + 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); + } + + gst_buffer_pool_set_config (pool, config); + /* and activate */ + gst_buffer_pool_set_active (pool, TRUE); + + gst_query_unref (query); + GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); return ret; @@ -2419,9 +2477,6 @@ GstBuffer * gst_video_decoder_alloc_output_buffer (GstVideoDecoder * decoder) { GstBuffer *buffer; - GstFlowReturn flow_ret; - GstVideoCodecState *state = decoder->priv->output_state; - int num_bytes = GST_VIDEO_INFO_SIZE (&state->info); GST_DEBUG ("alloc src buffer"); @@ -2429,8 +2484,7 @@ gst_video_decoder_alloc_output_buffer (GstVideoDecoder * decoder) if (G_UNLIKELY (decoder->priv->output_state_changed)) gst_video_decoder_set_src_caps (decoder); - flow_ret = GST_FLOW_OK; - buffer = gst_buffer_new_allocate (NULL, num_bytes, NULL); + gst_buffer_pool_acquire_buffer (decoder->priv->pool, &buffer, NULL); GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); @@ -2467,8 +2521,8 @@ gst_video_decoder_alloc_output_frame (GstVideoDecoder * GST_LOG_OBJECT (decoder, "alloc buffer size %d", num_bytes); GST_VIDEO_DECODER_STREAM_LOCK (decoder); - flow_ret = GST_FLOW_OK; - frame->output_buffer = gst_buffer_new_allocate (NULL, num_bytes, NULL); + flow_ret = gst_buffer_pool_acquire_buffer (decoder->priv->pool, + &frame->output_buffer, NULL); GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); diff --git a/gst-libs/gst/video/gstvideodecoder.h b/gst-libs/gst/video/gstvideodecoder.h index 611176192a..66e3eb92a4 100644 --- a/gst-libs/gst/video/gstvideodecoder.h +++ b/gst-libs/gst/video/gstvideodecoder.h @@ -27,8 +27,6 @@ #include #include -#include -#include #include G_BEGIN_DECLS