FFmpeg mxf扩展hdr、bt2020

    最近做广电音视频项目,从CCTV发布的《中央广播电视总台4K超高清电视节目制播技术规范(暂行)》来看需要支持mxf封装XAVC编码的HLG视频。于是欣然完成了FFmpeg中XAVC Intra Class300/480的扩展工作,并且将HLG的信息封装进了H.264 sps vui中的color_trc、color_primaries。MediaInfo、FFprobe解析视频均解析到HLG/BT2020信息,完美。

    今天拿到索贝提供的HLG样片,分析发现样片居然没有vui信息,然而MediaInfo明明解析出HLG/BT2020信息,但是奇怪的是FFProbe居然解析不出。直觉告诉样片的这部分信息一定是存在于mxf的容器封装里面,而不在h264的语法元素内。而且FFmpeg不支持这mxf部分信息的封装。

    由于网上没有找到公开的mxf spec/uid定义资料,因此必须通过MediaInfo解码的逆向工程完成FFmpeg mxf的封装支持。

    下载MediaInfo源码:

    https://netix.dl.sourceforge.net/project/mediainfo/binary/mediainfogui/18.08.1/MediaInfo_GUI_18.08.1_GNU_FromSource.tar.xz

    查看mxf解析源码:MediaInfoLib/Source/MediaInfo/Multiple/File_Mxf.cpp

 1327 //---------------------------------------------------------------------------
 1328 static const char* Mxf_TransferCharacteristic(const int128u TransferCharacteristic)
 1329 {
 1330     int32u Code_Compare4=(int32u)TransferCharacteristic.lo;
 1331     int32u c1 = (int32u)(TransferCharacteristic.lo >> 32);
 1332     int32u c2 = (int32u)(TransferCharacteristic.hi);
 1333     int32u c3 = (int32u)(TransferCharacteristic.hi >> 32);
 1334     printf("c0 %p\n", Code_Compare4);
 1335     printf("c1 %p\n", c1);
 1336     printf("c2 %p\n", c2);
 1337     printf("c3 %p\n", c3);
 1338     switch ((int8u)(Code_Compare4>>16))
 1339     {
 1340         case 0x01 : return "BT.601";
 1341         case 0x02 : return "BT.709";
 1342         case 0x03 : return "SMPTE 240M";
 1343         case 0x04 : return "SMPTE 274M";
 1344         case 0x05 : return "BT.1361";
 1345         case 0x06 : return "Linear";
 1346         case 0x07 : return "SMPTE 428M";
 1347         case 0x08 : return "xvYCC";
 1348         case 0x09 : return "BT.2020"; // ISO does a difference of value between 10 and 12 bit
 1349         case 0x0A : return "PQ";
 1350         case 0x0B : return "HLG";
 1351         default   : return "";
 1352     }
 1353 }

       添加打印,打印出样片color_trc=HLG对应的完整uid值:

c0 0x10b0000
c1 0x4010101
c2 0x401010d
c3 0x60e2b34
 1305 static const char* Mxf_ColorPrimaries(const int128u ColorPrimaries)
 1306 {
 1307     int32u Code_Compare4=(int32u)ColorPrimaries.lo;
 1308     int32u c1 = (int32u)(ColorPrimaries.lo >> 32);
 1309     int32u c2 = (int32u)(ColorPrimaries.hi);
 1310     int32u c3 = (int32u)(ColorPrimaries.hi >> 32);
 1311     printf("p0 %p\n", Code_Compare4);
 1312     printf("p1 %p\n", c1);
 1313     printf("p2 %p\n", c2);
 1314     printf("p3 %p\n", c3);
 1315     switch ((int8u)(Code_Compare4>>16))
 1316     {
 1317         case 0x01 : return "BT.601 NTSC";
 1318         case 0x02 : return "BT.601 PAL";
 1319         case 0x03 : return "BT.709";
 1320         case 0x04 : return "BT.2020";
 1321         case 0x05 : return "XYZ";
 1322         case 0x06 : return "Display P3";
 1323         default   : return "";
 1324     }
 1325 }

    同样对color_primaries添加打印,打印BT.2020的完整uid:

p0 0x3040000
p1 0x4010101
p2 0x4010101
p3 0x60e2b34

   在获取常见关心的BT.709、BT.2020、HDR10(PQ)、HLG的uid后,在FFmpeg mxfenc.c 中添加:

From e3de4edf8ba509f2321223304ef54e6a95a4ba49 Mon Sep 17 00:00:00 2001
  2 From: James 
  3 Date: Tue, 30 Oct 2018 16:48:06 +0800
  4 Subject: [PATCH] extends mxf color_trc and color_primaries
  5 
  6 Signed-off-by: James 
  7 ---
  8  libavformat/mxfenc.c | 29 ++++++++++++++++++++++++++++-
  9  1 file changed, 28 insertions(+), 1 deletion(-)
 10 
 11 diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
 12 index 46cf231a53..626245cfdb 100644
 13 --- a/libavformat/mxfenc.c
 14 +++ b/libavformat/mxfenc.c
 15 @@ -1171,6 +1171,26 @@ static int get_trc(UID ul, enum AVColorTransferCharacteristic trc)
 16      case AVCOL_TRC_SMPTE428  :
 17          memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00}), 16);
 18          return 0;
 19 +    case AVCOL_TRC_SMPTE2084 :
 20 +        memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0A,0x00,0x00}), 16);
 21 +        return 0;
 22 +    case AVCOL_TRC_ARIB_STD_B67 :
 23 +        memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0B,0x00,0x00}), 16);
 24 +        return 0;
 25 +    default:
 26 +        return -1;
 27 +    }
 28 +}
 29 +
 30 +static int get_color_primaries(UID ul, enum AVColorPrimaries p)
 31 +{
 32 +    switch (p) {
 33 +    case AVCOL_PRI_BT709:
 34 +        memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00}), 16);
 35 +        return 0;
 36 +    case AVCOL_PRI_BT2020:
 37 +        memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x03,0x04,0x00,0x00}), 16);
 38 +        return 0;
 39      default:
 40          return -1;
 41      }
 42 @@ -1185,10 +1205,11 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
 43      int display_height;
 44      int f1, f2;
 45      UID transfer_ul = {0};
 46 +    UID color_primaries_ul = {0};
 47      int64_t pos = mxf_write_generic_desc(s, st, key);
 48 
 49 -    av_log(s, AV_LOG_ERROR, "mxf color_trc %d\n", st->codecpar->color_trc);
 50      get_trc(transfer_ul, st->codecpar->color_trc);
 51 +    get_color_primaries(color_primaries_ul, st->codecpar->color_primaries);
 52 
 53      mxf_write_local_tag(pb, 4, 0x3203);
 54      avio_wb32(pb, stored_width);
 55 @@ -1342,6 +1363,12 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
 56          avio_w8(pb, sc->field_dominance);
 57      }
 58 
 59 +    //Color Primaries
 60 +    if (color_primaries_ul[0]) {
 61 +        mxf_write_local_tag(pb, 16, 0x3219);
 62 +        avio_write(pb, color_primaries_ul, 16);
 63 +    }
 64 +
 65      return pos;
 66  }
 67 
 68 -- 
 69 2.17.1
 70 

     在libx264中去除对vui color_trc和color_primaries的信息添加,确保只有mxf携带,测试:

./ffmpeg -i '/home/lyh/4K/Customer/Sobey/2018080927test_video/10M_SR012CA3.mp4' -r 50 -pix_fmt yuv422p10le -c:v libx264 -avcintra-class 300 -x264opts avcintra-class=300 -x264opts avcintra-flavor=sony -color_primaries bt2020 -color_trc arib-std-b67 -colorspace bt2020nc 1.mxf

     MediaInfo打印:

Video
ID                                       : 2
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : High 4:2:2 [email protected]
Format settings, CABAC                   : No
Format settings, GOP                     : N=1
Format settings, wrapping mode           : Frame
Codec ID                                 : 0D01030102106001-0401020201323001
Duration                                 : 1 s 600 ms
Bit rate                                 : 501 Mb/s
Width                                    : 3 840 pixels
Height                                   : 2 160 pixels
Display aspect ratio                     : 16:9
Frame rate                               : 50.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:2
Bit depth                                : 10 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 1.207
Stream size                              : 95.5 MiB (100%)
Color primaries                          : BT.2020
Transfer characteristics                 : HLG

    顺利识别。

你可能感兴趣的:(音视频)