diff mbox

[FFmpeg-devel,03/12] avformat/mxfenc: add mpeg-2 specific metadata, fix compatibility with sony content browser

Message ID 20180704183514.71654-3-baptiste.coudurier@gmail.com
State Accepted
Headers show

Commit Message

Baptiste Coudurier July 4, 2018, 6:35 p.m. UTC
---
 libavformat/mxfenc.c            | 46 ++++++++++++++++++++++++++++++---
 tests/ref/lavf/mxf              |  6 ++---
 tests/ref/lavf/mxf_d10          |  2 +-
 tests/ref/lavf/mxf_dv25         |  2 +-
 tests/ref/lavf/mxf_dvcpro50     |  2 +-
 tests/ref/lavf/mxf_opatom       |  2 +-
 tests/ref/lavf/mxf_opatom_audio |  2 +-
 7 files changed, 50 insertions(+), 12 deletions(-)

Comments

Baptiste Coudurier July 19, 2018, 3:42 p.m. UTC | #1
On Wed, Jul 4, 2018 at 11:35 AM, Baptiste Coudurier <
baptiste.coudurier@gmail.com> wrote:

> ---
>  libavformat/mxfenc.c            | 46 ++++++++++++++++++++++++++++++---
>  tests/ref/lavf/mxf              |  6 ++---
>  tests/ref/lavf/mxf_d10          |  2 +-
>  tests/ref/lavf/mxf_dv25         |  2 +-
>  tests/ref/lavf/mxf_dvcpro50     |  2 +-
>  tests/ref/lavf/mxf_opatom       |  2 +-
>  tests/ref/lavf/mxf_opatom_audio |  2 +-
>  7 files changed, 50 insertions(+), 12 deletions(-)
>

Will apply.
Baptiste Coudurier Oct. 12, 2018, 7:32 p.m. UTC | #2
On Thu, Jul 19, 2018 at 8:42 AM Baptiste Coudurier <
baptiste.coudurier@gmail.com> wrote:

> On Wed, Jul 4, 2018 at 11:35 AM, Baptiste Coudurier <
> baptiste.coudurier@gmail.com> wrote:
>
>> ---
>>  libavformat/mxfenc.c            | 46 ++++++++++++++++++++++++++++++---
>>  tests/ref/lavf/mxf              |  6 ++---
>>  tests/ref/lavf/mxf_d10          |  2 +-
>>  tests/ref/lavf/mxf_dv25         |  2 +-
>>  tests/ref/lavf/mxf_dvcpro50     |  2 +-
>>  tests/ref/lavf/mxf_opatom       |  2 +-
>>  tests/ref/lavf/mxf_opatom_audio |  2 +-
>>  7 files changed, 50 insertions(+), 12 deletions(-)
>>
>
> Will apply.
>

Applied.
diff mbox

Patch

diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 8c1e38353c..b54a94b62e 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -95,6 +95,10 @@  typedef struct MXFStreamContext {
     int video_bit_rate;
     int slice_offset;
     int frame_size;          ///< frame size in bytes
+    int seq_closed_gop;      ///< all gops in sequence are closed, used in mpeg-2 descriptor
+    int max_gop;             ///< maximum gop size, used by mpeg-2 descriptor
+    int b_picture_count;     ///< maximum number of consecutive b pictures, used in mpeg-2 descriptor
+    int low_delay;           ///< low delay, used in mpeg-2 descriptor
 } MXFStreamContext;
 
 typedef struct MXFContainerEssenceEntry {
@@ -528,7 +532,11 @@  static const MXFLocalTagPair mxf_local_tag_batch[] = {
     { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */
     // MPEG video Descriptor
     { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */
+    { 0x8003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x05,0x00,0x00}}, /* LowDelay */
+    { 0x8004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x06,0x00,0x00}}, /* ClosedGOP */
+    { 0x8006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x08,0x00,0x00}}, /* MaxGOP */
     { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */
+    { 0x8008, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x09,0x00,0x00}}, /* BPictureCount */
     // Wave Audio Essence Descriptor
     { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */
     { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */
@@ -1264,10 +1272,8 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
     avio_wb32(pb, sc->h_chroma_sub_sample);
 
     // vertical subsampling
-    if (sc->v_chroma_sub_sample) {
-        mxf_write_local_tag(pb, 4, 0x3308);
-        avio_wb32(pb, sc->v_chroma_sub_sample);
-    }
+    mxf_write_local_tag(pb, 4, 0x3308);
+    avio_wb32(pb, sc->v_chroma_sub_sample);
 
     // color siting
     mxf_write_local_tag(pb, 1, 0x3303);
@@ -1379,6 +1385,22 @@  static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
         if (!st->codecpar->profile)
             profile_and_level |= 0x80; // escape bit
         avio_w8(pb, profile_and_level);
+
+        // low delay
+        mxf_write_local_tag(pb, 1, 0x8003);
+        avio_w8(pb, sc->low_delay);
+
+        // closed gop
+        mxf_write_local_tag(pb, 1, 0x8004);
+        avio_w8(pb, sc->seq_closed_gop);
+
+        // max gop
+        mxf_write_local_tag(pb, 2, 0x8006);
+        avio_wb16(pb, sc->max_gop);
+
+        // b picture count
+        mxf_write_local_tag(pb, 2, 0x8008);
+        avio_wb16(pb, sc->b_picture_count);
     }
 
     mxf_update_klv_size(pb, pos);
@@ -1699,6 +1721,7 @@  static void mxf_write_index_table_segment(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     int i, j, temporal_reordering = 0;
     int key_index = mxf->last_key_index;
+    int prev_non_b_picture = 0;
     int64_t pos;
 
     av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
@@ -1777,6 +1800,7 @@  static void mxf_write_index_table_segment(AVFormatContext *s)
     }
 
     if (!mxf->edit_unit_byte_count) {
+        MXFStreamContext *sc = s->streams[0]->priv_data;
         mxf_write_local_tag(pb, 8 + mxf->edit_units_count*15, 0x3F0A);
         avio_wb32(pb, mxf->edit_units_count);  // num of entries
         avio_wb32(pb, 15);  // size of one entry
@@ -1785,6 +1809,7 @@  static void mxf_write_index_table_segment(AVFormatContext *s)
             int temporal_offset = 0;
 
             if (!(mxf->index_entries[i].flags & 0x33)) { // I-frame
+                sc->max_gop = FFMAX(sc->max_gop, i - mxf->last_key_index);
                 mxf->last_key_index = key_index;
                 key_index = i;
             }
@@ -1804,11 +1829,13 @@  static void mxf_write_index_table_segment(AVFormatContext *s)
             avio_w8(pb, temporal_offset);
 
             if ((mxf->index_entries[i].flags & 0x30) == 0x30) { // back and forward prediction
+                sc->b_picture_count = FFMAX(sc->b_picture_count, i - prev_non_b_picture);
                 avio_w8(pb, mxf->last_key_index - i);
             } else {
                 avio_w8(pb, key_index - i); // key frame offset
                 if ((mxf->index_entries[i].flags & 0x20) == 0x20) // only forward
                     mxf->last_key_index = key_index;
+                prev_non_b_picture = i;
             }
 
             if (!(mxf->index_entries[i].flags & 0x33) && // I-frame
@@ -2234,6 +2261,7 @@  static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
             if ((pkt->data[i+1] & 0xf0) == 0x10) { // seq ext
                 st->codecpar->profile = pkt->data[i+1] & 0x07;
                 st->codecpar->level   = pkt->data[i+2] >> 4;
+                sc->low_delay = pkt->data[i+6] >> 7;
             } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { // pict coding ext
                 sc->interlaced = !(pkt->data[i+5] & 0x80); // progressive frame
                 if (sc->interlaced)
@@ -2242,9 +2270,14 @@  static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
             }
         } else if (c == 0x1b8) { // gop
             if (pkt->data[i+4]>>6 & 0x01) { // closed
+                if (sc->seq_closed_gop == -1)
+                    sc->seq_closed_gop = 1;
                 sc->closed_gop = 1;
                 if (e->flags & 0x40) // sequence header present
                     e->flags |= 0x80; // random access
+            } else {
+                sc->seq_closed_gop = 0;
+                sc->closed_gop = 0;
             }
         } else if (c == 0x1b3) { // seq
             e->flags |= 0x40;
@@ -2356,6 +2389,7 @@  static int mxf_write_header(AVFormatContext *s)
             // Default component depth to 8
             sc->component_depth = 8;
             sc->h_chroma_sub_sample = 2;
+            sc->v_chroma_sub_sample = 2;
             sc->color_siting = 0xFF;
 
             if (pix_desc) {
@@ -2383,6 +2417,10 @@  static int mxf_write_header(AVFormatContext *s)
             if((ret = mxf_init_timecode(s, st, rate)) < 0)
                 return ret;
 
+            if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+                sc->seq_closed_gop = -1; // unknown yet
+            }
+
             sc->video_bit_rate = st->codecpar->bit_rate;
 
             if (s->oformat == &ff_mxf_d10_muxer ||
diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf
index e99f737ed8..7f6d698855 100644
--- a/tests/ref/lavf/mxf
+++ b/tests/ref/lavf/mxf
@@ -1,9 +1,9 @@ 
-96c0f82082eb420ecbddf7810f3b3943 *./tests/data/lavf/lavf.mxf
+eea31259441d909fedb9a0e0eb9bbdb2 *./tests/data/lavf/lavf.mxf
 526393 ./tests/data/lavf/lavf.mxf
 ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab
-4b73c93955f4ae2fcddb2fc99e5e7017 *./tests/data/lavf/lavf.mxf
+2c4a6634f646f7ab76bf2b7e71c8c893 *./tests/data/lavf/lavf.mxf
 561721 ./tests/data/lavf/lavf.mxf
 ./tests/data/lavf/lavf.mxf CRC=0xf21b1b48
-8376d69f7eccfc268041dffd82db1a61 *./tests/data/lavf/lavf.mxf
+e547b44d71cd5871582522a31511ae9c *./tests/data/lavf/lavf.mxf
 526393 ./tests/data/lavf/lavf.mxf
 ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab
diff --git a/tests/ref/lavf/mxf_d10 b/tests/ref/lavf/mxf_d10
index a40a42a2e2..0b9f49bb09 100644
--- a/tests/ref/lavf/mxf_d10
+++ b/tests/ref/lavf/mxf_d10
@@ -1,3 +1,3 @@ 
-ad3f0da2f77e5269e896b367f2a5b0b0 *./tests/data/lavf/lavf.mxf_d10
+9f299fd4da6a20ef93adad7fe6a9f481 *./tests/data/lavf/lavf.mxf_d10
 5332013 ./tests/data/lavf/lavf.mxf_d10
 ./tests/data/lavf/lavf.mxf_d10 CRC=0x6c74d488
diff --git a/tests/ref/lavf/mxf_dv25 b/tests/ref/lavf/mxf_dv25
index efec757218..200511e164 100644
--- a/tests/ref/lavf/mxf_dv25
+++ b/tests/ref/lavf/mxf_dv25
@@ -1,3 +1,3 @@ 
-cd1ea9497444b0b43d930b0dc56aecf7 *./tests/data/lavf/lavf.mxf_dv25
+358791c5468c39673239e038fb64a734 *./tests/data/lavf/lavf.mxf_dv25
 3834413 ./tests/data/lavf/lavf.mxf_dv25
 ./tests/data/lavf/lavf.mxf_dv25 CRC=0xbdaf7f52
diff --git a/tests/ref/lavf/mxf_dvcpro50 b/tests/ref/lavf/mxf_dvcpro50
index bbe4562ec4..f212c0321d 100644
--- a/tests/ref/lavf/mxf_dvcpro50
+++ b/tests/ref/lavf/mxf_dvcpro50
@@ -1,3 +1,3 @@ 
-ce601c92f0e2d7f07cbf6263a8a18ea5 *./tests/data/lavf/lavf.mxf_dvcpro50
+fac7c59ea81c752d769335ddaa818f90 *./tests/data/lavf/lavf.mxf_dvcpro50
 7431213 ./tests/data/lavf/lavf.mxf_dvcpro50
 ./tests/data/lavf/lavf.mxf_dvcpro50 CRC=0xe3bbe4b4
diff --git a/tests/ref/lavf/mxf_opatom b/tests/ref/lavf/mxf_opatom
index bca8f65154..5ea47f4df6 100644
--- a/tests/ref/lavf/mxf_opatom
+++ b/tests/ref/lavf/mxf_opatom
@@ -1,3 +1,3 @@ 
-76093fef1ac42587cc374012dc1945db *./tests/data/lavf/lavf.mxf_opatom
+49b0b3dfeb6a9ec024b047fc627b66fd *./tests/data/lavf/lavf.mxf_opatom
 4717625 ./tests/data/lavf/lavf.mxf_opatom
 ./tests/data/lavf/lavf.mxf_opatom CRC=0xf55aa22a
diff --git a/tests/ref/lavf/mxf_opatom_audio b/tests/ref/lavf/mxf_opatom_audio
index 380ce4f0a3..540f430cda 100644
--- a/tests/ref/lavf/mxf_opatom_audio
+++ b/tests/ref/lavf/mxf_opatom_audio
@@ -1,3 +1,3 @@ 
-8524f908a6fa8750a4755ab79cc1516c *./tests/data/lavf/lavf.mxf_opatom_audio
+862dc5c9f2c94bd2c545ca64f923d1a1 *./tests/data/lavf/lavf.mxf_opatom_audio
 102969 ./tests/data/lavf/lavf.mxf_opatom_audio
 ./tests/data/lavf/lavf.mxf_opatom_audio CRC=0xd155c6ff