mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
audioencoder: Decouple setting of output format and downstream negotiation
This makes the audio encoder base class more similar to the video encoder base class.
This commit is contained in:
parent
513d4f7cd1
commit
9309272309
2 changed files with 77 additions and 42 deletions
|
@ -188,6 +188,8 @@ typedef struct _GstAudioEncoderContext
|
||||||
GstAudioInfo info;
|
GstAudioInfo info;
|
||||||
|
|
||||||
/* output */
|
/* output */
|
||||||
|
GstCaps *caps;
|
||||||
|
gboolean output_caps_changed;
|
||||||
gint frame_samples_min, frame_samples_max;
|
gint frame_samples_min, frame_samples_max;
|
||||||
gint frame_max;
|
gint frame_max;
|
||||||
gint lookahead;
|
gint lookahead;
|
||||||
|
@ -458,6 +460,7 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full)
|
||||||
|
|
||||||
memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
|
memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
|
||||||
gst_audio_info_init (&enc->priv->ctx.info);
|
gst_audio_info_init (&enc->priv->ctx.info);
|
||||||
|
gst_caps_replace (&enc->priv->ctx.caps, NULL);
|
||||||
|
|
||||||
if (enc->priv->tags)
|
if (enc->priv->tags)
|
||||||
gst_tag_list_free (enc->priv->tags);
|
gst_tag_list_free (enc->priv->tags);
|
||||||
|
@ -602,7 +605,7 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
|
||||||
GST_FLOW_ERROR);
|
GST_FLOW_ERROR);
|
||||||
|
|
||||||
/* subclass should know what it is producing by now */
|
/* subclass should know what it is producing by now */
|
||||||
if (!gst_pad_has_current_caps (enc->srcpad))
|
if (!ctx->caps)
|
||||||
goto no_caps;
|
goto no_caps;
|
||||||
|
|
||||||
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
|
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
|
||||||
|
@ -611,13 +614,12 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
|
||||||
"accepting %" G_GSIZE_FORMAT " bytes encoded data as %d samples",
|
"accepting %" G_GSIZE_FORMAT " bytes encoded data as %d samples",
|
||||||
buf ? gst_buffer_get_size (buf) : -1, samples);
|
buf ? gst_buffer_get_size (buf) : -1, samples);
|
||||||
|
|
||||||
if (G_UNLIKELY (gst_pad_check_reconfigure (enc->srcpad))) {
|
if (G_UNLIKELY (ctx->output_caps_changed
|
||||||
GstCaps *caps = gst_pad_get_current_caps (enc->srcpad);
|
|| gst_pad_check_reconfigure (enc->srcpad))) {
|
||||||
if (!gst_audio_encoder_set_output_format (enc, caps)) {
|
if (!gst_audio_encoder_negotiate (enc)) {
|
||||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
gst_caps_unref (caps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark subclass still alive and providing */
|
/* mark subclass still alive and providing */
|
||||||
|
@ -2508,44 +2510,39 @@ gst_audio_encoder_merge_tags (GstAudioEncoder * enc,
|
||||||
GST_OBJECT_UNLOCK (enc);
|
GST_OBJECT_UNLOCK (enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* gst_audio_encoder_set_output_format:
|
* gst_audio_encoder_negotiate:
|
||||||
* @enc: a #GstAudioEncoder
|
* @dec: a #GstAudioEncoder
|
||||||
* @caps: #GstCaps
|
|
||||||
*
|
*
|
||||||
* Configure output caps on the srcpad of @enc.
|
* Negotiate with downstreame elements to currently configured #GstCaps.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE on success.
|
* Returns: #TRUE if the negotiation succeeded, else #FALSE.
|
||||||
**/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps)
|
gst_audio_encoder_negotiate (GstAudioEncoder * enc)
|
||||||
{
|
{
|
||||||
GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
|
GstAudioEncoderClass *klass;
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
GstCaps *templ_caps;
|
|
||||||
GstQuery *query = NULL;
|
GstQuery *query = NULL;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
GstAllocationParams params;
|
GstAllocationParams params;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
|
||||||
|
g_return_val_if_fail (GST_IS_CAPS (enc->priv->ctx.caps), FALSE);
|
||||||
|
|
||||||
|
klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
|
||||||
|
|
||||||
|
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
|
||||||
|
|
||||||
|
caps = enc->priv->ctx.caps;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
if (!gst_caps_is_fixed (caps))
|
|
||||||
goto refuse_caps;
|
|
||||||
|
|
||||||
/* Only allow caps that are a subset of the template caps */
|
|
||||||
templ_caps = gst_pad_get_pad_template_caps (enc->srcpad);
|
|
||||||
if (!gst_caps_is_subset (caps, templ_caps)) {
|
|
||||||
gst_caps_unref (templ_caps);
|
|
||||||
goto refuse_caps;
|
|
||||||
}
|
|
||||||
gst_caps_unref (templ_caps);
|
|
||||||
|
|
||||||
res = gst_pad_set_caps (enc->srcpad, caps);
|
res = gst_pad_set_caps (enc->srcpad, caps);
|
||||||
if (!res)
|
if (!res)
|
||||||
goto done;
|
goto done;
|
||||||
|
enc->priv->ctx.output_caps_changed = FALSE;
|
||||||
/* clear reconfigure so we don't set caps twice */
|
|
||||||
gst_pad_check_reconfigure (enc->srcpad);
|
|
||||||
|
|
||||||
query = gst_query_new_allocation (caps, TRUE);
|
query = gst_query_new_allocation (caps, TRUE);
|
||||||
if (!gst_pad_peer_query (enc->srcpad, query)) {
|
if (!gst_pad_peer_query (enc->srcpad, query)) {
|
||||||
|
@ -2579,6 +2576,53 @@ done:
|
||||||
if (query)
|
if (query)
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
|
|
||||||
|
GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_decide_allocation:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (enc, "Subclass failed to decide allocation");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gst_audio_encoder_set_output_format:
|
||||||
|
* @enc: a #GstAudioEncoder
|
||||||
|
* @caps: #GstCaps
|
||||||
|
*
|
||||||
|
* Configure output caps on the srcpad of @enc.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE on success.
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps)
|
||||||
|
{
|
||||||
|
gboolean res = FALSE;
|
||||||
|
GstCaps *templ_caps;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
|
||||||
|
if (!gst_caps_is_fixed (caps))
|
||||||
|
goto refuse_caps;
|
||||||
|
|
||||||
|
/* Only allow caps that are a subset of the template caps */
|
||||||
|
templ_caps = gst_pad_get_pad_template_caps (enc->srcpad);
|
||||||
|
if (!gst_caps_is_subset (caps, templ_caps)) {
|
||||||
|
gst_caps_unref (templ_caps);
|
||||||
|
goto refuse_caps;
|
||||||
|
}
|
||||||
|
gst_caps_unref (templ_caps);
|
||||||
|
|
||||||
|
gst_caps_replace (&enc->priv->ctx.caps, caps);
|
||||||
|
enc->priv->ctx.output_caps_changed = TRUE;
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -2588,12 +2632,6 @@ refuse_caps:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Errors */
|
|
||||||
no_decide_allocation:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (enc, "Subclass failed to decide allocation");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2617,14 +2655,10 @@ gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * enc, gsize size)
|
||||||
|
|
||||||
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
|
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
|
||||||
|
|
||||||
if (G_UNLIKELY (gst_pad_has_current_caps (enc->srcpad)
|
if (G_UNLIKELY (enc->priv->ctx.output_caps_changed || (enc->priv->ctx.caps
|
||||||
&& gst_pad_check_reconfigure (enc->srcpad))) {
|
&& gst_pad_check_reconfigure (enc->srcpad)))) {
|
||||||
GstCaps *caps = gst_pad_get_current_caps (enc->srcpad);
|
if (!gst_audio_encoder_negotiate (enc))
|
||||||
if (!gst_audio_encoder_set_output_format (enc, caps)) {
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer =
|
buffer =
|
||||||
|
|
|
@ -222,6 +222,7 @@ GstCaps * gst_audio_encoder_proxy_getcaps (GstAudioEncoder * enc,
|
||||||
gboolean gst_audio_encoder_set_output_format (GstAudioEncoder * enc,
|
gboolean gst_audio_encoder_set_output_format (GstAudioEncoder * enc,
|
||||||
GstCaps * caps);
|
GstCaps * caps);
|
||||||
|
|
||||||
|
gboolean gst_audio_encoder_negotiate (GstAudioEncoder * enc);
|
||||||
|
|
||||||
GstBuffer * gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * encoder,
|
GstBuffer * gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * encoder,
|
||||||
gsize size);
|
gsize size);
|
||||||
|
|
Loading…
Reference in a new issue