summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--gst/mxf/mxfdemux.c95
-rw-r--r--gst/mxf/mxfdemux.h2
-rw-r--r--gst/mxf/mxfparse.c40
-rw-r--r--gst/mxf/mxfparse.h2
-rw-r--r--gst/mxf/mxftypes.h6
6 files changed, 156 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 3bd1573c..c242ee44 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2008-11-27 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * gst/mxf/mxfdemux.c: (gst_mxf_demux_reset),
+ (gst_mxf_demux_handle_random_index_pack),
+ (gst_mxf_demux_pull_random_index_pack), (gst_mxf_demux_loop):
+ * gst/mxf/mxfdemux.h:
+ * gst/mxf/mxfparse.c: (mxf_random_index_pack_parse):
+ * gst/mxf/mxfparse.h:
+ * gst/mxf/mxftypes.h:
+ Implement parsing of the random index pack, which provides a seek
+ table (including body sid) to the start of partition packs.
+ Later this will be used for reading all index table segments of
+ the complete file efficiently.
+
+2008-11-27 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
* gst/mxf/Makefile.am:
* gst/mxf/mxfdemux.c:
(gst_mxf_demux_handle_header_metadata_update_streams),
diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c
index 0098951e..07151b5e 100644
--- a/gst/mxf/mxfdemux.c
+++ b/gst/mxf/mxfdemux.c
@@ -389,6 +389,11 @@ gst_mxf_demux_reset (GstMXFDemux * demux)
demux->src = NULL;
}
+ if (demux->partition_index) {
+ g_array_free (demux->partition_index, TRUE);
+ demux->partition_index = NULL;
+ }
+
gst_mxf_demux_reset_mxf_state (demux);
gst_mxf_demux_reset_metadata (demux);
}
@@ -1275,8 +1280,9 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
MXFMetadataEssenceContainerData, i);
for (j = 0; j < demux->content_storage.n_essence_container_data; j++) {
- if (mxf_ul_is_equal (&demux->content_storage.
- essence_container_data_uids[j], &data->instance_uid)) {
+ if (mxf_ul_is_equal (&demux->
+ content_storage.essence_container_data_uids[j],
+ &data->instance_uid)) {
demux->content_storage.essence_container_data[j] = data;
break;
}
@@ -2136,7 +2142,17 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
"Handling random index pack of size %u at offset %"
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
- /* TODO: Parse this */
+ if (demux->partition_index) {
+ GST_DEBUG_OBJECT (demux, "Already parsed random index pack");
+ return GST_FLOW_OK;
+ }
+
+ if (!mxf_random_index_pack_parse (key, GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer), &demux->partition_index)) {
+ GST_ERROR_OBJECT (demux, "Parsing random index pack failed");
+ return GST_FLOW_ERROR;
+ }
+
return GST_FLOW_OK;
}
@@ -2235,6 +2251,74 @@ beach:
return ret;
}
+void
+gst_mxf_demux_pull_random_index_pack (GstMXFDemux * demux)
+{
+ GstBuffer *buffer;
+ GstFlowReturn ret;
+ gint64 filesize = -1;
+ GstFormat fmt = GST_FORMAT_BYTES;
+ guint32 pack_size;
+ MXFUL key;
+
+ if (!gst_pad_query_peer_duration (demux->sinkpad, &fmt, &filesize) ||
+ fmt != GST_FORMAT_BYTES || filesize == -1) {
+ GST_DEBUG_OBJECT (demux, "Can't query upstream size");
+ return;
+ }
+
+ g_assert (filesize > 4);
+
+ if ((ret =
+ gst_mxf_demux_pull_range (demux, filesize - 4, 4,
+ &buffer)) != GST_FLOW_OK) {
+ GST_DEBUG_OBJECT (demux, "Failed pulling last 4 bytes");
+ return;
+ }
+
+ pack_size = GST_READ_UINT32_BE (GST_BUFFER_DATA (buffer));
+
+ gst_buffer_unref (buffer);
+
+ if (pack_size < 20) {
+ GST_DEBUG_OBJECT (demux, "Too small pack size");
+ return;
+ } else if (pack_size > filesize - 20) {
+ GST_DEBUG_OBJECT (demux, "Too large pack size");
+ return;
+ }
+
+ if ((ret =
+ gst_mxf_demux_pull_range (demux, filesize - pack_size, 16,
+ &buffer)) != GST_FLOW_OK) {
+ GST_DEBUG_OBJECT (demux, "Failed pulling random index pack key");
+ return;
+ }
+
+ memcpy (&key, GST_BUFFER_DATA (buffer), 16);
+ gst_buffer_unref (buffer);
+
+ if (!mxf_is_random_index_pack (&key)) {
+ GST_DEBUG_OBJECT (demux, "No random index pack");
+ return;
+ }
+
+ if ((ret =
+ gst_mxf_demux_pull_klv_packet (demux, filesize - pack_size, &key,
+ &buffer, NULL)) != GST_FLOW_OK) {
+ GST_DEBUG_OBJECT (demux, "Failed pulling random index pack");
+ return;
+ }
+
+
+ gst_mxf_demux_handle_random_index_pack (demux, &key, buffer);
+ gst_buffer_unref (buffer);
+
+ if (!demux->partition_index)
+ demux->partition_index =
+ g_array_new (FALSE, FALSE, sizeof (MXFRandomIndexPackEntry));
+}
+
static void
gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
{
@@ -2521,6 +2605,11 @@ gst_mxf_demux_loop (GstPad * pad)
goto pause;
}
+ /* First of all pull&parse the random index pack at EOF */
+ if (!demux->partition_index) {
+ gst_mxf_demux_pull_random_index_pack (demux);
+ }
+
/* Now actually do something */
ret = gst_mxf_demux_pull_and_handle_klv_packet (demux);
diff --git a/gst/mxf/mxfdemux.h b/gst/mxf/mxfdemux.h
index 83426d67..674e6c35 100644
--- a/gst/mxf/mxfdemux.h
+++ b/gst/mxf/mxfdemux.h
@@ -67,6 +67,8 @@ struct _GstMXFDemux
MXFPartitionPack partition;
MXFPrimerPack primer;
+ GArray *partition_index;
+
/* Structural metadata */
gboolean update_metadata;
gboolean final_metadata;
diff --git a/gst/mxf/mxfparse.c b/gst/mxf/mxfparse.c
index 90fa6348..aceebc97 100644
--- a/gst/mxf/mxfparse.c
+++ b/gst/mxf/mxfparse.c
@@ -556,6 +556,46 @@ mxf_partition_pack_reset (MXFPartitionPack * pack)
memset (pack, 0, sizeof (MXFPartitionPack));
}
+/* SMPTE 377M 11.1 */
+gboolean
+mxf_random_index_pack_parse (const MXFUL * key, const guint8 * data, guint size,
+ GArray ** array)
+{
+ guint len, i;
+ MXFRandomIndexPackEntry entry;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (array != NULL, FALSE);
+
+ if (size < 4)
+ return FALSE;
+
+ if ((size - 4) % 12 != 0)
+ return FALSE;
+
+ GST_DEBUG ("Parsing random index pack:");
+
+ len = (size - 4) / 12;
+
+ GST_DEBUG (" number of entries = %u", len);
+
+ *array =
+ g_array_sized_new (FALSE, FALSE, sizeof (MXFRandomIndexPackEntry), len);
+
+ for (i = 0; i < len; i++) {
+ entry.body_sid = GST_READ_UINT32_BE (data);
+ entry.offset = GST_READ_UINT64_BE (data + 4);
+ data += 12;
+
+ GST_DEBUG (" entry %u = body sid %u at offset %" G_GUINT64_FORMAT, i,
+ entry.body_sid, entry.offset);
+
+ g_array_append_val (*array, entry);
+ }
+
+ return TRUE;
+}
+
/* SMPTE 377M 8.2 Table 1 and 2 */
static void
diff --git a/gst/mxf/mxfparse.h b/gst/mxf/mxfparse.h
index 99295762..6cace267 100644
--- a/gst/mxf/mxfparse.h
+++ b/gst/mxf/mxfparse.h
@@ -77,6 +77,8 @@ void mxf_partition_pack_reset (MXFPartitionPack *pack);
gboolean mxf_primer_pack_parse (const MXFUL *key, MXFPrimerPack *pack, const guint8 *data, guint size);
void mxf_primer_pack_reset (MXFPrimerPack *pack);
+gboolean mxf_random_index_pack_parse (const MXFUL *key, const guint8 *data, guint size, GArray **array);
+
gboolean mxf_local_tag_parse (const guint8 * data, guint size, guint16 * tag,
guint16 * tag_size, const guint8 ** tag_data);
void gst_mxf_local_tag_free (MXFLocalTag *tag);
diff --git a/gst/mxf/mxftypes.h b/gst/mxf/mxftypes.h
index 6fd15fae..f6ca345e 100644
--- a/gst/mxf/mxftypes.h
+++ b/gst/mxf/mxftypes.h
@@ -63,6 +63,12 @@ typedef struct {
guint8 *data;
} MXFLocalTag;
+/* SMPTE 377M 11.1 */
+typedef struct {
+ guint32 body_sid;
+ guint64 offset;
+} MXFRandomIndexPackEntry;
+
typedef enum {
MXF_PARTITION_PACK_HEADER,
MXF_PARTITION_PACK_BODY,