On Sun, 27 Jun 2021, emco...@ffastrans.com wrote:
Am 2021-06-27 20:12, schrieb Marton Balint:
Why? I though it is enough if you store the partition number in the
metadata set, that way you should be able to compare if the existing
metadata set is better than the current one when adding a new metadata
set. Or am I missing something?
OK, i just had a try on this but honestly i don't know how this could work
without a very deep change of the whole mxfdec.c.
The problem is that i cannot just add a field to the struct MXFMetadataSet as
this points to raw data which has been read from the mxf file. I could add a
field but if i initialize the value, i will automatically destroy the
original raw data which was read from the mxf file.
See the attached patch, that is what I had in mind. Or is it overkill? Can
you test it with your dataset and see if it makes any difference?
Thanks,
Marton
From 7e4118232882ab8a72091d42e3660a63c0b53f1c Mon Sep 17 00:00:00 2001
From: Marton Balint <c...@passwd.hu>
Date: Sun, 27 Jun 2021 22:59:49 +0200
Subject: [PATCH] avformat/mxfdec: prefer footer and complete partitions for
metadata
Also do not store inferior metadata with the same UID.
Signed-off-by: Marton Balint <c...@passwd.hu>
---
libavformat/mxfdec.c | 51 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 4 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 3bf480a3a6..9e8730e9b5 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;
@@ -844,10 +857,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);
@@ -1402,7 +1444,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];
@@ -2871,9 +2913,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:
@@ -2898,7 +2941,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;
--
2.26.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".