P2 H264码流结构分析——Annexb与MP4格式的区别 (中)

2023-12-23 11:12

本文主要是介绍P2 H264码流结构分析——Annexb与MP4格式的区别 (中),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

 前言

01 Annexb格式

02 RTP格式(也叫MP4格式)


 前言

                             

从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3:《嵌入式音视频_@ChenPi的博客-CSDN博客》
🌺本篇简介  :这章记录编解码的基础理论知识——H264的码流结构

这章我们以一下这个图来讲解H264的码流结构

这个图是我从网上找的 

我们按照这个层级关系来学

 

01 Annexb格式

Annexb 格式使用起始码来表示一个编码数据的开始。

起始码他本身不是图像编码的内容,只是用来分隔用的,

而且他是大多数编码器默认输出 的码流格式,它的基本数据单位为NAL单元,也即NALU

为了从字节流中提取出NALU,协议规定,在每个NALU的前面加上起始码 。起始码有两

种,一种是 4 字节的“00 00 00 01”,一种是 3 字节的“00 00 01”。

这里需要注意一下,由于图像编码出来的数据中也有可能出现“00 00 00 01”和“00 00 01”的数据。

那这种情况怎么办呢?为了防止出现这种情况

H264会将图像编码数据中的下面的几种字节串做如下处理:

(1)“00 00 00”修改为“00 00 03 00”;

(2)“00 00 01”修改为“00 00 03 01”;

(3)“00 00 02”修改为“00 00 03 02”;

(4)“00 00 03”修改为“00 00 03 03”。

H264比特流 = Start_Code_Prefix + NALU + Start_Code_Prefix + NALU + …

这里也说一下为什么需要起始码?

主要是为了将相邻两个NALU划分开,让他们有一个界线,方便解码,比如将h264的数据存储在一个文件当中,解码器无法从数据流中分别每个NALU的起

始位置。 

02 RTP格式(也叫MP4格式)

MP4 格式没有起始码,而是在图像编码数据的开始使用了 4 个字节作为长度标识,用来表示编码数据的长度,这样我们每次读取 4 个字节,计 算出编码数据长度,然后取出编码数据,再继续读取 4 个字节得到长度,一直继续下去就可以取出所有的编码数据了。

h264的字节流格式,它是没有经过传输协议封装,所以也可以称他为裸流数据!

下一章我们重点讲解这个码流格式里面的NALU单元,也就是我们在本地拿到一个以.264格式的视频文件,我们首先去提取里面的NALU,这个才是重 点!

这篇关于P2 H264码流结构分析——Annexb与MP4格式的区别 (中)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v