audioencoder: Add function to set in-stream headers

API: gst_audio_encoder_set_headers()

This makes the hack in vorbisenc and probably others in ::pre_push()
unnecessary.
This commit is contained in:
Sebastian Dröge 2012-03-30 12:47:28 +02:00
parent c44397cccb
commit 78bcb67ea5
2 changed files with 52 additions and 0 deletions

View file

@ -195,6 +195,9 @@ typedef struct _GstAudioEncoderContext
/* MT-protected (with LOCK) */ /* MT-protected (with LOCK) */
GstClockTime min_latency; GstClockTime min_latency;
GstClockTime max_latency; GstClockTime max_latency;
GList *headers;
gboolean new_headers;
} GstAudioEncoderContext; } GstAudioEncoderContext;
struct _GstAudioEncoderPrivate struct _GstAudioEncoderPrivate
@ -439,6 +442,11 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full)
gst_audio_info_init (&enc->priv->ctx.info); gst_audio_info_init (&enc->priv->ctx.info);
memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx)); memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
g_list_foreach (enc->priv->ctx.headers, (GFunc) gst_buffer_unref, NULL);
g_list_free (enc->priv->ctx.headers);
enc->priv->ctx.headers = NULL;
enc->priv->ctx.new_headers = FALSE;
if (enc->priv->tags) if (enc->priv->tags)
gst_tag_list_free (enc->priv->tags); gst_tag_list_free (enc->priv->tags);
enc->priv->tags = NULL; enc->priv->tags = NULL;
@ -677,6 +685,33 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
if (G_LIKELY (buf)) { if (G_LIKELY (buf)) {
gsize size; gsize size;
/* Pushing headers first */
if (G_UNLIKELY (priv->ctx.new_headers)) {
GList *tmp;
GST_DEBUG_OBJECT (enc, "Sending headers");
for (tmp = priv->ctx.headers; tmp; tmp = tmp->next) {
GstBuffer *tmpbuf = gst_buffer_ref (tmp->data);
tmpbuf = gst_buffer_make_writable (tmpbuf);
size = gst_buffer_get_size (tmpbuf);
if (G_UNLIKELY (priv->discont)) {
GST_LOG_OBJECT (enc, "marking discont");
GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
priv->discont = FALSE;
}
GST_BUFFER_OFFSET (tmpbuf) = priv->bytes_out;
GST_BUFFER_OFFSET_END (tmpbuf) = priv->bytes_out + size;
priv->bytes_out += size;
gst_pad_push (enc->srcpad, tmpbuf);
}
priv->ctx.new_headers = FALSE;
}
size = gst_buffer_get_size (buf); size = gst_buffer_get_size (buf);
GST_LOG_OBJECT (enc, "taking %" G_GSIZE_FORMAT " bytes for output", size); GST_LOG_OBJECT (enc, "taking %" G_GSIZE_FORMAT " bytes for output", size);
@ -732,6 +767,7 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
if (ret != GST_FLOW_OK || !buf) { if (ret != GST_FLOW_OK || !buf) {
GST_DEBUG_OBJECT (enc, "subclass returned %s, buf %p", GST_DEBUG_OBJECT (enc, "subclass returned %s, buf %p",
gst_flow_get_name (ret), buf); gst_flow_get_name (ret), buf);
if (buf) if (buf)
gst_buffer_unref (buf); gst_buffer_unref (buf);
goto exit; goto exit;
@ -2045,6 +2081,19 @@ gst_audio_encoder_get_latency (GstAudioEncoder * enc,
GST_OBJECT_UNLOCK (enc); GST_OBJECT_UNLOCK (enc);
} }
void
gst_audio_encoder_set_headers (GstAudioEncoder * enc, GList * headers)
{
GST_DEBUG_OBJECT (enc, "new headers %p", headers);
if (enc->priv->ctx.headers) {
g_list_foreach (enc->priv->ctx.headers, (GFunc) gst_buffer_unref, NULL);
g_list_free (enc->priv->ctx.headers);
}
enc->priv->ctx.headers = headers;
enc->priv->ctx.new_headers = TRUE;
}
/** /**
* gst_audio_encoder_set_mark_granule: * gst_audio_encoder_set_mark_granule:
* @enc: a #GstAudioEncoder * @enc: a #GstAudioEncoder

View file

@ -243,6 +243,9 @@ void gst_audio_encoder_set_latency (GstAudioEncoder * enc,
GstClockTime min, GstClockTime min,
GstClockTime max); GstClockTime max);
void gst_audio_encoder_set_headers (GstAudioEncoder * enc,
GList * headers);
/* object properties */ /* object properties */
void gst_audio_encoder_set_mark_granule (GstAudioEncoder * enc, void gst_audio_encoder_set_mark_granule (GstAudioEncoder * enc,