typedef struct MXFContext {
int64_t footer_partition_offset;
int essence_container_count;
- uint8_t essence_containers_indices[sizeof(mxf_essence_container_uls)/
- sizeof(*mxf_essence_container_uls)];
+ uint8_t essence_containers_indices[FF_ARRAY_ELEMS(mxf_essence_container_uls)];
} MXFContext;
static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
-static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00,0x13,0x00,0x00,0x00 };
+static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13,0x00,0x00,0x00 };
/**
* complete key for operation pattern, partitions, and primer pack
{ 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
// Content Storage
{ 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
+ { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */
// Essence Container Data
{ 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
{ 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
{ 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
{ 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
// Source Clip
- { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Start position */
+ { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */
{ 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
{ 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
// File Descriptor
{ 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
{ 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
{ 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
- { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
+ { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
};
static void mxf_write_uuid(ByteIOContext *pb, enum MXFMetadataSetType type, int value)
static int mxf_get_essence_container_ul_index(enum CodecID id)
{
int i;
- for (i = 0; i < sizeof(mxf_essence_container_uls)/
- sizeof(*mxf_essence_container_uls); i++)
+ for (i = 0; i < FF_ARRAY_ELEMS(mxf_essence_container_uls); i++)
if (mxf_essence_container_uls[i].id == id)
return i;
return -1;
ByteIOContext *pb = s->pb;
int local_tag_number, i = 0;
- local_tag_number = sizeof(mxf_local_tag_batch)/sizeof(*mxf_local_tag_batch);
+ local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch);
put_buffer(pb, primer_pack_key, 16);
klv_encode_ber_length(pb, local_tag_number * 18 + 8);
mxf_write_metadata_key(pb, 0x011800);
PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
- klv_encode_ber_length(pb, 64);
+ klv_encode_ber_length(pb, 92);
// write uid
mxf_write_local_tag(pb, 16, 0x3C0A);
mxf_write_refs_count(pb, 2);
mxf_write_uuid(pb, MaterialPackage, 0);
mxf_write_uuid(pb, SourcePackage, 0);
-}
-
-static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
-{
- ByteIOContext *pb = s->pb;
- int i;
-
- if (type == MaterialPackage) {
- mxf_write_metadata_key(pb, 0x013600);
- PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
- klv_encode_ber_length(pb, 92 + 16 * s->nb_streams);
- } else {
- mxf_write_metadata_key(pb, 0x013700);
- PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
- klv_encode_ber_length(pb, 112 + 16 * s->nb_streams); // 20 bytes length for descriptor reference
- }
-
- // write uid
- mxf_write_local_tag(pb, 16, 0x3C0A);
- mxf_write_uuid(pb, type, 0);
- av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
- PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
-
- // write package umid
- mxf_write_local_tag(pb, 32, 0x4401);
- mxf_write_umid(pb, type, 0);
- PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
-
- // write create date
- mxf_write_local_tag(pb, 8, 0x4405);
- put_be64(pb, 0);
-
- // write modified date
- mxf_write_local_tag(pb, 8, 0x4404);
- put_be64(pb, 0);
-
- // write track refs
- mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x4403);
- mxf_write_refs_count(pb, s->nb_streams);
- for (i = 0; i < s->nb_streams; i++)
- mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
- // write multiple descriptor reference
- if (type == SourcePackage) {
- mxf_write_local_tag(pb, 16, 0x4701);
- mxf_write_uuid(pb, MultipleDescriptor, 0);
- }
+ // write essence container data
+ mxf_write_local_tag(pb, 8 + 16, 0x1902);
+ mxf_write_refs_count(pb, 1);
+ mxf_write_uuid(pb, EssenceContainerData, 0);
}
static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
{
ByteIOContext *pb = s->pb;
+ int stored_height = (st->codec->height+15)/16*16;
+ AVRational dar;
mxf_write_generic_desc(pb, st, mxf_mpegvideo_descriptor_key);
put_be32(pb, st->codec->width);
mxf_write_local_tag(pb, 4, 0x3202);
- put_be32(pb, st->codec->height);
+ put_be32(pb, stored_height);
+
+ av_reduce(&dar.num, &dar.den,
+ st->codec->width*st->codec->sample_aspect_ratio.num,
+ st->codec->height*st->codec->sample_aspect_ratio.den,
+ 1024*1024);
mxf_write_local_tag(pb, 8, 0x320E);
- put_be32(pb, st->codec->height * st->sample_aspect_ratio.den);
- put_be32(pb, st->codec->width * st->sample_aspect_ratio.num);
+ put_be32(pb, dar.num);
+ put_be32(pb, dar.den);
}
static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st)
put_be32(pb, st->codec->channels);
mxf_write_local_tag(pb, 4, 0x3D01);
- put_be32(pb, st->codec->bits_per_sample);
+ put_be32(pb, st->codec->bits_per_coded_sample);
}
-static void mxf_build_structural_metadata(AVFormatContext *s, enum MXFMetadataSetType type)
+static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
{
+ ByteIOContext *pb = s->pb;
int i;
- mxf_write_package(s, type);
- if (type == SourcePackage)
- mxf_write_multi_descriptor(s);
+ if (type == MaterialPackage) {
+ mxf_write_metadata_key(pb, 0x013600);
+ PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
+ klv_encode_ber_length(pb, 92 + 16 * s->nb_streams);
+ } else {
+ mxf_write_metadata_key(pb, 0x013700);
+ PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
+ klv_encode_ber_length(pb, 112 + 16 * s->nb_streams); // 20 bytes length for descriptor reference
+ }
+
+ // write uid
+ mxf_write_local_tag(pb, 16, 0x3C0A);
+ mxf_write_uuid(pb, type, 0);
+ av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
+ PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
+
+ // write package umid
+ mxf_write_local_tag(pb, 32, 0x4401);
+ mxf_write_umid(pb, type, 0);
+ PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
+
+ // write create date
+ mxf_write_local_tag(pb, 8, 0x4405);
+ put_be64(pb, 0);
+
+ // write modified date
+ mxf_write_local_tag(pb, 8, 0x4404);
+ put_be64(pb, 0);
+
+ // write track refs
+ mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x4403);
+ mxf_write_refs_count(pb, s->nb_streams);
+ for (i = 0; i < s->nb_streams; i++)
+ mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
+
+ // write multiple descriptor reference
+ if (type == SourcePackage) {
+ mxf_write_local_tag(pb, 16, 0x4701);
+ if (s->nb_streams > 1) {
+ mxf_write_uuid(pb, MultipleDescriptor, 0);
+ mxf_write_multi_descriptor(s);
+ } else
+ mxf_write_uuid(pb, SubDescriptor, 0);
+ }
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
}
}
+static int mxf_write_essence_container_data(AVFormatContext *s)
+{
+ ByteIOContext *pb = s->pb;
+
+ mxf_write_metadata_key(pb, 0x012300);
+ klv_encode_ber_length(pb, 64);
+
+ mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID
+ mxf_write_uuid(pb, EssenceContainerData, 0);
+
+ mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID
+ mxf_write_umid(pb, SourcePackage, 0);
+
+ mxf_write_local_tag(pb, 4, 0x3F07); // BodySID
+ put_be32(pb, 1);
+
+ return 0;
+}
+
static int mxf_write_header_metadata_sets(AVFormatContext *s)
{
mxf_write_preface(s);
mxf_write_identification(s);
mxf_write_content_storage(s);
- mxf_build_structural_metadata(s, MaterialPackage);
- mxf_build_structural_metadata(s, SourcePackage);
+ mxf_write_package(s, MaterialPackage);
+ mxf_write_package(s, SourcePackage);
+ mxf_write_essence_container_data(s);
return 0;
}
{
MXFContext *mxf = s->priv_data;
int i;
- uint8_t present[sizeof(mxf_essence_container_uls)/
- sizeof(*mxf_essence_container_uls)] = {0};
+ uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];