diff options
author | Marc-André Lureau <mlureau@flumotion.com> | 2010-02-02 11:43:22 -0500 |
---|---|---|
committer | Zaheer Abbas Merali <zaheerabbas@merali.org> | 2010-02-03 18:26:15 +0000 |
commit | 4d3a9654762698dadc98047f41956051ab45d32e (patch) | |
tree | 4dbe07bc98254b600a38e552a2589f335dee3958 | |
parent | 1537023905cf8f0192afa33c1ddfce2150ad8682 (diff) |
mpegtsmux: add PAT/PMT in streamheader
The check for PAT/PMT buffers was suggested by
Zaheer Abbas Merali.
https://bugzilla.gnome.org/show_bug.cgi?id=608896
-rw-r--r-- | gst/mpegtsmux/mpegtsmux.c | 80 | ||||
-rw-r--r-- | gst/mpegtsmux/mpegtsmux.h | 3 |
2 files changed, 75 insertions, 8 deletions
diff --git a/gst/mpegtsmux/mpegtsmux.c b/gst/mpegtsmux/mpegtsmux.c index 957b1ea21..cb630848d 100644 --- a/gst/mpegtsmux/mpegtsmux.c +++ b/gst/mpegtsmux/mpegtsmux.c @@ -148,6 +148,7 @@ static GstPad *mpegtsmux_request_new_pad (GstElement * element, static void mpegtsmux_release_pad (GstElement * element, GstPad * pad); static GstStateChangeReturn mpegtsmux_change_state (GstElement * element, GstStateChange transition); +static void mpegtsdemux_set_header_on_caps (MpegTsMux * mux); GST_BOILERPLATE (MpegTsMux, mpegtsmux, GstElement, GST_TYPE_ELEMENT); @@ -233,6 +234,8 @@ mpegtsmux_init (MpegTsMux * mux, MpegTsMuxClass * g_class) mux->is_delta = TRUE; mux->prog_map = NULL; + mux->streamheader = NULL; + mux->streamheader_sent = FALSE; } static void @@ -261,7 +264,19 @@ mpegtsmux_dispose (GObject * object) g_free (mux->programs); mux->programs = NULL; } - + if (mux->streamheader) { + GstBuffer *buf; + GList *sh; + + sh = mux->streamheader; + while (sh) { + buf = sh->data; + gst_buffer_unref (buf); + sh = g_list_next (sh); + } + g_list_free (mux->streamheader); + mux->streamheader = NULL; + } GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); } @@ -903,13 +918,6 @@ new_packet_cb (guint8 * data, guint len, void *user_data, gint64 new_pcr) /* In case of Normal Ts packets */ GST_LOG_OBJECT (mux, "Outputting a packet of length %d", len); buf = gst_buffer_new_and_alloc (len); - if (mux->is_delta) { - GST_LOG_OBJECT (mux, "marking as delta unit"); - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); - } else { - GST_DEBUG_OBJECT (mux, "marking as non-delta unit"); - mux->is_delta = TRUE; - } if (G_UNLIKELY (buf == NULL)) { mux->last_flow_ret = GST_FLOW_ERROR; return FALSE; @@ -918,6 +926,28 @@ new_packet_cb (guint8 * data, guint len, void *user_data, gint64 new_pcr) memcpy (GST_BUFFER_DATA (buf), data, len); GST_BUFFER_TIMESTAMP (buf) = mux->last_ts; + + if (!mux->streamheader_sent) { + guint pid = ((data[1] & 0x1f) << 8) | data[2]; + if (pid == 0x00 || pid == 0x02) { /* if it's a PAT or a PMT */ + mux->streamheader = + g_list_append (mux->streamheader, gst_buffer_copy (buf)); + } else if (mux->streamheader) { + mpegtsdemux_set_header_on_caps (mux); + mux->streamheader_sent = TRUE; + /* don't unset the streamheaders by pushing old caps */ + gst_buffer_set_caps (buf, GST_PAD_CAPS (mux->srcpad)); + } + } + + if (mux->is_delta) { + GST_LOG_OBJECT (mux, "marking as delta unit"); + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); + } else { + GST_DEBUG_OBJECT (mux, "marking as non-delta unit"); + mux->is_delta = TRUE; + } + ret = gst_pad_push (mux->srcpad, buf); if (G_UNLIKELY (ret != GST_FLOW_OK)) { mux->last_flow_ret = ret; @@ -928,6 +958,40 @@ new_packet_cb (guint8 * data, guint len, void *user_data, gint64 new_pcr) return TRUE; } +static void +mpegtsdemux_set_header_on_caps (MpegTsMux * mux) +{ + GstBuffer *buf; + GstStructure *structure; + GValue array = { 0 }; + GValue value = { 0 }; + GstCaps *caps = GST_PAD_CAPS (mux->srcpad); + GList *sh; + + caps = gst_caps_make_writable (caps); + structure = gst_caps_get_structure (caps, 0); + + g_value_init (&array, GST_TYPE_ARRAY); + + sh = mux->streamheader; + while (sh) { + buf = sh->data; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS); + g_value_init (&value, GST_TYPE_BUFFER); + gst_value_take_buffer (&value, buf); + gst_value_array_append_value (&array, &value); + g_value_unset (&value); + sh = g_list_next (sh); + } + + g_list_free (mux->streamheader); + mux->streamheader = NULL; + + gst_structure_set_value (structure, "streamheader", &array); + gst_pad_set_caps (mux->srcpad, caps); + g_value_unset (&array); +} + static gboolean mpegtsdemux_prepare_srcpad (MpegTsMux * mux) { diff --git a/gst/mpegtsmux/mpegtsmux.h b/gst/mpegtsmux/mpegtsmux.h index ac4957f0e..a94b99184 100644 --- a/gst/mpegtsmux/mpegtsmux.h +++ b/gst/mpegtsmux/mpegtsmux.h @@ -125,6 +125,9 @@ struct MpegTsMux { GstClockTime last_ts; gboolean is_delta; + + GList *streamheader; + gboolean streamheader_sent; }; struct MpegTsMuxClass { |