From 7b4bdcd68e1e0abfab21a8be81789531d649c1ff Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 27 Jun 2021 22:59:49 +0200 Subject: avformat/mxfdec: prefer footer and complete partitions for metadata Also do not store inferior metadata with the same UID. Signed-off-by: Marton Balint --- libavformat/mxfdec.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) (limited to 'libavformat/mxfdec.c') diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index f491914bf1..fd22680adb 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -108,12 +108,14 @@ typedef struct MXFPartition { typedef struct MXFCryptoContext { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID source_container_ul; } MXFCryptoContext; typedef struct MXFStructuralComponent { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID source_package_ul; UID source_package_uid; @@ -125,6 +127,7 @@ typedef struct MXFStructuralComponent { typedef struct MXFSequence { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID data_definition_ul; UID *structural_components_refs; @@ -135,6 +138,7 @@ typedef struct MXFSequence { typedef struct MXFTimecodeComponent { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; int drop_frame; int start_frame; @@ -144,12 +148,14 @@ typedef struct MXFTimecodeComponent { typedef struct { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID input_segment_ref; } MXFPulldownComponent; typedef struct { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID *structural_components_refs; int structural_components_count; @@ -158,6 +164,7 @@ typedef struct { typedef struct { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; char *name; char *value; @@ -165,6 +172,7 @@ typedef struct { typedef struct { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; MXFSequence *sequence; /* mandatory, and only one */ UID sequence_ref; @@ -183,6 +191,7 @@ typedef struct { typedef struct MXFDescriptor { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID essence_container_ul; UID essence_codec_ul; @@ -222,6 +231,7 @@ typedef struct MXFDescriptor { typedef struct MXFIndexTableSegment { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; int edit_unit_byte_count; int index_sid; @@ -237,6 +247,7 @@ typedef struct MXFIndexTableSegment { typedef struct MXFPackage { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID package_uid; UID package_ul; @@ -251,6 +262,7 @@ typedef struct MXFPackage { typedef struct MXFEssenceContainerData { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; UID package_uid; UID package_ul; @@ -260,6 +272,7 @@ typedef struct MXFEssenceContainerData { typedef struct MXFMetadataSet { UID uid; + MXFPartition *partition; enum MXFMetadataSetType type; } MXFMetadataSet; @@ -842,10 +855,39 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size return 0; } +static int partition_score(MXFPartition *p) +{ + if (p->type == Footer) + return 5; + if (p->complete) + return 4; + if (p->closed) + return 3; + return 1; +} + static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set) { MXFMetadataSet **tmp; - + MXFPartition *new_p = (*metadata_set)->partition; + enum MXFMetadataSetType type = (*metadata_set)->type; + + // Index Table is special because it might be added manually without + // partition and we iterate thorugh all instances of them. Also some files + // use the same Instance UID for different index tables... + if (type != IndexTableSegment) { + for (int i = 0; i < mxf->metadata_sets_count; i++) { + if (!memcmp((*metadata_set)->uid, mxf->metadata_sets[i]->uid, 16) && type == mxf->metadata_sets[i]->type) { + MXFPartition *old_p = mxf->metadata_sets[i]->partition; + int old_s = partition_score(old_p); + int new_s = partition_score(new_p); + if (old_s > new_s || old_s == new_s && old_p->this_partition > new_p->this_partition) { + mxf_free_metadataset(metadata_set, 1); + return 0; + } + } + } + } tmp = av_realloc_array(mxf->metadata_sets, mxf->metadata_sets_count + 1, sizeof(*mxf->metadata_sets)); if (!tmp) { mxf_free_metadataset(metadata_set, 1); @@ -1400,7 +1442,7 @@ static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMe if (!strong_ref) return NULL; - for (i = 0; i < mxf->metadata_sets_count; i++) { + for (i = mxf->metadata_sets_count - 1; i >= 0; i--) { if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) && (type == AnyType || mxf->metadata_sets[i]->type == type)) { return mxf->metadata_sets[i]; @@ -2873,9 +2915,10 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType }, }; -static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type) +static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type, MXFPartition *partition) { ctx->type = type; + ctx->partition = partition; switch (type){ case MultipleDescriptor: case Descriptor: @@ -2900,7 +2943,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF if (!meta) return AVERROR(ENOMEM); ctx = meta; - mxf_metadataset_init(meta, type); + mxf_metadataset_init(meta, type, mxf->current_partition); } else { meta = NULL; ctx = mxf; -- cgit v1.2.3