音视频技术

音视频技术

简介

由于时间不是很充裕,为了方便大家,从零开始学习音视频技术,需要大家注意的是,本文主要讲解一些理论知识和流程方面,不涉及相关具体细节和编程相关。

首先在我们的生活中,自己的电脑中有各种不同格式的电源文件,例如avi、mp4、rmvb、mkv等等,这里的格式其实就是代表的封装格式。封装简单的理解就是把视频数据和音频数据打包成一个文件的规范。

音视频技术主要为以下几个技术要点:

  • 封装技术
  • 音视频压缩编码技术
  • 音视频解码技术
  • 流媒体协议技术(网络传输)

IPCamera详解

  • 网络摄像头,IP Camera产生数字视频流,并将视频流通过无线网络传输的摄像头
  • IPCamera = 摄像机+网络视频模块

IPCamera模组

  • 镜头IR-CUT
  • 图像传感器(Sensor)
  • 数字信号处理器(DPS)
  • H264编码RTSP协议

14920485971458
14920486897432

IPCamera服务端

14920486396566

视频播放原理

14920487445972

解协议

  • 解协议的作用就是将协议的数据,解析为标准的封装格式数据
  • HTTP\RTSP\RTMP\MMS等等数据
  • 协议会携带一些指令数据,用于控制播放、暂停、停止、网络状况的描述等等
  • 例如:RTMP协议传输数据,经过解协议操作后,输出FLV格式的数据

解封装

  • 解封装就是将封装格式的数据分离为音视频压缩数据
  • MP4\MKV\RMVB\TS\FLV\AVI等等
  • 将音视频数据按照一定格式放到一起
  • 比如FLV格式的数据,解封装后,输出H.264编码的视频码流和AAC编码的音频码流

解码

  • 解码就是将音视频压缩编码数据,解码成为非压缩的音视频原始数据
  • 音频的压缩编码标准有AAC\MP3\AC-3等等
  • 视频的压缩编码有H264\MPEG2等等
  • 解码最重要、也是最复杂的一个环节
  • 视频解码后一般为YUV420P或RGB等等
  • 音频解码后一般为PCM数据

流媒体协议

名称 推出机构 传输层协议 客户端 目前使用领域
RTSP+RTP IETF TCP+UDP VLC,WMP IPTV
RTMP Adobe TCP Flash 互联网直播
RTMFP Adobe UDP Flash 互联网直播
MMS Microsoft TCP/UDP WMP 互联网直播+点播
HTTP WWW+IETF TCP Flash 互联网点播

封装格式

名称 推出机构 流媒体 支持视频的编码 支持视频的编码 目前使用领域
AVI Misrosoft 不支持 几乎所有格式 几乎所有格式 BT下载影视
MP4 MPEG 支持 MPEG-2,MPEG-4,H264… AAC,MPEG-1 Layers,AC-3 互联网视频网站
TS MPEG 支持 MPEG-2,MPEG-4,H264… MPEG-1 Layers,AAC… IPTV,数字电视
FLV Adobe 支持 VP6,H264 MP3,ADPCM,PCM,AAC等等 互联网视频网站
MKV CoreCodec 支持 几乎所有格式 几乎所有格式 互联网视频网站
RMVB Real Networks 支持 RealVideo8,9,10 AAC,Cook Codec, BT下载影视

视频编码

名称 推出机构 推出时间 目前使用领域
HEVC(H.265) MPEG/ITU-T 2013 研发中
H.264 MPEG/ITU-T 2003 各个领域
MPEG4 MPEG 2001 不温不火
MPEG2 MPEG 1994 数字电视
VP9 Google 2013 研发中
VP8 Google 2008 不普及
VC-1 Microsoft 2006 微软平台

音频编码

名称 推出机构 推出时间 目前使用领域
AAC MPEG 1997 各个领域(新)
AC-3 Dolby 1992 电影
MP3 MPEG 1993 各个领域(旧)
WMA Microsoft 1999 微软平台

RTSP协议

  • RTSP(Real-TimeStream Protocol)是一种基于文本的应用层协议
  • “网络远程控制”角色,媒体传送通过RTP/RTCP协议完成
  • OPIONS、DESCRIBE、SETUP、PLAY、TEARDOWN

FFmpeg

  • FFmpeg是一个非常快的音视频编解码
  • FFmpeg就是通常我们所说的软解
  • 常用视频解码,用于做万能播放器

14920503640445

14920503784028

iOS FFmpeg编译

14920504460821

FFmpeg使用

  • 简单流程

14920504664562

  • 详细流程

移动端流媒体播放实际流程

  • 初始化引擎(InitEngine)
  • 连接流(Connection Stream)
  • 读包(Read Packets)
  • 流管理系统(Streams Management)
  • 解码(DecodeVideo)
  • 渲染(Render)

初始化引擎(InitEngine)

  • avcodec_register_all()
  • av_register_all()
  • avformat_network_init()
  • av_log_set_level(AV_LOG_QUIET)

连接流(Connection Stream)

  • 初始化avformat_alloc_context()
  • 打开前先检查协议(rtsp,mms,http,rtmp…)
  • 打开流avformat_open_input()
  • 检查流获取流信息avformat_find_stream_info()
  • 然后初始化音视频流管理系统

读包(Read Packets)

  • 开启读包线程
  • while循环不断读取av_read_frame()
  • 把音视频分别加入对应的流管理系统
  • 通知播放音频和渲染视频

流管理系统(Streams Management)

  • 打开音视频解码器
  • 获取音视频流信息,视频宽高等等
  • 设置音频音量
  • 获取视频数据YUV/RGB

解码(Decode Video)

  • 音频解码avcodec_decode_audio4()
  • 音频使用AudioToolBox.framework播放
  • 视频解码avcodec_decode_video2()
  • 视频解码之后缓存帧buffer
  • 视频使用OpenGL ES渲染播放

渲染(Render)

  • 获取每帧画面的YUV数据或RGB数据
  • 设置OpenGL ES环境
  • 编译Shader脚本语言
  • YUV或RGB贴图显示

14920508384755

VertexShader

1
2
3
4
5
6
7
8
attribute vec4 position;
attribute vec2 texCoordIn;
varying vec2 texCoordOut;
void main() {
gl_Position = position;
texCoordOut = texCoordIn;
}

FragmentShader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
precision highp float;
varying highp vec2 texCoordOut;
uniform sampler2D s_texture_y;
uniform sampler2D s_texture_u;
uniform sampler2D s_texture_v;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main()
{
highp float y = texture2D(s_texture_y, texCoordOut).r;
highp float u = texture2D(s_texture_u, texCoordOut).r - 0.5;
highp float v = texture2D(s_texture_v, texCoordOut).r - 0.5;
highp float r = y + 1.13983 * v;
highp float g = y - 0.39465 * u - 0.58060 * v;
highp float b = y + 2.03211 * u;
gl_FragColor = vec4(vec3(r,g,b),1.0);
}

硬解

  • FFmpeg是使用CPU进行软解的,占用CPU资源,编解码效率不高
  • 硬解,一般系统会提供专业处理器对视频流进行编解码
  • iOS8.0之前没有开放,私有API的形式
  • iOS8.0之后开放,即VideoToolBox.framework
    14920509444869

H264码流结构

  • 提取sps和pps生成format description
  • 每个NALU的开始码是0x00 00 01,按照开始码定位NALU。
  • 通过类型信息找到sps和pps并提取,开始码后第一个byte的后5位,7代表sps,8代表pps。

14920509769334

14920509867329

CVPixelBufferRef

CoreVideo.framework,通过CVPixelBufferRef获取Y纹理,和UV纹理,然后渲染显示

1
2
3
4
5
6
7
8
9
10
11
12
13
CV_EXPORT CVReturn CVOpenGLESTextureCacheCreateTextureFromImage(
CFAllocatorRef CV_NULLABLE allocator,
CVOpenGLESTextureCacheRef CV_NONNULL textureCache,
CVImageBufferRef CV_NONNULL sourceImage,
CFDictionaryRef CV_NULLABLE textureAttributes,
GLenum target,
GLint internalFormat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
size_t planeIndex,
CV_RETURNS_RETAINED_PARAMETER CVOpenGLESTextureRef CV_NULLABLE * CV_NONNULL textureOut ) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);