h264_h264编码 - CSDN
h264 订阅
H.264,同时也是MPEG-4第十部分,是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。这个标准通常被称之为H.264/AVC(或者AVC/H.264或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)而明确的说明它两方面的开发者。H264标准各主要部分有Access Unit delimiter(访问单元分割符),SEI(附加增强信息),primary coded picture(基本图像编码),Redundant Coded Picture(冗余图像编码)。还有Instantaneous Decoding Refresh(IDR,即时解码刷新)、Hypothetical Reference Decoder(HRD,假想参考解码)、Hypothetical Stream Scheduler(HSS,假想码流调度器)。 展开全文
H.264,同时也是MPEG-4第十部分,是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。这个标准通常被称之为H.264/AVC(或者AVC/H.264或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)而明确的说明它两方面的开发者。H264标准各主要部分有Access Unit delimiter(访问单元分割符),SEI(附加增强信息),primary coded picture(基本图像编码),Redundant Coded Picture(冗余图像编码)。还有Instantaneous Decoding Refresh(IDR,即时解码刷新)、Hypothetical Reference Decoder(HRD,假想参考解码)、Hypothetical Stream Scheduler(HSS,假想码流调度器)。
信息
属    性
数字视频压缩格式
属    于
MPEG-4第十部分
中文名
H.264
主要部分
访问单元分割符
H.264背景介绍
H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式。H.264是ITU-T以H.26x系列为名称命名的视频编解码技术标准之一。H.264是ITU-T的VCEG(视频编码专家组)和ISO/IEC的MPEG(活动图像编码专家组)的联合视频组(JVT:joint video team)开发的一个数字视频编码标准。该标准最早来自于ITU-T的称之为H.26L的项目的开发。H.26L这个名称虽然不太常见,但是一直被使用着。H.264是ITU-T以H.26x系列为名称命名的标准之一,AVC是ISO/IEC MPEG一方的称呼。国际上制定视频编解码技术的组织有两个,一个是“国际电联(ITU-T)”,它制定的标准有H.261、H.263、H.263+等,另一个是“国际标准化组织(ISO)”它制定的标准有MPEG-1、MPEG-2、MPEG-4等。而H.264则是由两个组织联合组建的联合视频组(JVT)共同制定的新数字视频编码标准,所以它既是ITU-T的H.264,又是ISO/IEC的MPEG-4高级视频编码(Advanced Video Coding,AVC)的第10 部分。因此,不论是MPEG-4 AVC、MPEG-4 Part 10,还是ISO/IEC 14496-10,都是指H.264。1998年1月份标准开始草案征集,1999年9月,完成第一个草案,2001年5月制定了其测试模式TML-8,2002年6月的 JVT第5次会议通过了H.264的FCD板。2003年3月正式发布。在2005年又开发出了H.264的更高级应用标准MVC 和 SVC 版本。国际电联ITU和MPEG组织在发布了H.264标准之后,很快就发布公告,为下一代视频编解码标准H.265征集技术方案。为H.265设定的技术性能指标是:压缩效率比H.264提高1倍、且不明显提高编码和解码的计算量。据MPEG组织2009年西安会议的回顾,尚无一个技术提案达到上述指标。H.264是在MPEG-4技术的基础之上建立起来的,其编解码流程主要包括5个部分:帧间和帧内预测(Estimation)、变换(Transform)和反变换、量化(Quantization)和反量化、环路滤波(Loop Filter)、熵编码(Entropy Coding)。H.264标准的主要目标是:与其它现有的视频编码标准相比,在相同的带宽下提供更加优秀的图象质量。通过该标准,在同等图象质量下的压缩效率比以前的标准(MPEG2)提高了2倍左右。H.264可以提供11个等级、7个类别的子协议格式(算法),其中等级定义是对外部环境进行限定,例如带宽需求、内存需求、网络性能等等。等级越高,带宽要求就越高,视频质量也越高。类别定义则是针对特定应用,定义编码器所使用的特性子集,并规范不同应用环境中的编码器复杂程度。
收起全文
精华内容
参与话题
  • H.264/AVC视频编解码技术详解

    万人学习 2019-12-29 17:40:12
    本课程将从原理、标准和实现等多个角度,详细讲述了H.264/AVC视频编码标准的整体架构与技术细节,不但讲解了H.264/AVC标准协议文档中的内容,还通过实际的H.264码流分析/解码程序的开发来帮助观众更深入地理解H.264...
  • 视音频数据处理入门:H.264视频码流解析

    万次阅读 多人点赞 2016-02-01 01:24:08
    前两篇文章介绍的YUV/RGB处理程序以及PCM处理程序都属于视音频...该程序可以从H.264码流中分析得到它的基本单元NALU,并且可以简单解析NALU首部的字段。通过修改该程序可以实现不同的H.264码流处理功能。原理H.264

    =====================================================

    视音频数据处理入门系列文章:

    视音频数据处理入门:RGB、YUV像素数据处理

    视音频数据处理入门:PCM音频采样数据处理

    视音频数据处理入门:H.264视频码流解析

    视音频数据处理入门:AAC音频码流解析

    视音频数据处理入门:FLV封装格式解析

    视音频数据处理入门:UDP-RTP协议解析

    =====================================================


    前两篇文章介绍的YUV/RGB处理程序以及PCM处理程序都属于视音频原始数据的处理程序。从本文开始介绍视音频码流的处理程序。本文介绍的程序是视频码流处理程序。视频码流在视频播放器中的位置如下所示。


    本文中的程序是一个H.264码流解析程序。该程序可以从H.264码流中分析得到它的基本单元NALU,并且可以简单解析NALU首部的字段。通过修改该程序可以实现不同的H.264码流处理功能。


    原理

    H.264原始码流(又称为“裸流”)是由一个一个的NALU组成的。他们的结构如下图所示。


    其中每个NALU之间通过startcode(起始码)进行分隔,起始码分成两种:0x000001(3Byte)或者0x00000001(4Byte)。如果NALU对应的Slice为一帧的开始就用0x00000001,否则就用0x000001。

    H.264码流解析的步骤就是首先从码流中搜索0x000001和0x00000001,分离出NALU;然后再分析NALU的各个字段。本文的程序即实现了上述的两个步骤。


    代码

    整个程序位于simplest_h264_parser()函数中,如下所示。
    /**
     * 最简单的视音频数据处理示例
     * Simplest MediaData Test
     *
     * 雷霄骅 Lei Xiaohua
     * leixiaohua1020@126.com
     * 中国传媒大学/数字电视技术
     * Communication University of China / Digital TV Technology
     * http://blog.csdn.net/leixiaohua1020
     *
     * 本项目包含如下几种视音频测试示例:
     *  (1)像素数据处理程序。包含RGB和YUV像素格式处理的函数。
     *  (2)音频采样数据处理程序。包含PCM音频采样格式处理的函数。
     *  (3)H.264码流分析程序。可以分离并解析NALU。
     *  (4)AAC码流分析程序。可以分离并解析ADTS帧。
     *  (5)FLV封装格式分析程序。可以将FLV中的MP3音频码流分离出来。
     *  (6)UDP-RTP协议分析程序。可以将分析UDP/RTP/MPEG-TS数据包。
     *
     * This project contains following samples to handling multimedia data:
     *  (1) Video pixel data handling program. It contains several examples to handle RGB and YUV data.
     *  (2) Audio sample data handling program. It contains several examples to handle PCM data.
     *  (3) H.264 stream analysis program. It can parse H.264 bitstream and analysis NALU of stream.
     *  (4) AAC stream analysis program. It can parse AAC bitstream and analysis ADTS frame of stream.
     *  (5) FLV format analysis program. It can analysis FLV file and extract MP3 audio stream.
     *  (6) UDP-RTP protocol analysis program. It can analysis UDP/RTP/MPEG-TS Packet.
     *
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef enum {
    	NALU_TYPE_SLICE    = 1,
    	NALU_TYPE_DPA      = 2,
    	NALU_TYPE_DPB      = 3,
    	NALU_TYPE_DPC      = 4,
    	NALU_TYPE_IDR      = 5,
    	NALU_TYPE_SEI      = 6,
    	NALU_TYPE_SPS      = 7,
    	NALU_TYPE_PPS      = 8,
    	NALU_TYPE_AUD      = 9,
    	NALU_TYPE_EOSEQ    = 10,
    	NALU_TYPE_EOSTREAM = 11,
    	NALU_TYPE_FILL     = 12,
    } NaluType;
    
    typedef enum {
    	NALU_PRIORITY_DISPOSABLE = 0,
    	NALU_PRIRITY_LOW         = 1,
    	NALU_PRIORITY_HIGH       = 2,
    	NALU_PRIORITY_HIGHEST    = 3
    } NaluPriority;
    
    
    typedef struct
    {
    	int startcodeprefix_len;      //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)
    	unsigned len;                 //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)
    	unsigned max_size;            //! Nal Unit Buffer size
    	int forbidden_bit;            //! should be always FALSE
    	int nal_reference_idc;        //! NALU_PRIORITY_xxxx
    	int nal_unit_type;            //! NALU_TYPE_xxxx    
    	char *buf;                    //! contains the first byte followed by the EBSP
    } NALU_t;
    
    FILE *h264bitstream = NULL;                //!< the bit stream file
    
    int info2=0, info3=0;
    
    static int FindStartCode2 (unsigned char *Buf){
    	if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=1) return 0; //0x000001?
    	else return 1;
    }
    
    static int FindStartCode3 (unsigned char *Buf){
    	if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=0 || Buf[3] !=1) return 0;//0x00000001?
    	else return 1;
    }
    
    
    int GetAnnexbNALU (NALU_t *nalu){
    	int pos = 0;
    	int StartCodeFound, rewind;
    	unsigned char *Buf;
    
    	if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL) 
    		printf ("GetAnnexbNALU: Could not allocate Buf memory\n");
    
    	nalu->startcodeprefix_len=3;
    
    	if (3 != fread (Buf, 1, 3, h264bitstream)){
    		free(Buf);
    		return 0;
    	}
    	info2 = FindStartCode2 (Buf);
    	if(info2 != 1) {
    		if(1 != fread(Buf+3, 1, 1, h264bitstream)){
    			free(Buf);
    			return 0;
    		}
    		info3 = FindStartCode3 (Buf);
    		if (info3 != 1){ 
    			free(Buf);
    			return -1;
    		}
    		else {
    			pos = 4;
    			nalu->startcodeprefix_len = 4;
    		}
    	}
    	else{
    		nalu->startcodeprefix_len = 3;
    		pos = 3;
    	}
    	StartCodeFound = 0;
    	info2 = 0;
    	info3 = 0;
    
    	while (!StartCodeFound){
    		if (feof (h264bitstream)){
    			nalu->len = (pos-1)-nalu->startcodeprefix_len;
    			memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);     
    			nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bit
    			nalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bit
    			nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bit
    			free(Buf);
    			return pos-1;
    		}
    		Buf[pos++] = fgetc (h264bitstream);
    		info3 = FindStartCode3(&Buf[pos-4]);
    		if(info3 != 1)
    			info2 = FindStartCode2(&Buf[pos-3]);
    		StartCodeFound = (info2 == 1 || info3 == 1);
    	}
    
    	// Here, we have found another start code (and read length of startcode bytes more than we should
    	// have.  Hence, go back in the file
    	rewind = (info3 == 1)? -4 : -3;
    
    	if (0 != fseek (h264bitstream, rewind, SEEK_CUR)){
    		free(Buf);
    		printf("GetAnnexbNALU: Cannot fseek in the bit stream file");
    	}
    
    	// Here the Start code, the complete NALU, and the next start code is in the Buf.  
    	// The size of Buf is pos, pos+rewind are the number of bytes excluding the next
    	// start code, and (pos+rewind)-startcodeprefix_len is the size of the NALU excluding the start code
    
    	nalu->len = (pos+rewind)-nalu->startcodeprefix_len;
    	memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);//
    	nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bit
    	nalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bit
    	nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bit
    	free(Buf);
    
    	return (pos+rewind);
    }
    
    /**
     * Analysis H.264 Bitstream
     * @param url    Location of input H.264 bitstream file.
     */
    int simplest_h264_parser(char *url){
    
    	NALU_t *n;
    	int buffersize=100000;
    
    	//FILE *myout=fopen("output_log.txt","wb+");
    	FILE *myout=stdout;
    
    	h264bitstream=fopen(url, "rb+");
    	if (h264bitstream==NULL){
    		printf("Open file error\n");
    		return 0;
    	}
    
    	n = (NALU_t*)calloc (1, sizeof (NALU_t));
    	if (n == NULL){
    		printf("Alloc NALU Error\n");
    		return 0;
    	}
    
    	n->max_size=buffersize;
    	n->buf = (char*)calloc (buffersize, sizeof (char));
    	if (n->buf == NULL){
    		free (n);
    		printf ("AllocNALU: n->buf");
    		return 0;
    	}
    
    	int data_offset=0;
    	int nal_num=0;
    	printf("-----+-------- NALU Table ------+---------+\n");
    	printf(" NUM |    POS  |    IDC |  TYPE |   LEN   |\n");
    	printf("-----+---------+--------+-------+---------+\n");
    
    	while(!feof(h264bitstream)) 
    	{
    		int data_lenth;
    		data_lenth=GetAnnexbNALU(n);
    
    		char type_str[20]={0};
    		switch(n->nal_unit_type){
    			case NALU_TYPE_SLICE:sprintf(type_str,"SLICE");break;
    			case NALU_TYPE_DPA:sprintf(type_str,"DPA");break;
    			case NALU_TYPE_DPB:sprintf(type_str,"DPB");break;
    			case NALU_TYPE_DPC:sprintf(type_str,"DPC");break;
    			case NALU_TYPE_IDR:sprintf(type_str,"IDR");break;
    			case NALU_TYPE_SEI:sprintf(type_str,"SEI");break;
    			case NALU_TYPE_SPS:sprintf(type_str,"SPS");break;
    			case NALU_TYPE_PPS:sprintf(type_str,"PPS");break;
    			case NALU_TYPE_AUD:sprintf(type_str,"AUD");break;
    			case NALU_TYPE_EOSEQ:sprintf(type_str,"EOSEQ");break;
    			case NALU_TYPE_EOSTREAM:sprintf(type_str,"EOSTREAM");break;
    			case NALU_TYPE_FILL:sprintf(type_str,"FILL");break;
    		}
    		char idc_str[20]={0};
    		switch(n->nal_reference_idc>>5){
    			case NALU_PRIORITY_DISPOSABLE:sprintf(idc_str,"DISPOS");break;
    			case NALU_PRIRITY_LOW:sprintf(idc_str,"LOW");break;
    			case NALU_PRIORITY_HIGH:sprintf(idc_str,"HIGH");break;
    			case NALU_PRIORITY_HIGHEST:sprintf(idc_str,"HIGHEST");break;
    		}
    
    		fprintf(myout,"%5d| %8d| %7s| %6s| %8d|\n",nal_num,data_offset,idc_str,type_str,n->len);
    
    		data_offset=data_offset+data_lenth;
    
    		nal_num++;
    	}
    
    	//Free
    	if (n){
    		if (n->buf){
    			free(n->buf);
    			n->buf=NULL;
    		}
    		free (n);
    	}
    	return 0;
    }
    

    上文中的函数调用方法如下所示。
    simplest_h264_parser("sintel.h264");

    结果

    本程序的输入为一个H.264原始码流(裸流)的文件路径,输出为该码流的NALU统计数据,如下图所示。


    下载


    Simplest mediadata test


    项目主页

    SourceForge:https://sourceforge.net/projects/simplest-mediadata-test/

    Github:https://github.com/leixiaohua1020/simplest_mediadata_test

    开源中国:http://git.oschina.net/leixiaohua1020/simplest_mediadata_test


    CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/9422409


    本项目包含如下几种视音频数据解析示例:

     (1)像素数据处理程序。包含RGB和YUV像素格式处理的函数。
     (2)音频采样数据处理程序。包含PCM音频采样格式处理的函数。
     (3)H.264码流分析程序。可以分离并解析NALU。
     (4)AAC码流分析程序。可以分离并解析ADTS帧。
     (5)FLV封装格式分析程序。可以将FLV中的MP3音频码流分离出来。
     (6)UDP-RTP协议分析程序。可以将分析UDP/RTP/MPEG-TS数据包。


    雷霄骅 (Lei Xiaohua)
    leixiaohua1020@126.com
    http://blog.csdn.net/leixiaohua1020


    展开全文
  • H264基本原理

    万次阅读 多人点赞 2017-11-15 02:25:54
    H264视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的。随着 x264/openh264以及ffmpeg等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大降低了人们使用H264的成本。但为了用好H264,...

    前言

    H264视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的。随着 x264/openh264以及ffmpeg等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大降低了人们使用H264的成本。

    但为了用好H264,我们还是要对H264的基本原理弄清楚才行。今天我们就来看看H264的基本原理。

    H264概述

    H264压缩技术主要采用了以下几种方法对视频数据进行压缩。包括:

    • 帧内预测压缩,解决的是空域数据冗余问题。
    • 帧间预测压缩(运动估计与补偿),解决的是时域数据冗徐问题。
    • 整数离散余弦变换(DCT),将空间上的相关性变为频域上无关的数据然后进行量化。
    • CABAC压缩。

    经过压缩后的帧分为:I帧,P帧和B帧:

    • I帧:关键帧,采用帧内压缩技术。
    • P帧:向前参考帧,在压缩时,只参考前面已经处理的帧。采用帧音压缩技术。
    • B帧:双向参考帧,在压缩时,它即参考前而的帧,又参考它后面的帧。采用帧间压缩技术。

    除了I/P/B帧外,还有图像序列GOP。

    • GOP:两个I帧之间是一个图像序列,在一个图像序列中只有一个I帧。如下图所示:

    下面我们就来详细描述一下H264压缩技术。

    H264压缩技术

    H264的基本原理其实非常简单,下我们就简单的描述一下H264压缩数据的过程。通过摄像头采集到的视频帧(按每秒 30 帧算),被送到 H264 编码器的缓冲区中。编码器先要为每一幅图片划分宏块。

    以下面这张图为例:

    划分宏块

    H264默认是使用 16X16 大小的区域作为一个宏块,也可以划分成 8X8 大小。

    划分好宏块后,计算宏块的象素值。

    以此类推,计算一幅图像中每个宏块的像素值,所有宏块都处理完后如下面的样子。

    划分子块

    H264对比较平坦的图像使用 16X16 大小的宏块。但为了更高的压缩率,还可以在 16X16 的宏块上更划分出更小的子块。子块的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4非常的灵活。

    上幅图中,红框内的 16X16 宏块中大部分是蓝色背景,而三只鹰的部分图像被划在了该宏块内,为了更好的处理三只鹰的部分图像,H264就在 16X16 的宏块内又划分出了多个子块。

    这样再经过帧内压缩,可以得到更高效的数据。下图是分别使用mpeg-2和H264对上面宏块进行压缩后的结果。其中左半部分为MPEG-2子块划分后压缩的结果,右半部分为H264的子块划压缩后的结果,可以看出H264的划分方法更具优势。

    宏块划分好后,就可以对H264编码器缓存中的所有图片进行分组了。

    帧分组

    对于视频数据主要有两类数据冗余,一类是时间上的数据冗余,另一类是空间上的数据冗余。其中时间上的数据冗余是最大的。下面我们就先来说说视频数据时间上的冗余问题。

    为什么说时间上的冗余是最大的呢?假设摄像头每秒抓取30帧,这30帧的数据大部分情况下都是相关联的。也有可能不止30帧的的数据,可能几十帧,上百帧的数据都是关联特别密切的。

    对于这些关联特别密切的帧,其实我们只需要保存一帧的数据,其它帧都可以通过这一帧再按某种规则预测出来,所以说视频数据在时间上的冗余是最多的。

    为了达到相关帧通过预测的方法来压缩数据,就需要将视频帧进行分组。那么如何判定某些帧关系密切,可以划为一组呢?我们来看一下例子,下面是捕获的一组运动的台球的视频帧,台球从右上角滚到了左下角。


    H264编码器会按顺序,每次取出两幅相邻的帧进行宏块比较,计算两帧的相似度。如下图:

    通过宏块扫描与宏块搜索可以发现这两个帧的关联度是非常高的。进而发现这一组帧的关联度都是非常高的。因此,上面这几帧就可以划分为一组。其算法是:在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内,我们认为这样的图可以分到一组。

    在这样一组帧中,经过编码后,我们只保留第一帖的完整数据,其它帧都通过参考上一帧计算出来。我们称第一帧为IDR/I帧,其它帧我们称为P/B帧,这样编码后的数据帧组我们称为GOP

    运动估计与补偿

    在H264编码器中将帧分组后,就要计算帧组内物体的运动矢量了。还以上面运动的台球视频帧为例,我们来看一下它是如何计算运动矢量的。

    H264编码器首先按顺序从缓冲区头部取出两帧视频数据,然后进行宏块扫描。当发现其中一幅图片中有物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么就可以计算出物体的运动矢量了。下面这幅图就是搜索后的台球移动的位置。

    通过上图中台球位置相差,就可以计算出台图运行的方向和距离。H264依次把每一帧中球移动的距离和方向都记录下来就成了下面的样子。

    运动矢量计算出来后,将相同部分(也就是绿色部分)减去,就得到了补偿数据。我们最终只需要将补偿数据进行压缩保存,以后在解码时就可以恢复原图了。压缩补偿后的数据只需要记录很少的一点数据。如下所示:

    我们把运动矢量与补偿称为帧间压缩技术,它解决的是视频帧在时间上的数据冗余。除了帧间压缩,帧内也要进行数据压缩,帧内数据压缩解决的是空间上的数据冗余。下面我们就来介绍一下帧内压缩技术。

    帧内预测

    人眼对图象都有一个识别度,对低频的亮度很敏感,对高频的亮度不太敏感。所以基于一些研究,可以将一幅图像中人眼不敏感的数据去除掉。这样就提出了帧内预测技术。

    H264的帧内压缩与JPEG很相似。一幅图像被划分好宏块后,对每个宏块可以进行 9 种模式的预测。找出与原图最接近的一种预测模式。

    下面这幅图是对整幅图中的每个宏块进行预测的过程。

    帧内预测后的图像与原始图像的对比如下:

    然后,将原始图像与帧内预测后的图像相减得残差值。

    再将我们之前得到的预测模式信息一起保存起来,这样我们就可以在解码时恢复原图了。效果如下:

    经过帧内与帧间的压缩后,虽然数据有大幅减少,但还有优化的空间。

    对残差数据做DCT

    可以将残差数据做整数离散余弦变换,去掉数据的相关性,进一步压缩数据。如下图所示,左侧为原数据的宏块,右侧为计算出的残差数据的宏块。

    将残差数据宏块数字化后如下图所示:

    将残差数据宏块进行 DCT 转换。

    去掉相关联的数据后,我们可以看出数据被进一步压缩了。

    做完 DCT 后,还不够,还要进行 CABAC 进行无损压缩。

    CABAC

    上面的帧内压缩是属于有损压缩技术。也就是说图像被压缩后,无法完全复原。而CABAC属于无损压缩技术。

    无损压缩技术大家最熟悉的可能就是哈夫曼编码了,给高频的词一个短码,给低频词一个长码从而达到数据压缩的目的。MPEG-2中使用的VLC就是这种算法,我们以 A-Z 作为例子,A属于高频数据,Z属于低频数据。看看它是如何做的。

    CABAC也是给高频数据短码,给低频数据长码。同时还会根据上下文相关性进行压缩,这种方式又比VLC高效很多。其效果如下:

    现在将 A-Z 换成视频帧,它就成了下面的样子。

    从上面这张图中明显可以看出采用 CACBA 的无损压缩方案要比 VLC 高效的多。

    小结

    至此,我们就将H264的编码原理讲完了。本篇文章主要讲了以下以点内容:
    1. 简音介绍了H264中的一些基本概念。如I/P/B帧, GOP。
    2. 详细讲解了H264编码的基本原理,包括:

    • 宏块的划分
    • 图像分组
    • 帧内压缩技术原理
    • 帧间压缩技术原理。
    • DCT
    • CABAC压缩原理。

    希望以上内容能对您有所帮助。谢谢!

    展开全文
  • 从零了解H264结构

    万次阅读 2018-05-10 22:37:17
    从零了解H264结构 转自:http://www.iosxxx.com/blog/2017-08-09-%E4%BB%8E%E9%9B%B6%E4%BA%86%E8%A7%A3H264%E7%BB%93%E6%9E%84.html前言建议先看一下FFmpeg3的iOS版的入门格式转换器(无编码),我们可以了解H264处于...

    从零了解H264结构

     

    转自:http://www.iosxxx.com/blog/2017-08-09-%E4%BB%8E%E9%9B%B6%E4%BA%86%E8%A7%A3H264%E7%BB%93%E6%9E%84.html

    前言

    建议先看一下FFmpeg3的iOS版的入门格式转换器(无编码),我们可以了解H264处于编解码层。为什么需要编码呢?比如当前屏幕是1280*720.一秒24张图片.那么我们一秒的视频数据是

    1
    1280*720(位像素)*24(张) / 8(1字节8位)(结果:B) / 1024(结果:KB) / 1024 (结果:MB) =  2.64MB

    一秒的数据有2.64MB数据量。1分钟就会有100多MB。这对用户来说真心是灾难。所以现在我们需要一种压缩方式减小数据的大小.在更低 比特率(bps)的情况下依然提供清晰的视频。
    H264: H264/AVC是广泛采用的一种编码方式。我们这边会带大家了解。从大到小排序依次是 序列,图像,片组,片,NALU,宏块,亚宏块,块,像素。

    一. 原理

    H.264原始码流(裸流)是由一个接一个NALU组成,它的功能分为两层,VCL(视频编码层)和 NAL(网络提取层).

    1
    VCL(Video Coding Layer) + NAL(Network Abstraction Layer).
    1. VCL:包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码;
    2. NAL:负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别。

    在VCL进行数据传输或存储之前,这些编码的VCL数据,被映射或封装进NAL单元。(NALU)。

    1
    一个NALU = 一组对应于视频编码的NALU头部信息 + 一个原始字节序列负荷(RBSP,Raw Byte Sequence Payload).

    如图所示,上图中的NALU的头 + RBSP 就相当于一个NALU(Nal Unit),每个单元都按独立的NALU传送。H.264的结构全部都是以NALU为主,理解了NALU,就理解了H.264的结构。
    一个原始的H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成,其中 Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”

    1. NAL Header

    由三部分组成,forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。

    举例来说:

    1
    2
    3
    4
    00 00 00 01 06:  SEI信息   
    00 00 00 01 67: 0x67&0x1f = 0x07 :SPS
    00 00 00 01 68: 0x68&0x1f = 0x08 :PPS
    00 00 00 01 65: 0x65&0x1f = 0x05: IDR Slice

    2. RBSP


    图 6.69 RBSP 序列举例


    表 6.25 RBSP 描述.

    SODB与RBSP
    SODB 数据比特串 -> 是编码后的原始数据.
    RBSP 原始字节序列载荷 -> 在原始编码数据的后面添加了 结尾比特。一个 bit“1”若干比特“0”,以便字节对齐。

    二. 从NALU出发了解H.264里面的专业词语

    1
    2
    3
    1帧 = n个片
    1片 = n个宏块
    1宏块 = 16x16yuv数据

    1. Slice(片)

    如图所示,NALU的主体中包含了Slice(片).

    1
    一个片 = Slice Header + Slice Data

    片是H.264提出的新概念,通过编码图片后切分通过高效的方式整合出来的概念。一张图片有一个或者多个片,而片由NALU装载并进行网络传输的。但是NALU不一定是切片,这是充分不必要条件,因为 NALU 还有可能装载着其他用作描述视频的信息.

    那么为什么要设置片呢?
    设置片的目的是为了限制误码的扩散和传输,应使编码片相互间是独立的。某片的预测不能以其他片中的宏块为参考图像,这样某一片中的预测误差才不会传播到其他片中。

    可以看到上图中,每个图像中,若干宏块(Macroblock)被排列成片。一个视频图像可编程一个或更多个片,每片包含整数个宏块 (MB),每片至少包含一个宏块。
    片有一下五种类型:

    意义
    I 片只包含I宏块
    P 片包含P和I宏块
    B 片包含B和I宏块
    SP 片包含P 和/或 I宏块,用于不同码流之间的切换
    SI 片一种特殊类型的编码宏块

    2. 宏块(Macroblock)

    刚才在片中提到了宏块.那么什么是宏块呢?
    宏块是视频信息的主要承载者。一个编码图像通常划分为多个宏块组成.包含着每一个像素的亮度和色度信息。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中像素阵列。

    1
    一个宏块 = 一个16*16的亮度像素 + 一个8×8Cb + 一个8×8Cr彩色像素块组成。(YCbCr 是属于 YUV 家族的一员,在YCbCr 中 Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量)
    宏块分类意义
    I 宏块利用从当前片中已解码的像素作为参考进行帧内预测
    P 宏块利用前面已编码图像作为参考进行帧内预测,一个帧内编码的宏块可进一步作宏块的分割:即16×16.16×8.8×16.8×8亮度像素块。如果选了8×8的子宏块,则可再分成各种子宏块的分割,其尺寸为8×8,8×4,4×8,4×4
    B 宏块利用双向的参考图像(当前和未来的已编码图像帧)进行帧内预测

    图2.1句发元素的分层结构,在 H.264 中,句法元素共被组织成 序列、图像、片、宏块、子宏块五个层次。
    句法元素的分层结构有助于更有效地节省码流。例如,再一个图像中,经常会在各个片之间有相同的数据,如果每个片都同时携带这些数据,势必会造成码流的浪费。更为有效的做法是将该图像的公共信息抽取出来,形成图像一级的句法元素,而在片级只携带该片自身独有的句法元素。


    图2.2宏块的句法单元

    宏块分类意义
    mb_type确定该 MB 是帧内或帧间(P 或 B)编码模式,确定该 MB 分割的尺寸
    mb_pred确定帧内预测模式(帧内宏块)确定表 0 或表 1 参考图 像,和每一宏块分割的差分编码的运动矢量(帧间宏块,除 8×8 宏块分割的帧内 MB)
    sub_mb_pred(只对 8×8MB 分割的帧内 MB)确定每一子宏块的子宏 块分割,每一宏块分割的表 0 和/或表 1 的参考图象;每一 宏块子分割的差分编码运动矢量。
    coded_block_pattern指出哪个 8×8 块(亮度和彩色)包 编码变换系数
    mb_qp_delta量化参数的改变值
    residual预测后对应于残差图象取样的编码变换系数

    3.图像,场和帧

    图像是个集合概念,顶 场、底场、帧都可以称为图像。对于H.264 协议来说,我们平常所熟悉的那些称呼,例如: I 帧、P 帧、B帧等等,实际上都是我们把图像这个概念具体化和细小化了。我们 在 H.264里提到的“帧”通常就是指不分场的图像;

    视频的一场或一帧可用来产生一个编码图像。一帧通常是一个完整的图像。当采集视频信号时,如果采用隔行扫描(奇.偶数行),则扫描下来的一帧图像就被分为了两个部分,这每一部分就被称为 [场],根据次序氛围: [顶场] 和 [底场]

    方式作用域
    帧编码方式活动量较小或者静止的图像宜采用
    场编码方式活动量较大的运动图像


    图2.3

    4. I,P,B帧与pts/dts

    帧的分类中文意义
    I帧帧内编码帧,又称intra pictureI 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物
    P帧前向预测编码帧,又称predictive-frame通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧
    B帧双向预测帧,又称bi-directional interpolated prediction frame既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧

    I P B帧的不同:
    I frame:自身可以通过视频解压算法解压成一张单独的完整的图片。
    P frame:需要参考其前面的一个I frame 或者B frame来生成一张完整的图片。
    B frame:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片。

    名称意义
    PTS(Presentation Time Stamp)PTS主要用于度量解码后的视频帧什么时候被显示出来。
    DTS(Decode Time Stamp)DTS主要是标识内存中的bit流再什么时候开始送入解码器中进行解码。

    DTS与PTS的不同:
    DTS主要用户视频的解码,在解码阶段使用。PTS主要用于视频的同步和输出,在display的时候使用。再没有B frame的时候输出顺序一样。

    5. GOP

    GOP是画面组,一个GOP是一组连续的画面。
    GOP一般有两个数字,如M=3,N=12.M制定I帧与P帧之间的距离,N指定两个I帧之间的距离。那么现在的GOP结构是

    1
    I BBP BBP BBP BB I

    增大图片组能有效的减少编码后的视频体积,但是也会降低视频质量,至于怎么取舍,得看需求了

    6. IDR

    一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。
    I和IDR帧都使用帧内预测。I帧不用参考任何帧,但是之后的P帧和B帧是有可能参考这个I帧之前的帧的。IDR就不允许这样。
    比如这种情况:
    IDR1 P4 B2 B3 P7 B5 B6 I10 B8 B9 P13 B11 B12 P16 B14 B15 这里的B8可以跨过I10去参考P7

    核心作用:
    H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。

    三. 帧内预测和帧间预测

    1. 帧内预测(也叫帧内压缩)

    我们可以通过第 1、2、3、4、5 块的编码来推测和计算第 6 块的编码,因此就不需要对第 6 块进行编码了,从而压缩了第 6 块,节省了空间

    2. 帧间预测(也叫帧间压缩)

     

    可以看到前后两帧的差异其实是很小的,这时候用帧间压缩就很有意义。
    这里涉及到几个重要的概念:块匹配,残差,运动搜索(运动估计),运动补偿.

    帧间压缩最常用的方式就是块匹配(Block Matching)。找找看前面已经编码的几帧里面,和我当前这个块最类似的一个块,这样我不用编码当前块的内容了,只需要编码当前块和我找到的快的差异(残差)即可。找最想的块的过程叫运动搜索(Motion Search),又叫运动估计。用残差和原来的块就能推算出当前块的过程叫运动补偿(Motion Compensation).

    四. 延伸

    最近我才知道FFmpeg也支持h264的硬编。具体还没有试验,接下来我会写demo来测试一下。直接用系统进行硬编的方式已经尝试过。接口还是蛮简单的。据说iOS11正式版会出H.265/HEVC硬编。目前Beta版暂不支持。如有支持,我会第一时间更新到博客,敬请期待!

    参考链接:

    1.新一代视频压缩编码标准H.264
    2.深入浅出理解视频编码H264结构
    3.关于视频的一些概念
    4.I,P,B帧和PTS,DTS的关系

    展开全文
  • FFmpeg的H.264解码器源代码简单分析:概述

    万次阅读 多人点赞 2015-05-25 02:05:56
    本文简单记录FFmpeg中libavcodec的H.264解码器(H.264 Decoder)的源代码。这个H.264解码器十分重要,可以说FFmpeg项目今天可以几乎“垄断”视音频编解码技术,很大一部分贡献就来自于这个H.264解码器。这个H.264...

    =====================================================

    H.264源代码分析文章列表:

    【编码 - x264】

    x264源代码简单分析:概述

    x264源代码简单分析:x264命令行工具(x264.exe)

    x264源代码简单分析:编码器主干部分-1

    x264源代码简单分析:编码器主干部分-2

    x264源代码简单分析:x264_slice_write()

    x264源代码简单分析:滤波(Filter)部分

    x264源代码简单分析:宏块分析(Analysis)部分-帧内宏块(Intra)

    x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)

    x264源代码简单分析:宏块编码(Encode)部分

    x264源代码简单分析:熵编码(Entropy Encoding)部分

    FFmpeg与libx264接口源代码简单分析

    【解码 - libavcodec H.264 解码器】

    FFmpeg的H.264解码器源代码简单分析:概述

    FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分

    FFmpeg的H.264解码器源代码简单分析:解码器主干部分

    FFmpeg的H.264解码器源代码简单分析:熵解码(EntropyDecoding)部分

    FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧内宏块(Intra)

    FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

    FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分

    =====================================================


    本文简单记录FFmpeg中libavcodec的H.264解码器(H.264 Decoder)的源代码。这个H.264解码器十分重要,可以说FFmpeg项目今天可以几乎“垄断”视音频编解码技术,很大一部分贡献就来自于这个H.264解码器。这个H.264解码器一方面功能强大,性能稳定;另一方面源代码也比较复杂,难以深入研究。本文打算梳理一下这个H.264解码器的源代码结构,以方便以后深入学习H.264使用。

    PS:这部分代码挺复杂的,还有不少地方还比较模糊,还需要慢慢学习......

    函数调用关系图

    H.264解码器的函数调用关系图如下所示。



    下面解释一下图中关键标记的含义。


    作为接口的结构体

    FFmpeg和H.264解码器之间作为接口的结构体有2个:
    ff_h264_parser:用于解析H.264码流的AVCodecParser结构体。
    ff_h264_decoder:用于解码H.264码流的AVCodec结构体。

    函数背景色

    函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用:
    白色背景的函数:普通内部函数。
    粉红色背景函数:解析函数(Parser)。这些函数用于解析SPS、PPS等信息。
    紫色背景的函数:熵解码函数(Entropy Decoding)。这些函数读取码流数据并且进行CABAC或者CAVLC熵解码。
    绿色背景的函数:解码函数(Decode)。这些函数通过帧内预测、帧间预测、DCT反变换等方法解码压缩数据。
    黄色背景的函数:环路滤波函数(Loop Filter)。这些函数对解码后的数据进行滤波,去除方块效应。
    蓝色背景函数:汇编函数(Assembly)。这些函数是做过汇编优化的函数。图中主要画出了这些函数的C语言版本,此外这些函数还包含MMX版本、SSE版本、NEON版本等。

    箭头线

    箭头线标志了函数的调用关系:
    黑色箭头线:不加区别的调用关系。
    粉红色的箭头线:解析函数(Parser)之间的调用关系。
    紫色箭头线:熵解码函数(Entropy Decoding)之间的调用关系。
    绿色箭头线:解码函数(Decode)之间的调用关系。
    黄色箭头线:环路滤波函数(Loop Filter)之间的调用关系。
     

    函数所在的文件

    每个函数标识了它所在的文件路径。



    几个关键部分

    下文简单记录几个关键的部分。


    FFmpeg和H.264解码器之间作为接口的结构体

    FFmpeg和H.264解码器之间作为接口的结构体有2个:ff_h264_parser和ff_h264_decoder。

    ff_h264_parser
    ff_h264_parser是用于解析H.264码流的AVCodecParser结构体。AVCodecParser中包含了几个重要的函数指针:
    parser_init():初始化解析器。
    parser_parse():解析。
    parser_close():关闭解析器。
    在ff_h264_parser结构体中,上述几个函数指针分别指向下面几个实现函数:
    init():初始化H.264解析器。
    h264_parse():解析H.264码流。
    close():关闭H.264解析器。
    ff_h264_decoder
    ff_h264_decoder是用于解码H.264码流的AVCodec结构体。AVCodec中包含了几个重要的函数指针:
    init():初始化解码器。
    decode():解码。
    close():关闭解码器。
    在ff_h264_decoder结构体中,上述几个函数指针分别指向下面几个实现函数:
    ff_h264_decode_init():初始化H.264解码器。
    h264_decode_frame():解码H.264码流。
    h264_decode_end():关闭H.264解码器。

    普通内部函数

    普通内部函数指的是H.264解码器中还没有进行分类的函数。下面举几个例子。
    ff_h264_decoder中ff_h264_decode_init()调用的初始化函数:
    ff_h264dsp_init():初始化DSP相关的函数。包含了IDCT、环路滤波函数等。
    ff_h264qpel_init():初始化四分之一像素运动补偿相关的函数。
    ff_h264_pred_init():初始化帧内预测相关的函数。
    ff_h264_decode_extradata():解析AVCodecContext中的extradata。
    ff_h264_decoder中h264_decode_frame()逐层调用的和解码Slice相关的函数:
    decode_nal_units(),ff_h264_execute_decode_slices(),decode_slice()等。
    ff_h264_decoder中h264_decode_end()调用的清理函数:
    ff_h264_remove_all_refs():移除所有参考帧。
    ff_h264_free_context():释放在初始化H.264解码器的时候分配的内存。
    ff_h264_parser中h264_parse()逐层调用的和解析Slice相关的函数:
    h264_find_frame_end():查找NALU的结尾。
    parse_nal_units():解析一个NALU。

    解析函数(Parser)

    解析函数(Parser)用于解析H.264码流中的一些信息(例如SPS、PPS、Slice Header等)。在parse_nal_units()和decode_nal_units()中都调用这些解析函数完成了解析。下面举几个解析函数的例子。
    ff_h264_decode_nal():解析NALU。这个函数是后几个解析函数的前提。
    ff_h264_decode_slice_header():解析Slice Header。
    ff_h264_decode_sei():解析SEI。
    ff_h264_decode_seq_parameter_set():解析SPS。
    ff_h264_decode_picture_parameter_set():解析PPS。

    熵解码函数(Entropy Decoding)

    熵解码函数(Entropy Decoding)读取码流数据并且进行CABAC或者CAVLC熵解码。CABAC解码函数是ff_h264_decode_mb_cabac(),CAVLC解码函数是ff_h264_decode_mb_cavlc()。熵解码函数中包含了很多的读取指数哥伦布编码数据的函数,例如get_ue_golomb_long(),get_ue_golomb(),get_se_golomb(),get_ue_golomb_31()等等。
    在获取残差数据的时候需要进行CAVLC/CABAC解码。例如解码CAVLC的时候,会调用decode_residual()函数,而decode_residual()会调用get_vlc2()函数,get_vlc2()会调用OPEN_READER(),UPDATE_CACHE(),GET_VLC(),CLOSE_READER()几个函数读取CAVLC格式的数据。
    此外,在获取运动矢量的时候,会调用pred_motion()以及类似的几个函数获取运动矢量相关的信息。

    解码函数(Decode)

    解码函数(Decode)通过帧内预测、帧间预测、DCT反变换等方法解码压缩数据。解码函数是ff_h264_hl_decode_mb()。其中跟宏块类型的不同,会调用几个不同的函数,最常见的就是调用hl_decode_mb_simple_8()。
    hl_decode_mb_simple_8()的定义是无法在源代码中直接找到的,这是因为它实际代码的函数名称是使用宏的方式写的(以后再具体分析)。hl_decode_mb_simple_8()的源代码实际上就是FUNC(hl_decode_mb)()函数的源代码。
    FUNC(hl_decode_mb)()根据宏块类型的不同作不同的处理:如果宏块类型是INTRA,就会调用hl_decode_mb_predict_luma()进行帧内预测;如果宏块类型不是INTRA,就会调用FUNC(hl_motion_422)()或者FUNC(hl_motion_420)()进行四分之一像素运动补偿。
    随后FUNC(hl_decode_mb)()会调用hl_decode_mb_idct_luma()等几个函数对数据进行DCT反变换工作。

    环路滤波函数(Loop Filter)

    环路滤波函数(Loop Filter)对解码后的数据进行滤波,去除方块效应。环路滤波函数是loop_filter()。其中调用了ff_h264_filter_mb()和ff_h264_filter_mb_fast()。ff_h264_filter_mb_fast()中又调用了h264_filter_mb_fast_internal()。而h264_filter_mb_fast_internal()中又调用了下面几个函数进行滤波:
    filter_mb_edgeh():亮度水平滤波
    filter_mb_edgev():亮度垂直滤波
    filter_mb_edgech():色度水平滤波

    filter_mb_edgecv():色度垂直滤波


    汇编函数(Assembly)

    汇编函数(Assembly)是做过汇编优化的函数。为了提高效率,整个H.264解码器中(主要在解码部分和环路滤波部分)包含了大量的汇编函数。实际解码的过程中,FFmpeg会根据系统的特性调用相应的汇编函数(而不是C语言函数)以提高解码的效率。如果系统不支持汇编优化的话,FFmpeg才会调用C语言版本的函数。例如在帧内预测的时候,对于16x16亮度DC模式,有以下几个版本的函数:
    C语言版本的pred16x16_dc_8_c()
    NEON版本的ff_pred16x16_dc_neon()
    MMXEXT版本的ff_pred16x16_dc_8_mmxext()
    SSE2版本的ff_pred16x16_dc_8_sse2()


    附录

    在网上找到一张图(出处不详),分析了FFmpeg的H.264解码器每个函数运行的耗时情况,比较有参考意义,在这里附上。


    单击查看更清晰的图片


    从图中可以看出,熵解码、宏块解码、环路滤波耗时比例分别为:23.64%、51.85%、22.22%。



    至此FFmpeg的H.264解码器的结构就大致梳理完毕了。




    雷霄骅
    leixiaohua1020@126.com
    http://blog.csdn.net/leixiaohua1020




    展开全文
  • H264格式 详细介绍

    万次阅读 2015-09-24 16:33:28
    原文地址:... 名词解释 场和帧 : 视频的一场或一帧可用来产生一个编码图像。在电视中,为减少大面积闪烁现象,把一帧分成两个隔行的场。...片: 每个图象中,若干宏块被排列成片的形式。... 
  • H264编码简介

    千次阅读 2019-05-11 08:38:38
    H264编码简介 H.264,同时也是MPEG-4第十部分,是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。H.264 不仅...
  • H264码流和Mp4结构详解

    万次阅读 2018-08-07 17:17:54
    本文讲述的是对H264编码且封装成MP4格式的视频流进行RTP打包过程时需要了解的一些基本知识。 二、H264的基础知识 1.H264的编码格式 H.263 定义的码流结构是分级结构,共四层。自上而下分别为:图像层...
  • 入门理解H264编码

    万次阅读 多人点赞 2018-06-25 14:32:33
    最近入门音视频技术,一直在学习H264编解码标准,了解了不少关于H264的相关知识,对于网上各种类型的资料,始终没有找到一篇适合的知识梳理资料。可能是查找方式不对,所以花费了比较多的时间。经过一段时间的熟悉后...
  • H264基础知识简介

    千次阅读 2018-08-30 23:13:22
    简介 网络提取层(NAL network abstraction layer )和视频编码层(VCL video coding) 码率、帧率、分辨率 其它 总结 简介 ...视频编解码网上介绍很多,整理了不少笔记,经过近一年的学习,把整理的...
  • H.264就是MPEG4,MPEG4只是H.264的封装格式而已,H.264可以封装为MPEG4或者MP4或者AVI,画质只是从画面分辨率来判断的,和文件无关系。 1. MPEG4是一整套视频压缩规范,它包含的标准从ISO-IEC-14496-1 到 ISO-IEC-...
  • H.264与x264的区别

    万次阅读 2018-07-14 21:32:44
    1、H.264是MPEG4的第十部分,是一个标准。...对头,H.264是需要付费的编码格式,而x264是符合H.264标准的一个开源项目,是免费的,也就是H264的一个简化版,不支持某些高级特性。但x264非常优秀,并不...
  • MP4和H264关系

    万次阅读 2012-11-22 09:17:03
    MP4是容器,H264是编码。 见这篇文章: http://www.cnblogs.com/skyseraph/archive/2012/04/01/2429384.html
  • VLC解码播放H264文件

    万次阅读 2017-05-09 14:05:46
    昨天收到几个文件名是:xxx.264的文件,这种文件属于视频图像的raw files,即只包含视频数据。由于缺少视频头文件,所以一般播放器难以播放出来。网上很多介绍的是.H264文件如何打开,以及用一些非开
  • RTP封装h264

    万次阅读 2020-09-09 11:01:58
    文章部分借用网上搜索到的资料 网络抽象层单元类型 (NALU): NALU头由一个字节组成,它的语法如下: +---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+ ...F: 1
  • 几款H264码流分析工具

    万次阅读 2018-07-17 10:36:38
    包括CTI-TS、EasyICE、elecardstreameyetools、VideoEye 下载地址:https://download.csdn.net/download/jctian000/10545674
  • AVC与H264 区别

    万次阅读 2020-08-31 14:02:45
    AVC 实际上是 H.264 协议的别名。 但自从H.264协议中增加了SVC的部分之后,人们习惯将不包含SVC的H.264协议那一部分称为 AVC,而将SVC这一部分单独称为SVC。...
  • 测试h265和h264的编码效果

    万次阅读 2015-01-06 15:21:28
    --------编译 FFMPEG with h265-------- 1.安装 hg tool #yum install hg 2.下载 x265 source code 并 make #hg clone https://bitbucket.org/multicoreware/x265 #cd x265/build/linux #make #
  • H5解码H264实时视频流

    万次阅读 2018-05-19 13:02:36
    最近研究了一下,大体思路为通过websocket把裸H264传输到浏览器,在通过js封装成mp4格式,再通过Html5的video标签进行解码,效果还是比较不错。websocket传输数据可以参考本人上一篇基于net4.5websocket这里Html5...
  • h264检测是I帧还是P帧

    万次阅读 2012-05-11 17:24:44
    今天在网上找了一些资料,知道了如何检测h264中的帧类型,在这里记录下来。 首先,贴出nal单元类型定义(图从《新一代视频压缩编码标准H.264》摘录): 假设一段h264的码流为:00 00 00 01 41 E6 60……
1 2 3 4 5 ... 20
收藏数 87,693
精华内容 35,077
关键字:

h264