mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
mxfdec: parse MXF partitions
This commit is contained in:
parent
b263bf66b7
commit
d32b3f40c7
@ -52,6 +52,35 @@
|
||||
#include "internal.h"
|
||||
#include "mxf.h"
|
||||
|
||||
typedef enum {
|
||||
Header,
|
||||
BodyPartition,
|
||||
Footer
|
||||
} MXFPartitionType;
|
||||
|
||||
typedef enum {
|
||||
OP1a,
|
||||
OP1b,
|
||||
OP1c,
|
||||
OP2a,
|
||||
OP2b,
|
||||
OP2c,
|
||||
OP3a,
|
||||
OP3b,
|
||||
OP3c,
|
||||
OPAtom,
|
||||
} MXFOP;
|
||||
|
||||
typedef struct {
|
||||
int closed;
|
||||
int complete;
|
||||
MXFPartitionType type;
|
||||
uint64_t previous_partition;
|
||||
uint64_t footer_partition;
|
||||
int index_sid;
|
||||
int body_sid;
|
||||
} MXFPartition;
|
||||
|
||||
typedef struct {
|
||||
UID uid;
|
||||
enum MXFMetadataSetType type;
|
||||
@ -127,6 +156,9 @@ typedef struct {
|
||||
} MXFMetadataSet;
|
||||
|
||||
typedef struct {
|
||||
MXFPartition *partitions;
|
||||
unsigned partitions_count;
|
||||
MXFOP op;
|
||||
UID *packages_refs;
|
||||
int packages_count;
|
||||
MXFMetadataSet **metadata_sets;
|
||||
@ -376,6 +408,69 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid)
|
||||
{
|
||||
MXFContext *mxf = arg;
|
||||
MXFPartition *partition;
|
||||
UID op;
|
||||
|
||||
if (mxf->partitions_count+1 >= UINT_MAX / sizeof(*mxf->partitions))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
mxf->partitions = av_realloc(mxf->partitions, (mxf->partitions_count + 1) * sizeof(*mxf->partitions));
|
||||
if (!mxf->partitions)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
partition = &mxf->partitions[mxf->partitions_count++];
|
||||
|
||||
switch(uid[13]) {
|
||||
case 2:
|
||||
partition->type = Header;
|
||||
break;
|
||||
case 3:
|
||||
partition->type = BodyPartition;
|
||||
break;
|
||||
case 4:
|
||||
partition->type = Footer;
|
||||
break;
|
||||
default:
|
||||
av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
/* consider both footers to be closed (there is only Footer and CompleteFooter) */
|
||||
partition->closed = partition->type == Footer || !(uid[14] & 1);
|
||||
partition->complete = uid[14] > 2;
|
||||
avio_skip(pb, 16);
|
||||
partition->previous_partition = avio_rb64(pb);
|
||||
partition->footer_partition = avio_rb64(pb);
|
||||
avio_skip(pb, 16);
|
||||
partition->index_sid = avio_rb32(pb);
|
||||
avio_skip(pb, 8);
|
||||
partition->body_sid = avio_rb32(pb);
|
||||
avio_read(pb, op, sizeof(UID));
|
||||
|
||||
av_dlog(mxf->fc, "PartitionPack: PreviousPartition = 0x%lx, "
|
||||
"FooterPartition = 0x%lx, IndexSID = %i, BodySID = %i\n",
|
||||
partition->previous_partition, partition->footer_partition,
|
||||
partition->index_sid, partition->body_sid);
|
||||
|
||||
if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
|
||||
else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;
|
||||
else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;
|
||||
else if (op[12] == 2 && op[13] == 1) mxf->op = OP2a;
|
||||
else if (op[12] == 2 && op[13] == 2) mxf->op = OP2b;
|
||||
else if (op[12] == 2 && op[13] == 3) mxf->op = OP2c;
|
||||
else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a;
|
||||
else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b;
|
||||
else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c;
|
||||
else if (op[12] == 0x10) mxf->op = OPAtom;
|
||||
else
|
||||
av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh\n", op[12], op[13]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
|
||||
{
|
||||
if (mxf->metadata_sets_count+1 >= UINT_MAX / sizeof(*mxf->metadata_sets))
|
||||
@ -856,6 +951,16 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
|
||||
|
||||
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage },
|
||||
{ { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage },
|
||||
@ -949,7 +1054,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
if (klv.key[5] == 0x53) {
|
||||
res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type);
|
||||
} else
|
||||
res = metadata->read(mxf, s->pb, 0, 0, NULL);
|
||||
res = metadata->read(mxf, s->pb, 0, 0, klv.key);
|
||||
if (res < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
|
||||
return res;
|
||||
@ -990,6 +1095,7 @@ static int mxf_read_close(AVFormatContext *s)
|
||||
}
|
||||
av_freep(&mxf->metadata_sets[i]);
|
||||
}
|
||||
av_freep(&mxf->partitions);
|
||||
av_freep(&mxf->metadata_sets);
|
||||
av_freep(&mxf->aesc);
|
||||
av_freep(&mxf->local_tags);
|
||||
|
Loading…
Reference in New Issue
Block a user