Store all partitions & primer packs in memory for faster access
Store all partitions & primer packs in memory for faster access. This is later needed for fast seeking. Pre-fill the list of partitions with the content of the random index pack. Don't parse metadata of an partition twice.
This commit is contained in:
parent
158f24c786
commit
7ce5b5a2d6
@ -208,15 +208,29 @@ gst_mxf_demux_remove_pads (GstMXFDemux * demux)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mxf_demux_reset_mxf_state (GstMXFDemux * demux)
|
gst_mxf_demux_partition_free (GstMXFDemuxPartition * partition)
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (demux, "Resetting MXF state");
|
mxf_partition_pack_reset (&partition->partition);
|
||||||
mxf_partition_pack_reset (&demux->partition);
|
mxf_primer_pack_reset (&partition->primer);
|
||||||
mxf_primer_pack_reset (&demux->primer);
|
|
||||||
|
g_free (partition);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mxf_demux_reset_track_metadata (GstMXFDemux *demux)
|
gst_mxf_demux_reset_mxf_state (GstMXFDemux * demux)
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (demux, "Resetting MXF state");
|
||||||
|
|
||||||
|
g_list_foreach (demux->partitions, (GFunc) gst_mxf_demux_partition_free,
|
||||||
|
NULL);
|
||||||
|
g_list_free (demux->partitions);
|
||||||
|
demux->partitions = NULL;
|
||||||
|
|
||||||
|
demux->current_partition = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_mxf_demux_reset_track_metadata (GstMXFDemux * demux)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
@ -263,7 +277,6 @@ gst_mxf_demux_reset (GstMXFDemux * demux)
|
|||||||
|
|
||||||
demux->flushing = FALSE;
|
demux->flushing = FALSE;
|
||||||
|
|
||||||
demux->header_partition_pack_offset = 0;
|
|
||||||
demux->footer_partition_pack_offset = 0;
|
demux->footer_partition_pack_offset = 0;
|
||||||
demux->offset = 0;
|
demux->offset = 0;
|
||||||
|
|
||||||
@ -287,11 +300,10 @@ gst_mxf_demux_reset (GstMXFDemux * demux)
|
|||||||
|
|
||||||
gst_mxf_demux_remove_pads (demux);
|
gst_mxf_demux_remove_pads (demux);
|
||||||
|
|
||||||
if (demux->partition_index) {
|
if (demux->random_index_pack) {
|
||||||
g_array_free (demux->partition_index, TRUE);
|
g_array_free (demux->random_index_pack, TRUE);
|
||||||
demux->partition_index = NULL;
|
demux->random_index_pack = NULL;
|
||||||
}
|
}
|
||||||
demux->parsed_random_index_pack = FALSE;
|
|
||||||
|
|
||||||
if (demux->index_table) {
|
if (demux->index_table) {
|
||||||
guint i;
|
guint i;
|
||||||
@ -397,50 +409,60 @@ static GstFlowReturn
|
|||||||
gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
|
gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
if (demux->partition.valid) {
|
MXFPartitionPack partition;
|
||||||
mxf_partition_pack_reset (&demux->partition);
|
GList *l;
|
||||||
mxf_primer_pack_reset (&demux->primer);
|
GstMXFDemuxPartition *p = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Handling partition pack of size %u at offset %"
|
"Handling partition pack of size %u at offset %"
|
||||||
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
||||||
|
|
||||||
if (!mxf_partition_pack_parse (key, &demux->partition,
|
for (l = demux->partitions; l; l = l->next) {
|
||||||
|
GstMXFDemuxPartition *tmp = l->data;
|
||||||
|
|
||||||
|
if (tmp->partition.this_partition + demux->run_in == demux->offset &&
|
||||||
|
tmp->partition.major_version == 0x0001) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "Partition already parsed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!mxf_partition_pack_parse (key, &partition,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
||||||
GST_ERROR_OBJECT (demux, "Parsing partition pack failed");
|
GST_ERROR_OBJECT (demux, "Parsing partition pack failed");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (demux->partition.type == MXF_PARTITION_PACK_HEADER)
|
if (partition.this_partition != demux->offset + demux->run_in) {
|
||||||
demux->footer_partition_pack_offset = demux->partition.footer_partition;
|
GST_WARNING_OBJECT (demux, "Partition with incorrect offset");
|
||||||
|
partition.this_partition = demux->offset + demux->run_in;
|
||||||
if (!demux->parsed_random_index_pack) {
|
|
||||||
MXFRandomIndexPackEntry entry, *last_entry = NULL;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "Adding partition pack to index");
|
|
||||||
|
|
||||||
if (demux->partition_index && demux->partition_index->len > 0) {
|
|
||||||
last_entry =
|
|
||||||
&g_array_index (demux->partition_index, MXFRandomIndexPackEntry,
|
|
||||||
demux->partition_index->len - 1);
|
|
||||||
} else if (!demux->partition_index) {
|
|
||||||
demux->partition_index =
|
|
||||||
g_array_new (FALSE, FALSE, sizeof (MXFRandomIndexPackEntry));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_entry && last_entry->offset >= demux->offset) {
|
if (partition.type == MXF_PARTITION_PACK_HEADER)
|
||||||
GST_DEBUG_OBJECT (demux,
|
demux->footer_partition_pack_offset = partition.footer_partition;
|
||||||
"Not adding partition pack to index because it's before the last indexed one");
|
|
||||||
return GST_FLOW_OK;
|
for (l = demux->partitions; l; l = l->next) {
|
||||||
|
GstMXFDemuxPartition *tmp = l->data;
|
||||||
|
|
||||||
|
if (tmp->partition.this_partition + demux->run_in == demux->offset) {
|
||||||
|
p = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.offset = demux->offset;
|
if (p) {
|
||||||
entry.body_sid = demux->partition.body_sid;
|
mxf_partition_pack_reset (&p->partition);
|
||||||
|
memcpy (&p->partition, &partition, sizeof (MXFPartitionPack));
|
||||||
g_array_append_val (demux->partition_index, entry);
|
} else {
|
||||||
|
p = g_new0 (GstMXFDemuxPartition, 1);
|
||||||
|
memcpy (&p->partition, &partition, sizeof (MXFPartitionPack));
|
||||||
|
demux->partitions = g_list_prepend (demux->partitions, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
demux->current_partition = p;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,17 +474,17 @@ gst_mxf_demux_handle_primer_pack (GstMXFDemux * demux, const MXFUL * key,
|
|||||||
"Handling primer pack of size %u at offset %"
|
"Handling primer pack of size %u at offset %"
|
||||||
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
||||||
|
|
||||||
if (G_UNLIKELY (!demux->partition.valid)) {
|
if (G_UNLIKELY (!demux->current_partition)) {
|
||||||
GST_ERROR_OBJECT (demux, "Primer pack before partition pack");
|
GST_ERROR_OBJECT (demux, "Primer pack before partition pack");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (demux->primer.valid)) {
|
if (G_UNLIKELY (demux->current_partition->primer.mappings)) {
|
||||||
GST_ERROR_OBJECT (demux, "Primer pack already exists");
|
GST_DEBUG_OBJECT (demux, "Primer pack already exists");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mxf_primer_pack_parse (key, &demux->primer,
|
if (!mxf_primer_pack_parse (key, &demux->current_partition->primer,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
||||||
GST_ERROR_OBJECT (demux, "Parsing primer pack failed");
|
GST_ERROR_OBJECT (demux, "Parsing primer pack failed");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
@ -583,11 +605,11 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux)
|
|||||||
|
|
||||||
for (i = 0; i < demux->preface->content_storage->n_packages; i++) {
|
for (i = 0; i < demux->preface->content_storage->n_packages; i++) {
|
||||||
if (demux->preface->content_storage->packages[i] &&
|
if (demux->preface->content_storage->packages[i] &&
|
||||||
MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface->content_storage->
|
MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface->
|
||||||
packages[i])) {
|
content_storage->packages[i])) {
|
||||||
ret =
|
ret =
|
||||||
MXF_METADATA_GENERIC_PACKAGE (demux->preface->content_storage->
|
MXF_METADATA_GENERIC_PACKAGE (demux->preface->
|
||||||
packages[i]);
|
content_storage->packages[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,18 +895,23 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
|||||||
G_GUINT64_FORMAT " of type 0x%04x", GST_BUFFER_SIZE (buffer),
|
G_GUINT64_FORMAT " of type 0x%04x", GST_BUFFER_SIZE (buffer),
|
||||||
demux->offset, type);
|
demux->offset, type);
|
||||||
|
|
||||||
if (G_UNLIKELY (!demux->partition.valid)) {
|
if (G_UNLIKELY (!demux->current_partition)) {
|
||||||
GST_ERROR_OBJECT (demux, "Partition pack doesn't exist");
|
GST_ERROR_OBJECT (demux, "Partition pack doesn't exist");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (!demux->primer.valid)) {
|
if (G_UNLIKELY (!demux->current_partition->primer.mappings)) {
|
||||||
GST_ERROR_OBJECT (demux, "Primer pack doesn't exists");
|
GST_ERROR_OBJECT (demux, "Primer pack doesn't exists");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (demux->current_partition->parsed_metadata) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "Metadata of this partition was already parsed");
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
metadata =
|
metadata =
|
||||||
mxf_metadata_new (type, &demux->primer, demux->offset,
|
mxf_metadata_new (type, &demux->current_partition->primer, demux->offset,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
||||||
|
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
@ -892,13 +919,29 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
|||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
demux->update_metadata = TRUE;
|
||||||
|
|
||||||
if (!demux->metadata)
|
if (!demux->metadata)
|
||||||
demux->metadata = mxf_metadata_hash_table_new ();
|
demux->metadata = mxf_metadata_hash_table_new ();
|
||||||
|
|
||||||
old =
|
old =
|
||||||
g_hash_table_lookup (demux->metadata,
|
g_hash_table_lookup (demux->metadata,
|
||||||
&MXF_METADATA_BASE (metadata)->instance_uid);
|
&MXF_METADATA_BASE (metadata)->instance_uid);
|
||||||
if (old
|
|
||||||
|
if (old && G_TYPE_FROM_INSTANCE (old) != G_TYPE_FROM_INSTANCE (metadata)) {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
gchar str[48];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"Metadata with instance uid %s already exists and has different type '%s',"
|
||||||
|
" expected '%s'",
|
||||||
|
mxf_ul_to_string (&MXF_METADATA_BASE (metadata)->instance_uid, str),
|
||||||
|
g_type_name (G_TYPE_FROM_INSTANCE (old)),
|
||||||
|
g_type_name (G_TYPE_FROM_INSTANCE (metadata)));
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT (metadata));
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
} else if (old
|
||||||
&& MXF_METADATA_BASE (old)->offset >=
|
&& MXF_METADATA_BASE (old)->offset >=
|
||||||
MXF_METADATA_BASE (metadata)->offset) {
|
MXF_METADATA_BASE (metadata)->offset) {
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
@ -916,7 +959,6 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
|||||||
demux->preface = MXF_METADATA_PREFACE (metadata);
|
demux->preface = MXF_METADATA_PREFACE (metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
demux->update_metadata = TRUE;
|
|
||||||
gst_mxf_demux_reset_track_metadata (demux);
|
gst_mxf_demux_reset_track_metadata (demux);
|
||||||
|
|
||||||
g_hash_table_replace (demux->metadata,
|
g_hash_table_replace (demux->metadata,
|
||||||
@ -942,17 +984,23 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux,
|
|||||||
G_GUINT64_FORMAT " with scheme 0x%02x and type 0x%06x",
|
G_GUINT64_FORMAT " with scheme 0x%02x and type 0x%06x",
|
||||||
GST_BUFFER_SIZE (buffer), demux->offset, scheme, type);
|
GST_BUFFER_SIZE (buffer), demux->offset, scheme, type);
|
||||||
|
|
||||||
if (G_UNLIKELY (!demux->partition.valid)) {
|
if (G_UNLIKELY (!demux->current_partition)) {
|
||||||
GST_ERROR_OBJECT (demux, "Partition pack doesn't exist");
|
GST_ERROR_OBJECT (demux, "Partition pack doesn't exist");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (!demux->primer.valid)) {
|
if (G_UNLIKELY (!demux->current_partition->primer.mappings)) {
|
||||||
GST_ERROR_OBJECT (demux, "Primer pack doesn't exists");
|
GST_ERROR_OBJECT (demux, "Primer pack doesn't exists");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = mxf_descriptive_metadata_new (scheme, type, &demux->primer, demux->offset,
|
if (demux->current_partition->parsed_metadata) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "Metadata of this partition was already parsed");
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
m = mxf_descriptive_metadata_new (scheme, type,
|
||||||
|
&demux->current_partition->primer, demux->offset,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
||||||
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
@ -962,13 +1010,30 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux,
|
|||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
demux->update_metadata = TRUE;
|
||||||
|
|
||||||
if (!demux->metadata)
|
if (!demux->metadata)
|
||||||
demux->metadata = mxf_metadata_hash_table_new ();
|
demux->metadata = mxf_metadata_hash_table_new ();
|
||||||
|
|
||||||
old =
|
old =
|
||||||
g_hash_table_lookup (demux->metadata,
|
g_hash_table_lookup (demux->metadata,
|
||||||
&MXF_METADATA_BASE (m)->instance_uid);
|
&MXF_METADATA_BASE (m)->instance_uid);
|
||||||
if (old && MXF_METADATA_BASE (old)->offset >= MXF_METADATA_BASE (m)->offset) {
|
|
||||||
|
if (old && G_TYPE_FROM_INSTANCE (old) != G_TYPE_FROM_INSTANCE (m)) {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
gchar str[48];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"Metadata with instance uid %s already exists and has different type '%s',"
|
||||||
|
" expected '%s'",
|
||||||
|
mxf_ul_to_string (&MXF_METADATA_BASE (m)->instance_uid, str),
|
||||||
|
g_type_name (G_TYPE_FROM_INSTANCE (old)),
|
||||||
|
g_type_name (G_TYPE_FROM_INSTANCE (m)));
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT (m));
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
} else if (old
|
||||||
|
&& MXF_METADATA_BASE (old)->offset >= MXF_METADATA_BASE (m)->offset) {
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
gchar str[48];
|
gchar str[48];
|
||||||
#endif
|
#endif
|
||||||
@ -980,7 +1045,6 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux,
|
|||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
demux->update_metadata = TRUE;
|
|
||||||
gst_mxf_demux_reset_track_metadata (demux);
|
gst_mxf_demux_reset_track_metadata (demux);
|
||||||
|
|
||||||
g_hash_table_replace (demux->metadata, &MXF_METADATA_BASE (m)->instance_uid,
|
g_hash_table_replace (demux->metadata, &MXF_METADATA_BASE (m)->instance_uid,
|
||||||
@ -1020,8 +1084,8 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
|
|||||||
GST_DEBUG_OBJECT (demux, "Switching to component %u", pad->current_component);
|
GST_DEBUG_OBJECT (demux, "Switching to component %u", pad->current_component);
|
||||||
|
|
||||||
pad->component =
|
pad->component =
|
||||||
MXF_METADATA_SOURCE_CLIP (sequence->structural_components[pad->
|
MXF_METADATA_SOURCE_CLIP (sequence->
|
||||||
current_component]);
|
structural_components[pad->current_component]);
|
||||||
if (pad->component == NULL) {
|
if (pad->component == NULL) {
|
||||||
GST_ERROR_OBJECT (demux, "No such structural component");
|
GST_ERROR_OBJECT (demux, "No such structural component");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
@ -1029,8 +1093,8 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
|
|||||||
|
|
||||||
if (!pad->component->source_package
|
if (!pad->component->source_package
|
||||||
|| !pad->component->source_package->top_level
|
|| !pad->component->source_package->top_level
|
||||||
|| !MXF_METADATA_GENERIC_PACKAGE (pad->component->
|
|| !MXF_METADATA_GENERIC_PACKAGE (pad->component->source_package)->
|
||||||
source_package)->tracks) {
|
tracks) {
|
||||||
GST_ERROR_OBJECT (demux, "Invalid component");
|
GST_ERROR_OBJECT (demux, "Invalid component");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
@ -1167,7 +1231,8 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||||||
content_storage->essence_container_data[j];
|
content_storage->essence_container_data[j];
|
||||||
|
|
||||||
if (edata && p->source_package == edata->linked_package
|
if (edata && p->source_package == edata->linked_package
|
||||||
&& demux->partition.body_sid == edata->body_sid) {
|
&& demux->current_partition->partition.body_sid ==
|
||||||
|
edata->body_sid) {
|
||||||
pad = p;
|
pad = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1303,22 +1368,50 @@ static GstFlowReturn
|
|||||||
gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
|
gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Handling random index pack of size %u at offset %"
|
"Handling random index pack of size %u at offset %"
|
||||||
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
||||||
|
|
||||||
if (demux->partition_index || demux->parsed_random_index_pack) {
|
if (demux->random_index_pack) {
|
||||||
GST_DEBUG_OBJECT (demux, "Already parsed random index pack");
|
GST_DEBUG_OBJECT (demux, "Already parsed random index pack");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mxf_random_index_pack_parse (key, GST_BUFFER_DATA (buffer),
|
if (!mxf_random_index_pack_parse (key, GST_BUFFER_DATA (buffer),
|
||||||
GST_BUFFER_SIZE (buffer), &demux->partition_index)) {
|
GST_BUFFER_SIZE (buffer), &demux->random_index_pack)) {
|
||||||
GST_ERROR_OBJECT (demux, "Parsing random index pack failed");
|
GST_ERROR_OBJECT (demux, "Parsing random index pack failed");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
demux->parsed_random_index_pack = TRUE;
|
for (i = 0; i < demux->random_index_pack->len; i++) {
|
||||||
|
GList *l;
|
||||||
|
GstMXFDemuxPartition *p = NULL;
|
||||||
|
MXFRandomIndexPackEntry *e =
|
||||||
|
&g_array_index (demux->random_index_pack, MXFRandomIndexPackEntry, i);
|
||||||
|
|
||||||
|
if (e->offset < demux->run_in) {
|
||||||
|
GST_ERROR_OBJECT (demux, "Invalid random index pack entry");
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = demux->partitions; l; l = l->next) {
|
||||||
|
GstMXFDemuxPartition *tmp = l->data;
|
||||||
|
|
||||||
|
if (tmp->partition.this_partition + demux->run_in == e->offset) {
|
||||||
|
p = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
p = g_new0 (GstMXFDemuxPartition, 1);
|
||||||
|
p->partition.this_partition = e->offset - demux->run_in;
|
||||||
|
p->partition.body_sid = e->body_sid;
|
||||||
|
demux->partitions = g_list_prepend (demux->partitions, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
@ -1335,13 +1428,14 @@ gst_mxf_demux_handle_index_table_segment (GstMXFDemux * demux,
|
|||||||
"Handling index table segment of size %u at offset %"
|
"Handling index table segment of size %u at offset %"
|
||||||
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
||||||
|
|
||||||
if (!demux->primer.valid) {
|
if (!demux->current_partition->primer.mappings) {
|
||||||
GST_WARNING_OBJECT (demux, "Invalid primer pack");
|
GST_WARNING_OBJECT (demux, "Invalid primer pack");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mxf_index_table_segment_parse (key, &segment, &demux->primer,
|
if (!mxf_index_table_segment_parse (key, &segment,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
&demux->current_partition->primer, GST_BUFFER_DATA (buffer),
|
||||||
|
GST_BUFFER_SIZE (buffer))) {
|
||||||
|
|
||||||
GST_ERROR_OBJECT (demux, "Parsing index table segment failed");
|
GST_ERROR_OBJECT (demux, "Parsing index table segment failed");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
@ -1508,36 +1602,27 @@ gst_mxf_demux_pull_random_index_pack (GstMXFDemux * demux)
|
|||||||
static void
|
static void
|
||||||
gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
|
gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
|
||||||
{
|
{
|
||||||
MXFPartitionPack partition;
|
|
||||||
MXFPrimerPack primer;
|
|
||||||
guint64 old_offset = demux->offset;
|
guint64 old_offset = demux->offset;
|
||||||
MXFUL key;
|
MXFUL key;
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
guint read = 0;
|
guint read = 0;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
GstMXFDemuxPartition *old_partition = demux->current_partition;
|
||||||
|
|
||||||
memcpy (&partition, &demux->partition, sizeof (MXFPartitionPack));
|
demux->current_partition = NULL;
|
||||||
memcpy (&primer, &demux->primer, sizeof (MXFPrimerPack));
|
|
||||||
memset (&demux->partition, 0, sizeof (MXFPartitionPack));
|
|
||||||
memset (&demux->primer, 0, sizeof (MXFPrimerPack));
|
|
||||||
|
|
||||||
gst_mxf_demux_reset_metadata (demux);
|
gst_mxf_demux_reset_metadata (demux);
|
||||||
|
|
||||||
if (demux->footer_partition_pack_offset != 0) {
|
if (demux->footer_partition_pack_offset != 0) {
|
||||||
demux->offset =
|
demux->offset = demux->run_in + demux->footer_partition_pack_offset;
|
||||||
demux->header_partition_pack_offset +
|
|
||||||
demux->footer_partition_pack_offset;
|
|
||||||
} else {
|
} else {
|
||||||
MXFRandomIndexPackEntry *entry =
|
MXFRandomIndexPackEntry *entry =
|
||||||
&g_array_index (demux->partition_index, MXFRandomIndexPackEntry,
|
&g_array_index (demux->random_index_pack, MXFRandomIndexPackEntry,
|
||||||
demux->partition_index->len - 1);
|
demux->random_index_pack->len - 1);
|
||||||
demux->offset = entry->offset;
|
demux->offset = entry->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_try:
|
next_try:
|
||||||
mxf_partition_pack_reset (&demux->partition);
|
|
||||||
mxf_primer_pack_reset (&demux->primer);
|
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
|
gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
|
||||||
&read);
|
&read);
|
||||||
@ -1547,22 +1632,21 @@ next_try:
|
|||||||
if (!mxf_is_partition_pack (&key))
|
if (!mxf_is_partition_pack (&key))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!mxf_partition_pack_parse (&key, &demux->partition,
|
if (gst_mxf_demux_handle_partition_pack (demux, &key, buffer) != GST_FLOW_OK)
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
demux->offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
||||||
if (demux->partition.header_byte_count == 0) {
|
if (demux->current_partition->partition.header_byte_count == 0) {
|
||||||
if (demux->partition.prev_partition == 0
|
if (demux->current_partition->partition.prev_partition == 0
|
||||||
|| demux->partition.this_partition == 0)
|
|| demux->current_partition->partition.this_partition == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset + demux->partition.this_partition -
|
demux->run_in + demux->current_partition->partition.this_partition -
|
||||||
demux->partition.prev_partition;
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1572,8 +1656,9 @@ next_try:
|
|||||||
&read);
|
&read);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->run_in +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->current_partition->partition.this_partition -
|
||||||
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1582,16 +1667,19 @@ next_try:
|
|||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
} else if (mxf_is_primer_pack (&key)) {
|
} else if (mxf_is_primer_pack (&key)) {
|
||||||
if (!mxf_primer_pack_parse (&key, &demux->primer,
|
if (!demux->current_partition->primer.mappings) {
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
if (gst_mxf_demux_handle_primer_pack (demux, &key,
|
||||||
|
buffer) != GST_FLOW_OK) {
|
||||||
demux->offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->run_in +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->current_partition->partition.this_partition -
|
||||||
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
demux->offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
@ -1600,8 +1688,9 @@ next_try:
|
|||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->run_in +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->current_partition->partition.this_partition -
|
||||||
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1613,8 +1702,9 @@ next_try:
|
|||||||
&read);
|
&read);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->run_in +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->current_partition->partition.this_partition -
|
||||||
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1627,8 +1717,9 @@ next_try:
|
|||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
gst_mxf_demux_reset_metadata (demux);
|
gst_mxf_demux_reset_metadata (demux);
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->run_in +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->current_partition->partition.this_partition -
|
||||||
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
} else if (mxf_is_descriptive_metadata (&key)) {
|
} else if (mxf_is_descriptive_metadata (&key)) {
|
||||||
@ -1651,9 +1742,10 @@ next_try:
|
|||||||
GST_FLOW_OK
|
GST_FLOW_OK
|
||||||
|| gst_mxf_demux_handle_header_metadata_update_streams (demux) !=
|
|| gst_mxf_demux_handle_header_metadata_update_streams (demux) !=
|
||||||
GST_FLOW_OK) {
|
GST_FLOW_OK) {
|
||||||
|
demux->current_partition->parsed_metadata = TRUE;
|
||||||
demux->offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset + demux->partition.this_partition -
|
demux->run_in + demux->current_partition->partition.this_partition -
|
||||||
demux->partition.prev_partition;
|
demux->current_partition->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1661,12 +1753,8 @@ out:
|
|||||||
if (buffer)
|
if (buffer)
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
mxf_partition_pack_reset (&demux->partition);
|
|
||||||
mxf_primer_pack_reset (&demux->primer);
|
|
||||||
memcpy (&demux->partition, &partition, sizeof (MXFPartitionPack));
|
|
||||||
memcpy (&demux->primer, &primer, sizeof (MXFPrimerPack));
|
|
||||||
|
|
||||||
demux->offset = old_offset;
|
demux->offset = old_offset;
|
||||||
|
demux->current_partition = old_partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
@ -1682,6 +1770,7 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key,
|
|||||||
&& demux->preface
|
&& demux->preface
|
||||||
&& !mxf_is_metadata (key) && !mxf_is_descriptive_metadata (key)
|
&& !mxf_is_metadata (key) && !mxf_is_descriptive_metadata (key)
|
||||||
&& !mxf_is_fill (key)) {
|
&& !mxf_is_fill (key)) {
|
||||||
|
demux->current_partition->parsed_metadata = TRUE;
|
||||||
if ((ret =
|
if ((ret =
|
||||||
gst_mxf_demux_handle_header_metadata_resolve_references (demux)) !=
|
gst_mxf_demux_handle_header_metadata_resolve_references (demux)) !=
|
||||||
GST_FLOW_OK)
|
GST_FLOW_OK)
|
||||||
@ -1735,11 +1824,11 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key,
|
|||||||
/* In pull mode try to get the last metadata */
|
/* In pull mode try to get the last metadata */
|
||||||
if (mxf_is_partition_pack (key) && ret == GST_FLOW_OK
|
if (mxf_is_partition_pack (key) && ret == GST_FLOW_OK
|
||||||
&& demux->pull_footer_metadata
|
&& demux->pull_footer_metadata
|
||||||
&& demux->random_access && demux->partition.valid
|
&& demux->random_access && demux->current_partition
|
||||||
&& demux->partition.type == MXF_PARTITION_PACK_HEADER
|
&& demux->current_partition->partition.type == MXF_PARTITION_PACK_HEADER
|
||||||
&& (!demux->partition.closed || !demux->partition.complete)
|
&& (!demux->current_partition->partition.closed
|
||||||
&& (demux->footer_partition_pack_offset != 0 ||
|
|| !demux->current_partition->partition.complete)
|
||||||
demux->parsed_random_index_pack)) {
|
&& (demux->footer_partition_pack_offset != 0 || demux->random_index_pack)) {
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Open or incomplete header partition, trying to get final metadata from the last partitions");
|
"Open or incomplete header partition, trying to get final metadata from the last partitions");
|
||||||
gst_mxf_demux_parse_footer_metadata (demux);
|
gst_mxf_demux_parse_footer_metadata (demux);
|
||||||
@ -1800,7 +1889,6 @@ gst_mxf_demux_loop (GstPad * pad)
|
|||||||
"Found header partition pack at offset %" G_GUINT64_FORMAT,
|
"Found header partition pack at offset %" G_GUINT64_FORMAT,
|
||||||
demux->offset);
|
demux->offset);
|
||||||
demux->run_in = demux->offset;
|
demux->run_in = demux->offset;
|
||||||
demux->header_partition_pack_offset = demux->offset;
|
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1936,7 +2024,6 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf)
|
|||||||
"Found header partition pack at offset %" G_GUINT64_FORMAT,
|
"Found header partition pack at offset %" G_GUINT64_FORMAT,
|
||||||
demux->offset);
|
demux->offset);
|
||||||
demux->run_in = demux->offset;
|
demux->run_in = demux->offset;
|
||||||
demux->header_partition_pack_offset = demux->offset;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gst_adapter_flush (demux->adapter, 1);
|
gst_adapter_flush (demux->adapter, 1);
|
||||||
|
@ -41,6 +41,13 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _GstMXFDemux GstMXFDemux;
|
typedef struct _GstMXFDemux GstMXFDemux;
|
||||||
typedef struct _GstMXFDemuxClass GstMXFDemuxClass;
|
typedef struct _GstMXFDemuxClass GstMXFDemuxClass;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MXFPartitionPack partition;
|
||||||
|
MXFPrimerPack primer;
|
||||||
|
gboolean parsed_metadata;
|
||||||
|
} GstMXFDemuxPartition;
|
||||||
|
|
||||||
struct _GstMXFDemux
|
struct _GstMXFDemux
|
||||||
{
|
{
|
||||||
GstElement element;
|
GstElement element;
|
||||||
@ -68,11 +75,10 @@ struct _GstMXFDemux
|
|||||||
guint64 footer_partition_pack_offset;
|
guint64 footer_partition_pack_offset;
|
||||||
|
|
||||||
/* MXF file state */
|
/* MXF file state */
|
||||||
MXFPartitionPack partition;
|
GList *partitions;
|
||||||
MXFPrimerPack primer;
|
GstMXFDemuxPartition *current_partition;
|
||||||
|
|
||||||
gboolean parsed_random_index_pack;
|
GArray *random_index_pack;
|
||||||
GArray *partition_index;
|
|
||||||
GArray *index_table;
|
GArray *index_table;
|
||||||
|
|
||||||
/* Structural metadata */
|
/* Structural metadata */
|
||||||
|
@ -603,8 +603,6 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pack->valid = TRUE;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -966,8 +964,6 @@ mxf_primer_pack_parse (const MXFUL * key, MXFPrimerPack * pack,
|
|||||||
mxf_ul_to_string (uid, str));
|
mxf_ul_to_string (uid, str));
|
||||||
}
|
}
|
||||||
|
|
||||||
pack->valid = TRUE;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -81,8 +81,6 @@ typedef enum {
|
|||||||
|
|
||||||
/* SMPTE 377M 6.1, Table 1 and 2 */
|
/* SMPTE 377M 6.1, Table 1 and 2 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean valid;
|
|
||||||
|
|
||||||
MXFPartitionPackType type;
|
MXFPartitionPackType type;
|
||||||
|
|
||||||
gboolean closed;
|
gboolean closed;
|
||||||
@ -114,8 +112,6 @@ typedef struct {
|
|||||||
|
|
||||||
/* SMPTE 377M 8.1 */
|
/* SMPTE 377M 8.1 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean valid;
|
|
||||||
|
|
||||||
GHashTable *mappings;
|
GHashTable *mappings;
|
||||||
} MXFPrimerPack;
|
} MXFPrimerPack;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user