mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
9b57d2f0a9
commit
7b4bdcd68e
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user