mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
audiodecoder: Add propose_allocation, decide_allocation vfuncs and functions to allocate buffers with information from the allocation query results
This commit is contained in:
parent
0513d3d9f4
commit
0814d38e98
2 changed files with 139 additions and 0 deletions
|
@ -199,6 +199,9 @@ typedef struct _GstAudioDecoderContext
|
|||
/* MT-protected (with LOCK) */
|
||||
GstClockTime min_latency;
|
||||
GstClockTime max_latency;
|
||||
|
||||
GstAllocator *allocator;
|
||||
GstAllocationParams params;
|
||||
} GstAudioDecoderContext;
|
||||
|
||||
struct _GstAudioDecoderPrivate
|
||||
|
@ -298,6 +301,11 @@ static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
|
|||
GstQuery * query);
|
||||
static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full);
|
||||
|
||||
static gboolean gst_audio_decoder_decide_allocation_default (GstAudioDecoder *
|
||||
dec, GstQuery * query);
|
||||
static gboolean gst_audio_decoder_propose_allocation_default (GstAudioDecoder *
|
||||
dec, GstQuery * query);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass);
|
||||
|
@ -378,6 +386,10 @@ gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_eventfunc);
|
||||
audiodecoder_class->src_event =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_decoder_src_eventfunc);
|
||||
audiodecoder_class->propose_allocation =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_decoder_propose_allocation_default);
|
||||
audiodecoder_class->decide_allocation =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_decoder_decide_allocation_default);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -466,6 +478,10 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full)
|
|||
g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
|
||||
g_list_free (dec->priv->pending_events);
|
||||
dec->priv->pending_events = NULL;
|
||||
|
||||
if (dec->priv->ctx.allocator)
|
||||
gst_object_unref (dec->priv->ctx.allocator);
|
||||
dec->priv->ctx.allocator = NULL;
|
||||
}
|
||||
|
||||
g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
|
||||
|
@ -518,10 +534,14 @@ gboolean
|
|||
gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
|
||||
const GstAudioInfo * info)
|
||||
{
|
||||
GstAudioDecoderClass *klass = GST_AUDIO_DECODER_GET_CLASS (dec);
|
||||
gboolean res = TRUE;
|
||||
guint old_rate;
|
||||
GstCaps *caps = NULL;
|
||||
GstCaps *templ_caps;
|
||||
GstQuery *query = NULL;
|
||||
GstAllocator *allocator;
|
||||
GstAllocationParams params;
|
||||
|
||||
GST_DEBUG_OBJECT (dec, "Setting output format");
|
||||
|
||||
|
@ -561,8 +581,41 @@ gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
|
|||
|
||||
res = gst_pad_set_caps (dec->srcpad, caps);
|
||||
gst_caps_unref (caps);
|
||||
if (!res)
|
||||
goto done;
|
||||
|
||||
query = gst_query_new_allocation (caps, TRUE);
|
||||
if (!gst_pad_peer_query (dec->srcpad, query)) {
|
||||
GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
|
||||
}
|
||||
|
||||
g_assert (klass->decide_allocation != NULL);
|
||||
res = klass->decide_allocation (dec, query);
|
||||
|
||||
GST_DEBUG_OBJECT (dec, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, res,
|
||||
query);
|
||||
|
||||
if (!res)
|
||||
goto no_decide_allocation;
|
||||
|
||||
/* we got configuration from our peer or the decide_allocation method,
|
||||
* parse them */
|
||||
if (gst_query_get_n_allocation_params (query) > 0) {
|
||||
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
|
||||
} else {
|
||||
allocator = NULL;
|
||||
gst_allocation_params_init (¶ms);
|
||||
}
|
||||
|
||||
if (dec->priv->ctx.allocator)
|
||||
gst_object_unref (dec->priv->ctx.allocator);
|
||||
dec->priv->ctx.allocator = allocator;
|
||||
dec->priv->ctx.params = params;
|
||||
|
||||
done:
|
||||
if (query)
|
||||
gst_query_unref (query);
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -572,6 +625,11 @@ refuse_caps:
|
|||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
no_decide_allocation:
|
||||
{
|
||||
GST_WARNING_OBJECT (dec, "Subclass failed to decide allocation");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1808,6 +1866,43 @@ gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_audio_decoder_decide_allocation_default (GstAudioDecoder * dec,
|
||||
GstQuery * query)
|
||||
{
|
||||
GstAllocator *allocator = NULL;
|
||||
GstAllocationParams params;
|
||||
gboolean update_allocator;
|
||||
|
||||
/* we got configuration from our peer or the decide_allocation method,
|
||||
* parse them */
|
||||
if (gst_query_get_n_allocation_params (query) > 0) {
|
||||
/* try the allocator */
|
||||
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
|
||||
update_allocator = TRUE;
|
||||
} else {
|
||||
allocator = NULL;
|
||||
gst_allocation_params_init (¶ms);
|
||||
update_allocator = FALSE;
|
||||
}
|
||||
|
||||
if (update_allocator)
|
||||
gst_query_set_nth_allocation_param (query, 0, allocator, ¶ms);
|
||||
else
|
||||
gst_query_add_allocation_param (query, allocator, ¶ms);
|
||||
if (allocator)
|
||||
gst_object_unref (allocator);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_audio_decoder_propose_allocation_default (GstAudioDecoder * dec,
|
||||
GstQuery * query)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gst_audio_encoded_audio_convert:
|
||||
* @fmt: audio format of the encoded audio
|
||||
|
@ -2681,3 +2776,33 @@ gst_audio_decoder_merge_tags (GstAudioDecoder * dec,
|
|||
gst_tag_list_free (otags);
|
||||
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_audio_decoder_allocate_output_buffer:
|
||||
* @enc: a #GstAudioDecoder
|
||||
* @size: size of the buffer
|
||||
*
|
||||
* Helper function that allocates a buffer to hold an audio frame
|
||||
* for @dec's current output format.
|
||||
*
|
||||
* Returns: (transfer full): allocated buffer
|
||||
*/
|
||||
GstBuffer *
|
||||
gst_audio_decoder_allocate_output_buffer (GstAudioDecoder * dec, gsize size)
|
||||
{
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_return_val_if_fail (size > 0, NULL);
|
||||
|
||||
GST_DEBUG ("alloc src buffer");
|
||||
|
||||
GST_AUDIO_DECODER_STREAM_LOCK (dec);
|
||||
|
||||
buffer =
|
||||
gst_buffer_new_allocate (dec->priv->ctx.allocator, size,
|
||||
&dec->priv->ctx.params);
|
||||
|
||||
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -213,6 +213,12 @@ struct _GstAudioDecoder
|
|||
* @close: Optional.
|
||||
* Called when the element changes to GST_STATE_NULL.
|
||||
* Allows closing external resources.
|
||||
* @decide_allocation: Optional.
|
||||
* Setup the allocation parameters for allocating output
|
||||
* buffers. The passed in query contains the result of the
|
||||
* downstream allocation query.
|
||||
* @propose_allocation: Optional.
|
||||
* Propose buffer allocation parameters for upstream elements.
|
||||
*
|
||||
* Subclasses can override any of the available virtual methods or not, as
|
||||
* needed. At minimum @handle_frame (and likely @set_format) needs to be
|
||||
|
@ -253,6 +259,11 @@ struct _GstAudioDecoderClass
|
|||
|
||||
gboolean (*close) (GstAudioDecoder *dec);
|
||||
|
||||
gboolean (*decide_allocation) (GstAudioDecoder *dec, GstQuery *query);
|
||||
|
||||
gboolean (*propose_allocation) (GstAudioDecoder *dec,
|
||||
GstQuery * query);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE-2];
|
||||
};
|
||||
|
@ -265,6 +276,9 @@ gboolean gst_audio_decoder_set_output_format (GstAudioDecoder * dec
|
|||
GstFlowReturn gst_audio_decoder_finish_frame (GstAudioDecoder * dec,
|
||||
GstBuffer * buf, gint frames);
|
||||
|
||||
GstBuffer * gst_audio_decoder_allocate_output_buffer (GstAudioDecoder * decoder,
|
||||
gsize size);
|
||||
|
||||
/* context parameters */
|
||||
GstAudioInfo * gst_audio_decoder_get_audio_info (GstAudioDecoder * dec);
|
||||
|
||||
|
|
Loading…
Reference in a new issue