音视频开发之H.264 入门知识
大家如果有做过音视频相关的项目,那么肯定对 H.264 相关的概念了解的比较通透,这里我为什么还要写这样一篇文章呢?一来是为了对知识的总结,二来是为了给刚入门音视频的同学一个参考。
基础概念
H.264 又称为 MPEG-4 , 它是一种面向块,基于运动补偿的视频编码标准,是目前市面上最常用的一种视频编码格式,在 Android 中你可以通过 MediaCodec.createEncoderByType("video/avc") 的形式来创建一个编码器,也可以通过软编 avcodec_find_encoder(AV_CODEC_ID_H264) / avcodec_find_encoder_by_name("libx264") 的形式来创建一个编码器。因为该篇文章的主题是分析 H.264 码流,就不再过多介绍怎么来进行编码了。现在就直接来了解一些常用概念吧。
GOP
两个 I 帧之间形成的一组图片,就是 GOP (Group Of Picture) 的概念。
I 帧
I 帧又称为视频的关键帧,你可以理解为它是一帧画面的完整图像,可以直接拿这个 I 帧来解码
特点:
1、它是一个全帧压缩编码帧,它将全帧图像信息进行 JPEG 压缩编码及传输
2、解码时仅用 I 帧的数据就可以重构完整图像
3、I 帧描述了图像背景和运动主体的详情
4、I 帧不需要参考其它画面而生成
5、I 帧是 P/B 帧的参考帧(其质量直接影响到同组中以后个帧的质量)
6、I 帧是帧组 GOP 的第一帧,在一组中只有一个 I 帧
7、I 帧不需要考虑运动矢量
8、I 帧所占数据的信息量比较大
B 帧
B 帧又称为双向差别帧,也就是本帧与前后帧的差别,大白话的意思就是要解码 B 帧,不仅要拿到之前缓存的画面,还要解码之后的画面,通过前后画面的叠加来还原最终的画面。
特点:
1、B 帧是由前面的 I 帧或 P 帧和后面的 P 帧来进行预测的
2、B 帧传送的是它前面的 I 帧或 P 帧和后面的 P 帧之前的预测误差及运动矢量
3、B 帧是双向预测编码帧
4、B 帧压缩率最高,因为它只反映参考帧间运动主体的变化情况,预测比较准确
5、B 帧不是参考帧,不会造成解码错误的扩散
P 帧
P 帧又称为前预测编码帧。P 帧表示的是这一帧跟之前的一个 I 或 P 帧的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,来生成最终画面。
特点:
1、P 帧是 I 帧后面相隔 1~2 帧的编码帧
2、P 帧采用运动补偿的方法传送它与前面的 I 或 P 真的差值及运动矢量
3、解码时必须将 I 帧中的预测值与预测误差求和后才能重构完整的 P 帧图像
4、P 帧属于前向预测的帧间编码。它只参考前面最靠近它的 I 或者 P 帧
5、P 帧可以是其后面的 P 帧的参考帧,也可以是其前后的 B 帧的参考帧
6、由于 P 帧是参考帧,所以它可能造成解码错误的扩散
7、由于是差值传送,所以 P 帧的压缩率比较高
基本的帧概念了解的差不多了,下一步我们基于代码来分析码流
码流分析
H.264 又称为裸流,是由多个 NALU 组成。如果 NALU 对应的 Slice 为一帧的开始,那么就用 4 个 字节表示,即 0x00 00 00 01 , 否则用 3 字节表示,0x00 00 01。要分析 H.264 码流首先是从码流中搜索起始位,也就是刚刚说的 0x00 00 00 01 或者 0x00 00 01 起始位,然后在分离 NALU, 最后再解析各个字段。下面我们先来看下 NALU Header type 代表的含义:
| type | 说明 |
|---|---|
| 0 | 保留 |
| 1 | 非 IDR 图像中不采用数据划分的片段 |
| 2 | 非 IDR 图像中 A 类数据划分的片段 |
| 3 | 非 IDR 图像中 B 类数据划分的片段 |
| 4 | 非 IDR 图像中 C 类数据划分的片段 |
| 5 | IDR 图像的片段 |
| 6 | 补充增强信心 (SEI) |
| 7 | SPS (序列参数集) |
| 8 | PPS (图像参数集) |
| 9 | 分割符 |
| 10 | 序列结束符 |
| 11 | 流结束符 |
| 12 | 填充数据 |
| 13 | 序列参数集扩展 |
| 14 | 带前缀的 NAL 单元 |
| 15 | 子序列参数集 |
| 16 - 18 | 保留 |
| 19 | 不采用数据划分的辅助编码图像片段 |
| 20 | 编码片段扩展 |
| 21 - 23 | 保留 |
| 24 - 31 | 保留 |
在实际开发中用的最多的也就是 1 、5 、7、8 , 下面我们用代码来进行分析:
代码分析
代码很简单,就是读文件,搜索起始码然后一个字节一个字节读,这里直接贴结果吧
如何进阶学习
成体系的音视频入门进阶的资料少之又少,一个刚毕业小白可能很难切入理解,因为音视频中涉及大量理论知识,而代码的书写需要结合这些理论,所以搞懂音视频,编解码等理论知识至关重要。
本人也是从实习开始接触音视频项目,看过很多人的文章,无意中在GitHub上发现一个标星6.8K的开源项目,在这里分享给大家,让更多准备学习音视频的同学更快入门进阶。
以下是这份开发文档的部分章节:
阶段一:Android多媒体
第1章 三种方式绘制图片
第2章 AudioRecord录制PCM音频
第3章 AudioTrack播放PCM音频
第4章 Camera视频采集
第5章 MediaExtractor MediaMuxer 实现视频的解封装与合成
第6章 MediaCodec硬编解流程与实践

阶段二:OpenGL ES
第7章 OpenGL ES 基本概念
第8章 GLSL及Shader的渲染流程
第9章 OpenGL ES 绘制平面图形
第10章 GLSurfaceView源码解析&EGL环境
第11章 OpenGL ES矩阵变换与坐标系统
第12章 OpenGL ES之纹理
第13章 OpenGL ES 滤镜 (篇一)
第14章 OpenGL ES 实时滤镜
第15章 OpenGL ES粒子系统 - 喷泉
第16章 OpenGL ES粒子效果-烟花爆炸


阶段三::JNI&NDK
第17章 JNI与NDK的学习和使用
第18章 JNI - 引用类型、异常处理、函数注册
第19章 NDK构建方式 ndk-build与cmake
第20章 指针、内存模型、引用
第21章 运算符重载、继承、多态、模版
第22章 STL 之 容器


子系列 算法
第23章 算法系列 - 冒泡排序
第24章 算法系列-快速排序
第25章 算法系列-堆排序
第26章 算法系列-选择、插入排序以及STL中sort的实现
第27章 算法序列 - 二叉查找树
第28章 算法序列 - 平衡二叉树
第29章 算法序列 - 散列表

阶段四 : FFmpeg
第30章 音视频基础知识
第31章 FFMPEG常用命令
第32章 FFMPEG +OPENSL ES实现音频解码和播放
第33章 FFMPEG + OPENGLES 边解码边播放视频

有需要的朋友可以【点击此处】找我免费领取。
小结
音视频行业已经发展很多年了,随着近几年移动端越来越多的音视频APP的出现,将音视频推向一个高潮,但是由于音视频的学习成本很高,很多开发者望而却步,为了跟紧时代的步伐,需要的朋友可以免费获取一下上文的资料,给大家破除音视频的“高门槛”,希望可以共同进步。
总之,音视频已经强势崛起,相信未来的十年一定是音视频的十年。并且将音视频技术与计算机视觉和人工智能结合将引领未来二十年。
以后我将多多分享相关文章,关注我不要迷路!
现在正是学习音视技术的最佳时机,大家一定要把握住机会,跟上时代的步伐,让自己可以在未来大有作为。
音视频开发之H.264 入门知识的更多相关文章
- WebRTC 音视频开发之路
早在2014年就通过WebRTC实现了PC客户端的实时视频语音,那时P2P连接的建立使用的WebRTC自带的libjingle库,使用peerconnection的API实现的.后来在做远程桌面,文件 ...
- 直播平台搭建之音视频开发:认识主流视频编码技术H.264
H.264简介 什么是H.264?H.264是一种高性能的视频编解码技术.目前国际上制定视频编解码技术的组织有两个,一个是"国际电联",它制定的标准有H.261.H.263.H.2 ...
- 【秒懂音视频开发】23_H.264编码
本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...
- FFMPEG学习----分离视频里的H.264与YUV数据
#include <stdio.h> extern "C" { #include "libavcodec/avcodec.h" #include & ...
- 李洪强iOS开发之OC语言基础知识
OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能 ...
- cocos2dx实例开发之flappybird(入门版)
cocos2dx社区里有个系列博客完整地复制原版flappybird的全部特性.只是那个代码写得比較复杂,新手学习起来有点捉摸不透,这里我写了个简单的版本号.演演示样例如以下: watermark/2 ...
- iOS开发之Auto Layout入门(转)
随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享. 什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新 ...
- android开发之gridlayout使用入门
这个东东以前没怎么用过,今天研究了一下,不难,感觉只是在某些方面很好用. 记录下,做个计算器. <GridLayout xmlns:android="http://schemas.an ...
- python 小白(无编程基础,无计算机基础)的开发之路,辅助知识6 python字符串/元组/列表/字典互转
神奇的相互转换,小白同学可以看看,很有帮助 #1.字典dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type ...
随机推荐
- Unity StateMachineBehaviour
在unity animator中单个Animator Clip中点击Add Behaviour增加当执行该动画时的一些状态代码,请看如下 创建完之后基本代码结构如下:(如果想修改默认代码结构,请看示例 ...
- Kubernetes中予许及限制(PodSecurityPolicy)使用宿主机资源
1.在pod中使用宿主机命名空间.端口等资源 pod中的容器通常在分开的Linux命名空间中运行.这些命名空间将容器中的进程与其他容器中,或者宿主机默认命名空间中的进程隔离开来. 例如,每一个pod有 ...
- 从零开始学前端,React框架背后的核心机制和原理JSX
什么是React React是起源于Facebook的一个前端框架,用于构建用户界面的JavaScript库,Facebook用来探索一种更加高效优雅的Javascript MVC框架来架设Insta ...
- 最新的.NET 热重载介绍
今天,我们很高兴的向您介绍 Visual Studio 2019 版本 16.11(预览版 1)和 .NET 6 中的 dotnet watch 命令行工具(预览版 4)中的 .NET 热重载体验的可 ...
- Quartz和Spring Task定时任务的简单应用和比较
看了两个项目,一个用的是Quartz写的定时器,一个是使用spring的task写的,网上看了2篇文章,写的比较清楚,这里做一下留存 链接一.菠萝大象:http://www.blogjava.net/ ...
- 基于redis的分布式锁防止高并发重复请求
需求: 我们先举个某系统验证的列子:(A渠道系统,业务B系统,外部厂商C系统)(1)B业务系统调用A渠道系统,验证传入的手机.身份证.姓名三要素是否一致.(2)A渠道系统再调用外部厂商C系统.(3)A ...
- Oracle_RAC共享存储
<<ASM.sh>> 第2-3步可以使用"附件ASM.sh"脚本执行 此操作说明,此操作在2个节点都执行(可以复制) 编辑/etc/scsi_id.conf ...
- AspNetCore&MassTransit Courier实现分布式事务
在之前的一篇博文中,CAP框架可以方便我们实现非实时.异步场景下的最终一致性,而有些用例总是无法避免的需要在实时.同步场景下进行,可以借助Saga事务来解决这一困扰.在一些博文和仓库中也搜寻到了.Ne ...
- Linux下如何使用Rsync备份服务器重要数据
Rsync介绍: Rsync英文全称Remote synchronization,从软件的名称就可以看出来,Rsync具有可使本地和远程两台主机之间的数据快速复制同步镜像,远程备份的功能,这个功能类似 ...
- JAVA入门基础及流程控制
JAVA入门基础及流程控制 数据类型 位 存储单位 eg:0001 0011 八位 字节 byte 处理数据单位 一字节等于八位 eg:1b=0011 0001 类变量: static int num ...