summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorIain Holmes <iain@prettypeople.org>2003-07-29 17:46:14 +0000
committerIain Holmes <iain@prettypeople.org>2003-07-29 17:46:14 +0000
commit27d2925a1acc839d2860b078f81540f8dd1aaf12 (patch)
tree7e39a47cb254c0448e173631702f9759b639d261 /gst
parent066b70c789d3178750f2d3e3e4f64f21b4cfce95 (diff)
At end of stream, rewrite the header with the correct number of bytes
Original commit message from CVS: At end of stream, rewrite the header with the correct number of bytes
Diffstat (limited to 'gst')
-rw-r--r--gst/wavenc/gstwavenc.c114
-rw-r--r--gst/wavenc/gstwavenc.h5
2 files changed, 80 insertions, 39 deletions
diff --git a/gst/wavenc/gstwavenc.c b/gst/wavenc/gstwavenc.c
index aca1397e..2dde7c6c 100644
--- a/gst/wavenc/gstwavenc.c
+++ b/gst/wavenc/gstwavenc.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
/* GStreamer
* Copyright (C) <2002> Iain Holmes <iain@prettypeople.org>
*
@@ -112,6 +113,17 @@ GST_PAD_TEMPLATE_FACTORY (src_factory,
static GstElementClass *parent_class = NULL;
+static const GstEventMask *
+gst_wavenc_get_event_masks (GstPad *pad)
+{
+ static const GstEventMask src_event_masks[] = {
+ { GST_EVENT_EOS, 0 },
+ { 0, }
+ };
+
+ return src_event_masks;
+}
+
static GType
gst_wavenc_get_type (void)
{
@@ -240,13 +252,59 @@ gst_wavenc_sinkconnect (GstPad *pad,
}
static void
+gst_wavenc_stop_file (GstWavEnc *wavenc)
+{
+ GstEvent *event;
+ GstBuffer *outbuf;
+
+ event = gst_event_new_seek (GST_FORMAT_BYTES |
+ GST_SEEK_METHOD_SET, 0);
+ gst_pad_send_event (GST_PAD_PEER (wavenc->srcpad), event);
+
+ outbuf = gst_buffer_new_and_alloc (WAV_HEADER_LEN);
+ WRITE_U32 (wavenc->header + 4, wavenc->length);
+ memcpy (GST_BUFFER_DATA (outbuf), wavenc->header, WAV_HEADER_LEN);
+
+ gst_pad_push (wavenc->srcpad, outbuf);
+}
+
+static gboolean
+gst_wavenc_handle_event (GstPad *pad,
+ GstEvent *event)
+{
+ GstWavEnc *wavenc;
+ GstEventType type;
+
+ wavenc = GST_WAVENC (gst_pad_get_parent (pad));
+
+ type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
+
+ switch (type) {
+ case GST_EVENT_EOS:
+ wavenc->pad_eos = TRUE;
+ gst_wavenc_stop_file (wavenc);
+ gst_pad_push (wavenc->srcpad,
+ GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
+ gst_element_set_eos (GST_ELEMENT (wavenc));
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
gst_wavenc_init (GstWavEnc *wavenc)
{
wavenc->sinkpad = gst_pad_new_from_template (sinktemplate, "sink");
gst_element_add_pad (GST_ELEMENT (wavenc), wavenc->sinkpad);
gst_pad_set_chain_function (wavenc->sinkpad, gst_wavenc_chain);
gst_pad_set_link_function (wavenc->sinkpad, gst_wavenc_sinkconnect);
-
+ gst_pad_set_event_function (wavenc->sinkpad, gst_wavenc_handle_event);
+ gst_pad_set_event_mask_function (wavenc->sinkpad, gst_wavenc_get_event_masks);
+
wavenc->srcpad = gst_pad_new_from_template (srctemplate, "src");
gst_element_add_pad (GST_ELEMENT (wavenc), wavenc->srcpad);
@@ -262,44 +320,26 @@ gst_wavenc_chain (GstPad *pad,
wavenc = GST_WAVENC (gst_pad_get_parent (pad));
- if (GST_IS_EVENT (buf)) {
- GstEvent *event = GST_EVENT (buf);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- /* Should do something... */
- gst_event_unref (event);
-
- if (GST_PAD_IS_USABLE (wavenc->srcpad))
- gst_pad_push (wavenc->srcpad, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
- gst_element_set_eos (GST_ELEMENT (wavenc));
- break;
- default:
- gst_pad_event_default (pad, event);
- return;
- }
- }
- else {
- if (!wavenc->setup) {
- gst_buffer_unref (buf);
- gst_element_error (GST_ELEMENT (wavenc), "encoder not initialised (input is not audio?)");
- return;
- }
-
- if (GST_PAD_IS_USABLE (wavenc->srcpad)) {
- if (wavenc->flush_header) {
- GstBuffer *outbuf;
-
- outbuf = gst_buffer_new_and_alloc (WAV_HEADER_LEN);
- memcpy (GST_BUFFER_DATA (outbuf), wavenc->header, WAV_HEADER_LEN);
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+ if (!wavenc->setup) {
+ gst_buffer_unref (buf);
+ gst_element_error (GST_ELEMENT (wavenc), "encoder not initialised (input is not audio?)");
+ return;
+ }
- gst_pad_push (wavenc->srcpad, outbuf);
- wavenc->flush_header = FALSE;
- }
-
- gst_pad_push (wavenc->srcpad, buf);
+ if (GST_PAD_IS_USABLE (wavenc->srcpad)) {
+ if (wavenc->flush_header) {
+ GstBuffer *outbuf;
+
+ outbuf = gst_buffer_new_and_alloc (WAV_HEADER_LEN);
+ memcpy (GST_BUFFER_DATA (outbuf), wavenc->header, WAV_HEADER_LEN);
+ GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+
+ gst_pad_push (wavenc->srcpad, outbuf);
+ wavenc->flush_header = FALSE;
}
+
+ wavenc->length += GST_BUFFER_SIZE (buf);
+ gst_pad_push (wavenc->srcpad, buf);
}
}
diff --git a/gst/wavenc/gstwavenc.h b/gst/wavenc/gstwavenc.h
index fbc148c0..cec9415c 100644
--- a/gst/wavenc/gstwavenc.h
+++ b/gst/wavenc/gstwavenc.h
@@ -54,8 +54,9 @@ struct _GstWavEnc {
guint rate;
guint channels;
guint width;
-
- gboolean setup, flush_header;
+ guint32 length;
+
+ gboolean setup, flush_header, pad_eos;
guchar header[WAV_HEADER_LEN];
};