mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
Store MXF metadata in a hash table, keyed by UID
Store the MXF metadata in a hash table, keyed by the instance UID. This simplifies resolval of the metadata and makes looping over all metadata sets unnecessary in most cases. Additionally parse metadata always. If we already have a metadata set with the same UID replace it only if the new metadata set is from a later offset. This fixes metadata parsing of files where following partitions don't have a complete copy of the previous metadata.
This commit is contained in:
parent
52028f2e11
commit
716ce72e46
7 changed files with 802 additions and 818 deletions
|
@ -216,17 +216,10 @@ gst_mxf_demux_reset_mxf_state (GstMXFDemux * demux)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mxf_demux_reset_metadata (GstMXFDemux * demux)
|
gst_mxf_demux_reset_track_metadata (GstMXFDemux *demux)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "Resetting metadata");
|
|
||||||
|
|
||||||
demux->update_metadata = TRUE;
|
|
||||||
demux->metadata_resolved = FALSE;
|
|
||||||
|
|
||||||
demux->current_package = NULL;
|
|
||||||
|
|
||||||
if (demux->src) {
|
if (demux->src) {
|
||||||
for (i = 0; i < demux->src->len; i++) {
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
||||||
|
@ -241,19 +234,24 @@ gst_mxf_demux_reset_metadata (GstMXFDemux * demux)
|
||||||
pad->source_package = NULL;
|
pad->source_package = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_mxf_demux_reset_metadata (GstMXFDemux * demux)
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (demux, "Resetting metadata");
|
||||||
|
|
||||||
|
demux->update_metadata = TRUE;
|
||||||
|
demux->metadata_resolved = FALSE;
|
||||||
|
|
||||||
|
gst_mxf_demux_reset_track_metadata (demux);
|
||||||
|
|
||||||
|
demux->current_package = NULL;
|
||||||
|
|
||||||
demux->preface = NULL;
|
demux->preface = NULL;
|
||||||
|
|
||||||
if (demux->metadata) {
|
if (demux->metadata) {
|
||||||
guint i;
|
g_hash_table_destroy (demux->metadata);
|
||||||
|
|
||||||
for (i = 0; i < demux->metadata->len; i++) {
|
|
||||||
GstMiniObject *o = g_ptr_array_index (demux->metadata, i);
|
|
||||||
|
|
||||||
if (o)
|
|
||||||
gst_mini_object_unref (o);
|
|
||||||
}
|
|
||||||
g_ptr_array_free (demux->metadata, TRUE);
|
|
||||||
demux->metadata = NULL;
|
demux->metadata = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,8 +474,9 @@ gst_mxf_demux_handle_primer_pack (GstMXFDemux * demux, const MXFUL * key,
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
||||||
{
|
{
|
||||||
guint i;
|
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
GHashTableIter iter;
|
||||||
|
MXFMetadataBase *m = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "Resolve metadata references");
|
GST_DEBUG_OBJECT (demux, "Resolve metadata references");
|
||||||
demux->update_metadata = FALSE;
|
demux->update_metadata = FALSE;
|
||||||
|
@ -487,17 +486,16 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append NULL terminator */
|
g_hash_table_iter_init (&iter, demux->metadata);
|
||||||
g_ptr_array_add (demux->metadata, NULL);
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) & m)) {
|
||||||
|
m->resolved = MXF_METADATA_BASE_RESOLVE_STATE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < demux->metadata->len - 1; i++) {
|
g_hash_table_iter_init (&iter, demux->metadata);
|
||||||
MXFMetadataBase *m =
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) & m)) {
|
||||||
MXF_METADATA_BASE (g_ptr_array_index (demux->metadata, i));
|
|
||||||
gboolean resolved;
|
gboolean resolved;
|
||||||
|
|
||||||
resolved =
|
resolved = mxf_metadata_base_resolve (m, demux->metadata);
|
||||||
mxf_metadata_base_resolve (m,
|
|
||||||
(MXFMetadataBase **) demux->metadata->pdata);
|
|
||||||
|
|
||||||
/* Resolving can fail for anything but the preface, as the preface
|
/* Resolving can fail for anything but the preface, as the preface
|
||||||
* will resolve everything required */
|
* will resolve everything required */
|
||||||
|
@ -865,7 +863,7 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
guint16 type;
|
guint16 type;
|
||||||
MXFMetadata *metadata = NULL;
|
MXFMetadata *metadata = NULL, *old = NULL;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
type = GST_READ_UINT16_BE (key->u + 13);
|
type = GST_READ_UINT16_BE (key->u + 13);
|
||||||
|
@ -886,44 +884,43 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata =
|
metadata =
|
||||||
mxf_metadata_new (type, &demux->primer, GST_BUFFER_DATA (buffer),
|
mxf_metadata_new (type, &demux->primer, demux->offset,
|
||||||
GST_BUFFER_SIZE (buffer));
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
||||||
|
|
||||||
if (metadata && !MXF_IS_METADATA_PREFACE (metadata)
|
|
||||||
&& !demux->update_metadata) {
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
|
||||||
"Skipping parsing of metadata because it's older than what we have");
|
|
||||||
gst_mini_object_unref ((GstMiniObject *) metadata);
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
GST_ERROR_OBJECT (demux, "Parsing metadata failed");
|
GST_ERROR_OBJECT (demux, "Parsing metadata failed");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MXF_IS_METADATA_PREFACE (metadata)) {
|
if (!demux->metadata)
|
||||||
MXFMetadataPreface *preface = MXF_METADATA_PREFACE (metadata);
|
demux->metadata = mxf_metadata_hash_table_new ();
|
||||||
|
|
||||||
|
old =
|
||||||
|
g_hash_table_lookup (demux->metadata,
|
||||||
|
&MXF_METADATA_BASE (metadata)->instance_uid);
|
||||||
|
if (old
|
||||||
|
&& MXF_METADATA_BASE (old)->offset >=
|
||||||
|
MXF_METADATA_BASE (metadata)->offset) {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
gchar str[48];
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!demux->preface
|
|
||||||
|| (!mxf_timestamp_is_unknown (&preface->last_modified_date)
|
|
||||||
&& mxf_timestamp_compare (&demux->preface->last_modified_date,
|
|
||||||
&preface->last_modified_date) < 0)) {
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Timestamp of new preface is newer than old, updating metadata");
|
"Metadata with instance uid %s already exists and is newer",
|
||||||
gst_mxf_demux_reset_metadata (demux);
|
mxf_ul_to_string (&MXF_METADATA_BASE (metadata)->instance_uid, str));
|
||||||
demux->preface = preface;
|
gst_mini_object_unref (GST_MINI_OBJECT (metadata));
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (demux, "Preface is older than already parsed preface");
|
|
||||||
gst_mini_object_unref ((GstMiniObject *) metadata);
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MXF_IS_METADATA_PREFACE (metadata)) {
|
||||||
|
demux->preface = MXF_METADATA_PREFACE (metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!demux->metadata)
|
demux->update_metadata = TRUE;
|
||||||
demux->metadata = g_ptr_array_new ();
|
gst_mxf_demux_reset_track_metadata (demux);
|
||||||
|
|
||||||
g_ptr_array_add (demux->metadata, metadata);
|
g_hash_table_replace (demux->metadata,
|
||||||
|
&MXF_METADATA_BASE (metadata)->instance_uid, metadata);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -935,7 +932,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux,
|
||||||
guint32 type;
|
guint32 type;
|
||||||
guint8 scheme;
|
guint8 scheme;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
MXFDescriptiveMetadata *m = NULL;
|
MXFDescriptiveMetadata *m = NULL, *old = NULL;
|
||||||
|
|
||||||
scheme = GST_READ_UINT8 (key->u + 12);
|
scheme = GST_READ_UINT8 (key->u + 12);
|
||||||
type = GST_READ_UINT24_BE (key->u + 13);
|
type = GST_READ_UINT24_BE (key->u + 13);
|
||||||
|
@ -955,14 +952,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux,
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!demux->update_metadata) {
|
m = mxf_descriptive_metadata_new (scheme, type, &demux->primer, demux->offset,
|
||||||
GST_DEBUG_OBJECT (demux,
|
|
||||||
"Skipping parsing of metadata because it's older than what we have");
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m = mxf_descriptive_metadata_new (scheme, type, &demux->primer,
|
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
||||||
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
|
@ -973,10 +963,28 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!demux->metadata)
|
if (!demux->metadata)
|
||||||
demux->metadata = g_ptr_array_new ();
|
demux->metadata = mxf_metadata_hash_table_new ();
|
||||||
|
|
||||||
g_ptr_array_add (demux->metadata, m);
|
old =
|
||||||
|
g_hash_table_lookup (demux->metadata,
|
||||||
|
&MXF_METADATA_BASE (m)->instance_uid);
|
||||||
|
if (old && MXF_METADATA_BASE (old)->offset >= MXF_METADATA_BASE (m)->offset) {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
gchar str[48];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"Metadata with instance uid %s already exists and is newer",
|
||||||
|
mxf_ul_to_string (&MXF_METADATA_BASE (m)->instance_uid, str));
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT (m));
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
demux->update_metadata = TRUE;
|
||||||
|
gst_mxf_demux_reset_track_metadata (demux);
|
||||||
|
|
||||||
|
g_hash_table_replace (demux->metadata, &MXF_METADATA_BASE (m)->instance_uid,
|
||||||
|
m);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1502,7 +1510,7 @@ gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
|
||||||
{
|
{
|
||||||
MXFPartitionPack partition;
|
MXFPartitionPack partition;
|
||||||
MXFPrimerPack primer;
|
MXFPrimerPack primer;
|
||||||
guint64 offset, 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;
|
||||||
|
@ -1516,21 +1524,23 @@ gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
|
||||||
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) {
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->header_partition_pack_offset +
|
||||||
demux->footer_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->partition_index, MXFRandomIndexPackEntry,
|
||||||
demux->partition_index->len - 1);
|
demux->partition_index->len - 1);
|
||||||
offset = entry->offset;
|
demux->offset = entry->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_try:
|
next_try:
|
||||||
mxf_partition_pack_reset (&demux->partition);
|
mxf_partition_pack_reset (&demux->partition);
|
||||||
mxf_primer_pack_reset (&demux->primer);
|
mxf_primer_pack_reset (&demux->primer);
|
||||||
|
|
||||||
ret = gst_mxf_demux_pull_klv_packet (demux, offset, &key, &buffer, &read);
|
ret =
|
||||||
|
gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
|
||||||
|
&read);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1541,7 +1551,7 @@ next_try:
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)))
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
||||||
|
@ -1550,44 +1560,46 @@ next_try:
|
||||||
|| demux->partition.this_partition == 0)
|
|| demux->partition.this_partition == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset + demux->partition.this_partition -
|
demux->header_partition_pack_offset + demux->partition.this_partition -
|
||||||
demux->partition.prev_partition;
|
demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
ret = gst_mxf_demux_pull_klv_packet (demux, offset, &key, &buffer, &read);
|
ret =
|
||||||
|
gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
|
||||||
|
&read);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->header_partition_pack_offset +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->partition.this_partition - demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mxf_is_fill (&key)) {
|
if (mxf_is_fill (&key)) {
|
||||||
offset += read;
|
demux->offset += read;
|
||||||
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 (!mxf_primer_pack_parse (&key, &demux->primer,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
||||||
offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->header_partition_pack_offset +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->partition.this_partition - demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->header_partition_pack_offset +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->partition.this_partition - demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
|
@ -1596,9 +1608,11 @@ next_try:
|
||||||
|
|
||||||
/* parse metadata */
|
/* parse metadata */
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
ret = gst_mxf_demux_pull_klv_packet (demux, offset, &key, &buffer, &read);
|
ret =
|
||||||
|
gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
|
||||||
|
&read);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->header_partition_pack_offset +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->partition.this_partition - demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
|
@ -1606,19 +1620,24 @@ next_try:
|
||||||
|
|
||||||
if (mxf_is_metadata (&key)) {
|
if (mxf_is_metadata (&key)) {
|
||||||
ret = gst_mxf_demux_handle_metadata (demux, &key, buffer);
|
ret = gst_mxf_demux_handle_metadata (demux, &key, buffer);
|
||||||
offset += read;
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
||||||
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);
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset +
|
demux->header_partition_pack_offset +
|
||||||
demux->partition.this_partition - demux->partition.prev_partition;
|
demux->partition.this_partition - demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
}
|
}
|
||||||
} else if (mxf_is_descriptive_metadata (&key) || mxf_is_fill (&key)) {
|
} else if (mxf_is_descriptive_metadata (&key)) {
|
||||||
offset += read;
|
ret = gst_mxf_demux_handle_descriptive_metadata (demux, &key, buffer);
|
||||||
|
demux->offset += read;
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
buffer = NULL;
|
||||||
|
} else if (mxf_is_fill (&key)) {
|
||||||
|
demux->offset += read;
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1632,7 +1651,7 @@ 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) {
|
||||||
offset =
|
demux->offset =
|
||||||
demux->header_partition_pack_offset + demux->partition.this_partition -
|
demux->header_partition_pack_offset + demux->partition.this_partition -
|
||||||
demux->partition.prev_partition;
|
demux->partition.prev_partition;
|
||||||
goto next_try;
|
goto next_try;
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct _GstMXFDemux
|
||||||
|
|
||||||
gboolean metadata_resolved;
|
gboolean metadata_resolved;
|
||||||
MXFMetadataPreface *preface;
|
MXFMetadataPreface *preface;
|
||||||
GPtrArray *metadata;
|
GHashTable *metadata;
|
||||||
|
|
||||||
MXFUMID current_package_uid;
|
MXFUMID current_package_uid;
|
||||||
MXFMetadataGenericPackage *current_package;
|
MXFMetadataGenericPackage *current_package;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -56,7 +56,7 @@ mxf_metadata_base_handle_tag (MXFMetadataBase * self, MXFPrimerPack * primer,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_base_resolve_default (MXFMetadataBase * self,
|
mxf_metadata_base_resolve_default (MXFMetadataBase * self,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ mxf_metadata_base_parse (MXFMetadataBase * self, MXFPrimerPack * primer,
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mxf_metadata_base_resolve (MXFMetadataBase * self, MXFMetadataBase ** metadata)
|
mxf_metadata_base_resolve (MXFMetadataBase * self, GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataBaseClass *klass;
|
MXFMetadataBaseClass *klass;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
|
@ -262,8 +262,8 @@ mxf_metadata_register (guint16 type_id, GType type)
|
||||||
}
|
}
|
||||||
|
|
||||||
MXFMetadata *
|
MXFMetadata *
|
||||||
mxf_metadata_new (guint16 type, MXFPrimerPack * primer, const guint8 * data,
|
mxf_metadata_new (guint16 type, MXFPrimerPack * primer, guint64 offset,
|
||||||
guint size)
|
const guint8 * data, guint size)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
GType t = G_TYPE_INVALID;
|
GType t = G_TYPE_INVALID;
|
||||||
|
@ -289,6 +289,10 @@ mxf_metadata_new (guint16 type, MXFPrimerPack * primer, const guint8 * data,
|
||||||
t = MXF_TYPE_METADATA;
|
t = MXF_TYPE_METADATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GST_DEBUG ("Metadata type 0x%06x is handled by type %s", type,
|
||||||
|
g_type_name (t));
|
||||||
|
|
||||||
ret = (MXFMetadata *) g_type_create_instance (t);
|
ret = (MXFMetadata *) g_type_create_instance (t);
|
||||||
if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
|
if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
|
||||||
GST_ERROR ("Parsing metadata failed");
|
GST_ERROR ("Parsing metadata failed");
|
||||||
|
@ -297,6 +301,7 @@ mxf_metadata_new (guint16 type, MXFPrimerPack * primer, const guint8 * data,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->type = type;
|
ret->type = type;
|
||||||
|
ret->parent.offset = offset;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,48 +450,49 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_preface_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata)
|
mxf_metadata_preface_resolve (MXFMetadataBase * m, GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
|
MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
|
||||||
MXFMetadataBase **p = metadata, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
while (*p && (self->primary_package == NULL || self->content_storage == NULL)) {
|
current = g_hash_table_lookup (metadata, &self->primary_package_uid);
|
||||||
current = *p;
|
if (!current || !MXF_IS_METADATA_GENERIC_PACKAGE (current)) {
|
||||||
|
GST_ERROR ("Primary package not found");
|
||||||
if (MXF_IS_METADATA_GENERIC_PACKAGE (current) &&
|
} else {
|
||||||
mxf_ul_is_equal (&self->primary_package_uid, ¤t->instance_uid)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
if (mxf_metadata_base_resolve (current, metadata))
|
|
||||||
self->primary_package = MXF_METADATA_GENERIC_PACKAGE (current);
|
self->primary_package = MXF_METADATA_GENERIC_PACKAGE (current);
|
||||||
} else if (MXF_IS_METADATA_CONTENT_STORAGE (current) &&
|
|
||||||
mxf_ul_is_equal (&self->content_storage_uid, ¤t->instance_uid)) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata))
|
|
||||||
self->content_storage = MXF_METADATA_CONTENT_STORAGE (current);
|
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
current = NULL;
|
||||||
|
|
||||||
|
current = g_hash_table_lookup (metadata, &self->content_storage_uid);
|
||||||
|
if (!current || !MXF_IS_METADATA_CONTENT_STORAGE (current)) {
|
||||||
|
GST_ERROR ("Content storage not found");
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
|
self->content_storage = MXF_METADATA_CONTENT_STORAGE (current);
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Couldn't resolve content storage");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = NULL;
|
||||||
|
|
||||||
|
if (self->identifications)
|
||||||
|
memset (self->identifications, 0,
|
||||||
|
sizeof (gpointer) * self->n_identifications);
|
||||||
|
else
|
||||||
self->identifications =
|
self->identifications =
|
||||||
g_new0 (MXFMetadataIdentification *, self->n_identifications);
|
g_new0 (MXFMetadataIdentification *, self->n_identifications);
|
||||||
for (i = 0; i < self->n_identifications; i++) {
|
for (i = 0; i < self->n_identifications; i++) {
|
||||||
p = metadata;
|
current = g_hash_table_lookup (metadata, &self->identifications_uids[i]);
|
||||||
while (*p) {
|
if (current && MXF_IS_METADATA_IDENTIFICATION (current)) {
|
||||||
current = *p;
|
if (mxf_metadata_base_resolve (m, metadata))
|
||||||
|
|
||||||
if (MXF_IS_METADATA_IDENTIFICATION (current) &&
|
|
||||||
mxf_ul_is_equal (&self->identifications_uids[i],
|
|
||||||
¤t->instance_uid)) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata))
|
|
||||||
self->identifications[i] = MXF_METADATA_IDENTIFICATION (current);
|
self->identifications[i] = MXF_METADATA_IDENTIFICATION (current);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
p++;
|
current = NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self->content_storage) {
|
|
||||||
GST_ERROR ("Couldn't resolve content storage");
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -727,49 +733,53 @@ error:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_content_storage_resolve (MXFMetadataBase * m,
|
mxf_metadata_content_storage_resolve (MXFMetadataBase * m,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
|
MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
|
||||||
MXFMetadataBase **p = metadata, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
gboolean have_package = FALSE;
|
gboolean have_package = FALSE;
|
||||||
gboolean have_ecd = FALSE;
|
gboolean have_ecd = FALSE;
|
||||||
|
|
||||||
|
if (self->packages)
|
||||||
|
memset (self->packages, 0, sizeof (gpointer) * self->n_packages);
|
||||||
|
else
|
||||||
self->packages = g_new0 (MXFMetadataGenericPackage *, self->n_packages);
|
self->packages = g_new0 (MXFMetadataGenericPackage *, self->n_packages);
|
||||||
|
|
||||||
for (i = 0; i < self->n_packages; i++) {
|
for (i = 0; i < self->n_packages; i++) {
|
||||||
p = metadata;
|
current = g_hash_table_lookup (metadata, &self->packages_uids[i]);
|
||||||
while (*p) {
|
if (current && MXF_IS_METADATA_GENERIC_PACKAGE (current)) {
|
||||||
current = *p;
|
|
||||||
if (MXF_IS_METADATA_GENERIC_PACKAGE (current) &&
|
|
||||||
mxf_ul_is_equal (¤t->instance_uid, &self->packages_uids[i])) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
self->packages[i] = MXF_METADATA_GENERIC_PACKAGE (current);
|
self->packages[i] = MXF_METADATA_GENERIC_PACKAGE (current);
|
||||||
have_package = TRUE;
|
have_package = TRUE;
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Couldn't resolve package");
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
GST_ERROR ("Package not found");
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->essence_container_data)
|
||||||
|
memset (self->essence_container_data, 0,
|
||||||
|
sizeof (gpointer) * self->n_essence_container_data);
|
||||||
|
else
|
||||||
self->essence_container_data =
|
self->essence_container_data =
|
||||||
g_new0 (MXFMetadataEssenceContainerData *,
|
g_new0 (MXFMetadataEssenceContainerData *,
|
||||||
self->n_essence_container_data);
|
self->n_essence_container_data);
|
||||||
for (i = 0; i < self->n_essence_container_data; i++) {
|
for (i = 0; i < self->n_essence_container_data; i++) {
|
||||||
p = metadata;
|
current =
|
||||||
while (*p) {
|
g_hash_table_lookup (metadata, &self->essence_container_data_uids[i]);
|
||||||
current = *p;
|
if (current && MXF_IS_METADATA_ESSENCE_CONTAINER_DATA (current)) {
|
||||||
if (MXF_IS_METADATA_ESSENCE_CONTAINER_DATA (current) &&
|
|
||||||
mxf_ul_is_equal (¤t->instance_uid,
|
|
||||||
&self->essence_container_data_uids[i])) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
self->essence_container_data[i] =
|
self->essence_container_data[i] =
|
||||||
MXF_METADATA_ESSENCE_CONTAINER_DATA (current);
|
MXF_METADATA_ESSENCE_CONTAINER_DATA (current);
|
||||||
have_ecd = TRUE;
|
have_ecd = TRUE;
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Couldn't resolve essence container data");
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
GST_ERROR ("Essence container data not found");
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,15 +868,16 @@ error:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_essence_container_data_resolve (MXFMetadataBase * m,
|
mxf_metadata_essence_container_data_resolve (MXFMetadataBase * m,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataEssenceContainerData *self =
|
MXFMetadataEssenceContainerData *self =
|
||||||
MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
|
MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
|
||||||
MXFMetadataBase **p = metadata, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
|
GHashTableIter iter;
|
||||||
|
|
||||||
while (*p) {
|
g_hash_table_iter_init (&iter, metadata);
|
||||||
current = *p;
|
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
|
||||||
if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
|
if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
|
||||||
MXFMetadataSourcePackage *package = MXF_METADATA_SOURCE_PACKAGE (current);
|
MXFMetadataSourcePackage *package = MXF_METADATA_SOURCE_PACKAGE (current);
|
||||||
|
|
||||||
|
@ -878,7 +889,6 @@ mxf_metadata_essence_container_data_resolve (MXFMetadataBase * m,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->linked_package) {
|
if (!self->linked_package) {
|
||||||
|
@ -1013,27 +1023,25 @@ error:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_generic_package_resolve (MXFMetadataBase * m,
|
mxf_metadata_generic_package_resolve (MXFMetadataBase * m,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
|
MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
|
||||||
MXFMetadataBase **p, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
gboolean have_track = FALSE;
|
gboolean have_track = FALSE;
|
||||||
|
|
||||||
|
if (self->tracks)
|
||||||
|
memset (self->tracks, 0, sizeof (gpointer) * self->n_tracks);
|
||||||
|
else
|
||||||
self->tracks = g_new0 (MXFMetadataTrack *, self->n_tracks);
|
self->tracks = g_new0 (MXFMetadataTrack *, self->n_tracks);
|
||||||
for (i = 0; i < self->n_tracks; i++) {
|
for (i = 0; i < self->n_tracks; i++) {
|
||||||
p = metadata;
|
current = g_hash_table_lookup (metadata, &self->tracks_uids[i]);
|
||||||
while (*p) {
|
if (current && MXF_IS_METADATA_TRACK (current)) {
|
||||||
current = *p;
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
|
|
||||||
if (MXF_IS_METADATA_TRACK (current)) {
|
|
||||||
MXFMetadataTrack *track = MXF_METADATA_TRACK (current);
|
MXFMetadataTrack *track = MXF_METADATA_TRACK (current);
|
||||||
|
|
||||||
if (mxf_ul_is_equal (¤t->instance_uid, &self->tracks_uids[i])) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
|
||||||
self->tracks[i] = track;
|
self->tracks[i] = track;
|
||||||
have_track = TRUE;
|
have_track = TRUE;
|
||||||
|
|
||||||
if ((track->type & 0xf0) == 0x10)
|
if ((track->type & 0xf0) == 0x10)
|
||||||
self->n_timecode_tracks++;
|
self->n_timecode_tracks++;
|
||||||
else if ((track->type & 0xf0) == 0x20)
|
else if ((track->type & 0xf0) == 0x20)
|
||||||
|
@ -1042,13 +1050,11 @@ mxf_metadata_generic_package_resolve (MXFMetadataBase * m,
|
||||||
self->n_essence_tracks++;
|
self->n_essence_tracks++;
|
||||||
else if ((track->type & 0xf0) == 0x40)
|
else if ((track->type & 0xf0) == 0x40)
|
||||||
self->n_other_tracks++;
|
self->n_other_tracks++;
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Track couldn't be resolved");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
break;
|
GST_ERROR ("Track not found");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,7 +1090,7 @@ G_DEFINE_TYPE (MXFMetadataMaterialPackage, mxf_metadata_material_package,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_material_package_resolve (MXFMetadataBase * m,
|
mxf_metadata_material_package_resolve (MXFMetadataBase * m,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
gboolean ret =
|
gboolean ret =
|
||||||
MXF_METADATA_BASE_CLASS
|
MXF_METADATA_BASE_CLASS
|
||||||
|
@ -1194,12 +1200,11 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_source_package_resolve (MXFMetadataBase * m,
|
mxf_metadata_source_package_resolve (MXFMetadataBase * m, GHashTable * metadata)
|
||||||
MXFMetadataBase ** metadata)
|
|
||||||
{
|
{
|
||||||
MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
|
MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
|
||||||
MXFMetadataGenericPackage *package = MXF_METADATA_GENERIC_PACKAGE (m);
|
MXFMetadataGenericPackage *package = MXF_METADATA_GENERIC_PACKAGE (m);
|
||||||
MXFMetadataBase **p = metadata, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i, j;
|
guint i, j;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
MXFMetadataGenericDescriptor *d = NULL;
|
MXFMetadataGenericDescriptor *d = NULL;
|
||||||
|
@ -1209,18 +1214,15 @@ mxf_metadata_source_package_resolve (MXFMetadataBase * m,
|
||||||
MXF_METADATA_BASE_CLASS
|
MXF_METADATA_BASE_CLASS
|
||||||
(mxf_metadata_source_package_parent_class)->resolve (m, metadata);
|
(mxf_metadata_source_package_parent_class)->resolve (m, metadata);
|
||||||
|
|
||||||
while (*p) {
|
current = g_hash_table_lookup (metadata, &self->descriptors_uid);
|
||||||
current = *p;
|
if (current && MXF_IS_METADATA_GENERIC_DESCRIPTOR (current)) {
|
||||||
|
|
||||||
if (MXF_IS_METADATA_GENERIC_DESCRIPTOR (current) &&
|
|
||||||
mxf_ul_is_equal (¤t->instance_uid, &self->descriptors_uid)) {
|
|
||||||
d = MXF_METADATA_GENERIC_DESCRIPTOR (current);
|
d = MXF_METADATA_GENERIC_DESCRIPTOR (current);
|
||||||
break;
|
} else {
|
||||||
}
|
GST_ERROR ("Descriptor not found");
|
||||||
p++;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d || !mxf_metadata_base_resolve (MXF_METADATA_BASE (d), metadata)) {
|
if (!mxf_metadata_base_resolve (MXF_METADATA_BASE (d), metadata)) {
|
||||||
GST_ERROR ("Couldn't resolve descriptor");
|
GST_ERROR ("Couldn't resolve descriptor");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1230,6 +1232,8 @@ mxf_metadata_source_package_resolve (MXFMetadataBase * m,
|
||||||
|
|
||||||
if (m->sub_descriptors) {
|
if (m->sub_descriptors) {
|
||||||
self->n_descriptors = m->n_sub_descriptors + 1;
|
self->n_descriptors = m->n_sub_descriptors + 1;
|
||||||
|
if (self->descriptors)
|
||||||
|
g_free (self->descriptors);
|
||||||
self->descriptors =
|
self->descriptors =
|
||||||
g_new0 (MXFMetadataGenericDescriptor *, self->n_descriptors);
|
g_new0 (MXFMetadataGenericDescriptor *, self->n_descriptors);
|
||||||
|
|
||||||
|
@ -1241,6 +1245,8 @@ mxf_metadata_source_package_resolve (MXFMetadataBase * m,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->n_descriptors = 1;
|
self->n_descriptors = 1;
|
||||||
|
if (self->descriptors)
|
||||||
|
g_free (self->descriptors);
|
||||||
self->descriptors = g_new0 (MXFMetadataGenericDescriptor *, 1);
|
self->descriptors = g_new0 (MXFMetadataGenericDescriptor *, 1);
|
||||||
self->descriptors[0] = d;
|
self->descriptors[0] = d;
|
||||||
}
|
}
|
||||||
|
@ -1264,6 +1270,8 @@ mxf_metadata_source_package_resolve (MXFMetadataBase * m,
|
||||||
n_descriptor++;
|
n_descriptor++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (package->tracks[i]->descriptor)
|
||||||
|
g_free (package->tracks[i]->descriptor);
|
||||||
package->tracks[i]->descriptor =
|
package->tracks[i]->descriptor =
|
||||||
g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
|
g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
|
||||||
package->tracks[i]->n_descriptor = n_descriptor;
|
package->tracks[i]->n_descriptor = n_descriptor;
|
||||||
|
@ -1372,28 +1380,24 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_track_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata)
|
mxf_metadata_track_resolve (MXFMetadataBase * m, GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
|
MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
|
||||||
MXFMetadataBase **p = metadata, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
while (*p) {
|
current = g_hash_table_lookup (metadata, &self->sequence_uid);
|
||||||
current = *p;
|
if (current && MXF_IS_METADATA_SEQUENCE (current)) {
|
||||||
if (MXF_IS_METADATA_SEQUENCE (current) &&
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
mxf_ul_is_equal (¤t->instance_uid, &self->sequence_uid)) {
|
|
||||||
self->sequence = MXF_METADATA_SEQUENCE (current);
|
self->sequence = MXF_METADATA_SEQUENCE (current);
|
||||||
break;
|
} else {
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self->sequence
|
|
||||||
|| !mxf_metadata_base_resolve (MXF_METADATA_BASE (self->sequence),
|
|
||||||
metadata)) {
|
|
||||||
GST_ERROR ("Couldn't resolve sequence");
|
GST_ERROR ("Couldn't resolve sequence");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Couldn't find sequence");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
self->type =
|
self->type =
|
||||||
mxf_metadata_track_identifier_parse (&self->sequence->data_definition);
|
mxf_metadata_track_identifier_parse (&self->sequence->data_definition);
|
||||||
|
@ -1674,39 +1678,35 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_sequence_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata)
|
mxf_metadata_sequence_resolve (MXFMetadataBase * m, GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
|
MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
|
||||||
MXFMetadataBase **p, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
guint have_sc = 0;
|
|
||||||
|
|
||||||
|
if (self->structural_components)
|
||||||
|
memset (self->structural_components, 0,
|
||||||
|
sizeof (gpointer) * self->n_structural_components);
|
||||||
|
else
|
||||||
self->structural_components =
|
self->structural_components =
|
||||||
g_new0 (MXFMetadataStructuralComponent *, self->n_structural_components);
|
g_new0 (MXFMetadataStructuralComponent *,
|
||||||
|
self->n_structural_components);
|
||||||
for (i = 0; i < self->n_structural_components; i++) {
|
for (i = 0; i < self->n_structural_components; i++) {
|
||||||
p = metadata;
|
current =
|
||||||
|
g_hash_table_lookup (metadata, &self->structural_components_uids[i]);
|
||||||
while (*p) {
|
if (current && MXF_IS_METADATA_STRUCTURAL_COMPONENT (current)) {
|
||||||
current = *p;
|
|
||||||
|
|
||||||
if (MXF_IS_METADATA_STRUCTURAL_COMPONENT (current)
|
|
||||||
&& mxf_ul_is_equal (¤t->instance_uid,
|
|
||||||
&self->structural_components_uids[i])) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
self->structural_components[i] =
|
self->structural_components[i] =
|
||||||
MXF_METADATA_STRUCTURAL_COMPONENT (current);
|
MXF_METADATA_STRUCTURAL_COMPONENT (current);
|
||||||
have_sc++;
|
} else {
|
||||||
break;
|
GST_ERROR ("Couldn't resolve structural component");
|
||||||
}
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (have_sc != self->n_structural_components) {
|
|
||||||
GST_ERROR ("Couldn't resolve all structural components");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Structural component not found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->resolve (m,
|
MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->resolve (m,
|
||||||
|
@ -1913,15 +1913,15 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_source_clip_resolve (MXFMetadataBase * m,
|
mxf_metadata_source_clip_resolve (MXFMetadataBase * m, GHashTable * metadata)
|
||||||
MXFMetadataBase ** metadata)
|
|
||||||
{
|
{
|
||||||
MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
|
MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
|
||||||
MXFMetadataBase **p, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
|
GHashTableIter iter;
|
||||||
|
|
||||||
p = metadata;
|
g_hash_table_iter_init (&iter, metadata);
|
||||||
while (*p) {
|
|
||||||
current = *p;
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
|
||||||
if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
|
if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
|
||||||
MXFMetadataGenericPackage *p = MXF_METADATA_GENERIC_PACKAGE (current);
|
MXFMetadataGenericPackage *p = MXF_METADATA_GENERIC_PACKAGE (current);
|
||||||
|
|
||||||
|
@ -1930,7 +1930,6 @@ mxf_metadata_source_clip_resolve (MXFMetadataBase * m,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -2143,30 +2142,24 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_dm_segment_resolve (MXFMetadataBase * m,
|
mxf_metadata_dm_segment_resolve (MXFMetadataBase * m, GHashTable * metadata)
|
||||||
MXFMetadataBase ** metadata)
|
|
||||||
{
|
{
|
||||||
MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
|
MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
|
||||||
MXFMetadataBase **p = metadata, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
|
|
||||||
while (*p) {
|
current = g_hash_table_lookup (metadata, &self->dm_framework_uid);
|
||||||
current = *p;
|
if (current && MXF_IS_DESCRIPTIVE_METADATA_FRAMEWORK (current)) {
|
||||||
|
|
||||||
if (MXF_IS_DESCRIPTIVE_METADATA_FRAMEWORK (current)
|
|
||||||
&& mxf_ul_is_equal (¤t->instance_uid, &self->dm_framework_uid)) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
self->dm_framework = MXF_DESCRIPTIVE_METADATA_FRAMEWORK (current);
|
self->dm_framework = MXF_DESCRIPTIVE_METADATA_FRAMEWORK (current);
|
||||||
}
|
} else {
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self->dm_framework) {
|
|
||||||
GST_ERROR ("Couldn't resolve DM framework");
|
GST_ERROR ("Couldn't resolve DM framework");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Couldn't find DM framework");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->resolve
|
MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->resolve
|
||||||
|
@ -2257,28 +2250,28 @@ error:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_generic_descriptor_resolve (MXFMetadataBase * m,
|
mxf_metadata_generic_descriptor_resolve (MXFMetadataBase * m,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
|
MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
|
||||||
MXFMetadataBase **p, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
gboolean have_locator = FALSE;
|
gboolean have_locator = FALSE;
|
||||||
|
|
||||||
|
if (self->locators)
|
||||||
|
memset (self->locators, 0, sizeof (gpointer) * self->n_locators);
|
||||||
|
else
|
||||||
self->locators = g_new0 (MXFMetadataLocator *, self->n_locators);
|
self->locators = g_new0 (MXFMetadataLocator *, self->n_locators);
|
||||||
for (i = 0; i < self->n_locators; i++) {
|
for (i = 0; i < self->n_locators; i++) {
|
||||||
p = metadata;
|
current = g_hash_table_lookup (metadata, &self->locators_uids[i]);
|
||||||
while (*p) {
|
if (current && MXF_IS_METADATA_LOCATOR (current)) {
|
||||||
current = *p;
|
|
||||||
|
|
||||||
if (MXF_IS_METADATA_LOCATOR (current) &&
|
|
||||||
mxf_ul_is_equal (¤t->instance_uid, &self->locators_uids[i])) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
self->locators[i] = MXF_METADATA_LOCATOR (current);
|
self->locators[i] = MXF_METADATA_LOCATOR (current);
|
||||||
have_locator = TRUE;
|
have_locator = TRUE;
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Couldn't resolve locator");
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
GST_ERROR ("Locator not found");
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3149,35 +3142,33 @@ error:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mxf_metadata_multiple_descriptor_resolve (MXFMetadataBase * m,
|
mxf_metadata_multiple_descriptor_resolve (MXFMetadataBase * m,
|
||||||
MXFMetadataBase ** metadata)
|
GHashTable * metadata)
|
||||||
{
|
{
|
||||||
MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
|
MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
|
||||||
MXFMetadataBase **p, *current;
|
MXFMetadataBase *current = NULL;
|
||||||
guint i, have_subdescriptors = 0;
|
guint i, have_subdescriptors = 0;
|
||||||
|
|
||||||
|
if (self->sub_descriptors)
|
||||||
|
memset (self->sub_descriptors, 0,
|
||||||
|
sizeof (gpointer) * self->n_sub_descriptors);
|
||||||
|
else
|
||||||
self->sub_descriptors =
|
self->sub_descriptors =
|
||||||
g_new0 (MXFMetadataGenericDescriptor *, self->n_sub_descriptors);
|
g_new0 (MXFMetadataGenericDescriptor *, self->n_sub_descriptors);
|
||||||
for (i = 0; i < self->n_sub_descriptors; i++) {
|
for (i = 0; i < self->n_sub_descriptors; i++) {
|
||||||
p = metadata;
|
current = g_hash_table_lookup (metadata, &self->sub_descriptors_uids[i]);
|
||||||
while (*p) {
|
if (current && MXF_IS_METADATA_GENERIC_DESCRIPTOR (current)) {
|
||||||
current = *p;
|
|
||||||
if (MXF_IS_METADATA_GENERIC_DESCRIPTOR (current) &&
|
|
||||||
mxf_ul_is_equal (¤t->instance_uid,
|
|
||||||
&self->sub_descriptors_uids[i])) {
|
|
||||||
if (mxf_metadata_base_resolve (current, metadata)) {
|
if (mxf_metadata_base_resolve (current, metadata)) {
|
||||||
self->sub_descriptors[i] = MXF_METADATA_GENERIC_DESCRIPTOR (current);
|
self->sub_descriptors[i] = MXF_METADATA_GENERIC_DESCRIPTOR (current);
|
||||||
have_subdescriptors++;
|
have_subdescriptors++;
|
||||||
}
|
} else {
|
||||||
break;
|
GST_ERROR ("Couldn't resolve descriptor");
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (have_subdescriptors != self->n_sub_descriptors) {
|
|
||||||
GST_ERROR ("Couldn't resolve all subdescriptors");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Descriptor not found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
MXF_METADATA_BASE_CLASS
|
MXF_METADATA_BASE_CLASS
|
||||||
|
@ -3358,7 +3349,7 @@ mxf_descriptive_metadata_register (guint8 scheme, GSList * sets)
|
||||||
|
|
||||||
MXFDescriptiveMetadata *
|
MXFDescriptiveMetadata *
|
||||||
mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
|
mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
|
||||||
MXFPrimerPack * primer, const guint8 * data, guint size)
|
MXFPrimerPack * primer, guint64 offset, const guint8 * data, guint size)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
GType t = G_TYPE_INVALID;
|
GType t = G_TYPE_INVALID;
|
||||||
|
@ -3400,6 +3391,9 @@ mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("DM scheme 0x%02x type 0x%06x is handled by type %s", scheme, type,
|
||||||
|
g_type_name (t));
|
||||||
|
|
||||||
ret = (MXFDescriptiveMetadata *) g_type_create_instance (t);
|
ret = (MXFDescriptiveMetadata *) g_type_create_instance (t);
|
||||||
if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
|
if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
|
||||||
GST_ERROR ("Parsing metadata failed");
|
GST_ERROR ("Parsing metadata failed");
|
||||||
|
@ -3408,6 +3402,7 @@ mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->type = type;
|
ret->type = type;
|
||||||
|
ret->parent.offset = offset;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3445,3 +3440,11 @@ mxf_descriptive_metadata_framework_get_type (void)
|
||||||
|
|
||||||
return (GType) type;
|
return (GType) type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHashTable *
|
||||||
|
mxf_metadata_hash_table_new (void)
|
||||||
|
{
|
||||||
|
return g_hash_table_new_full ((GHashFunc) mxf_ul_hash,
|
||||||
|
(GEqualFunc) mxf_ul_is_equal, (GDestroyNotify) NULL,
|
||||||
|
(GDestroyNotify) gst_mini_object_unref);
|
||||||
|
}
|
||||||
|
|
|
@ -373,6 +373,8 @@ struct _MXFMetadataBase {
|
||||||
MXFUL instance_uid;
|
MXFUL instance_uid;
|
||||||
MXFUL generation_uid;
|
MXFUL generation_uid;
|
||||||
|
|
||||||
|
guint64 offset;
|
||||||
|
|
||||||
MXFMetadataBaseResolveState resolved;
|
MXFMetadataBaseResolveState resolved;
|
||||||
|
|
||||||
GHashTable *other_tags;
|
GHashTable *other_tags;
|
||||||
|
@ -382,7 +384,7 @@ struct _MXFMetadataBaseClass {
|
||||||
GstMiniObjectClass parent;
|
GstMiniObjectClass parent;
|
||||||
|
|
||||||
gboolean (*handle_tag) (MXFMetadataBase *self, MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint tag_size);
|
gboolean (*handle_tag) (MXFMetadataBase *self, MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint tag_size);
|
||||||
gboolean (*resolve) (MXFMetadataBase *self, MXFMetadataBase **metadata);
|
gboolean (*resolve) (MXFMetadataBase *self, GHashTable *metadata);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MXFMetadata {
|
struct _MXFMetadata {
|
||||||
|
@ -745,9 +747,9 @@ struct _MXFDescriptiveMetadataFrameworkInterface {
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean mxf_metadata_base_parse (MXFMetadataBase *self, MXFPrimerPack *primer, const guint8 *data, guint size);
|
gboolean mxf_metadata_base_parse (MXFMetadataBase *self, MXFPrimerPack *primer, const guint8 *data, guint size);
|
||||||
gboolean mxf_metadata_base_resolve (MXFMetadataBase *self, MXFMetadataBase **metadata);
|
gboolean mxf_metadata_base_resolve (MXFMetadataBase *self, GHashTable *metadata);
|
||||||
|
|
||||||
MXFMetadata *mxf_metadata_new (guint16 type, MXFPrimerPack *primer, const guint8 *data, guint size);
|
MXFMetadata *mxf_metadata_new (guint16 type, MXFPrimerPack *primer, guint64 offset, const guint8 *data, guint size);
|
||||||
void mxf_metadata_register (guint16 type_id, GType type);
|
void mxf_metadata_register (guint16 type_id, GType type);
|
||||||
void mxf_metadata_init_types (void);
|
void mxf_metadata_init_types (void);
|
||||||
|
|
||||||
|
@ -757,6 +759,8 @@ void mxf_metadata_generic_picture_essence_descriptor_set_caps (MXFMetadataGeneri
|
||||||
void mxf_metadata_generic_sound_essence_descriptor_set_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps);
|
void mxf_metadata_generic_sound_essence_descriptor_set_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps);
|
||||||
|
|
||||||
void mxf_descriptive_metadata_register (guint8 scheme, GSList *sets);
|
void mxf_descriptive_metadata_register (guint8 scheme, GSList *sets);
|
||||||
MXFDescriptiveMetadata * mxf_descriptive_metadata_new (guint8 scheme, guint32 type, MXFPrimerPack * primer, const guint8 * data, guint size);
|
MXFDescriptiveMetadata * mxf_descriptive_metadata_new (guint8 scheme, guint32 type, MXFPrimerPack * primer, guint64 offset, const guint8 * data, guint size);
|
||||||
|
|
||||||
|
GHashTable *mxf_metadata_hash_table_new (void);
|
||||||
|
|
||||||
#endif /* __MXF_METADATA_H__ */
|
#endif /* __MXF_METADATA_H__ */
|
||||||
|
|
|
@ -215,6 +215,20 @@ mxf_ul_is_zero (const MXFUL * key)
|
||||||
return (memcmp (key, &key_zero, 16) == 0);
|
return (memcmp (key, &key_zero, 16) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
mxf_ul_hash (const MXFUL * key)
|
||||||
|
{
|
||||||
|
guint32 ret = 0;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
ret ^=
|
||||||
|
(key->u[i * 4 + 0] << 24) | (key->u[i * 4 + 1] << 16) | (key->u[i * 4 +
|
||||||
|
2] << 8) | (key->u[i * 4 + 3] << 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
mxf_ul_to_string (const MXFUL * key, gchar str[48])
|
mxf_ul_to_string (const MXFUL * key, gchar str[48])
|
||||||
{
|
{
|
||||||
|
@ -302,26 +316,6 @@ mxf_umid_from_string (const gchar * str, MXFUMID * umid)
|
||||||
return umid;
|
return umid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
|
||||||
gst_mxf_ul_hash (const MXFUL * key)
|
|
||||||
{
|
|
||||||
guint32 ret = 0;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
ret ^=
|
|
||||||
(key->u[i * 4 + 0] << 24) | (key->u[i * 4 + 1] << 16) | (key->u[i * 4 +
|
|
||||||
2] << 8) | (key->u[i * 4 + 3] << 0);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_mxf_ul_equal (const MXFUL * a, const MXFUL * b)
|
|
||||||
{
|
|
||||||
return (memcmp (a, b, 16) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mxf_timestamp_parse (MXFTimestamp * timestamp, const guint8 * data, guint size)
|
mxf_timestamp_parse (MXFTimestamp * timestamp, const guint8 * data, guint size)
|
||||||
{
|
{
|
||||||
|
@ -1015,7 +1009,7 @@ mxf_local_tag_parse (const guint8 * data, guint size, guint16 * tag,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_mxf_local_tag_free (MXFLocalTag * tag)
|
mxf_local_tag_free (MXFLocalTag * tag)
|
||||||
{
|
{
|
||||||
g_free (tag->data);
|
g_free (tag->data);
|
||||||
g_slice_free (MXFLocalTag, tag);
|
g_slice_free (MXFLocalTag, tag);
|
||||||
|
@ -1036,9 +1030,9 @@ mxf_local_tag_add_to_hash_table (const MXFPrimerPack * primer,
|
||||||
|
|
||||||
if (*hash_table == NULL)
|
if (*hash_table == NULL)
|
||||||
*hash_table =
|
*hash_table =
|
||||||
g_hash_table_new_full ((GHashFunc) gst_mxf_ul_hash,
|
g_hash_table_new_full ((GHashFunc) mxf_ul_hash,
|
||||||
(GEqualFunc) gst_mxf_ul_equal, (GDestroyNotify) NULL,
|
(GEqualFunc) mxf_ul_is_equal, (GDestroyNotify) NULL,
|
||||||
(GDestroyNotify) gst_mxf_local_tag_free);
|
(GDestroyNotify) mxf_local_tag_free);
|
||||||
|
|
||||||
g_return_val_if_fail (*hash_table != NULL, FALSE);
|
g_return_val_if_fail (*hash_table != NULL, FALSE);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ typedef struct {
|
||||||
gchar * mxf_ul_to_string (const MXFUL *ul, gchar str[48]);
|
gchar * mxf_ul_to_string (const MXFUL *ul, gchar str[48]);
|
||||||
gboolean mxf_ul_is_equal (const MXFUL *a, const MXFUL *b);
|
gboolean mxf_ul_is_equal (const MXFUL *a, const MXFUL *b);
|
||||||
gboolean mxf_ul_is_zero (const MXFUL *ul);
|
gboolean mxf_ul_is_zero (const MXFUL *ul);
|
||||||
|
guint mxf_ul_hash (const MXFUL *ul);
|
||||||
|
|
||||||
gchar *mxf_umid_to_string (const MXFUMID * umid, gchar str[96]);
|
gchar *mxf_umid_to_string (const MXFUMID * umid, gchar str[96]);
|
||||||
MXFUMID *mxf_umid_from_string (const gchar *str, MXFUMID * umid);
|
MXFUMID *mxf_umid_from_string (const gchar *str, MXFUMID * umid);
|
||||||
|
|
Loading…
Reference in a new issue