avformat/mxfenc: allow muxing prores
authorPaul B Mahol <onemda@gmail.com>
Wed, 5 Dec 2018 17:10:37 +0000 (18:10 +0100)
committerPaul B Mahol <onemda@gmail.com>
Mon, 10 Dec 2018 16:25:49 +0000 (17:25 +0100)
libavformat/mxfenc.c

index 3549b41..e481b19 100644 (file)
@@ -146,6 +146,7 @@ enum ULIndex {
     INDEX_JPEG2000,
     INDEX_H264,
     INDEX_S436M,
+    INDEX_PRORES,
 };
 
 static const struct {
@@ -159,6 +160,7 @@ static const struct {
     { AV_CODEC_ID_DNXHD,      INDEX_DNXHD },
     { AV_CODEC_ID_JPEG2000,   INDEX_JPEG2000 },
     { AV_CODEC_ID_H264,       INDEX_H264 },
+    { AV_CODEC_ID_PRORES,     INDEX_PRORES },
     { AV_CODEC_ID_NONE }
 };
 
@@ -314,6 +316,11 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
       { 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 },
+    // ProRes
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x1c,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x17,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x03,0x00 },
+      mxf_write_cdci_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 },
@@ -1946,6 +1953,43 @@ static int mxf_write_partition(AVFormatContext *s, int bodysid,
 }
 
 static const struct {
+    int profile;
+    UID codec_ul;
+} mxf_prores_codec_uls[] = {
+    { FF_PROFILE_PRORES_PROXY,    { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x01,0x00 } },
+    { FF_PROFILE_PRORES_LT,       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x02,0x00 } },
+    { FF_PROFILE_PRORES_STANDARD, { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x03,0x00 } },
+    { FF_PROFILE_PRORES_HQ,       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x04,0x00 } },
+    { FF_PROFILE_PRORES_4444,     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x05,0x00 } },
+    { FF_PROFILE_PRORES_XQ,       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x03,0x06,0x06,0x00 } },
+};
+
+static int mxf_parse_prores_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt)
+{
+    MXFContext *mxf = s->priv_data;
+    MXFStreamContext *sc = st->priv_data;
+    int i, profile;
+
+    if (mxf->header_written)
+        return 1;
+
+    sc->codec_ul = NULL;
+    profile = st->codecpar->profile;
+    for (i = 0; i < FF_ARRAY_ELEMS(mxf_prores_codec_uls); i++) {
+        if (profile == mxf_prores_codec_uls[i].profile) {
+            sc->codec_ul = &mxf_prores_codec_uls[i].codec_ul;
+            break;
+        }
+    }
+    if (!sc->codec_ul)
+        return 0;
+
+    sc->frame_size = pkt->size;
+
+    return 1;
+}
+
+static const struct {
     int cid;
     UID codec_ul;
 } mxf_dnxhd_codec_uls[] = {
@@ -2736,6 +2780,11 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
             av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n");
             return -1;
         }
+    } else if (st->codecpar->codec_id == AV_CODEC_ID_PRORES) {
+        if (!mxf_parse_prores_frame(s, st, pkt)) {
+            av_log(s, AV_LOG_ERROR, "could not get prores profile\n");
+            return -1;
+        }
     } else if (st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO) {
         if (!mxf_parse_dv_frame(s, st, pkt)) {
             av_log(s, AV_LOG_ERROR, "could not get dv profile\n");