mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
vorbisenc: only push header buffers following initial events
This commit is contained in:
parent
bc6f00becb
commit
a7f508012c
2 changed files with 46 additions and 24 deletions
|
@ -106,6 +106,8 @@ static GstFlowReturn gst_vorbis_enc_handle_frame (GstAudioEncoder * enc,
|
||||||
static GstCaps *gst_vorbis_enc_getcaps (GstAudioEncoder * enc);
|
static GstCaps *gst_vorbis_enc_getcaps (GstAudioEncoder * enc);
|
||||||
static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
|
static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
static GstFlowReturn gst_vorbis_enc_pre_push (GstAudioEncoder * enc,
|
||||||
|
GstBuffer ** buffer);
|
||||||
|
|
||||||
static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
|
static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
|
||||||
|
|
||||||
|
@ -163,6 +165,7 @@ gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
|
||||||
base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
|
base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
|
||||||
base_class->getcaps = GST_DEBUG_FUNCPTR (gst_vorbis_enc_getcaps);
|
base_class->getcaps = GST_DEBUG_FUNCPTR (gst_vorbis_enc_getcaps);
|
||||||
base_class->event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
|
base_class->event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
|
||||||
|
base_class->pre_push = GST_DEBUG_FUNCPTR (gst_vorbis_enc_pre_push);
|
||||||
|
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
|
||||||
g_param_spec_int ("max-bitrate", "Maximum Bitrate",
|
g_param_spec_int ("max-bitrate", "Maximum Bitrate",
|
||||||
|
@ -255,6 +258,8 @@ gst_vorbis_enc_stop (GstAudioEncoder * enc)
|
||||||
vorbisenc->last_message = NULL;
|
vorbisenc->last_message = NULL;
|
||||||
gst_tag_list_free (vorbisenc->tags);
|
gst_tag_list_free (vorbisenc->tags);
|
||||||
vorbisenc->tags = NULL;
|
vorbisenc->tags = NULL;
|
||||||
|
g_slist_foreach (vorbisenc->headers, (GFunc) gst_buffer_unref, NULL);
|
||||||
|
vorbisenc->headers = NULL;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -620,6 +625,8 @@ gst_vorbis_enc_push_header (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
|
||||||
"Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
|
"Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
|
||||||
GST_BUFFER_OFFSET_END (buffer),
|
GST_BUFFER_OFFSET_END (buffer),
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
|
||||||
|
gst_buffer_set_caps (buffer,
|
||||||
|
GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc)));
|
||||||
return gst_pad_push (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc), buffer);
|
return gst_pad_push (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc), buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,20 +747,16 @@ gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
|
||||||
gst_buffer_set_caps (buf1, caps);
|
gst_buffer_set_caps (buf1, caps);
|
||||||
gst_buffer_set_caps (buf2, caps);
|
gst_buffer_set_caps (buf2, caps);
|
||||||
gst_buffer_set_caps (buf3, caps);
|
gst_buffer_set_caps (buf3, caps);
|
||||||
|
gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc), caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
/* push out buffers */
|
/* store buffers for later pre_push sending */
|
||||||
/* push_buffer takes the reference even for failure */
|
g_slist_foreach (vorbisenc->headers, (GFunc) gst_buffer_unref, NULL);
|
||||||
if ((ret = gst_vorbis_enc_push_header (vorbisenc, buf1)) != GST_FLOW_OK)
|
vorbisenc->headers = NULL;
|
||||||
goto failed_header_push;
|
GST_DEBUG_OBJECT (vorbisenc, "storing header buffers");
|
||||||
if ((ret = gst_vorbis_enc_push_header (vorbisenc, buf2)) != GST_FLOW_OK) {
|
vorbisenc->headers = g_slist_prepend (vorbisenc->headers, buf3);
|
||||||
buf2 = NULL;
|
vorbisenc->headers = g_slist_prepend (vorbisenc->headers, buf2);
|
||||||
goto failed_header_push;
|
vorbisenc->headers = g_slist_prepend (vorbisenc->headers, buf1);
|
||||||
}
|
|
||||||
if ((ret = gst_vorbis_enc_push_header (vorbisenc, buf3)) != GST_FLOW_OK) {
|
|
||||||
buf3 = NULL;
|
|
||||||
goto failed_header_push;
|
|
||||||
}
|
|
||||||
|
|
||||||
vorbisenc->header_sent = TRUE;
|
vorbisenc->header_sent = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -785,18 +788,6 @@ gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
|
||||||
ret = gst_vorbis_enc_output_buffers (vorbisenc);
|
ret = gst_vorbis_enc_output_buffers (vorbisenc);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* error cases */
|
|
||||||
failed_header_push:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (vorbisenc, "Failed to push headers");
|
|
||||||
/* buf1 is always already unreffed */
|
|
||||||
if (buf2)
|
|
||||||
gst_buffer_unref (buf2);
|
|
||||||
if (buf3)
|
|
||||||
gst_buffer_unref (buf3);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -836,6 +827,36 @@ gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_vorbis_enc_pre_push (GstAudioEncoder * enc, GstBuffer ** buffer)
|
||||||
|
{
|
||||||
|
GstVorbisEnc *vorbisenc;
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
|
vorbisenc = GST_VORBISENC (enc);
|
||||||
|
|
||||||
|
/* FIXME 0.11 ? get rid of this special ogg stuff and have it
|
||||||
|
* put and use 'codec data' in caps like anything else,
|
||||||
|
* with all the usual out-of-band advantage etc */
|
||||||
|
if (G_UNLIKELY (vorbisenc->headers)) {
|
||||||
|
GSList *header = vorbisenc->headers;
|
||||||
|
|
||||||
|
/* try to push all of these, if we lose one, might as well lose all */
|
||||||
|
while (header) {
|
||||||
|
if (ret == GST_FLOW_OK)
|
||||||
|
ret = gst_vorbis_enc_push_header (vorbisenc, header->data);
|
||||||
|
else
|
||||||
|
gst_vorbis_enc_push_header (vorbisenc, header->data);
|
||||||
|
header = g_slist_next (header);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free (vorbisenc->headers);
|
||||||
|
vorbisenc->headers = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
|
gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
GParamSpec * pspec)
|
GParamSpec * pspec)
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct _GstVorbisEnc {
|
||||||
gboolean setup;
|
gboolean setup;
|
||||||
gboolean header_sent;
|
gboolean header_sent;
|
||||||
gchar *last_message;
|
gchar *last_message;
|
||||||
|
GSList *headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstVorbisEncClass {
|
struct _GstVorbisEncClass {
|
||||||
|
|
Loading…
Reference in a new issue