[FFmpeg-devel] [PATCH 09/12] lavf/mxfenc: support creating s436m data tracks
Baptiste Coudurier
baptiste.coudurier at gmail.com
Wed Jul 4 21:35:11 EEST 2018
---
libavformat/mxf.c | 1 +
libavformat/mxfdec.c | 3 +++
libavformat/mxfenc.c | 41 +++++++++++++++++++++++++++++++++++++----
libavformat/utils.c | 6 +++++-
4 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index 8376a2b9bf..451cbcfb2c 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -28,6 +28,7 @@
const MXFCodecUL ff_mxf_data_definition_uls[] = {
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO },
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO },
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x03,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_DATA },
{ { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x6F,0x3C,0x8C,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_VIDEO }, /* LegacyPicture Avid Media Composer MXF */
{ { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x78,0xE1,0xEB,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_AUDIO }, /* LegacySound Avid Media Composer MXF */
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVMEDIA_TYPE_DATA },
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 8c417aea26..3f443bbbc9 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -3291,6 +3291,9 @@ static int mxf_set_pts(MXFContext *mxf, AVStream *st, AVPacket *pkt, int64_t nex
int ret = mxf_set_audio_pts(mxf, par, pkt);
if (ret < 0)
return ret;
+ } else {
+ pkt->dts = pkt->pts = mxf->current_edit_unit;
+ pkt->duration = 1;
}
return 0;
}
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 036adce011..6da27bf4f5 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -175,6 +175,7 @@ static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
+static void mxf_write_s436m_anc_desc(AVFormatContext *s, AVStream *st);
static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
@@ -361,6 +362,11 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
{ 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
mxf_write_mpegvideo_desc },
+ // S436M ANC
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x0D,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 },
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x17,0x01,0x02,0x00 },
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x01,0x5C,0x00 },
+ mxf_write_s436m_anc_desc },
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
@@ -695,9 +701,14 @@ static void mxf_write_essence_container_refs(AVFormatContext *s)
mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count));
av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
- for (i = 0; i < c->essence_container_count; i++) {
+ for (i = 0; i < s->nb_streams; i++) {
MXFStreamContext *sc = s->streams[i]->priv_data;
+ // check first track of essence container type and only write it once
+ if (sc->track_essence_element_key[15] != 0)
+ continue;
avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
+ if (c->essence_container_count == 1)
+ break;
}
if (c->essence_container_count > 1)
@@ -1154,6 +1165,7 @@ static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI
return pos;
}
+static const UID mxf_s436m_anc_descriptor_key = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 };
static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
@@ -1369,6 +1381,12 @@ static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
mxf_update_klv_size(s->pb, pos);
}
+static void mxf_write_s436m_anc_desc(AVFormatContext *s, AVStream *st)
+{
+ int64_t pos = mxf_write_generic_desc(s, st, mxf_s436m_anc_descriptor_key);
+ mxf_update_klv_size(s->pb, pos);
+}
+
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
{
AVIOContext *pb = s->pb;
@@ -1723,6 +1741,7 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
int i, j, temporal_reordering = 0;
int key_index = mxf->last_key_index;
int prev_non_b_picture = 0;
+ int audio_frame_size = 0;
int64_t pos;
av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
@@ -1792,9 +1811,11 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
} else if (i == 0) { // video track
avio_w8(pb, 0); // slice number
avio_wb32(pb, KAG_SIZE); // system item size including klv fill
- } else { // audio track
- unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
- audio_frame_size += klv_fill_size(audio_frame_size);
+ } else { // audio or data track
+ if (!audio_frame_size) {
+ audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
+ audio_frame_size += klv_fill_size(audio_frame_size);
+ }
avio_w8(pb, 1);
avio_wb32(pb, (i-1)*audio_frame_size); // element delta
}
@@ -2505,6 +2526,18 @@ static int mxf_write_header(AVFormatContext *s)
sc->frame_size = (st->codecpar->channels * spf[0].samples_per_frame[0] *
av_get_bits_per_sample(st->codecpar->codec_id)) / 8;
}
+ } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
+ AVDictionaryEntry *e = av_dict_get(st->metadata, "data_type", NULL, 0);
+ if (e && !strcmp(e->value, "vbi_vanc_smpte_436M")) {
+ sc->index = 38;
+ } else {
+ av_log(s, AV_LOG_ERROR, "track %d: unsupported data type\n", i);
+ return -1;
+ }
+ if (st->index != s->nb_streams - 1) {
+ av_log(s, AV_LOG_ERROR, "data track must be placed last\n");
+ return -1;
+ }
}
if (!sc->index) {
diff --git a/libavformat/utils.c b/libavformat/utils.c
index c9cdd2b470..36a32ad9c2 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1003,6 +1003,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
*pnum = frame_size;
*pden = sample_rate;
break;
+ case AVMEDIA_TYPE_DATA:
+ *pnum = st->time_base.num;
+ *pden = st->time_base.den;
+ break;
default:
break;
}
@@ -1405,7 +1409,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts));
/* update flags */
- if (is_intra_only(st->codecpar->codec_id))
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || is_intra_only(st->codecpar->codec_id))
pkt->flags |= AV_PKT_FLAG_KEY;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
--
2.17.0 (Apple Git-106)
More information about the ffmpeg-devel
mailing list