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
@ -199,6 +199,9 @@ typedef struct _GstAudioDecoderContext
|
|||||||
/* MT-protected (with LOCK) */
|
/* MT-protected (with LOCK) */
|
||||||
GstClockTime min_latency;
|
GstClockTime min_latency;
|
||||||
GstClockTime max_latency;
|
GstClockTime max_latency;
|
||||||
|
|
||||||
|
GstAllocator *allocator;
|
||||||
|
GstAllocationParams params;
|
||||||
} GstAudioDecoderContext;
|
} GstAudioDecoderContext;
|
||||||
|
|
||||||
struct _GstAudioDecoderPrivate
|
struct _GstAudioDecoderPrivate
|
||||||
@ -298,6 +301,11 @@ static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
|
|||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full);
|
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 GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass);
|
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);
|
GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_eventfunc);
|
||||||
audiodecoder_class->src_event =
|
audiodecoder_class->src_event =
|
||||||
GST_DEBUG_FUNCPTR (gst_audio_decoder_src_eventfunc);
|
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
|
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_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
|
||||||
g_list_free (dec->priv->pending_events);
|
g_list_free (dec->priv->pending_events);
|
||||||
dec->priv->pending_events = NULL;
|
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);
|
g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
|
||||||
@ -518,10 +534,14 @@ gboolean
|
|||||||
gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
|
gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
|
||||||
const GstAudioInfo * info)
|
const GstAudioInfo * info)
|
||||||
{
|
{
|
||||||
|
GstAudioDecoderClass *klass = GST_AUDIO_DECODER_GET_CLASS (dec);
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
guint old_rate;
|
guint old_rate;
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
GstCaps *templ_caps;
|
GstCaps *templ_caps;
|
||||||
|
GstQuery *query = NULL;
|
||||||
|
GstAllocator *allocator;
|
||||||
|
GstAllocationParams params;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dec, "Setting output format");
|
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);
|
res = gst_pad_set_caps (dec->srcpad, caps);
|
||||||
gst_caps_unref (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:
|
done:
|
||||||
|
if (query)
|
||||||
|
gst_query_unref (query);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
@ -572,6 +625,11 @@ refuse_caps:
|
|||||||
res = FALSE;
|
res = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
no_decide_allocation:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (dec, "Subclass failed to decide allocation");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1808,6 +1866,43 @@ gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||||||
return ret;
|
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:
|
* gst_audio_encoded_audio_convert:
|
||||||
* @fmt: audio format of the encoded audio
|
* @fmt: audio format of the encoded audio
|
||||||
@ -2681,3 +2776,33 @@ gst_audio_decoder_merge_tags (GstAudioDecoder * dec,
|
|||||||
gst_tag_list_free (otags);
|
gst_tag_list_free (otags);
|
||||||
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
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.
|
* @close: Optional.
|
||||||
* Called when the element changes to GST_STATE_NULL.
|
* Called when the element changes to GST_STATE_NULL.
|
||||||
* Allows closing external resources.
|
* 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
|
* Subclasses can override any of the available virtual methods or not, as
|
||||||
* needed. At minimum @handle_frame (and likely @set_format) needs to be
|
* needed. At minimum @handle_frame (and likely @set_format) needs to be
|
||||||
@ -253,6 +259,11 @@ struct _GstAudioDecoderClass
|
|||||||
|
|
||||||
gboolean (*close) (GstAudioDecoder *dec);
|
gboolean (*close) (GstAudioDecoder *dec);
|
||||||
|
|
||||||
|
gboolean (*decide_allocation) (GstAudioDecoder *dec, GstQuery *query);
|
||||||
|
|
||||||
|
gboolean (*propose_allocation) (GstAudioDecoder *dec,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING_LARGE-2];
|
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,
|
GstFlowReturn gst_audio_decoder_finish_frame (GstAudioDecoder * dec,
|
||||||
GstBuffer * buf, gint frames);
|
GstBuffer * buf, gint frames);
|
||||||
|
|
||||||
|
GstBuffer * gst_audio_decoder_allocate_output_buffer (GstAudioDecoder * decoder,
|
||||||
|
gsize size);
|
||||||
|
|
||||||
/* context parameters */
|
/* context parameters */
|
||||||
GstAudioInfo * gst_audio_decoder_get_audio_info (GstAudioDecoder * dec);
|
GstAudioInfo * gst_audio_decoder_get_audio_info (GstAudioDecoder * dec);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user