视频编解码,视频编解码芯片

http://www.itjxue.com  2023-01-07 04:21  来源:未知  点击次数: 

视频解码会被发现吗

视频解码会被发现。

视频解码的意思是对已编码的数字视频进行还原解码操作的程序(视频播放器)或设备,比如系统安装了real编码器那就能将其他格式文件转换成rm或rmvb格式,如果安装了real解码器那就能播放rm或rmvb格式文件。

视频编解码器,是指一个能够对数字视频进行压缩或者解压缩的程序或者设备。通常这种压缩属于有损数据压缩。历史上,视频信号是以模拟形式存储在磁带上的。随着CompactDisc的出现并进入市场,音频信号以数字化方式进行存储,视频信号也开始使用数字化格式,一些相关技术也开始随之发展起来。

什么是视频编解码器?

一、什么是视频编解码器

视频编解码器,是指一个能够对数字视频进行压缩或者解压缩的程序或者设备。压缩和可能改变视频内容格式的过程,将模拟源更改为数字源。音频和视频都需要可定制的压缩方法。在压缩方面,目标是减少占用空间。只要是数字视频,就是需要经过视频编码器信号传输,更好地为视频直播提供技术实现。

视频编解码器是通过软件或硬件应用程序完成的视频压缩标准。

视频编码器:就是一个压缩的程序。

视频解码器:就是一个解压缩的程序。

二、视频编解码器的作用

1、视频在没有压缩的情况下,由于正常的连接速度不够,视频内容将使许多人无法通过因特网流式传输内容。特别是与流媒体相关的,视频编码器它通过互联网传输视频变得更加容易。这是因为压缩减少了所需的带宽,同时提供了高质量的体验。

2、视频编码兼容性。有时内容已经被压缩到足够的大小,但仍然需要进行编码以实现兼容性,尽管这通常被更准确地描述为代码转换。

3、对于通过互联网的高质量视频流,H.264已经成为一种常见的编解码器,解码器是因为音频视频数据存储要先通过压缩,否则数据量太庞大。

而压缩需要通过一定的编码,才能用最小的容量来存贮质量最高的音频视频数据.因此在需要对数据进行播放时要先通过解码器进行解码。

二、视频编解码基础知识

图像信息经采集后生成的原始视频数据,数据量非常大,对于某些采集后直接本地播放的应用场合,不需要考虑压缩技术。但现实中更多的应用场合,涉及视频的传输与存储,传输网络与存储设备无法容忍原始视频数据的巨大数据量,必须将原始视频数据经过编码压缩后,再进行传输与存储。

(1)未经压缩的数字视频的数据量巨大

(2)存储困难,如:一张DVD只能存储几秒钟的未压缩数字视频

(3)传输困难,如:1兆的带宽传输一秒的数字电视视频需要大约4分钟,720p RGB 15帧每秒码率计算: 1280 x 720 x 3 x 15 ≈ 41MB ≈ 331Mb

将视频数据中的冗余信息去除,寻找像素之间的相关性,还有不同时间的图像帧之间的相关性。

视频编码 是压缩和可能改变视频内容格式的过程,有时甚至将模拟源更改为数字源。在压缩方面,目标是减少占用空间。这是因为它是一个有损的过程,会抛弃与视频相关的信息。在解压缩以进行回放时,创建原始的近似值。应用的压缩越多,抛出的数据越多,近似值与原始数据相比越差。

视频编解码器是通过软件或硬件应用程序完成的视频压缩标准。编解码器,如:H.264,VP8,RV40以及其他标准或更高版本(VP9)

注:音频编解码器,如:LAME / MP3,Fraunhofer FDK AAC,FLAC等。

根据已经编码好的块信息得到一个预测值,这样只需要编码实际值与预测值之间的差异即可。

空间冗余的消除:

帧内预测:根据同一帧中相邻已编码好的块信息得到预测数据,编码差异数据

时间冗余的消除:

帧间预测:根据已编码帧中的块信息得到预测数据,编码差异数据

I 帧:仅采用帧内压缩技术,压缩效率最低,编解码无需用到其他帧的信息,是GOP的起始点。

P 帧:前向预测帧,编解码只参考前一个帧,可作为其他图像编码时的参考帧,属帧间压缩技术。

B 帧:双向预测帧,编解码既参考前一帧也可参考后一帧,压缩效率最高,复杂度高,时延较大,属帧间压缩技术。

GOP(group of pictures)一般指两个I帧之间的间隔帧数,两个I帧之间是一个图像序列,在一个图像序列中只有一个I帧。

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

VCL负责有效表示视频数据的内容。

H264除了实现了对视频的压缩处理之外,为了方便网络传输,提供了对应的视频编码和分片策略;类似于网络数据封装成IP帧,在H264中将其称为组(gop)、片(slice)、宏块(Macroblock)这些一起组成了H264的码流分层结构;H264将其组织成为序列(GOP)、图片(pictrue)、片(Slice)、宏块(Macroblock)、子块(subblock)五个层次。

宏块:视频编码的基本单元,h264通常宏块大小为16x16个像素,所以编码器一般会对图像的宽 高有要求,需要为16的倍数。

Slice:条带,图像的划分,一帧图像可编码成一个或者多个条带,每条带包含整数个宏块。

SPS: 序列参数集,包含应用于完整视频序列的语法元素,比如图像宽,高等。

PPS: 图像参数集,包含应用于编码图像的语法元素,比如量化参数,参考帧列表大小等。

NAL定义了数据封装的格式和统一的网络接口,负责格式化VCL数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。

NAL基本单元为NALU,每一个NALU包含一个字节的头信息和其后的负载数据。

参考文档

重点链接:NAL/NALU详解可以查阅:

附上几篇文章:

Android平台市面上大部分的芯片厂商的硬编硬解都适配,例如:高通,三星Exynos,联发科,海思等;windows平台上支持Intel qsv硬编硬解。

分辨率:(矩形)图片的长度和宽带,即图片的尺寸。影响图像大小,与图像大小成正比;分辨率越高,图像越大;分辨率越低,图像越小。

分辨率是指视频画面横向和纵向被切分成多少块。

区别 1080P , 3MP ,4K

P 720P 、1080P 表示的是"视频像素的总函数" ,' P ' (Progressive的缩写)表示的是"逐行扫描"

K 2K 、4K 等是表示 "视频像素的总列数" ,4K表示的是视频有4000列的像素数,具体是3840列或4096列。

MP 代表的是像素总数,指像素的行数(P)与列数(K)相乘后的一个结果(百万像素)。

帧率 是指每秒图像的数量,一帧代表的就是一副静止的画面,连续的帧就形成了动画。影响画面流畅度,与画面流畅度成正比:帧率越大,画面越流畅;帧率越小,画面越有跳动感。帧率就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。

码率 指编码器每秒编出的数据大小,单位是kbps

视频文件在单位时间内使用的数据流量,指把每秒显示的图片进行压缩后的数据量。影响体积,与体积成正比:码率越大,体积越大,码率越小,体积越小。(体积=码率X时间)

压缩前的每秒数据量 = 帧率 x 分辨率(单位是字节)

压缩比 = 压缩前的每秒数据量 / 码率(对于同一视频源并采用同一种视频编码算法,压缩比越高,画面质量越差)

清晰度

在码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。

在分辨率一定的情况下,码率与清晰度成正比关系,码率越高,图像越清晰;码率越低,图像越不清晰。

好文章理解分辨率、帧率和码率三者之间的关系:

都看到这里了,点个赞呗 0.0

视频的编解码-编码篇

四、视频的编解码-编码篇

时间?2016-08-05 10:22:59 Twenty's 时间念

原文

主题 iOS开发 MacOS

在此之前我们通常使用的FFmpeg多媒体库,利用CPU来进行视频的编解码,占用CPU资源,效率低下,俗称软编解码.而苹果在2014年的iOS8中,开放了VideoToolbox.framwork框架,此框架使用GPU或专用的处理器来进行编解码,俗称硬编解码.而此框架在此之前只有MAC OS系统中可以使用,在iOS作为私有框架.终于苹果在iOS8.0中得到开放引入.

2014年的WWDC Direct Access to Video Encoding and Decoding 中,苹果介绍了使用videoToolbox硬编解码.

使用硬编解码有几个优点: * 提高性能; * 增加效率; * 延长电量的使用

对于编解码,AVFoundation框架只有以下几个功能: 1. 直接解压后显示;

2. 直接压缩到一个文件当中;

而对于Video Toolbox,我们可以通过以下功能获取到数据,进行网络流传输等多种保存: 1. 解压为图像的数据结构;

2. 压缩为视频图像的容器数据结构.

一、videoToolbox的基本数据

Video Toolbox视频编解码前后需要应用的数据结构进行说明。

CVPixelBuffer:编码前和解码后的图像数据结构。此内容包含一系列的CVPixelBufferPool内容

CMTime、CMClock和CMTimebase:时间戳相关。时间以64-bit/32-bit的形式出现。

pixelBufferAttributes:字典设置.可能包括Width/height、pixel format type、? Compatibility (e.g., OpenGL ES, Core Animation)

CMBlockBuffer:编码后,结果图像的数据结构。

CMVideoFormatDescription:图像存储方式,编解码器等格式描述。

(CMSampleBuffer:存放编解码前后的视频图像的容器数据结构。

CMClock

CMTimebase: 关于CMClock的一个控制视图,包含CMClock、时间映射(Time mapping)、速率控制(Rate control)

由二、采集视频数据可知,我们获取到的数据(CMSampleBufferRef)sampleBuffer为未编码的数据;

图1.1

上图中,编码前后的视频图像都封装在CMSampleBuffer中,编码前以CVPixelBuffer进行存储;编码后以CMBlockBuffer进行存储。除此之外两者都包括CMTime、CMVideoFormatDesc.

二、视频数据流编码并上传到服务器

1.将CVPixelBuffer使用VTCompressionSession进行数据流的硬编码。

(1)初始化VTCompressionSession

VT_EXPORT OSStatus VTCompressionSessionCreate(? ? CM_NULLABLE CFAllocatorRef? ? ? ? ? ? ? ? ? ? ? ? ? allocator,? ? int32_t? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? width,? ? int32_t? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? height,? ? CMVideoCodecType? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? codecType,? ? CM_NULLABLE CFDictionaryRef? ? ? ? ? ? ? ? ? ? ? ? encoderSpecification,? ? CM_NULLABLE CFDictionaryRef? ? ? ? ? ? ? ? ? ? ? ? sourceImageBufferAttributes,? ? CM_NULLABLE CFAllocatorRef? ? ? ? ? ? ? ? ? ? ? ? ? compressedDataAllocator,? ? CM_NULLABLE VTCompressionOutputCallback? ? ? ? ? ? outputCallback,? ? void * CM_NULLABLE? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? outputCallbackRefCon,? ? CM_RETURNS_RETAINED_PARAMETER CM_NULLABLE VTCompressionSessionRef * CM_NONNULL compressionSessionOut)? ? __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_8_0);

VTCompressionSession的初始化参数说明:

allocator:分配器,设置NULL为默认分配

width: 宽

height: 高

codecType: 编码类型,如kCMVideoCodecType_H264

encoderSpecification: 编码规范。设置NULL由videoToolbox自己选择

sourceImageBufferAttributes: 源像素缓冲区属性.设置NULL不让videToolbox创建,而自己创建

compressedDataAllocator: 压缩数据分配器.设置NULL,默认的分配

outputCallback: 当VTCompressionSessionEncodeFrame被调用压缩一次后会被异步调用.注:当你设置NULL的时候,你需要调用VTCompressionSessionEncodeFrameWithOutputHandler方法进行压缩帧处理,支持iOS9.0以上

outputCallbackRefCon: 回调客户定义的参考值.

compressionSessionOut: 压缩会话变量。

(2)配置VTCompressionSession

使用VTSessionSetProperty()调用进行配置compression。 * kVTCompressionPropertyKey AllowFrameReordering: 允许帧重新排序.默认为true * kVTCompressionPropertyKey AverageBitRate: 设置需要的平均编码率 * kVTCompressionPropertyKey H264EntropyMode:H264的 熵编码 模式。有两种模式:一种基于上下文的二进制算数编码CABAC和可变长编码VLC.在slice层之上(picture和sequence)使用定长或变长的二进制编码,slice层及其以下使用VLC或CABAC. 详情请参考 * kVTCompressionPropertyKey RealTime: 视频编码压缩是否是实时压缩。可设置CFBoolean或NULL.默认为NULL * kVTCompressionPropertyKey ProfileLevel: 对于编码流指定配置和标准 .比如kVTProfileLevel H264 Main AutoLevel

配置过VTCompressionSession后,可以可选的调用VTCompressionSessionPrepareToEncodeFrames进行准备工作编码帧。

(3)开始硬编码流入的数据

使用VTCompressionSessionEncodeFrame方法进行编码.当编码结束后调用outputCallback回调函数。

VT_EXPORT OSStatus? VTCompressionSessionEncodeFrame(? ? ? CM_NONNULL VTCompressionSessionRef? session,? ? CM_NONNULL CVImageBufferRef? ? ? ? imageBuffer,? ? CMTime? ? ? ? ? ? ? ? ? ? ? ? ? ? ? presentationTimeStamp,? ? CMTime? ? ? ? ? ? ? ? ? ? ? ? ? ? ? duration,// may be kCMTimeInvalidCM_NULLABLE CFDictionaryRef? ? ? ? frameProperties,void* CM_NULLABLE? ? ? ? ? ? ? ? ? sourceFrameRefCon,? ? VTEncodeInfoFlags * CM_NULLABLE? ? infoFlagsOut )? ? __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_8_0);

presentationTimeStamp: 获取到的这个sample buffer数据的展示时间戳。每一个传给这个session的时间戳都要大于前一个展示时间戳.

duration: 对于获取到sample buffer数据,这个帧的展示时间.如果没有时间信息,可设置kCMTimeInvalid.

frameProperties: 包含这个帧的属性.帧的改变会影响后边的编码帧.

sourceFrameRefCon: 回调函数会引用你设置的这个帧的参考值.

infoFlagsOut: 指向一个VTEncodeInfoFlags来接受一个编码操作.如果使用异步运行,kVTEncodeInfo_Asynchronous被设置;同步运行,kVTEncodeInfo_FrameDropped被设置;设置NULL为不想接受这个信息.

(4)执行VTCompressionOutputCallback回调函数

typedefvoid(*VTCompressionOutputCallback)(void* CM_NULLABLE outputCallbackRefCon,void* CM_NULLABLE sourceFrameRefCon,? ? ? ? OSStatus status,? ? ? ? VTEncodeInfoFlags infoFlags,? ? ? ? CM_NULLABLE CMSampleBufferRef sampleBuffer );

outputCallbackRefCon: 回调函数的参考值

sourceFrameRefCon: VTCompressionSessionEncodeFrame函数中设置的帧的参考值

status: 压缩的成功为noErr,如失败有错误码

infoFlags: 包含编码操作的信息标识

sampleBuffer: 如果压缩成功或者帧不丢失,则包含这个已压缩的数据CMSampleBuffer,否则为NULL

(5)将压缩成功的sampleBuffer数据进行处理为基本流NSData上传到服务器

MPEG-4是一套用于音频、视频信息的压缩编码标准.

由 图1.1 可知,已压缩 $$CMSampleBuffer = CMTime(可选) + CMBlockBuffer + CMVideoFormatDesc$$。

5.1 先判断压缩的数据是否正确

//不存在则代表压缩不成功或帧丢失if(!sampleBuffer)return;if(status != noErr)return;//返回sampleBuffer中包括可变字典的不可变数组,如果有错误则为NULLCFArrayRefarray=? CMSampleBufferGetSampleAttachmentsArray(sampleBuffer,true);if(!array)return;? CFDictionaryRef dic = CFArrayGetValueAtIndex(array,0);if(!dic)return;//issue 3:kCMSampleAttachmentKey_NotSync:没有这个键意味着同步, yes: 异步. no:同步BOOL keyframe = !CFDictionaryContainsKey(dic, kCMSampleAttachmentKey_NotSync);//此代表为同步

而对于 issue 3 从字面意思理解即为以上的说明,但是网上看到很多都是做为查询是否是视频关键帧,而查询文档看到有此关键帧key值kCMSampleBufferAttachmentKey_ForceKeyFrame存在,因此对此值如若有了解情况者敬请告知详情.

5.2 获取CMVideoFormatDesc数据由 三、解码篇 可知CMVideoFormatDesc 包括编码所用的profile,level,图像的宽和高,deblock滤波器等.具体包含 第一个NALU的SPS (Sequence Parameter Set)和 第二个NALU的PPS (Picture Parameter Set).

//if (keyframe !encoder - sps) {? ? //获取sample buffer 中的 CMVideoFormatDesc? ? CMFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);? ? //获取H264参数集合中的SPS和PPS? ? const uint8_t * sparameterSet;size_t sparameterSetSize,sparameterSetCount ;? OSStatus statusCode =? ? CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 0, sparameterSet, sparameterSetSize, sparameterSetCount,0);if (statusCode == noErr) {? ? ? ? size_t pparameterSetSize, pparameterSetCount;? ? ? ? const uint8_t *pparameterSet;OSStatus statusCode =? ? CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 1, pparameterSet, pparameterSetSize, pparameterSetCount,0);if (statusCode == noErr) {? ? ? ? ? ? encoder-sps = [NSData dataWithBytes:sparameterSetlength:sparameterSetSize];encoder-pps = [NSData dataWithBytes:pparameterSetlength:pparameterSetSize];}? ? }}

5.3 获取CMBlockBuffer并转换成数据

CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);? ? size_t? lengthAtOffset,totalLength;char*dataPointer;//接收到的数据展示OSStatus blockBufferStatus = CMBlockBufferGetDataPointer(blockBuffer,0, lengthAtOffset, totalLength, dataPointer);if(blockBufferStatus != kCMBlockBufferNoErr)? ? {? ? ? ? size_t bufferOffset =0;staticconstintAVCCHeaderLength =4;while(bufferOffset totalLength -? AVCCHeaderLength) {// Read the NAL unit lengthuint32_t NALUnitLength =0;/**

*? void *memcpy(void *dest, const void *src, size_t n);

*? 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

*/memcpy(NALUnitLength, dataPointer + bufferOffset, AVCCHeaderLength);//字节从高位反转到低位NALUnitLength = CFSwapInt32BigToHost(NALUnitLength);? ? ? ? ? ? RTAVVideoFrame * frame = [RTAVVideoFramenew];? ? ? ? ? ? frame.sps = encoder - sps;? ? ? ? ? ? frame.pps = encoder - pps;? ? ? ? ? ? frame.data = [NSData dataWithBytes:(dataPointer+bufferOffset+AVCCHeaderLength) length:NALUnitLength];? ? ? ? ? ? bufferOffset += NALUnitLength + AVCCHeaderLength;? ? ? ? }? ? }

此得到的H264数据应用于后面的RTMP协议做推流准备。

音视频-编/解码概念

当需要播放音频时,得先解码(解压缩)出PCM数据,然后再进行播放。

需要注意的是:音频文件格式并不等于音频编码。比如:

WAV只是一种文件格式,并不是一种编码

FLAC既是一种文件格式,又是一种编码

AAC编码的文件扩展名主要有3种:

参考 : 【秒懂音视频开发】07_重识音频

(责任编辑:IT教学网)

更多

推荐人物新闻文章