summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
Diffstat (limited to 'gst')
-rw-r--r--gst/mpegtsparse/mpegtspacketizer.c156
-rw-r--r--gst/mpegtsparse/mpegtspacketizer.h2
2 files changed, 110 insertions, 48 deletions
diff --git a/gst/mpegtsparse/mpegtspacketizer.c b/gst/mpegtsparse/mpegtspacketizer.c
index d55d8a97..9b48a4f7 100644
--- a/gst/mpegtsparse/mpegtspacketizer.c
+++ b/gst/mpegtsparse/mpegtspacketizer.c
@@ -33,7 +33,7 @@ static void mpegts_packetizer_finalize (GObject * object);
#define CONTINUITY_UNSET 255
#define MAX_CONTINUITY 15
-#define SECTION_VERSION_NUMBER_NOTSET 255
+#define VERSION_NUMBER_NOTSET 255
typedef struct
{
@@ -41,24 +41,54 @@ typedef struct
/* the spec says sub_table_extension is the fourth and fifth byte of a
* section when the section_syntax_indicator is set to a value of "1". If
* section_syntax_indicator is 0, sub_table_extension will be set to 0 */
- guint16 sub_table_extension;
+ guint16 subtable_extension;
+ guint8 version_number;
+} MpegTSPacketizerStreamSubtable;
+
+typedef struct
+{
guint continuity_counter;
GstAdapter *section_adapter;
guint section_length;
- guint8 section_version_number;
+ GSList *subtables;
} MpegTSPacketizerStream;
+static gint
+mpegts_packetizer_stream_subtable_compare (gconstpointer a, gconstpointer b)
+{
+ MpegTSPacketizerStreamSubtable *asub, *bsub;
+
+ asub = (MpegTSPacketizerStreamSubtable *) a;
+ bsub = (MpegTSPacketizerStreamSubtable *) b;
+
+ if (asub->table_id == bsub->table_id &&
+ asub->subtable_extension == bsub->subtable_extension)
+ return 0;
+ return -1;
+}
+
+static MpegTSPacketizerStreamSubtable *
+mpegts_packetizer_stream_subtable_new (guint8 table_id,
+ guint16 subtable_extension)
+{
+ MpegTSPacketizerStreamSubtable *subtable;
+
+ subtable = g_new0 (MpegTSPacketizerStreamSubtable, 1);
+ subtable->version_number = VERSION_NUMBER_NOTSET;
+ subtable->table_id = table_id;
+ subtable->subtable_extension = subtable_extension;
+ return subtable;
+}
+
static MpegTSPacketizerStream *
-mpegts_packetizer_stream_new (guint8 table_id, guint16 sub_table_extension)
+mpegts_packetizer_stream_new ()
{
MpegTSPacketizerStream *stream;
stream = (MpegTSPacketizerStream *) g_new0 (MpegTSPacketizerStream, 1);
stream->section_adapter = gst_adapter_new ();
- stream->table_id = table_id;
- stream->sub_table_extension = sub_table_extension;
stream->continuity_counter = CONTINUITY_UNSET;
- stream->section_version_number = SECTION_VERSION_NUMBER_NOTSET;
+ stream->subtables = NULL;
return stream;
}
@@ -67,6 +97,8 @@ mpegts_packetizer_stream_free (MpegTSPacketizerStream * stream)
{
gst_adapter_clear (stream->section_adapter);
g_object_unref (stream->section_adapter);
+ g_slist_foreach (stream->subtables, (GFunc) g_free, NULL);
+ g_slist_free (stream->subtables);
g_free (stream);
}
@@ -94,7 +126,7 @@ static void
mpegts_packetizer_init (MpegTSPacketizer * packetizer)
{
packetizer->adapter = gst_adapter_new ();
- packetizer->streams = g_hash_table_new (g_str_hash, g_str_equal);
+ packetizer->streams = g_hash_table_new (g_direct_hash, g_direct_equal);
}
static void
@@ -207,6 +239,8 @@ mpegts_packetizer_parse_section_header (MpegTSPacketizer * packetizer,
{
guint8 tmp;
guint8 *data;
+ MpegTSPacketizerStreamSubtable *subtable;
+ GSList *subtable_list = NULL;
section->complete = TRUE;
/* get the section buffer, pass the ownership to the caller */
@@ -215,6 +249,23 @@ mpegts_packetizer_parse_section_header (MpegTSPacketizer * packetizer,
data = GST_BUFFER_DATA (section->buffer);
section->table_id = *data++;
+ if ((data[0] & 0x80) == 0)
+ section->subtable_extension = 0;
+ else
+ section->subtable_extension = GST_READ_UINT16_BE (data + 2);
+
+ subtable = mpegts_packetizer_stream_subtable_new (section->table_id,
+ section->subtable_extension);
+
+ subtable_list = g_slist_find_custom (stream->subtables, subtable,
+ mpegts_packetizer_stream_subtable_compare);
+ if (subtable_list) {
+ g_free (subtable);
+ subtable = (MpegTSPacketizerStreamSubtable *) (subtable_list->data);
+ } else {
+ stream->subtables = g_slist_prepend (stream->subtables, subtable);
+ }
+
section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
data += 2;
@@ -224,18 +275,20 @@ mpegts_packetizer_parse_section_header (MpegTSPacketizer * packetizer,
tmp = *data++;
section->version_number = (tmp >> 1) & 0x1F;
section->current_next_indicator = tmp & 0x01;
-
if (!section->current_next_indicator)
goto not_applicable;
- if (section->version_number == stream->section_version_number)
+ if (section->version_number == subtable->version_number)
goto not_applicable;
-
- stream->section_version_number = section->version_number;
+ subtable->version_number = section->version_number;
return TRUE;
not_applicable:
+ GST_LOG
+ ("not applicable pid %d table_id %d subtable_extension %d, current_next %d version %d",
+ section->pid, section->table_id, section->subtable_extension,
+ section->current_next_indicator, section->version_number);
section->complete = FALSE;
gst_buffer_unref (section->buffer);
return TRUE;
@@ -504,6 +557,7 @@ mpegts_packetizer_parse_nit (MpegTSPacketizer * packetizer,
GValueArray *descriptors = NULL;
gchar *dbg_str;
+ GST_DEBUG ("NIT");
/* fixed header + CRC == 16 */
if (GST_BUFFER_SIZE (section->buffer) < 23) {
GST_WARNING ("PID %d invalid NIT size %d",
@@ -670,6 +724,7 @@ mpegts_packetizer_parse_sdt (MpegTSPacketizer * packetizer,
GValue service_value = { 0 };
gchar *dbg_str;
+ GST_DEBUG ("SDT");
/* fixed header + CRC == 16 */
if (GST_BUFFER_SIZE (section->buffer) < 14) {
GST_WARNING ("PID %d invalid SDT size %d",
@@ -1058,11 +1113,10 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
gboolean res = FALSE;
MpegTSPacketizerStream *stream;
guint8 pointer, table_id;
- guint16 sub_table_extension;
+ guint16 subtable_extension;
guint section_length;
GstBuffer *sub_buf;
guint8 *data;
- gchar *sub_table_identifier;
g_return_val_if_fail (GST_IS_MPEGTS_PACKETIZER (packetizer), FALSE);
g_return_val_if_fail (packet != NULL, FALSE);
@@ -1081,59 +1135,65 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
data += pointer;
}
- table_id = *data++;
- /* sub_table_extension should be read from 4th and 5th bytes only if
- * section_syntax_indicator is 1 */
- if ((data[0] & 0x80) == 0)
- sub_table_extension = 0;
- else
- sub_table_extension = GST_READ_UINT16_BE (data + 2);
- sub_table_identifier =
- g_strdup_printf ("%d,%d", table_id, sub_table_extension);
- GST_DEBUG ("sub table identifier is: %s", sub_table_identifier);
- stream = (MpegTSPacketizerStream *) g_hash_table_lookup (packetizer->streams,
- sub_table_identifier);
- if (stream == NULL) {
- stream = mpegts_packetizer_stream_new (table_id, sub_table_extension);
- g_hash_table_insert (packetizer->streams, sub_table_identifier, stream);
- } else {
- g_free (sub_table_identifier);
- }
-
- section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
- data += 2;
-
/* create a sub buffer from the start of the section (table_id and
* section_length included) to the end */
sub_buf = gst_buffer_create_sub (packet->buffer,
- data - 3 - GST_BUFFER_DATA (packet->buffer), packet->data_end - data + 3);
+ data - GST_BUFFER_DATA (packet->buffer), packet->data_end - data);
+
+ stream = (MpegTSPacketizerStream *) g_hash_table_lookup (packetizer->streams,
+ GINT_TO_POINTER ((gint) packet->pid));
+ if (stream == NULL) {
+ stream = mpegts_packetizer_stream_new ();
+ g_hash_table_insert (packetizer->streams,
+ GINT_TO_POINTER ((gint) packet->pid), stream);
+ }
if (packet->payload_unit_start_indicator) {
+ table_id = *data++;
+ /* subtable_extension should be read from 4th and 5th bytes only if
+ * section_syntax_indicator is 1 */
+ if ((data[0] & 0x80) == 0)
+ subtable_extension = 0;
+ else
+ subtable_extension = GST_READ_UINT16_BE (data + 2);
+ GST_DEBUG ("pid: %d table_id %d sub_table_extension %d",
+ packet->pid, table_id, subtable_extension);
+
+ section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
+
if (stream->continuity_counter != CONTINUITY_UNSET) {
- GST_WARNING ("PID %d payload_unit_start_indicator set but section "
+ GST_DEBUG
+ ("PID %d table_id %d sub_table_extension %d payload_unit_start_indicator set but section "
"not complete (last_continuity: %d continuity: %d sec len %d buffer %d avail %d",
- packet->pid, stream->continuity_counter, packet->continuity_counter,
- section_length, GST_BUFFER_SIZE (sub_buf),
+ packet->pid, table_id, subtable_extension, stream->continuity_counter,
+ packet->continuity_counter, section_length, GST_BUFFER_SIZE (sub_buf),
gst_adapter_available (stream->section_adapter));
mpegts_packetizer_clear_section (packetizer, stream);
+ } else {
+ GST_DEBUG
+ ("pusi set and new stream section is %d long and data we have is: %d",
+ section_length, packet->data_end - packet->data);
}
-
stream->continuity_counter = packet->continuity_counter;
stream->section_length = section_length;
gst_adapter_push (stream->section_adapter, sub_buf);
res = TRUE;
- } else if (packet->continuity_counter == stream->continuity_counter + 1 ||
- (stream->continuity_counter == MAX_CONTINUITY &&
- packet->continuity_counter == 0)) {
+ } else if (stream->continuity_counter != CONTINUITY_UNSET &&
+ (packet->continuity_counter == stream->continuity_counter + 1 ||
+ (stream->continuity_counter == MAX_CONTINUITY &&
+ packet->continuity_counter == 0))) {
stream->continuity_counter = packet->continuity_counter;
gst_adapter_push (stream->section_adapter, sub_buf);
res = TRUE;
} else {
- GST_WARNING ("PID %d section discontinuity "
- "(last_continuity: %d continuity: %d", packet->pid,
- stream->continuity_counter, packet->continuity_counter);
+ if (stream->continuity_counter == CONTINUITY_UNSET)
+ GST_DEBUG ("PID %d waiting for pusi", packet->pid);
+ else
+ GST_DEBUG ("PID %d section discontinuity "
+ "(last_continuity: %d continuity: %d", packet->pid,
+ stream->continuity_counter, packet->continuity_counter);
mpegts_packetizer_clear_section (packetizer, stream);
gst_buffer_unref (sub_buf);
}
@@ -1146,7 +1206,6 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
* section_length */
if (gst_adapter_available (stream->section_adapter) >=
stream->section_length + 3) {
-
res = mpegts_packetizer_parse_section_header (packetizer,
stream, section);
@@ -1157,6 +1216,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
section->complete = FALSE;
}
} else {
+ GST_WARNING ("section not complete");
section->complete = FALSE;
}
diff --git a/gst/mpegtsparse/mpegtspacketizer.h b/gst/mpegtsparse/mpegtspacketizer.h
index d8901ac0..f156ce5f 100644
--- a/gst/mpegtsparse/mpegtspacketizer.h
+++ b/gst/mpegtsparse/mpegtspacketizer.h
@@ -49,6 +49,7 @@ struct _MpegTSPacketizer {
GObject object;
GstAdapter *adapter;
+ /* streams hashed by pid */
GHashTable *streams;
gboolean disposed;
};
@@ -78,6 +79,7 @@ typedef struct
GstBuffer *buffer;
gint16 pid;
guint8 table_id;
+ guint16 subtable_extension;
guint section_length;
guint8 version_number;
guint8 current_next_indicator;