ffmpeg7.0 flv支持hdr

2024-05-07 02:20
文章标签 支持 flv hdr ffmpeg7.0

本文主要是介绍ffmpeg7.0 flv支持hdr,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ffmpeg7.0 flv支持hdr

自从ffmpeg6.0应用enhance rtmp支持h265/av1的flv格式后,7.0迎来了flv的hdr能力。本文介绍ffmpeg7.0如何支持hdr in flv。

如果对enhance rtmp如何支持h265不了解,推荐详解Enhanced-RTMP支持H.265

1. enhance rtmp关于hdr

文档enhance-rtmp-v2.md中,metadata-frame章节规定相关支持HDR部分。

定义一个新的VideoPacketType.Metadata,其内容为AMF格式的metadata(AMF是一种简便的描述格式,非常节省内存),具体内部有HDR相关的colorInfo数据(每次hdr参数更新的时候,就发送该metadata)。

type ColorInfo = {colorConfig: {// number of bits used to record the color channels for each pixelbitDepth:                 number, // SHOULD be 8, 10 or 12//// colorPrimaries, transferCharacteristics and matrixCoefficients are defined // in ISO/IEC 23091-4/ITU-T H.273. The values are an index into // respective tables which are described in “Colour primaries”, // "Transfer characteristics" and "Matrix coefficients" sections. // It is RECOMMENDED to provide these values.//// indicates the chromaticity coordinates of the source color primariescolorPrimaries:           number, // enumeration [0-255]// opto-electronic transfer characteristic function (ex. PQ, HLG)transferCharacteristics:  number, // enumeration [0-255]// matrix coefficients used in deriving luma and chroma signalsmatrixCoefficients:       number, // enumeration [0-255]},hdrCll: {//// maximum value of the frame average light level// (in 1 cd/m2) of the entire playback sequence//maxFall:  number,     // [0.0001-10000]//// maximum light level of any single pixel (in 1 cd/m2)// of the entire playback sequence//maxCLL:   number,     // [0.0001-10000]},//// The hdrMdcv object defines mastering display (i.e., where// creative work is done during the mastering process) color volume (a.k.a., mdcv)// metadata which describes primaries, white point and min/max luminance. The// hdrMdcv object SHOULD be provided.//// Specification of the metadata along with its ranges adhere to the// ST 2086:2018 - SMPTE Standard (except for minLuminance see// comments below)//hdrMdcv: {//// Mastering display color volume (mdcv) xy Chromaticity Coordinates within CIE// 1931 color space.//// Values SHALL be specified with four decimal places. The x coordinate SHALL// be in the range [0.0001, 0.7400]. The y coordinate SHALL be // in the range [0.0001, 0.8400].//redX:         number,redY:         number,greenX:       number,greenY:       number,blueX:        number,blueY:        number,whitePointX:  number,whitePointY:  number,//// max/min display luminance of the mastering display (in 1 cd/m2 ie. nits)//// note: ST 2086:2018 - SMPTE Standard specifies minimum display mastering// luminance in multiples of 0.0001 cd/m2.// // For consistency we specify all values// in 1 cd/m2. Given that a hypothetical perfect screen has a peak brightness// of 10,000 nits and a black level of .0005 nits we do not need to// switch units to 0.0001 cd/m2 to increase resolution on the lower end of the// minLuminance property. The ranges (in nits) mentioned below suffice// the theoretical limit for Mastering Reference Displays and adhere to the// SMPTE ST 2084 standard (a.k.a., PQ) which is capable of representing full gamut// of luminance level.//maxLuminance: number,     // [5-10000]minLuminance: number,     // [0.0001-5]},
}

2. flv mux

在libavformat/flvenc.c中,新增flv_write_metadata_packet函数,用于添加metadata。
flv的数据结构:


typedef struct FLVContext {.....int metadata_pkt_written;//0: 还未写过,需要写;1: 写过了,不需要写。
} FLVContext;

在函数flv_write_metadata_packet中实现,见注释:

static void flv_write_metadata_packet(AVFormatContext *s, AVCodecParameters *par, unsigned int ts) {FLVContext *flv = s->priv_data;//不需要写入,就返回;可以通过设置这个标志变量来使能/去使能更新写metadataif (flv->metadata_pkt_written)return;//支持h265, av1, vp9if (par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1 || par->codec_id == AV_CODEC_ID_VP9) {......//写入tag头,标识其为视频avio_w8(pb, FLV_TAG_TYPE_VIDEO); //write video tag typemetadata_size_pos = avio_tell(pb);avio_wb24(pb, 0 + flags_size);put_timestamp(pb, ts); //ts = pkt->dts, genavio_wb24(pb, flv->reserved);//根据enhance rtmp标志,写入FLV_IS_EX_HEADER标识,和fourCC的字段(hvc1 or av01 or vp09)if (par->codec_id == AV_CODEC_ID_HEVC) {avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeMetadata| FLV_FRAME_VIDEO_INFO_CMD); // ExVideoTagHeader mode with PacketTypeMetadataavio_write(pb, "hvc1", 4);} else if (par->codec_id == AV_CODEC_ID_AV1 || par->codec_id == AV_CODEC_ID_VP9) {avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeMetadata| FLV_FRAME_VIDEO_INFO_CMD);avio_write(pb, par->codec_id == AV_CODEC_ID_AV1 ? "av01" : "vp09", 4);}//下面为写入AMF格式的hdr相关的colorInfo数据avio_w8(pb, AMF_DATA_TYPE_STRING);put_amf_string(pb, "colorInfo");avio_w8(pb, AMF_DATA_TYPE_OBJECT);put_amf_string(pb, "colorConfig");  // colorConfigavio_w8(pb, AMF_DATA_TYPE_OBJECT);if (par->color_trc != AVCOL_TRC_UNSPECIFIED &&par->color_trc < AVCOL_TRC_NB) {put_amf_string(pb, "transferCharacteristics");  // color_trcput_amf_double(pb, par->color_trc);}if (par->color_space != AVCOL_SPC_UNSPECIFIED &&par->color_space < AVCOL_SPC_NB) {put_amf_string(pb, "matrixCoefficients"); // colorspaceput_amf_double(pb, par->color_space);}if (par->color_primaries != AVCOL_PRI_UNSPECIFIED &&par->color_primaries < AVCOL_PRI_NB) {put_amf_string(pb, "colorPrimaries"); // color_primariesput_amf_double(pb, par->color_primaries);}put_amf_string(pb, "");avio_w8(pb, AMF_END_OF_OBJECT);if (lightMetadata) {put_amf_string(pb, "hdrCll");avio_w8(pb, AMF_DATA_TYPE_OBJECT);put_amf_string(pb, "maxFall");put_amf_double(pb, lightMetadata->MaxFALL);put_amf_string(pb, "maxCLL");put_amf_double(pb, lightMetadata->MaxCLL);put_amf_string(pb, "");avio_w8(pb, AMF_END_OF_OBJECT);}if (displayMetadata && (displayMetadata->has_primaries || displayMetadata->has_luminance)) {put_amf_string(pb, "hdrMdcv");avio_w8(pb, AMF_DATA_TYPE_OBJECT);if (displayMetadata->has_primaries) {put_amf_string(pb, "redX");put_amf_double(pb, av_q2d(displayMetadata->display_primaries[0][0]));put_amf_string(pb, "redY");put_amf_double(pb, av_q2d(displayMetadata->display_primaries[0][1]));put_amf_string(pb, "greenX");put_amf_double(pb, av_q2d(displayMetadata->display_primaries[1][0]));put_amf_string(pb, "greenY");put_amf_double(pb, av_q2d(displayMetadata->display_primaries[1][1]));put_amf_string(pb, "blueX");put_amf_double(pb, av_q2d(displayMetadata->display_primaries[2][0]));put_amf_string(pb, "blueY");put_amf_double(pb, av_q2d(displayMetadata->display_primaries[2][1]));put_amf_string(pb, "whitePointX");put_amf_double(pb, av_q2d(displayMetadata->white_point[0]));put_amf_string(pb, "whitePointY");put_amf_double(pb, av_q2d(displayMetadata->white_point[1]));}if (displayMetadata->has_luminance) {put_amf_string(pb, "maxLuminance");put_amf_double(pb, av_q2d(displayMetadata->max_luminance));put_amf_string(pb, "minLuminance");put_amf_double(pb, av_q2d(displayMetadata->min_luminance));}put_amf_string(pb, "");avio_w8(pb, AMF_END_OF_OBJECT);}put_amf_string(pb, "");avio_w8(pb, AMF_END_OF_OBJECT);flv->metadata_pkt_written = 1;//标识写过了}
}

其中HDR的数据来源为AVCodecParameters *par数据结构中的内容:

typedef struct AVCodecParameters {..../*** Video only. Additional colorspace characteristics.*/enum AVColorRange                  color_range;enum AVColorPrimaries              color_primaries;enum AVColorTransferCharacteristic color_trc;enum AVColorSpace                  color_space;enum AVChromaLocation              chroma_location;/** 类型: AV_PKT_DATA_CONTENT_LIGHT_LEVEL, 数据: AVContentLightMetadata* lightMetadata* 类型: AV_PKT_DATA_MASTERING_DISPLAY_METADATA, 数据: AVMasteringDisplayMetadata *displayMetadata*/AVPacketSideData *coded_side_data;....
}

3. flv demux

解析函数在libavformat/flvdec.c文件中,函数amf_parse_object中。

static int amf_parse_object(AVFormatContext *s, AVStream *astream,AVStream *vstream, const char *key,int64_t max_pos, int depth)
{FLVMetaVideoColor *meta_video_color = flv->metaVideoColor;......if (meta_video_color) {if (amf_type == AMF_DATA_TYPE_NUMBER ||amf_type == AMF_DATA_TYPE_BOOL) {if (!strcmp(key, "colorPrimaries")) {meta_video_color->primaries = num_val;} else if (!strcmp(key, "transferCharacteristics")) {meta_video_color->transfer_characteristics = num_val;} else if (!strcmp(key, "matrixCoefficients")) {meta_video_color->matrix_coefficients = num_val;} else if (!strcmp(key, "maxFall")) {meta_video_color->max_fall = num_val;} else if (!strcmp(key, "maxCLL")) {meta_video_color->max_cll = num_val;} else if (!strcmp(key, "redX")) {meta_video_color->mastering_meta.r_x = num_val;} else if (!strcmp(key, "redY")) {meta_video_color->mastering_meta.r_y = num_val;} else if (!strcmp(key, "greenX")) {meta_video_color->mastering_meta.g_x = num_val;} else if (!strcmp(key, "greenY")) {meta_video_color->mastering_meta.g_y = num_val;} else if (!strcmp(key, "blueX")) {meta_video_color->mastering_meta.b_x = num_val;} else if (!strcmp(key, "blueY")) {meta_video_color->mastering_meta.b_y = num_val;} else if (!strcmp(key, "whitePointX")) {meta_video_color->mastering_meta.white_x = num_val;} else if (!strcmp(key, "whitePointY")) {meta_video_color->mastering_meta.white_y = num_val;} else if (!strcmp(key, "maxLuminance")) {meta_video_color->mastering_meta.max_luminance = num_val;} else if (!strcmp(key, "minLuminance")) {meta_video_color->mastering_meta.min_luminance = num_val;}}}......
}

4. 感谢Zhu Pengfei的提交

Author: Zhu Pengfei <411294962@qq.com>
Date:   Mon Mar 4 21:52:04 2024 +0800avformat/flvenc: support enhanced flv PacketTypeMetadataSigned-off-by: Zhu Pengfei <411294962@qq.com>Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
``

这篇关于ffmpeg7.0 flv支持hdr的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/966059

相关文章

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑

sqlite不支持中文排序,采用java排序

方式一 不支持含有重复字段进行排序 /*** sqlite不支持中文排序,改用java排序* 根据指定的对象属性字段,排序对象集合,顺序* @param list* @param field* @return*/public static List sortListByField(List<?> list,String field){List temp = new ArrayList(

一款支持同一个屏幕界面同时播放多个视频的视频播放软件

GridPlayer 是一款基于 VLC 的免费开源跨平台多视频同步播放工具,支持在一块屏幕上同时播放多个视频。其主要功能包括: 多视频播放:用户可以在一个窗口中同时播放任意数量的视频,数量仅受硬件性能限制。支持多种格式和流媒体:GridPlayer 支持所有由 VLC 支持的视频格式以及流媒体 URL(如 m3u8 链接)。自定义网格布局:用户可以配置播放器的网格布局,以适应不同的观看需求。硬

Science Robotics 首尔国立大学研究团队推出BBEX外骨骼,实现多维力量支持!

重复性举起物体可能会对脊柱和背部肌肉造成损伤,由此引发的腰椎损伤是工业环境等工作场所中一个普遍且令人关注的问题。为了减轻这类伤害,有研究人员已经研发出在举起任务中为工人提供辅助的背部支撑装置。然而,现有的这类装置通常无法在非对称性的举重过程中提供多维度的力量支持。此外,针对整个人体脊柱的设备安全性验证也一直是一个缺失的环节。 据探索前沿科技边界,传递前沿科技成果的X-robot投稿,来自首尔国立

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密 可以将表情,动物,水果,表情,手势,猫语,兽语,狗语,爱语,符号,数字,字母,加密和解密 可以将文字、字母、数字、代码、标点符号等内容转换成新的文字形式,通过简单的文字以不同的排列顺序来表达不同的内容 源码截图: https://www.httple.net/152649.html

QtC++截图支持窗口获取

介绍 在截图工具中你会发现,接触到窗口后会自动圈出目标窗口,个别强大一点的还能进行元素识别可以自动圈出元素,那么今天简单分析一下QTc++如何获取窗口并圈出当前鼠标下的窗口。 介绍1.如何获取所有窗口2.比较函数3.实现窗口判断 结尾 1.如何获取所有窗口 1.我们需要调用windows接口EnumWindowsProc回调函数来获取所有顶级窗口,需要包含windows.

Nacos Config 配置中心支持配置共享

文章目录 一、什么是配置中心二、Nacos Config2.1 Nacos Config 工作原理 (★)2.2 Nacos Config 的使用2.3 动态刷新2.4 配置共享2.4.1 同一个微服务的不同环境之间共享配置2.4.2 不同微服务中间共享配置 一、什么是配置中心 微服务架构下关于配置文件的存在以下问题: 配置文件相对分散。在一个微服务架构下,配置文件会随

spring笔记 多线程的支持

spring的工作机制 136  属性编辑器 140 spring事件的体系结构 168 Bean间的关系 109 继承 依赖 引用     Bean的继承          1 为了简化初始化的属性注入;          2 子Bean和父Bean相同的属性值,使用子Bean的     Bean的依赖 Srping控制相互依赖的Bean之间,属性注入的顺序,防止出错  depend-on

PageOfficeCtrl支持直接打开服务器磁盘文件

一般来说,PageOfficeCtrl控件的WebOpen方法的第一个参数是待打开文档的URL,此URL可以是相对于当前页面的相对URL,也可以是相对于整个网站根的相对URL,还可以是http开头的完整URL,但是这个URL必须是当前网站的URL,不能跨域。 现在为了更加方便开发者编程,WebOpen支持打开服务器磁盘文件。也就是说,第一个参数可以写成服务器文件的绝对磁盘路径。例如: P

Jasperreports+jaspersoft studio 实现支持富文本格式的数据

昨天有位博友给我发邮件问我:Jasperreports+jaspersoft studio 如何实现支持富文本格式的数据! 其实,我也是第一次遇到这个问题;我就百度搜索,我记得之前:我解决过用百度编辑器,解析富文本格式的数据,是设置一个属性; 最后,只百度到一篇文章;https://zhidao.baidu.com/question/1430121390482093659.html 废话不多