summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <mlureau@flumotion.com>2010-02-02 11:43:22 -0500
committerZaheer Abbas Merali <zaheerabbas@merali.org>2010-02-03 18:26:15 +0000
commit4d3a9654762698dadc98047f41956051ab45d32e (patch)
tree4dbe07bc98254b600a38e552a2589f335dee3958
parent1537023905cf8f0192afa33c1ddfce2150ad8682 (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.c80
-rw-r--r--gst/mpegtsmux/mpegtsmux.h3
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 {