mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
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.
This commit is contained in:
parent
9e6654352e
commit
a926db34ad
6 changed files with 156 additions and 3 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ struct _GstMXFDemux
|
|||
MXFPartitionPack partition;
|
||||
MXFPrimerPack primer;
|
||||
|
||||
GArray *partition_index;
|
||||
|
||||
/* Structural metadata */
|
||||
gboolean update_metadata;
|
||||
gboolean final_metadata;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue