summaryrefslogtreecommitdiff
path: root/libavformat/mxfdec.c
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2021-06-27 22:59:49 +0200
committerMarton Balint <cus@passwd.hu>2021-08-01 02:57:53 +0200
commit7b4bdcd68e1e0abfab21a8be81789531d649c1ff (patch)
tree6832f08a6c574132b77bcfe6b169578d0e2ace48 /libavformat/mxfdec.c
parent9b57d2f0a967195dc1c72fda8f3a983a0132a243 (diff)
avformat/mxfdec: prefer footer and complete partitions for metadata
Also do not store inferior metadata with the same UID. Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavformat/mxfdec.c')
-rw-r--r--libavformat/mxfdec.c51
1 files changed, 47 insertions, 4 deletions
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;