1.1 音视频基础概念
学习目标
1.掌握FFmpeg的模块化架构,解码流程及关键数据结构。
2.理解视频分辨率、视频帧率、视频编码格式及音频采样率、音频编码等基本概念。
3.了解RTMP协议三次握手的大致过程。
环境准备
在开始学习之前,建议读者具备以下基础知识:
|-------------|-----------------|------------------------|
| 项目 | 要求 | 说明 |
| C++基础 | 掌握C++基本语法 | 熟悉类、指针、内存管理等概念 |
| Windows开发环境 | 安装Visual Studio | 使用C++进行Windows桌面应用程序开发 |
| 概念准备 | 了解音视频基础概念 | 熟悉采样率、帧率、编码格式等基本概念 |
一、概述
本节系统介绍音视频开发的核心基础知识,包括FFmpeg框架架构、音视频基本概念以及RTMP协议原理,为后续实战开发奠定理论基础。
二、核心知识
1 .FFmpeg核心架构
FFmpeg是全球最流行的开源音视频处理框架,由法国开发者Fabrice Bellard于2000年发起。它提供了完整的音视频录制、转换、流化功能,几乎涵盖了音视频处理的所有环节。理解FFmpeg的模块化架构,是高效使用它的前提。
1.模块化架构
FFmpeg采用高度模块化的设计,各个模块各司其职,通过统一的API协同工作:
|---------------|-----------------------|------------------------------------------|
| 模块名称 | 功能说明 | 核心用途 |
| libavformat | 封装格式处理库(Demux/Mux) | 解析MP4、FLV、MKV等容器格式,读取/写入音视频数据包 |
| libavcodec | 编解码核心库(Encode/Decode) | 支持H.264、H.265、AAC、MP3等数百种编解码格式 |
| libavutil | 基础工具库 | 提供数据结构(AVFrame、AVPacket等)、数学运算、时间处理等基础功能 |
| libswscale | 图像缩放与格式转换库 | 在YUV、RGB、BGR等像素格式之间进行转换和图像缩放 |
| libswresample | 音频重采样库 | 在不同采样率、声道数、采样格式之间进行音频转换 |
2.FFmpeg解码流程图
下面的流程图展示了FFmpeg从输入源到最终播放/输出的完整数据流:
|----------------------------|---|-----------------------------------|---|-----------------------------------------|---|------------------------------------------|---|-----------------------------|
| Input Source RTMP/MP4/RTSP | → | libavformat Demux av_read_frame() | → | libavcodec Decode avcodec_send_packet() | → | libswscale/ libswresample Format convert | → | Display/Play OpenCV/WaveOut |
**输入源:**可以是网络流(RTMP/RTSP)、本地文件(MP4/MKV)、设备输入(摄像头/麦克风)等。
**解封装(Demux):**由libavformat完成,从容器中分离出音频流和视频流的压缩数据包(AVPacket)。
**解码(Decode):**由libavcodec完成,将压缩的音视频数据包解码为原始帧(AVFrame:YUV像素数据或PCM采样数据)。
**格式转换:**由libswscale(视频)或libswresample(音频)完成,将解码后的数据转换为显示/播放所需的格式。
**显示/播放:**视频通过OpenCV的Mat对象显示到窗口,音频通过Windows WaveOut API输出到扬声器。
3.关键数据结构
FFmpeg的核心操作围绕着几个关键数据结构展开,理解它们是编写FFmpeg程序的基础:
|-----------------|-------------------------------------|----------------------|
| 数据结构 | 说明 | 类比理解 |
| AVFormatContext | 封装格式上下文,保存输入/输出的全局信息,包括流数量、格式、元数据等 | 文件的"总管家",管理所有音视频流 |
| AVCodecContext | 编解码器上下文,保存编解码器参数(分辨率、采样率、码率等)和状态 | 编解码器的"配置面板" |
| AVFrame | 数据帧结构,存放解码后的原始视频帧(YUV像素)或音频帧(PCM采样) | 一张"画布",承载一帧图像或一段音频数据 |
| AVPacket | 数据包结构,存放压缩的音视频数据(H.264 NALU、AAC帧等) | 一个"快递包裹",承载压缩后的数据 |
| AVStream | 流结构,描述一条音视频流的基本信息(编解码参数、时间基等) | 一条"通道",文件中的视频轨道或音频轨道 |
提示 数据结构之间的关系
一个AVFormatContext包含多个AVStream(视频流、音频流等),每个AVStream对应一个AVCodecContext。解码时,AVPacket从流中读取,送入解码器后输出AVFrame。
2 .音视频基础概念
在深入代码实现之前,有必要先了解一些音视频领域的基础概念。这些知识将帮助你更好地理解后续章节中的各种参数配置和API调用。
1.视频基础
分辨率(Resolution)
分辨率指图像的像素尺寸,通常表示为"宽 x 高"。常见的视频分辨率包括:
●4K:3840 x 2160 像素(Ultra HD)
●1080P:1920 x 1080 像素(Full HD)
●720P:1280 x 720 像素(HD)
●480P:640 x 480 像素(SD)
帧率(Frame Rate)
帧率是每秒显示的画面数量,单位为fps(frames per second)。帧率越高,画面越流畅:
●电影标准:24fps
●网络直播常用:25fps 或 30fps
●高帧率游戏:60fps
编码格式(Codec)
编码格式决定了视频数据的压缩方式,直接影响画质和文件大小:
|--------------|--------------------------------|----------------|
| 编码格式 | 特点 | 典型应用 |
| H.264 / AVC | 最主流的视频编码标准,兼容性极佳,压缩效率高 | 直播、点播、视频会议 |
| H.265 / HEVC | H.264的继任者,在相同画质下比H.264节省约50%带宽 | 4K视频、高画质直播 |
| VP8 / VP9 | Google主导的开源编码格式 | WebRTC、YouTube |
容器格式(Container)
容器格式(也叫封装格式)负责将编码后的音视频数据和字幕、元数据等组织到一起:
|----------|---------------------------|------------|
| 容器格式 | 特点 | 典型应用 |
| MP4 | 最通用的容器格式,兼容性最好 | 视频点播、移动端 |
| FLV | Flash Video格式,RTMP协议的标准封装 | RTMP直播推流 |
| MKV | 开源容器,支持多种编码格式和字幕 | 高清视频存储 |
| TS | 传输流格式,支持容错 | HLS直播、IPTV |
提示 容器 vs 编码
容器格式和编码格式是两个不同层次的概念。打个比方:容器格式好比"快递箱",编码格式好比箱内的"物品包装方式"。同一个MP4文件中,视频可以是H.264编码也可以是H.265编码,音频可以是AAC也可以是MP3。
2.音频基础
采样率(Sample Rate)
采样率指每秒对声音信号采样的次数,单位为Hz。采样率越高,音质越好:
●8000 Hz:电话音质
●22050 Hz:FM广播音质
●44100 Hz:CD音质(最常用)
●48000 Hz:专业音频(DAT级别)
声道数(Channels)
●单声道(Mono):1个声道
●立体声(Stereo):2个声道(左、右)
●5.1环绕声:6个声道
采样位深(Bit Depth)
采样位深决定了每个采样点的精度:
●16位:CD标准,最常用的音频位深
●24位:专业音频录制
●32位浮点:音频处理中间格式
音频编码格式
|----------|-----------------------|--------------|
| 编码格式 | 特点 | 典型应用 |
| AAC | MP3的继任者,在相同码率下音质优于MP3 | 直播、流媒体、MP4文件 |
| MP3 | 最广泛使用的音频编码格式 | 音乐文件、播客 |
| Opus | 开源编码,低延迟高音质 | WebRTC、语音通话 |
3 .RTMP协议简介
RTMP(Real-Time Messaging Protocol,实时消息传输协议)是由Macromedia(后被Adobe收购)开发的流媒体传输协议,虽然Adobe已停止更新Flash,但RTMP凭借其低延迟的优势,至今仍是直播领域最广泛使用的推流协议。
握手过程
RTMP基于TCP连接,建立连接时需要进行三次握手:
|----------------|-----------------|--------------|
| Client A | RTMP Server | Client B |
| C0+C1 | ↔ | S0+S1+S2 |
| C2 | ↔ | |
| connect() | ↔ | _result |
| createStream() | ↔ | _result |
| play() | ↔ | A/V Data |
消息类型
|-----------------|------------------------------------------|
| 消息类型 | 说明 |
| Command Message | 控制命令,如connect、createStream、play、publish等 |
| Audio Message | 承载音频数据(AAC/MP3编码帧) |
| Video Message | 承载视频数据(H.264/H.265编码帧) |
| Data Message | 元数据信息,如视频分辨率、编码格式等 |
为什么选择RTMP
●低延迟:基于TCP长连接,传输延迟可低于0.5秒
●生态成熟:几乎所有直播CDN都支持RTMP推流
●FLV封装:RTMP默认使用FLV封装格式,FFmpeg对FLV的支持非常完善
●易于调试:可使用FFmpeg命令行工具快速验证RTMP流的可用性