---
libavformat/mxfenc.c | 102 ++-
1 file changed, 85 insertions(+), 17 deletions(-)
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 7b400b3..0b8dfd6 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -313,6 +313,7 @@ typedef struct MXFContext {
uint8_t umid[16];/// unique material identifier
int channel_count;
uint32_t tagged_value_count;
+AVRational audio_edit_rate;
} MXFContext;
static const uint8_t uuid_base[]= {
0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
@@ -781,8 +782,14 @@ static void mxf_write_track(AVFormatContext *s, AVStream
*st, enum MXFMetadataSe
avio_write(pb, sc-track_essence_element_key + 12, 4);
mxf_write_local_tag(pb, 8, 0x4B01);
-avio_wb32(pb, mxf-time_base.den);
-avio_wb32(pb, mxf-time_base.num);
+
+if (st == mxf-timecode_track s-oformat == ff_mxf_opatom_muxer){
+avio_wb32(pb, mxf-tc.rate.num);
+avio_wb32(pb, mxf-tc.rate.den);
+} else {
+avio_wb32(pb, mxf-time_base.den);
+avio_wb32(pb, mxf-time_base.num);
+}
// write origin
mxf_write_local_tag(pb, 8, 0x4B02);
@@ -811,7 +818,12 @@ static void mxf_write_common_fields(AVFormatContext *s,
AVStream *st)
// write duration
mxf_write_local_tag(pb, 8, 0x0202);
-avio_wb64(pb, mxf-duration);
+
+if (st != mxf-timecode_track s-oformat == ff_mxf_opatom_muxer
st-codec-codec_type == AVMEDIA_TYPE_AUDIO){
+avio_wb64(pb, mxf-body_offset / mxf-edit_unit_byte_count);
+} else {
+avio_wb64(pb, mxf-duration);
+}
}
static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum
MXFMetadataSetType type)
@@ -1090,8 +1102,17 @@ static void
mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, con
AVIOContext *pb = s-pb;
MXFContext *mxf = s-priv_data;
int show_warnings = !mxf-footer_partition_offset;
+int duration_size = 0;
+
+if (s-oformat == ff_mxf_opatom_muxer)
+duration_size = 12;
-mxf_write_generic_desc(s, st, key, size+5+12+8+8);
+mxf_write_generic_desc(s, st, key, size+duration_size+5+12+8+8);
+
+if (duration_size 0){
+mxf_write_local_tag(pb, 8, 0x3002);
+avio_wb64(pb, mxf-body_offset / mxf-edit_unit_byte_count);
+}
// audio locked
mxf_write_local_tag(pb, 1, 0x3D02);
@@ -1114,7 +1135,7 @@ static void
mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, con
av_log(s, AV_LOG_WARNING, d10_channelcount shall be set to 4 or 8
: the output will not comply to MXF D-10 specs\n);
avio_wb32(pb, mxf-channel_count);
} else {
-if (show_warnings mxf-channel_count != -1)
+if (show_warnings mxf-channel_count != -1 s-oformat !=
ff_mxf_opatom_muxer)
av_log(s, AV_LOG_ERROR, -d10_channelcount requires MXF D-10 and
will be ignored\n);
avio_wb32(pb, st-codec-channels);
}
@@ -1963,6 +1984,19 @@ static void mxf_gen_umid(AVFormatContext *s)
mxf-instance_number = seed 0xFF;
}
+static int mxf_init_timecode(AVFormatContext *s, AVStream *st, AVRational rate)
+{
+MXFContext *mxf = s-priv_data;
+AVDictionaryEntry *tcr = av_dict_get(s-metadata, timecode, NULL, 0);
+if (!tcr)
+tcr = av_dict_get(st-metadata, timecode, NULL, 0);
+
+if (tcr)
+return av_timecode_init_from_string(mxf-tc, rate, tcr-value, s);
+else
+return av_timecode_init(mxf-tc, rate, 0, 0, s);
+}
+
static int mxf_write_header(AVFormatContext *s)
{
MXFContext *mxf = s-priv_data;
@@ -1971,7 +2005,6 @@ static int mxf_write_header(AVFormatContext *s)
const MXFSamplesPerFrame *spf = NULL;
AVDictionaryEntry *t;
int64_t timestamp = 0;
-AVDictionaryEntry *tcr = av_dict_get(s-metadata, timecode, NULL, 0);
if (!s-nb_streams)
return -1;
@@ -1988,7 +2021,7 @@ static int mxf_write_header(AVFormatContext *s)
return AVERROR(ENOMEM);
st-priv_data = sc;
-if ((i == 0) ^ (st-codec-codec_type == AVMEDIA_TYPE_VIDEO)) {
+if (((i == 0) ^ (st-codec-codec_type == AVMEDIA_TYPE_VIDEO))
s-oformat != ff_mxf_opatom_muxer) {
av_log(s, AV_LOG_ERROR, there must be exactly one video stream
and it must be the first one\n);
return -1;
}
@@ -2008,14 +2041,9 @@ static int mxf_write_header(AVFormatContext *s)
mxf-time_base = spf-time_base;
rate = av_inv_q(mxf-time_base);
avpriv_set_pts_info(st, 64, mxf-time_base.num,
mxf-time_base.den);
-if (!tcr)
-tcr = av_dict_get(st-metadata, timecode, NULL, 0);
-if (tcr)
-ret = av_timecode_init_from_string(mxf-tc, rate, tcr-value,
s);
-else
-ret = av_timecode_init(mxf-tc, rate, 0, 0, s);
-if (ret 0)
+if((ret = mxf_init_timecode(s, st, rate)) 0)