FFmpeg mxf扩展hdr、bt2020

本文详述了在FFmpeg中实现XAVCIntraClass300/480扩展并支持HLG视频的过程,包括如何逆向工程MediaInfo以支持mxf容器中的特定信息,最终成功在mxf封装中携带HLG/BT2020信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    最近做广电音视频项目,从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 <mydota@qq.com>
  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 <mydota@qq.com>
  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 Intra@L5.2
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

    顺利识别。

<think>好的,我现在要解决用户的问题:视频元数据错误导致无法正确显示在Premiere Pro(PR)中。之前用户已经询问过关于使用FFmpeg调整分辨率的问题,现在可能遇到了类似或相关的问题,但这次是在PR中显示不正确。我需要先理解用户的具体情况,然后给出有效的解决方案。 首先,用户提到视频的元数据错误。元数据错误可能包括分辨率、宽高比(SAR/DAR)、编码参数等不正确,导致PR无法正确解析视频的显示方式。比如,之前用户遇到的是播放时分辨率显示异常,现在在PR中可能遇到类似问题,或者更复杂的情况,比如时间码错误、帧率不符、色彩空间设置错误等。 接下来,我需要考虑用户可能的操作环境。用户之前使用PotPlayer和FFmpeg,现在在PR中工作,可能是在视频编辑或后期制作中遇到了问题。PR对视频的元数据要求可能更严格,尤其是在时间码、帧率、场序(隔行/逐行)等方面。如果这些参数设置错误,PR可能无法正确导入或显示视频,导致剪辑困难。 可能的元数据错误类型包括: 1. **宽高比问题**:存储宽高比(SAR)与显示宽高比(DAR)不匹配,导致视频在PR中被拉伸或压缩。 2. **帧率不一致**:视频的实际帧率与元数据中记录的帧率不符,导致PR中的时间轴不同步。 3. **场序错误**:隔行扫描的视频场序设置错误,导致画面出现锯齿或抖动。 4. **色彩空间问题**:颜色参数(如primaries、transfer characteristics、matrix coefficients)不正确,导致颜色显示异常。 5. **时间码错误**:时间码不连续或格式错误,影响剪辑时的同步。 6. **编码格式不支持**:PR可能不支持某些编码格式,需要转码。 接下来,我需要确定用户的具体问题是什么。用户提到“无法正确显示”,可能指的是视频在PR中的预览窗口显示异常,比如变形、比例不对、颜色问题,或者无法导入、导入后无法播放等。不同的症状对应不同的解决方法。 可能的解决方案步骤: 1. **检查元数据**:使用FFprobe或MediaInfo查看视频的详细元数据,确认问题所在。 2. **修正宽高比**:如果问题出在SAR/DAR,使用FFmpeg调整元数据或重新编码。 3. **调整帧率**:确保视频帧率与项目设置一致,可能需要重新封装或转码。 4. **修复场序**:设置正确的场序参数,或去隔行处理。 5. **修正色彩空间**:添加正确的色彩元数据。 6. **转码为PR支持的格式**:如ProRes、DNxHD等中间格式,确保兼容性。 另外,用户之前的问题涉及使用FFmpeg调整分辨率,可能现在的问题也类似,但需要结合PR的具体需求来处理。例如,PR可能在处理某些H.264/MP4文件时出现兼容性问题,需要转码为中间格式。 需要提醒用户备份原始文件,避免操作失误导致数据丢失。同时,提供多种解决方案,如仅修改元数据(无需重新编码)和重新编码的方法,根据用户的需求选择。 可能还需要考虑PR的项目设置是否与视频参数匹配,比如项目分辨率、帧率、场序等,如果项目设置不正确,即使视频元数据正确,也可能显示异常。因此,建议用户检查PR的项目设置是否与视频参数一致。 最后,给出验证步骤,确保问题解决,比如在PR中重新导入处理后的视频,检查显示是否正确,或使用FFprobe确认元数据已修正。</think>--- ### **问题诊断** 当Premiere Pro(PR)无法正确解析视频元数据时,通常由以下原因导致: 1. **宽高比参数异常**:SAR(存储宽高比)与DAR(显示宽高比)冲突 2. **帧率元数据错误**:时间基(timebase)与实际帧率不匹配 3. **场序(Field Order)设置错误**:隔行扫描视频未正确标记场序 4. **色彩空间元数据缺失**:HDR/SDR参数未正确写入 --- ### **解决方案总览** #### **步骤1:精准诊断元数据** 使用`ffprobe`获取完整元数据: ```bash ffprobe -v error -show_entries stream=index,codec_name,width,height,sample_aspect_ratio,display_aspect_ratio,r_frame_rate,field_order,color_space,color_primaries,color_transfer -show_entries format=filename input.mp4 ``` #### **步骤2:针对性修复方案** 根据诊断结果选择对应修复方式: --- ### **场景1:宽高比异常修复** **症状**:视频在PR中显示拉伸/压缩 **修复命令**: ```bash ffmpeg -i input.mp4 -c:v copy -c:a copy -aspect 16:9 -metadata:s:v:0 rotate=0 output.mp4 ``` - `-aspect 16:9`:强制设定显示宽高比(DAR) - `-metadata:s:v:0 rotate=0`:清除旋转标记(部分手机会写入旋转标记导致PR识别错误) --- ### **场景2:帧率元数据校正** **症状**:PR时间轴显示时长异常 **修复命令**: ```bash ffmpeg -r 25 -i input.mp4 -c:v libx264 -x264-params "force-cfr=1" -vsync cfr -c:a copy output.mp4 ``` - `-r 25`:强制指定输入帧率为25fps - `force-cfr=1`:恒定帧率模式(修复VFR可变帧率问题) - `-vsync cfr`:输出恒定帧率 --- ### **场景3:隔行扫描场序修复** **症状**:画面出现场撕裂 **修复命令**: ```bash ffmpeg -i input.mp4 -vf "bwdif=1:1,setfield=prog" -c:v prores_ks -profile:v 3 -c:a pcm_s24le output.mov ``` - `bwdif=1:1`:使用高质量去隔行算法 - `setfield=prog`:标记为逐行扫描 - `prores_ks`:输出PR原生支持的ProRes格式 --- ### **场景4:色彩空间元数据注入** **症状**:HDR素材过曝/色偏 **修复命令**: ```bash ffmpeg -i input.mp4 -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc -c:v copy -c:a copy output.mp4 ``` - `bt2020`:HDR色域参数 - `smpte2084`:PQ曲线HDR元数据 --- ### **高级修复方案** 对于专业工作流建议: ```bash ffmpeg -i input.mp4 \ -vf "scale=1920:1080:flags=lanczos+full_chroma_inp+accurate_rnd,setparams=range=tv:color_primaries=bt709:color_trc=bt709:colorspace=bt709" \ -c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p \ -timecode 01:02:03:04 \ -output_ts_offset 0.5 \ -output_timebase 1/1000 \ -movflags write_colr \ output.mov ``` - `-timecode`:写入精确时间码 - `-output_ts_offset`:调整时间戳偏移 - `-movflags write_colr`:强制写入色彩元数据 --- ### **PR兼容性优化建议** 1. **格式转换**:将H.264/HEVC转码为ProRes/DNxHD 2. **音频同步**:使用`-af "aresample=async=1"`修复音画不同步 3. **MXF封装**:对广播级工作流建议使用MXF容器: ```bash ffmpeg -i input.mp4 -c:v dnxhd -profile:v dnxhr_444 -c:a pcm_s24le -f mxf output.mxf ``` --- ### **验证与调试** 1. **PR项目设置验证**: - 时间轴分辨率与视频DAR一致 - 帧率模式选择"帧采样"而非"帧混合" 2. **元数据深度检查**: ```bash mediainfo --Output=JSON input.mp4 | jq '.media.track[] | select(."@type"=="Video")' ``` --- ### **技术原理** Premiere Pro的视频解析遵循以下优先级: ``` 容器元数据 > 视频流头信息 > 文件扩展名隐含规则 ``` 当三者存在冲突时,会导致解析异常。通过FFmpeg的`-metadata`、`-aspect`、`-disposition`等参数可精确控制各层元数据。 --- 需要提供具体视频的`ffprobe`分析报告吗?可进一步定制修复方案。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值