mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
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
This commit is contained in:
parent
1537023905
commit
4d3a965476
2 changed files with 74 additions and 7 deletions
|
@ -148,6 +148,7 @@ static GstPad *mpegtsmux_request_new_pad (GstElement * element,
|
||||||
static void mpegtsmux_release_pad (GstElement * element, GstPad * pad);
|
static void mpegtsmux_release_pad (GstElement * element, GstPad * pad);
|
||||||
static GstStateChangeReturn mpegtsmux_change_state (GstElement * element,
|
static GstStateChangeReturn mpegtsmux_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
static void mpegtsdemux_set_header_on_caps (MpegTsMux * mux);
|
||||||
|
|
||||||
GST_BOILERPLATE (MpegTsMux, mpegtsmux, GstElement, GST_TYPE_ELEMENT);
|
GST_BOILERPLATE (MpegTsMux, mpegtsmux, GstElement, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
@ -233,6 +234,8 @@ mpegtsmux_init (MpegTsMux * mux, MpegTsMuxClass * g_class)
|
||||||
mux->is_delta = TRUE;
|
mux->is_delta = TRUE;
|
||||||
|
|
||||||
mux->prog_map = NULL;
|
mux->prog_map = NULL;
|
||||||
|
mux->streamheader = NULL;
|
||||||
|
mux->streamheader_sent = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -261,7 +264,19 @@ mpegtsmux_dispose (GObject * object)
|
||||||
g_free (mux->programs);
|
g_free (mux->programs);
|
||||||
mux->programs = NULL;
|
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));
|
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 */
|
/* In case of Normal Ts packets */
|
||||||
GST_LOG_OBJECT (mux, "Outputting a packet of length %d", len);
|
GST_LOG_OBJECT (mux, "Outputting a packet of length %d", len);
|
||||||
buf = gst_buffer_new_and_alloc (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)) {
|
if (G_UNLIKELY (buf == NULL)) {
|
||||||
mux->last_flow_ret = GST_FLOW_ERROR;
|
mux->last_flow_ret = GST_FLOW_ERROR;
|
||||||
return FALSE;
|
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);
|
memcpy (GST_BUFFER_DATA (buf), data, len);
|
||||||
GST_BUFFER_TIMESTAMP (buf) = mux->last_ts;
|
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);
|
ret = gst_pad_push (mux->srcpad, buf);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
mux->last_flow_ret = ret;
|
mux->last_flow_ret = ret;
|
||||||
|
@ -928,6 +958,40 @@ new_packet_cb (guint8 * data, guint len, void *user_data, gint64 new_pcr)
|
||||||
return TRUE;
|
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
|
static gboolean
|
||||||
mpegtsdemux_prepare_srcpad (MpegTsMux * mux)
|
mpegtsdemux_prepare_srcpad (MpegTsMux * mux)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,6 +125,9 @@ struct MpegTsMux {
|
||||||
|
|
||||||
GstClockTime last_ts;
|
GstClockTime last_ts;
|
||||||
gboolean is_delta;
|
gboolean is_delta;
|
||||||
|
|
||||||
|
GList *streamheader;
|
||||||
|
gboolean streamheader_sent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MpegTsMuxClass {
|
struct MpegTsMuxClass {
|
||||||
|
|
Loading…
Reference in a new issue