1.h.264����Դ��
2.H264 NALU分析
3.H.264çç¼ç å解ç
4.H264 视频码流分析
5.ffmpeg解码h264,码源码画面很模糊?
h.264����Դ��
需求 在移动端做音视频开发不同于基本的UI业务逻辑工作,音视频开发需要你懂得音视频中一些基本概念,针对编解码而言,我们必须提前懂得编解码器的一些特性,码流的结构,码流中一些重要信息如sps,pps,vps,start code以及基本的工作原理,而大多同学都只是一知半解,所以导致代码中的部分内容虽可以简单理解却不知其意,所以,在这里总结出了当前主流的H.,H.编码相关的原理,以供学习.
1. 概览
编码技术的主要目标是减少音视频数据的存储和传输需求,而不会显著影响质量。码源码编码涉及将原始数据压缩成更紧凑的码源码形式,然后解码将压缩数据还原为原始形式。码源码编码和解码的码源码过程依赖于特定的算法,如H.和H.,码源码小甲鱼c 源码它们用于视频数据。码源码
1.1. 为什么要编码
原始视频数据量非常庞大。码源码例如,码源码一个P fps的码源码视频,每秒钟产生大约MB的码源码数据。因此,码源码直接在网络中传输原始视频数据是码源码不可行的。视频编码技术通过压缩数据来减少其大小,码源码使网络传输和存储成为可能。码源码
1.2. 编码技术
经过多年的开发,出现了多种高效的编码技术。H.和H.是目前主流的视频编码标准。此外,谷歌开发了VP8和VP9。对于移动设备,苹果提供了VideoToolbox框架来实现这些编码。完美重启源码
1.3. 编码分类
H.和H.编码各有优缺点。H.(HEVC)通常提供更高的压缩比和更好的图像质量,但计算需求也更高。
1.4. 编码原理
编码过程将原始视频数据压缩成三种基本帧类型:I帧(Intra)、P帧(Predictive)和B帧(Bi-directional)。I帧独立编码,P帧依赖于前一帧,B帧依赖于前后帧。这些帧类型有助于高效压缩视频数据。
补充: I帧的压缩率大约为7,与JPG相似;P帧的压缩率约为;B帧的压缩率可达。iOS系统中一般不开启B帧,以避免时间戳同步的复杂性。
两种核心算法
帧内压缩和帧间压缩是视频编码的两大核心算法。帧内压缩独立处理每一帧,而帧间压缩利用帧间的相似性减少数据量。帧间压缩算法,如帧差值,比较相邻帧之间的差异,只记录差异值,从而显著减少数据。御林军分时源码
有损压缩与无损压缩
有损压缩会减少一些信息以获得更高的压缩率,如H.和H.;无损压缩保持原始数据的完整性,但通常不能达到相同的压缩率。
DTS和PTS
解码器使用DTS(Decoding Time Stamp)和PTS(Presentation Time Stamp)来管理视频的呈现时间。I帧的解码不需要任何依赖,而P帧依赖于前一帧的I帧或P帧,B帧依赖于前一帧的I帧或P帧和后一帧的P帧。
编码数据码流结构
视频不仅仅是一系列静态图像的集合,而是包含帧、顶场和底场的动态序列。编码码流中的“图像”是集合的概念,包括I帧、P帧和B帧。VPS(Video Parameter Set)、SPS(Sequence Parameter Set)和PPS(Picture Parameter Set)是关键参数集,分别用于传输视频参数、序列参数和图像参数。
编码数据的组织
原始视频数据通过一系列NALU(Network Abstraction Layer Unit)单元进行组织。每个NALU单元可能包含图像数据和编码器参数信息。NALU有Annex B和AVCC两种封装格式,分别以起始码和长度作为分隔符。火狐源码github
iOS中的视频编解码
在iOS中,视频处理框架分为多个层次,选择框架时需要根据实际需求考虑可定制性和使用难度。VideoToolbox框架允许直接访问硬件加速的编解码器,实现对H.文件或传输流的编码和解码。
编码数据裸流处理
在编码后的数据中,需要添加起始码以区分不同NALU单元。在iOS中,使用VTCompressionSession编码的数据可能缺少起始码,需要在推流前自行添加。
将H.裸流解码为CMSampleBuffer
从H.码流中提取关键信息(SPS、PPS和VPS)并转换为CMSampleBuffer格式,以便于解码工作。CMSampleBuffer包含时间信息、格式描述和数据缓冲区,是iOS中处理视频数据的标准形式。
显示CMSampleBuffer到界面
将解码后的CMSampleBuffer数据渲染到屏幕上,可以采用两种方式:直接渲染或通过AVPlayer或其他播放器框架显示。
H NALU分析
H简介
H.从年开始开发,于年形成草案,年正式定稿。主机平台源码它在ITU标准中被称为H.,在MPEG标准中是MPEG-4的一部分,即MPEG-4 Part ,也称为Advanced Video Codec,简称AVC。
H编码原理
H.通过帧内压缩和帧间压缩提高编码效率,支持I帧、P帧和B帧来实现连续帧之间的压缩。I帧不依赖任何其他帧,P帧和B帧则利用与前一帧或后一帧的相似性进行压缩。
H中的I帧、P帧和B帧
H.使用I帧、P帧和B帧策略进行连续帧之间的压缩,I帧独立编码,P帧和B帧依赖于前一帧或后一帧。
H编码结构解析
H.组织为序列(GOP)、、片、宏块和子块五个层次,提供编码和分片策略,方便网络传输。GOP指两个I帧之间的间隔,Reference指两个P帧之间的距离。
IDR图像的核心作用
IDR图像用于解码重同步,其后图像不再使用IDR帧的数据进行解码,提供解码错误恢复机会。
H码流举例
码流分析表明B帧不能作为参考帧。
GOP结构
GOP表示两个I帧之间的距离,影响编码效率和图像质量。设置合理可平衡码率、图像质量和编码效率。
NALU解析
NALU分为VCL和NAL单元,其中SPS和PPS是关键参数集,I帧、P帧和B帧分别代表帧内编码、前向预测和双向预测编码。
H NALU结构
NALU由起始码、头部信息和原始字节序列负荷组成,头部信息包括NALU类型、参考标识和禁止位。
H的annexb模式与mp4模式
annexb模式有起始码,适用于传统编码,而mp4模式无起始码,SPS和PPS等信息在容器中封装,适用于现代编码格式。
H编码优化与学习资源
优化H编码并获取学习资料,请访问企鹅裙 ,领取C++音视频学习包,内容覆盖音视频开发、面试题、FFmpeg、WebRTC等。
H.çç¼ç å解ç
请åè§ï¼å表çç §ç¸æºä¸æ¿è½½è§é¢æµç¼ç å 为 H. ç¼ç å解ç è¦æ±å¤§éç计ç®è½åå¨ç¹å®ç±»åçç®æ¯è¿ç®ï¼å¨éç¨ Cpu è¿è¡ç软件å®ç°é«æçé常è¾å°åéãä¸è¿ï¼ææ°çåæ ¸éç¨ x Cpu æ足å¤ç计ç®è½åæ¥æ§è¡å®æ¶æ æ¸ åé«æ¸ ç¼ç ãå缩æçåå³äºè§é¢çç®æ³å®ç°ï¼ä¸å¨æ¯å¦ä½¿ç¨ç¡¬ä»¶æ软件æ¥å®ç°ãå æ¤ï¼ç¡¬ä»¶å软件åºäºçæ§è¡æ´æ¯çµæºæçã çµæ´»æ§åææ¬ä¹é´çå·®å¼ã为æé«çµæºæçååå°ç¡¬ä»¶å½¢å¼å ç´ ï¼å¯è½éç¨ä¸ç¨ç¡¬ä»¶ï¼ä¸ºå®æ´çç¼ç æ解ç è¿ç¨ä¸ï¼æå¨ CPU æ§å¶çç¯å¢å å éæ´å©ã
åºäº CPU ç解å³åæ³æ¯å·²ç¥æ¯çµæ´»å¾å¤ï¼å°¤å ¶æ¯ç¼ç å¿ é¡»è¿è¡æ¶åæ¶å¤æ ¼å¼ã å¤æ¯ç¹çåå项å³è®® ï¼å¤å±å¹è§é¢ï¼ åå¯è½ç¨ä¸ç容å¨æ ¼å¼æ¯æçéå åè½ï¼å è¿ç»¼åç广ååè½çãåºäº CPU ç软件解å³æ¹æ¡é常使å¾æ´å®¹æå¨ç¸åç CPU å çå¤ä¸ªå¹¶åç¼ç ä¼è¯è¿è¡è´è½½å¹³è¡¡ã
ä»ç»äºå¨ å¹´ 1 æ CES ï¼æ¶è´¹çµåå±) ç第 2 代è±ç¹å°æ¡è¿ªæ¡¥é ·ç¿ i3/i5/i7å¤çå¨æä¾ç§°ä¸ºè±ç¹å°å¿«éåæ¥è§é¢ä¸è¯çç¡¬ä»¶å ¨é¢é«æ¸ H. ç¼ç å¨ã
硬件 H. ç¼ç å¨å¯ä»¥æ¯ASICæFPGAãFPGA æ¯ä¸ä¸ªä¸è¬çå¯ç¼ç¨è¯çãè¦ä½¿ç¨ FPGA ä½ä¸ºç¡¬ä»¶ç¼ç å¨ï¼H. ç¼ç å¨è®¾è®¡éè¦èªå®ä¹åºç¨ç¨åºçè¯çãå®æ´çé«æ¸ H. ç¼ç å¨å¯ä»¥å¨ä¸ä¸ªåä¸çä½ææ¬ FPGA è¯çä¸è¿è¡ å¹´ (é«é ç½®æ件ã æ°´å¹³ 4.1ï¼pï¼ å¸§/ç§)ã
ASIC ç¼ç å¨ä¸ H. ç¼ç å¨åè½ï¼å¯ä»è®¸å¤ä¸åçå导ä½å ¬å¸ï¼ä½å¨ ASIC ä¸ä½¿ç¨çæ ¸å¿è®¾è®¡é常ç±è¯çååªä½ï¼ On2 (å Hantroï¼ç±è°·ææ¶è´ï¼ï¼æ³è±¡åçææ¯ï¼NGCodec çå ä¸ªå ¬å¸çä¸ä¸ªææãä¸äºå ¬å¸å·²æä¾ç FPGA å ASIC 产åã
å¾·å·ä»ªå¨ç产ä¸çº¿çARM+ æ§è¡ DSP H BP ç DSP å æ ¸ç¼ç p 帧æ¯ç§ãè¿å 许 ï¼å ¶ä¸ï¼ä½ä¸ºé«åº¦ä¼åç DSP 代ç å®ç°ï¼ çç¼è§£ç å¨ççµæ´»æ§æ¶æ£å¨æ¯éç¨ CPU ä¸ç软件æçæ´é«ã
H 视频码流分析
H 视频码流解析
NAL层,即网络抽象层,负责在H编码视频在网络上传输时的拆包和组包操作。每个帧被拆成多个包进行传输,所有拆包与组包操作皆由NAL层处理。
VCL层,视频数据编码层,对原始视频数据进行压缩处理。
视频帧序列中,每一帧图像由多个Slice组成,在实际传输中,一帧图像通常就是一个Slice,不作进一步细分。
SODB(原始数据比特流)由VCL层产生,数据长度可能不是8的倍数,处理较为复杂。
RBSP(原始字节序列载荷)是将SODB加上后续位后的编码数据流,在编码数据最后一位补1,不按字节对齐补0,以确保数据流的完整性。
EBSP(封装字节序列载荷)在生成编码数据流后,在每个帧前添加起始位,通常为十六进制的,以区分帧的开始。预防数据与起始位冲突,如出现连续两个0x,则额外增加一个0x。
NALU(NAL单元)由EBSP加上网络头部构成,是H码流的基本组成单位。
Slice与宏块分层在VCL层中,切片由头和数据组成,数据包含多个宏块,宏块内存储类型、预测值和残差值等信息。
H编码视频序列包括一系列NAL单元,每个单元包含一个RBSP。原始H. NALU单元通常由[StartCode]、[NALU头部]和[NALU负载]三部分组成,StartCode用于标示NALU单元开始,必须为" "或" "。
NAL头部编码用于表示RBSP信息,包含种格式,占一个字节,由三部分组成:forbidden_bit、nal_reference_bit和nal_unit_type。
forbidden_bit禁止位,nal_reference_bit表示当前NAL的优先级,nal_unit_type表示NAL类型。
IDR帧(关键帧)的作用是即时刷新,防止解码错误传播,从IDR帧开始新序列编码。I帧不能被跨帧参考,但IDR帧不允许使用IDR之前的图像数据解码。
IDR帧核心作用是重同步,当解码器解码到IDR图像时,清除参考帧队列,重新查找参数集,开始新序列,避免前一序列重大错误影响解码。
H码流由一个个NAL单元组成,包括SPS、PPS、IDR和SLICE类型数据,由NAL头部定义。
SPS和PPS分别包含序列参数集和图像参数集,SPS包含如视频尺寸、参考帧数等通用参数,PPS包含熵编码类型、有效参考图像数等参数。
指数哥伦布编码是熵编码的一种,通过对出现概率较大的符号使用较短码长,较小概率符号使用较长码长进行数据压缩,减少冗余。
网络传输时,以等长编码方式会增加大量冗余,使用有效字节传输能大幅减少冗余。指数哥伦布编码能有效压缩数据,并方便解码,提高网络传输效率。
ffmpeg解码h,画面很模糊?
在FFmpeg中,处理H编码的视频时,通常需要将其转换为YUVP格式,这是为了优化解码和渲染过程。本文将详细解释如何进行这一转换。在YUV格式中,每个像素由一个亮度(Y)值和两个颜色(U和V)值组成,分别代表蓝色差和红色差。具体来说,对于八个像素,格式如下:
八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3][Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8]
码流为:Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8
经过映射后,像素点变为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7][Y5 U0 V5] [Y6 U0 V5] [Y7U2 V7] [Y8 U2 V7]
值得注意的是,每个字节代表8个像素。
为了更好地理解这一过程,可以画一个矩阵进行直观表示。矩阵显示了码流数据(以4:2:0比例存储)与最终映射像素点之间的对应关系。
理解上述过程后,我们需要使用FFmpeg来将H帧解码为YUV格式。首先,初始化FFmpeg环境:
代码示例:
然后,将H帧传递给解码器进行解码,输出为YUV数据:
代码示例:
为了加深理解,推荐观看以下相关视频教程:
LinuxC++音视频开发视频: 免费FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
文章福利:音视频学习资料、视频和学习路线图资料、以及面试题(资料包括C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等),免费分享,有需要的可以加君羊领取哦! ~学习交流裙加入领取资料
通过调用`decoderObj.pYuvFrame.data[0]`,我们可以获取到YUV数据。最后,不要忘记释放内存:
代码示例:
为了验证解码过程,可以使用`ffplay`指令播放一帧YUV数据:
需要强调的是,`avcodec_decode_video2`函数可能会修改codec_结构体中的参数,例如将原始设置的分辨率更改为实际视频的分辨率。