音视频入门基础:H.264专题(19)——FFmpeg源码中,获取avcC封装的H.264码流中每个NALU的长度的实现

一、引言 

从《音视频入门基础:H.264专题(18)——AVCDecoderConfigurationRecord简介》中可以知道,avcC跟AnnexB不一样,avcC包装的H.264码流中,每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitLength,在读取某个NALU之前,先把该NALU前面的NALUnitLength读取出来,拿到该NALU的总长度,然后根据该长度读取相应的字节数,读取出整个NALU。

而FFmpeg源码内部使用get_nalsize函数读取出某个NALU前面的NALUnitLength。

二、get_nalsize函数的定义

get_nalsize函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavcodec/h2645_parse.h中:

static inline int get_nalsize(int nal_length_size, const uint8_t *buf,int buf_size, int *buf_index, void *logctx)
{int i, nalsize = 0;if (*buf_index >= buf_size - nal_length_size) {// the end of the buffer is reached, refill itreturn AVERROR_INVALIDDATA;}for (i = 0; i < nal_length_size; i++)nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)++];if (nalsize <= 0 || nalsize > buf_size - *buf_index) {av_log(logctx, AV_LOG_ERROR,"Invalid NAL unit size (%d > %d).\n", nalsize, buf_size - *buf_index);return AVERROR_INVALIDDATA;}return nalsize;
}

该函数作用是读取avcC封装的H.264码流中某个NALU前面的NALUnitLength,或者读取AVCDecoderConfigurationRecord中某个SPS前面的sequenceParameterSetLength,或者读取AVCDecoderConfigurationRecord中某个PPS前面的pictureParameterSetLength。由于SPS和PPS都属于一种特殊的NALU,所以sequenceParameterSetLength和pictureParameterSetLength也算是一种NALUnitLength。只是存贮每个sequenceParameterSetLength和pictureParameterSetLength需要固定2字节空间,而存贮每个NALUnitLength所需的空间由AVCDecoderConfigurationRecord中的lengthSizeMinusOne属性决定而已。

形参nal_length_size:输入型参数。如果是要读取某个NALU前面的NALUnitLength,形参nal_length_size的值为“存贮该NALU对应NALUnitLength所需的以字节为单位的空间”;如果是要读取sequenceParameterSetLength或pictureParameterSetLength,形参nal_length_size的值固定为2。

形参buf:输入型参数,指向某个缓冲区。

1.如果是要读取某个NALU前面的NALUnitLength,该缓冲区存放该NALU对应的NALUnitLength + NALU Header + EBSP;

2.如果是要读取某个SPS前面的sequenceParameterSetLength,该缓冲区存放该SPS对应的sequenceParameterSetLength + NALU Header + 该SPS实际的NALU数据(该SPS的EBSP);

3.如果是要读取某个PPS前面的pictureParameterSetLength,该缓冲区存放该PPS对应的pictureParameterSetLength + NALU Header + 该PPS实际的NALU数据(该PPS的EBSP);

形参buf_size:形参buf指向的缓冲区的长度,单位为字节。

形参buf_index:既是输入型参数也是输出型参数。表示读取到形参buf指向的缓冲区的第几个字节了。

形参logctx:输入型参数。用来输出日志,可忽略。

返回值:执行成功返回读取到的NALUnitLength或sequenceParameterSetLength或pictureParameterSetLength,失败返回一个负数。

三、get_nalsize函数的内部实现分析

get_nalsize函数中,首先判断是否读到了形参buf指向的缓冲区的末尾。如果已经读到了末尾,返回AVERROR_INVALIDDATA:

    if (*buf_index >= buf_size - nal_length_size) {// the end of the buffer is reached, refill itreturn AVERROR_INVALIDDATA;}

如果还没读到末尾,继续执行。通过下面语句,读取NALUnitLength或sequenceParameterSetLength或pictureParameterSetLength,存贮到局部变量nalsize中:

    for (i = 0; i < nal_length_size; i++)nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)++];

如果读取到的该NALU的总长度小于0,或者读取到的该NALU的总长度大于形参buf指向的缓冲区中剩下的还未被读取的空间,打印日志"Invalid NAL unit size”,并返回AVERROR_INVALIDDATA:

    if (nalsize <= 0 || nalsize > buf_size - *buf_index) {av_log(logctx, AV_LOG_ERROR,"Invalid NAL unit size (%d > %d).\n", nalsize, buf_size - *buf_index);return AVERROR_INVALIDDATA;}

读取成功返回NALUnitLength或sequenceParameterSetLength或pictureParameterSetLength的值:

    return nalsize;

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

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

相关文章

Linux文件的查找和打包以及压缩

文件的查找 文件查找的用处&#xff0c;在我们需要文件但却又不知道文件在哪里的时候 文件查找存在着三种类型的查找 1、which或whereis&#xff1a;查找命令的程序文件位置 2、locate&#xff1a;也是一种文件查找&#xff0c;但是基于数据库的查找 3、find&#xff1a;针…

基于SpringBoot+Vue+uniapp微信小程序的社区门诊管理系统的详细设计和实现(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

01 设计模式-创造型模式-工厂模式

工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;使得创建对象的过程与使用对象的过程分离。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 通过使用工厂模式…

1.2.3 TCP IP模型

TCP/IP模型&#xff08;接网叔用&#xff09; 网络接口层 网络层 传输层 应用层 理念&#xff1a;如果某些应用需要“数据格式转换”“会话管理功能”&#xff0c;就交给应用层的特定协议去实现 tip&#xff1a;数据 局部正确不等于全局正确 但是&#xff0c;数据的 全局正…

数码准备记录

1.数据结构 常见的数据结构包括数组、链表、栈、队列、树&#xff08;如二叉树、B树、B树&#xff09;、图等 2.队列和栈的区别 队列是一种先入先出的数据结构&#xff0c;即最先加入的元素被最先移除&#xff1b; 栈是一种后进后出的数据结构&#xff0c;即最后加入的元素…

SQL Server的介绍以及存储过程和函数的使用

SQL Server 是由微软开发的一个关系型数据库管理系统(RDBMS)。以下是关于 SQL Server 的详细介绍: 一、主要特点 强大的数据处理能力: 支持大规模数据存储和处理,可以处理海量的结构化数据。无论是小型企业应用还是大型企业级系统,SQL Server 都能提供高效的数据存储和检…

数据分箱:如何确定分箱的最优数量?

选择最优分箱可以考虑以下几种方法&#xff1a; 一、基于业务理解 分析业务背景&#xff1a;从业务角度出发&#xff0c;某些特征可能有自然的分组或区间划分。例如&#xff0c;年龄可以根据不同的人生阶段进行分箱&#xff0c;收入可以根据常见的收入等级划分。 优点&#x…

RTMP协议分析

理论 总体介绍 RTMP协议是应⽤层协议&#xff0c;是要靠底层可靠的传输层协议&#xff08;通常是TCP&#xff09;来保证信息传输的可靠性的。在基于传输层协议的链接建⽴完成后&#xff0c;RTMP协议也要客户端和服务器通过“握⼿”来建⽴基于传输层链接之上的RTMP Connection链…

《测试能否转产品经理?——优势与难点并存的转型之路》

引言 在软件行业中&#xff0c;测试人员和产品经理这两个角色似乎有着不同的定位和职责。然而&#xff0c;随着行业的发展和个人职业发展的需求&#xff0c;越来越多的测试人员开始思考一个问题&#xff1a;我能不能转产品经理呢&#xff1f; 一、测试转产品经理的优势 对产…

Collection 单列集合 List Set

集合概念 集合是一种特殊类 ,这些类可以存储任意类对象,并且长度可变, 这些集合类都位于java.util中,使用的话必须导包 按照存储结构可以分为两大类 单列集合 Collection 双列集合 Map 两种 区别如下 Collection 单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两…

plsql查询Oracle数据库发现有的数据是乱码

原因&#xff1a;Oracle数据库字符集和plsql客户端所使用的字符集不一致。 查询时&#xff0c;可能因为解码问题导致解出错误的字符。 也可能插入时就没有使用正确的字符集&#xff0c;解码时用utf-8自然也无法解出正确的字符。 环境变量 NLS_LANG 定义了客户端使用的语言、地…

MySQL多表操作--外键约束多表关系

外键约束介绍 Mysql外键约束&#xff08;foreign key&#xff09;是表的一个特殊字段&#xff0c;常与主键约束一起使用。外键约束是一种用于维护两个表之间数据一致性的方法。它确保引用表中的每个值都存在于主表中的某个列中。外键约束通常用于实现数据库的参照完整性。对于两…

LeetCode 1343.大小为K且平均值大于等于阈值的子数组数目

题目&#xff1a; 给你一个整数数组 arr 和两个整数 k 和 threshold 。 请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。 思路&#xff1a;定长滑动窗口 入 更新 出 代码&#xff1a; class Solution {public int numOfSubarrays(int[] arr, int k, int t…

Electron-(二)桌面应用的启动动画创建

一、概述 在很多桌面应用中都会有启动画面的显示。启动画面可以解决在启动时耗时较长&#xff0c;将每一步反馈给用户。另外一方面解决启动过程中的环境检查及检查结果的反馈。 在当今的桌面应用领域&#xff0c;启动动画已成为提升用户体验的重要组成部分。它不仅仅是一个简单…

【Linux】main函数的参数列表从何而来?

Linux系统进程通过exec系列函数启动新程序时&#xff0c;argc整型 、 argv数组 和 环境变量表 environ 会作为 exec 系列函数的参数&#xff0c;显式传递给新程序的 main 函数。 main函数的参数列表 在C语言中&#xff0c;main函数的标准参数列表通常如下所示&#xff1a; in…

极客wordpress模板

这是一个展示WordPress主题的网页设计。页面顶部有一个导航栏&#xff0c;包含多个选项&#xff0c;如“关于我们”、“产品中心”、“案例展示”、“新闻动态”、“联系我们”和“技术支持”。页面中间部分展示了多个产品&#xff0c;每个产品都有一个图片和简短的描述。页面下…

MySQL【知识改变命运】06

前言&#xff1a;在05这节数据结构里面&#xff0c;我们知道select * from 这个操作很危险&#xff0c;如果数据库很大&#xff0c;会把服务器资源耗尽&#xff0c;接下来提到的查询可以有效的限制返回记录 1&#xff1a;分页查询 分页查询可以有效控制一次查询出来的结果集的…

AutoSar AP CM原始数据流传输接口总结

一、原始数据流传输接口概述 自适应 AUTOSAR 通信管理通常基于面向服务的通信&#xff0c;但对于高级驾驶辅助系统&#xff08;ADAS&#xff09;应用&#xff0c;高效传输原始二进制数据流很重要&#xff0c;原始数据二进制流 API 为此提供了解决方案。它能与车辆外部传感器高…

【CTF刷题9】2024.10.19

[MoeCTF 2021]babyRCE 考点&#xff1a;关键词过滤&#xff08;绕过方法参考往期博客&#xff09; 来源&#xff1a;nssctf <?php$rce $_GET[rce]; if (isset($rce)) {if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\|\%|\&g…

TiDB 关联子查询及半连接的优化实践

作者&#xff1a; 数据源的TiDB学习之路 原文来源&#xff1a; https://tidb.net/blog/e9563a23 导读 TiDB 针对子查询语句会执行多种 子查询相关的优化 &#xff0c;以提升子查询的执行性能。半连接语句和关联子查询语句是常用的两类子查询&#xff0c;TiDB 优化器默认包…