【音视频开发】第五章 FFmpeg基础

【音视频开发】第五章 FFmpeg基础

文章目录

一、播放器框架

1.媒体文件读取阶段

  1. 媒体文件(输入)
    通过 avformat_alloc_context() 和 avformat_open_input() 创建和打开输入文件,生成 AVFormatContext
  2. 解复用器(音视频解封装)
    使用 av_read_frame() 从媒体流中读取数据包(AVPacket),根据 AVStream 区分音频或视频数据

2.音频处理流程

  • 音频包队列(Packet Queue)
    接收音频AVPacket
  • 音频解码
    使用 avcodec_send_packet() 送入解码器,avcodec_receive_frame() 获取 AVFrame,即解码后的音频帧
  • 采样帧队列(Frame Queue)
    将音频帧缓存用于后续播放
  • 音频处理
    包括重采样、音量调节等,最终送入扬声器播放

3.视频处理流程

  • 视频包队列(Packet Queue)
    接收视频 AVPacket
  • 视频解码
    同样使用 avcodec_send_packet() 和 avcodec_recceive_frame() 获取视频帧
  • 图像帧队列(Frame Queue)
    存储待显示的图像帧
  • 图像处理
    包括格式转换、缩放、显示等,最终在显示器上播放

二、常用音视频概念

1.常用音视频术语

  • 容器/文件(Container/File):即特定格式的多媒体文件,比如 mp4、flv、mkv 等
  • 媒体流(Stream):表示时间轴上的一段连续数据,如一段声音数据、一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器(有些码流音频是纯 PCM)
  • 数据帧/数据包(Frame/Packet):通常,一个媒体流是由大量的数据帧组成的,对于压缩数据,帧对应着编解码器的最小处理单元,分属于不同媒体流的数据帧交错存储于容器之中
  • 编解码器:编解码器是以帧为单位实现压缩数据和原始数据之间的相互转换的

2.复用器

"复用器"这个词,英文是 Multiplexer(简称 Mux),在音视频处理中是一个非常关键的概念,和"解复用器"(Demuxer)是相对的。

复用器的作用是把多个独立的音视频流、字幕流、元信息等数据,打包成一个统一的媒体文件格式,比如 .mp4、.mkv、.ts 等,把音频、视频、字幕合并打包成一个完整的视频文件,这个过程就叫复用。

假设有两段数据:

  • 一段是 .aac 音频
  • 一段是 .h264 视频

你想把它们合成一个 .mp4 文件,可以通过复用器完成

在 FFmpeg 命令行中就是:

bash 复制代码
ffmpeg -i video.h264 -i audio.aac -c copy output.mp4

这条命令里,-c copy 表示不重新编码,直接复用音视频流

3.编解码器

"编解码器"是音视频领域最核心的概念之一,英文叫 Codec,是 "编码器(Encoder)" 和 "解码器(Decoder)" 的合称。

  • 编码器:把原始的音视频数据压缩,变成更小、更易传输的格式(比如 H.264,AAC)
  • 解码器:把压缩后的数据还原为可播放的原始数据

拿手机拍了一个视频,这个过程可能涉及:

  • 摄像头捕获的是"原始图像数据"(未压缩,体积很大)
  • 编码器将图像压缩为 H.264 格式的视频流,生成 .mp4 文件
  • 播放这个 .mp4 文件时,解码器会把 H.264 解码为图像帧显示出来

常见编解码器

三、FFmpeg 库

1.整体结构


上层工具(命令行工具)

  • ffmpeg:核心命令行工具,用于转码、提取音视频、格式转换、滤镜处理等
  • ffplay:简单播放器,基于 SDL 和 FFmpeg,可以用来测试播放
  • ffprobe:分析媒体文件的信息(码率、时长、分辨率、流信息等)

中间核心库(libav 系列)

  • libavformat:封装/解封装库(复用器/解复用器),处理媒体容器格式,比如 MP4/MKV/FLV
  • libavcodec:编解码器库,支持各种音视频编码(如 H264、AAC、MP3)
  • libavutil:工具库,提供常用的数学、时间戳、内存处理、数据结构等工具
  • libswscale:图像缩放/像素格式转换库,比如 RGB -> YUV
  • libswreasample:音频重采样库,比如立体声转单声道,变采样率
  • libavfilter:滤镜处理库,用于音视频的剪辑、旋转、叠加等复杂处理
  • libpostproc:后处理库,主要用于解码后图像增强

编解码器支持库(第三方)

这些库不属于 FFmpeg 本身,但可以被 libavcodec 调用来支持更多的格式

  • x264:最常用的 H.264 编码器(开源)
  • fdk-aac:高质量 AAC 编码器(非完全开源)
  • voaac_enc:另一种 AAC 编码器实现

模块调用关系

bash 复制代码
ffmpeg 命令
   ↓
libavformat (封装/解封装)
   ↓
libavcodec (编解码)
   ↓
调用第三方编解码器(如 x264、fdk-aac)
   ↓
libswscale / libswresample(图像、音频处理)
   ↓
libavfilter(可选滤镜)
   ↓
libavutil(提供底层支持)

如果在开发中只想播放或分析视频,常用的是 libavformat + libavcodec + libavutil

如果要处理图像、声音或添加滤镜,就会涉及 libswscale、libswresample 和 libavfilter

四、FFmpeg 常用函数

1.libavformat 封装/解封装

2.libavcodec 编解码

3.libavutil 工具函数库

4.libswscale 图像缩放、像素格式转换

5.libswresample 音频重采样

6.内存与资源释放相关

五、FFmpeg 常用结构体

1.封装/解封装相关结构体(libavformat)

  • AVFormatContext:媒体容器上下文,负责读写媒体文件(如 MP4、MKV)
  • AVInputFormat/AVOutputFormat:输入/输出格式,(解封装器/封装器)
  • AVStream:媒体流(视频、音频、字幕等)
  • AVPacket:编码后的数据包(压缩数据,如一帧 H264)

2.编解码相关结构体(libavcodec)

  • AVCodecContext:编解码上下文,保存参数、状态等
  • AVCodec:编码器或解码器对象(如 H.264、AAC)
  • AVFrame:原始数据帧(未压缩图像/音频)
  • AVPicture(旧):图像帧结构体,已被 AVFrame 替代
  • AVCodecParameters:编解码参数(音频采样率、分辨率、码率等)

六、FFmpeg 内存模型

FFmpeg 的内存模型涉及到多个模块(编解码、封装、滤镜等)中内存的分配、使用、释放策略。掌握 FFmpeg 的内存模型,有助于写出高效稳定、不泄露内存的多媒体程序。

1.FFmpeg 内存模型核心思想

FFmpeg 的内存分配分为两类:

  • 短期内存:用于存储临时数据,如 AVPacket、AVFrame,每处理一帧就释放
  • 长期内存:如 AVFormatContext、AVCodecContext,在整个生命周期内使用,最后统一释放

2.内存生命周期关系图

bash 复制代码
打开文件
 ↓
[AVFormatContext]        ← 用于封装/解封装,生命周期较长
   ↓
 [AVStream]              ← 每个轨道对应一个 AVStream
   ↓
 [AVCodecParameters]     ← 编解码参数

打开编解码器
 ↓
[AVCodecContext]         ← 主要负责一条轨道的解码
 ↓
[AVFrame] / [AVPacket]   ← 每处理一帧数据时临时分配和释放

处理结束
 ↓
手动释放所有结构体及其 buffer

3.常用结构体的内存管理方式

4.典型内存释放策略

c 复制代码
// 分配
AVFormatContext *fmt_ctx = NULL;
avformat_open_input(&fmt_ctx, filename, NULL, NULL);

AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
avcodec_open2(codec_ctx, codec, NULL);

AVPacket *pkt = av_packet_alloc();
AVFrame *frame = av_frame_alloc();

// 使用
while(av_read_frame(fmt_ctx, pkt) >= 0){
	// 解码
	avcodec_send_packet(codec_ctx, pkt);
	avcodec_receive_frame(codec_ctx, frame);

	// 使用完后释放这帧
	av_packet_unref(pkt);
	av_frame_unref(frame);
}

// 释放资源
av_packet_free(&pkt);
av_frame_free(&frame);
avcodec_free_context(&codec_ctx);
avformat_close_input(&fmt_ctx);
相关推荐
Panesle10 小时前
HunyuanCustom:文生视频框架论文速读
人工智能·算法·音视频·文生视频
程序员JerrySUN16 小时前
驱动开发硬核特训 · Day 30(下篇): 深入解析 lm48100q I2C 音频编解码器驱动模型(基于 i.MX8MP)
linux·驱动开发·架构·音视频
读心悦21 小时前
5000字总结 HTML5 中的音频和视频,关羽标签、属性、API 和最佳实践
前端·音视频·html5
东风西巷1 天前
BLURRR剪辑软件免费版:创意剪辑,轻松上手,打造个性视频
android·智能手机·音视频·生活·软件需求
weixin_446260851 天前
视觉革命来袭!ComfyUI-LTXVideo 让视频创作更高效
人工智能·音视频
拧螺丝专业户1 天前
外网访问内网海康威视监控视频的方案:WebRTC + Coturn 搭建
音视频·webrtc·监控视频
追随远方1 天前
Android平台FFmpeg音视频开发深度指南
android·ffmpeg·音视频
Oliverro1 天前
嵌入式音视频通话EasyRTC基于WebRTC技术驱动智能带屏音箱:开启智能交互新体验
人工智能·音视频
佩奇的技术笔记2 天前
AI编程: 使用Trae1小时做成的音视频工具,提取音频并识别文本
音视频·ai编程
路溪非溪2 天前
音频类网站或者资讯总结
音视频