summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-11-27 16:26:39 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-11-27 16:26:39 +0000
commita926db34ad8b983c95ef72ed9a5cb884c55430d1 (patch)
tree2b47b510a32a870e75251a402c4d231f3d11daec /gst
parent9e6654352e1e92664efad60f9a951cc2dd3c2a8a (diff)
downloadgst-plugins-bad-a926db34ad8b983c95ef72ed9a5cb884c55430d1.tar.gz
gst-plugins-bad-a926db34ad8b983c95ef72ed9a5cb884c55430d1.tar.bz2
gst-plugins-bad-a926db34ad8b983c95ef72ed9a5cb884c55430d1.zip
gst/mxf/: Implement parsing of the random index pack, which provides a seek table (including body sid) to the start o...
Original commit message from CVS: * 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.
Diffstat (limited to 'gst')
-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
5 files changed, 142 insertions, 3 deletions
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,