音视频入门基础:H.264专题(13)——FFmpeg源码中通过SPS属性获取视频色彩格式的实现

news2024/9/24 1:15:08

一、引言

通过FFmpeg命令可以获取到H.264裸流文件的色彩格式(又译作色度采样结构、像素格式):

在vlc中也可以获取到色彩格式(vlc底层也使用了FFmpeg进行解码):

这个色彩格式就是之前的文章《音视频入门基础:像素格式专题(4)——YUV简介》中描述的像素格式。所以FFmpeg和vlc是怎样获取到H.264编码的视频的色彩格式呢?它们其实是通过SPS中的属性chroma_format_idc获取的。

二、H.264官方文档对chroma_format_idc的描述

chroma_format_idc属性在H.264官方文档《T-REC-H.264-202108-I!!PDF-E.pdf》第44页中定义:

根据H.264官方文档《T-REC-H.264-202108-I!!PDF-E.pdf》第22页,当chroma_format_idc = 0时,色彩格式为单色;chroma_format_idc = 1时,色彩格式为YUV 4:2:0;chroma_format_idc = 2时,色彩格式为YUV 4:2:2;chroma_format_idc = 3时,色彩格式为YUV 4:4:4:

根据H.264官方文档第74页,chroma_format_idc的值应该在0到3的范围内(包括0和3)。当chroma_format_idc不存在时,应推断其值为1(4:2:0的色度格式)。

也就是说,只有当profile_idc等于下面红框里的这些值时,chroma_format_idc才会存在。如果profile_idc不是这些值,chroma_format_idc的值就是1,表示色彩格式为YUV 4:2:0:

三、计算色彩格式的例子

下面以某个视频文件为例,讲述怎么计算它的色彩格式。用Elecard Stream Analyzer工具打开一个用H.264编码的视频文件,看到其profile_idc值为77。由于profile_idc不是上图红框里的那些值,所以chroma_format_idc值为1,所以该视频的色彩格式为YUV 4:2:0:

用Elecard StreamEye工具可以看到该视频的色彩格式确实为YUV 4:2:0,证明我们的计算是正确的:

四、FFmpeg源码中获取色彩格式的实现

从文章《音视频入门基础:H.264专题(10)——FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析》中,我们可以知道,FFmpeg源码中通过ff_h264_decode_seq_parameter_set函数解码SPS,从而拿到SPS中的属性。

在ff_h264_decode_seq_parameter_set函数中有如下代码,通过下面的这部分代码拿到SPS中的chroma_format_idc:

int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
                                     H264ParamSets *ps, int ignore_truncation)
{
    //...
    if (sps->profile_idc == 100 ||  // High profile
        sps->profile_idc == 110 ||  // High10 profile
        sps->profile_idc == 122 ||  // High422 profile
        sps->profile_idc == 244 ||  // High444 Predictive profile
        sps->profile_idc ==  44 ||  // Cavlc444 profile
        sps->profile_idc ==  83 ||  // Scalable Constrained High profile (SVC)
        sps->profile_idc ==  86 ||  // Scalable High Intra profile (SVC)
        sps->profile_idc == 118 ||  // Stereo High profile (MVC)
        sps->profile_idc == 128 ||  // Multiview High profile (MVC)
        sps->profile_idc == 138 ||  // Multiview Depth High profile (MVCD)
        sps->profile_idc == 144) {  // old High444 profile
        sps->chroma_format_idc = get_ue_golomb_31(gb);
    //...
    }else {
        sps->chroma_format_idc = 1;
        //...
    }
    //...
}

然后在FFmpeg源码的源文件libavcodec/h264_parser.c的parse_nal_units函数中,通过如下代码,得到色彩格式:

static inline int parse_nal_units(AVCodecParserContext *s,
                                  AVCodecContext *avctx,
                                  const uint8_t * const buf, int buf_size)
{
    //...
    
    for (;;) {
        switch (nal.type) {
        case H264_NAL_SPS:
            ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0);
            break;
         
        //...
 
        case H264_NAL_IDR_SLICE:
        
        //...
 
            switch (sps->bit_depth_luma) {
            case 9:
                if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P9;
                else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P9;
                else                                  s->format = AV_PIX_FMT_YUV420P9;
                break;
            case 10:
                if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P10;
                else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P10;
                else                                  s->format = AV_PIX_FMT_YUV420P10;
                break;
            case 8:
                if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P;
                else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P;
                else                                  s->format = AV_PIX_FMT_YUV420P;
                break;
            default:
                s->format = AV_PIX_FMT_NONE;
            }
        //... 
        }
        //...
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1926758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

03-Charles实战

一、抓包分析问题示例 1)问题描述 2)抓包分析 这是后台响应回来的错误信息,说明问题一是后台的原因;但是后台只响应了一条信息,而前端页面却显示两条错误信息,说明前端页面处理异常的时候逻辑有问题&#…

《昇思25天学习打卡营第3天|03张量Tensor》

说在开始 学习下mindspore中对tensor的处理逻辑。 Tensor属性 张量的属性包括形状、数据类型、转置张量、单个元素大小、占用字节数量、维数、元素个数和每一维步长。 形状(shape):Tensor的shape,是一个tuple。 数据类型&…

windows USB 设备驱动开发- USB Type-C支持(一)

传统的 USB 连接使用两端都有 USB A 和 USB B 接头的电缆。 USB A 连接器始终插入主机端,USB B 连接器连接功能端,该功能端是手机) 或外设 (鼠标、键盘) 的设备 (。 使用这些连接器,只能将主机连接到函数;绝不是另一个主机的主机或另一个函数…

如何安装dotenv,避坑指南,安装包的包名有误?

嗨,大家好,我是蓝若姐姐。最近在研究AI大模型,想写一个调用openai接口的demo,结果发现在装一个三方库的时候一直报错,mac电脑安装dotenv报错,具体情况是 执行这个命令: pip install dotenv 遇…

提升 Kubernetes 日志记录能力,提高可观察性

介绍 在微服务和容器化应用时代,有效管理和监控应用的健康和性能至关重要。Kubernetes是一个用于自动部署、扩展和管理容器化应用的开源系统,已成为寻求敏捷性和弹性的企业的首选解决方案。 然而,由于 Kubernetes 的分布式架构、高日志量和…

【数据结构】栈和队列的深度探索,从实现到应用详解

💎所属专栏:数据结构与算法学习 💎 欢迎大家互三:2的n次方_ 🍁1. 栈的介绍 栈是一种后进先出的数据结构,栈中的元素只能从栈顶进行插入和删除操作,类似于叠盘子,最后放上去的盘子最…

Git代码管理工具 — 4 Git分支详解

目录 1 Git 分支概念 2 Git 分支基本操作 2.1 git branch查看与创建本地分支 2.2 git checkout切换分支 2.3 git merge合并分支 2.4 删除分支 3 解决冲突 1 Git 分支概念 Git 分支允许你从当前开发线上分离出来,进行独立的开发工作,而不会影响主…

用 AI 写歌词,让音乐表达与众不同

在音乐的广袤天地中,我们都渴望通过独特的表达来触动人心,展现自我。而如今,AI 技术的崛起为音乐创作带来了全新的突破,让我们能够以一种前所未有的方式赋予音乐独特的灵魂。 “妙笔生词智能写歌词软件(veve522&#…

Window10下安装WSL-Ubuntu20.04

1.开启并更新WSL 1.1开启WSL 首先先来看一下电脑是否能够开启WSL:待补充... 然后再来看一下如何开启WSL:win->设置->应用->应用和功能->程序和功能,如下所示: 最后选择启用或关闭Windows功能,开启两个选项:1.Hyper-V…

大语言模型诞生过程剖析

过程图如下 📚 第一步:海量文本的无监督学习 得到基座大模型🎉 🔍 原料:首先,我们需要海量的文本数据,这些数据可以来自互联网上的各种语料库,包括书籍、新闻、科学论文、社交媒体帖…

K8S系列-Kubernetes基本概念及Pod、Deployment、Service的使用

一、Kubernetes 的基本概念和术语 一、资源对象 ​ Kubernetes 的基本概念和术语大多是围绕资源对象 Resource Object 来说的,而资源对象在总体上可分为以下两类: 1、某种资源的对象 ​ 例如节点 Node) Pod 服务 (Service) 、存储卷 (Volume)。 2、…

记录些Redis题集(4)

Redis 通讯协议(RESP) Redis 通讯协议(Redis Serialization Protocol,RESP)是 Redis 服务端与客户端之间进行通信的协议。它是一种二进制安全的文本协议,设计简洁且易于实现。RESP 主要用于支持客户端和服务器之间的请求响应交互…

Adminer-CVE-2021-21311

在其4.0.0到4.7.9版本之间,连接 ElasticSearch 和 ClickHouse 数据库时存在一处服务端请求伪造漏洞(SSRF)。 VPS开启HTTP服务 VPS 开启HTTP 再同时跑POC 确保能访问poc里的链接文件 第一是目标地址 第二个是跳转地址 第三个是监听地址 如果…

昇思25天学习打卡营第21天|DCGAN生成漫画头像

DCGAN原理 DCGAN(深度卷积对抗生成网络,Deep Convolutional Generative Adversarial Networks)是GAN的直接扩展。不同之处在于,DCGAN会分别在判别器和生成器中使用卷积和转置卷积层。 它最早由Radford等人在论文Unsupervised Re…

【软件建模与设计】-03-软件生存周期模型和过程

目录 1、瀑布模型 2、抛弃型原型 3、演化式-增量模型 4、螺旋模型 5、统一软件开发过程RUP 6、设计验证和确认 6.1、软件质量保证 6.2、软件设计的性能分析 7、软件生存周期的活动 7.1、需求分析和规约 7.2、体系结构设计 7.3、详细设计 7.4、编码 8、软件测试 …

element-ui 插槽自定义样式怎么居中

场景:使用element-ui组件,scope内部自定义样式导致的错位 效果图: 解决思路: template标签可理解为一个内嵌组件,宽高重新定义,可在自定义内容外层套一层盒子,让盒子占满所有空间,再…

DBA 数据库管理 表管理 数据批量处理。表头约束

表管理 建库 库名命名规则:仅可以使用数字、字母、下划线、不能纯数字 不可使用MySQL命令或特殊字符 库名区分字母大小写 加if not exists 命令避免重名报错 create database if not exists gamedb; 建表 drop database if exists gamedb ; 删表…

从JDK源码探究Java线程与操作系统的交互

文章目录 从JDK源码探究Java线程与操作系统的交互一、序言二、线程基础概念1、操作系统线程实现方式(1)内核级线程(Kernel-Level Thread)(2)用户级线程(User-Level Thread)&#xff…

【DevOps系列】DevOps简介及基础环境安装

作者:后端小肥肠 目录 1. 前言 2. DevOps(详细介绍) 3. Code阶段工具 3.1 Git安装 3.2 GitLab安装 4. Build阶段工具 5. Operate阶段工具 5.1 Docker安装 5.2 Docker-Compose安装 6. Integrate工具 6.1 Jenkins介绍 6.2 Jenkins安…

8-1 搭建solidity开发环境,自己定制一个truffle

8-1 搭建solidity开发环境,自己定制一个truffle(react区块链实战) 从零开始搭建一个项目 自己实现一套类似truffle的自动编译系统,加深理解 此处可以跳过无需自己实现编译合约的模块,使用已有的truffle模块即可 项目…