当前位置: 首页 > news >正文

音视频入门基础: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;

相关文章:

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

一、引言 从《音视频入门基础&#xff1a;H.264专题&#xff08;18&#xff09;——AVCDecoderConfigurationRecord简介》中可以知道&#xff0c;avcC跟AnnexB不一样&#xff0c;avcC包装的H.264码流中&#xff0c;每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitL…...

【uniapp】设置公共样式,实现公共背景等

目录 1、 全局渐变背景色 2.1 创建common目录 2.2 在common下新建style和images等目录 2.3 在style下新建common-style.scss 2.4 common-style输入全局渐变颜色 2.5 引入样式 2.6 业务页面引入 2.7 展示 2、全局字体颜色 2.1 新建base-style.scss文件 2.2 设置base-…...

Node.js学习笔记

回顾&#xff1a; javascript 可以在浏览器运行 &#xff08;js代码会JavaScript的解析引擎执行&#xff09;chrome 》V8 &#xff08;性能最好&#xff09;FireFox 》 奥丁猴safri 》JSCoreIE浏览器 》查克拉JavaScript可以在浏览器端操作DOM 和BOM每一个浏览器都内置了B…...

resnetv1骨干

# 普通的卷积残差块 def apply_basic_block( x, filters, kernel_size3, stride1, conv_shortcutTrue, nameNone ): # 预设块名称前缀 if name is None: name f"v1_basic_block_{keras.backend.get_uid(v1_basic_block_)}" # 设置残差连接前…...

设计模式,面试级别的详解(持续更新中)

设计模式&#xff0c;面试级别的详解(持续更新中) 软件的设计原则 常⽤的⾯向对象设计原则包括7个&#xff0c;这些原则并不是孤⽴存在的&#xff0c;它们相互依赖&#xff0c;相互补充。 开闭原则&#xff08;Open Closed Principle&#xff0c;OCP&#xff09;单⼀职责原则…...

第9篇:网络访问控制与认证机制

目录 引言 9.1 访问控制策略概述 9.2 认证机制的使用 9.3 密钥分发与证书机制 9.4 访问控制与认证在网络安全中的应用 9.5 网络访问控制与认证的挑战 9.6 总结 第9篇&#xff1a;网络访问控制与认证机制 引言 随着计算机网络的不断普及&#xff0c;安全问题日益受到关…...

CentOS安装NVIDIA驱动、CUDA以及nvidia-container-toolkit

0.提前准备 0.1.更新yum源&#xff08;以阿里为例&#xff09; 0.1.1 备份当前的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 0.1.2 下载新的CentOS-Base.repo 到/etc/yum.repos.d/ CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base…...

STM32调试,发现HAL_Init();之后无法调试,甚至无法让程序停下来

参考文档&#xff1a; STM32调试,发现HAL_Init();之后无法调试,甚至无法让程序停下来 - asml - 博客园 症状 最近开始学习STM32Cube,发现新建工程后无法正常调试,过了HAL_Init();之后就无法继续调试了. 无法进行让程序暂停以及停止等操作.并在输出窗口不断刷出 ERROR: Can n…...

Ajax(web笔记)

文章目录 1.Ajax的概念2.Ajax 的作用3.原生Ajax4.Axios4.1Axios的概念4.2Axios入门 1.Ajax的概念 AsynchronousJavaScriptAndXML&#xff0c;异步的JavaScript和XML 2.Ajax 的作用 数据交换:过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。异步交互:可以在…...

多入口+vite+vue3预渲染方案

如果你的项目要求加载速度要快,我们如果使用传统的vue3+sfc模式去开发,因为只有一个根节点,空白页面加载出来之后js才回去加载组件渲染,这样页面总是有一个短暂的空白。我们这里不讨论服务器端ssr和预渲染方案,仅仅是为了满足比较极端的优化需求,在这种情况下我的这套方案…...

Vue3+Ts函数封装与应用

目录 一、基础函数 二、实际应用 2.1、根据id找到对应的value值(找第一个) 2.2、根据id找到对应的value值(找所有) 2.3、不重复的升序数组找数字(二分查找) 2.4、重复的无序数组找数字(统计个数) 2.5、将数组整理为树结构(省市区为例) 为什么要积累呢&#xff1f;因为面…...

C语言全局变量和局部变量同时应用的题题型[求一堆数组中10个学生的成绩里最高分、最低分和平均分。]

C语言函数 全局变量与局部结合变量题。 本片代码中包含全局变量max和min。 以及局部变量aver。 全局变量运用于从定义变量开始&#xff0c;局部变量运用于定义它的调用函数内。 正文开始: #include <stdio.h> int max0,min0; int main() { int average(int array[…...

深度学习实战94-基于图卷积神经网络GCN模型的搭建以及在金融领域的场景

大家好,我是微学AI,今天给大家介绍一下深度学习实战94-基于图卷积神经网络GCN模型的搭建以及在金融领域的场景。文章首先介绍了GCN模型的原理及模型结构,随后提供了数据样例,并详细展示了实战代码。通过本文,读者可以深入了解GCN模型在金融场景下的应用,同时掌握代码的具…...

.NET 6新特性 | System.Text.Json功能改进

在.NET 6.0中&#xff0c;JSON处理库得到了显著的改进&#xff0c;主要体现在System.Text.Json上。以下是对.NET 6.0中改进的JSON处理库的详细分析&#xff1a; 一、System.Text.Json的引入与优势 在.NET 6中&#xff0c;Microsoft引入了新的JSON库System.Text.Json作为官方推…...

Matlab如何对全局优化算法启动并行计算

在 MATLAB 中&#xff0c;启用并行计算可以显著提高一些优化算法&#xff08;如遗传算法 ga 和粒子群算法 particleswarm&#xff09;的速度&#xff0c;特别是在种群或粒子群较大时。要启用并行计算&#xff0c;可以使用 UseParallel 参数。 1. 启用并行计算步骤 Step 1: 检…...

MYSQL-查看数据库中的存储过程语法(六)

13.7.5.9 SHOW CREATE PROCEDURE 语句 SHOW CREATE PROCEDURE proc_name此语句是 MySQL 扩展。它返回确切的字符串 &#xff0c;可用于重新创建命名的存储过程。SHOW CREATE FUNCTION&#xff0c;显示有关存储函数的信息 &#xff08;参见第 13.7.5.8 节“ SHOW CREATE FUNCTI…...

【深度学习】(12)--模型部署 <连接客户端与服务端>

文章目录 模型部署一、模型部署的定义与目的二、模型部署的步骤三、模型部署的方式四、Flask框架五、实现模型部署1. 搭建服务端1.1 初始化Flask app1.2 加载模型1.3 数据预处理1.4 构建装饰器1.5 完整代码 2. 搭建客户端2.1 服务端网址2.2 发送请求2.3 完整代码 六、运行使用 …...

优化SQL查询的最佳实践:提升数据库性能的关键

SQL 查询是数据库操作的核心&#xff0c;特别是当数据量庞大时&#xff0c;性能问题尤为明显。优化 SQL 查询不仅能减少响应时间&#xff0c;还能提高系统整体的可伸缩性。本文将从索引、查询结构、数据库设计和缓存等方面详细介绍如何优化 SQL 查询以提升性能。 一、索引的使…...

【AIGC视频生成】视频扩散模型(综述+最新进展)

文章目录 一、综述1.1 扩散模型1.1.1 Denoising Diffusion Probabilistic Models (DDPMs)1.1.2 Score-Based Generative Models (SGMs)1.1.3 Stochastic Differential Equations (Score SDEs) 1.2 相关任务1.3 数据集1.4 评价指标 二、年度进展1.runway gen2.1 Gen-1&#xff1…...

如何下载3GPP协议?

一、进入3GPP网页 https://www.3gpp.org/ 二、点击“Specifications &Technologies” 三、点击“FTP Server” 网址&#xff1a; https://www.3gpp.org/specifications-technologies 四、找到“latest”&#xff0c;查看最新版 网址&#xff1a; https://www.3gpp.org/ftp…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...