GstBuffer * in_buf);
static gboolean gst_speex_enc_sink_event (GstAudioEncoder * enc,
GstEvent * event);
+static GstFlowReturn
+gst_speex_enc_pre_push (GstAudioEncoder * benc, GstBuffer ** buffer);
#define gst_speex_enc_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstSpeexEnc, gst_speex_enc, GST_TYPE_AUDIO_ENCODER,
base_class->set_format = GST_DEBUG_FUNCPTR (gst_speex_enc_set_format);
base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_speex_enc_handle_frame);
base_class->event = GST_DEBUG_FUNCPTR (gst_speex_enc_sink_event);
+ base_class->pre_push = GST_DEBUG_FUNCPTR (gst_speex_enc_pre_push);
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_QUALITY,
g_param_spec_float ("quality", "Quality", "Encoding quality",
GST_DEBUG_OBJECT (enc, "start");
speex_bits_init (&enc->bits);
- enc->tags = gst_tag_list_new ();
+ enc->tags = gst_tag_list_new_empty ();
enc->header_sent = FALSE;
return TRUE;
speex_bits_destroy (&enc->bits);
gst_tag_list_free (enc->tags);
enc->tags = NULL;
+ g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
+ enc->headers = NULL;
+
+ gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
return TRUE;
}
gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
if (merged_tags == NULL)
- merged_tags = gst_tag_list_new ();
+ merged_tags = gst_tag_list_new_empty ();
GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags);
comments = gst_tag_list_to_vorbiscomment_buffer (merged_tags, NULL,
gint frame_size = enc->frame_size;
gint bytes = frame_size * 2 * enc->channels, samples;
gint outsize, written, dtx_ret = 0;
- guint8 *data, *bdata, *outdata;
+ guint8 *data, *data0 = NULL, *bdata, *outdata;
gsize bsize, size;
GstBuffer *outbuf;
GstFlowReturn ret = GST_FLOW_OK;
GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
size = ((bsize / bytes) + 1) * bytes;
- data = g_malloc0 (size);
+ data0 = data = g_malloc0 (size);
memcpy (data, bdata, bsize);
gst_buffer_unmap (buf, bdata, bsize);
bdata = NULL;
outbuf, samples);
done:
+ g_free (data0);
return ret;
}
/* negotiate with these caps */
GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
- /* push out buffers */
- ret = gst_speex_enc_push_buffer (enc, buf1);
-
- if (ret != GST_FLOW_OK) {
- gst_buffer_unref (buf2);
- goto done;
- }
-
- ret = gst_speex_enc_push_buffer (enc, buf2);
+ gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), caps);
+ gst_caps_unref (caps);
- if (ret != GST_FLOW_OK)
- goto done;
+ /* push out buffers */
+ /* store buffers for later pre_push sending */
+ g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
+ enc->headers = NULL;
+ GST_DEBUG_OBJECT (enc, "storing header buffers");
+ enc->headers = g_slist_prepend (enc->headers, buf2);
+ enc->headers = g_slist_prepend (enc->headers, buf1);
enc->header_sent = TRUE;
}
ret = gst_speex_enc_encode (enc, buf);
-done:
return ret;
}
+static GstFlowReturn
+gst_speex_enc_pre_push (GstAudioEncoder * benc, GstBuffer ** buffer)
+{
+ GstSpeexEnc *enc;
+ GstFlowReturn ret = GST_FLOW_OK;
+
+ enc = GST_SPEEX_ENC (benc);
+
+ /* 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 (enc->headers)) {
+ GSList *header = enc->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_speex_enc_push_buffer (enc, header->data);
+ else
+ gst_speex_enc_push_buffer (enc, header->data);
+ header = g_slist_next (header);
+ }
+
+ g_slist_free (enc->headers);
+ enc->headers = NULL;
+ }
+
+ return ret;
+}
static void
gst_speex_enc_get_property (GObject * object, guint prop_id, GValue * value,