From: Tomas Härdin <[email protected]>
---
libavformat/mxfdec.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 107 insertions(+), 1 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index c4c3f59..b8767c2 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -52,6 +52,35 @@
#include "internal.h"
#include "mxf.h"
+typedef enum {
+ PART_TYPE_HEADER,
+ PART_TYPE_BODY,
+ PART_TYPE_FOOTER
+} MXFPartitionType;
+
+typedef enum {
+ OP_1A,
+ OP_1B,
+ OP_1C,
+ OP_2A,
+ OP_2B,
+ OP_2C,
+ OP_3A,
+ OP_3B,
+ OP_3C,
+ OP_ATOM,
+} 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;
@@ -374,6 +406,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 = PART_TYPE_HEADER;
+ break;
+ case 3:
+ partition->type = PART_TYPE_BODY;
+ break;
+ case 4:
+ partition->type = PART_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 == PART_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 = OP_1A;
+ else if (op[12] == 1 && op[13] == 2) mxf->op = OP_1B;
+ else if (op[12] == 1 && op[13] == 3) mxf->op = OP_1C;
+ else if (op[12] == 2 && op[13] == 1) mxf->op = OP_2A;
+ else if (op[12] == 2 && op[13] == 2) mxf->op = OP_2B;
+ else if (op[12] == 2 && op[13] == 3) mxf->op = OP_2C;
+ else if (op[12] == 3 && op[13] == 1) mxf->op = OP_3A;
+ else if (op[12] == 3 && op[13] == 2) mxf->op = OP_3B;
+ else if (op[12] == 3 && op[13] == 3) mxf->op = OP_3C;
+ else if (op[12] == 0x10) mxf->op = OP_ATOM;
+ 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))
@@ -854,6 +949,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 },
@@ -945,7 +1050,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 -1;
@@ -986,6 +1091,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);
--
1.7.8
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel