当前位置: 首页 > news >正文

嵌入式音视频开发——FFmpeg入门

FFmpeg 是一款功能强大且广泛使用的开源多媒体处理框架,主要用于处理音视频数据,包括转码、剪辑、合并、推流等操作。FFmpeg 的功能建立在一系列分工明确的核心库之上。为了更直观地理解它们如何协同工作,我准备了一张流程图,展示了处理媒体文件时这些库的典型协作关系:
在这里插入图片描述

上述流程展示了各库如何协作。

📊 核心组件库详解

库名称主要功能重要数据结构/API常见应用场景
libavformat处理多媒体文件的封装格式(容器,如MP4、MKV、FLV)和流媒体协议(如RTMP、RTSP、HLS)。负责解封装(Demuxing)和封装(Muxing)。AVFormatContext, AVInputFormat, AVOutputFormat, avformat_open_input(), av_read_frame(), avformat_write_header()读取本地文件或网络流、视频转封装(如MKV转MP4)、流媒体推送/拉流。
libavcodec提供丰富的编解码器(Codec),用于对音视频数据进行编码(压缩)和解码(解压缩),支持H.264、H.265、AAC、MP3等众多编解码标准。AVCodecContext, AVCodec, AVPacket, AVFrame, avcodec_send_packet(), avcodec_receive_frame()视频转码(如H.264转H.265)、提取音频、视频播放器的解码核心。
libavfilter支持通过滤镜(Filter)对音视频流进行复杂处理,如缩放、裁剪、叠加水印、降噪、变速等,并可组合成滤镜图(Filtergraph)。AVFilterGraph, AVFilterContext, AVFilter, avfilter_graph_create_filter(), av_buffersrc_add_frame(), av_buffersink_get_frame()给视频加水印、生成画中画、音频混音或降噪、高级剪辑特效。
libavutil一个包含通用工具函数的辅助库,提供哈希、数学运算、日志、时间戳转换、内存管理等常用功能,是其他库的基础。AVDictionary, AVRational, av_malloc(), av_log(), av_rescale_q()几乎所有FFmpeg操作都会间接使用它,用于基础工具操作和数据结构。
libswscale专门用于处理视频图像缩放、色彩空间转换(如YUV与RGB互转)和像素格式转换。SwsContext, sws_getContext(), sws_scale()调整视频分辨率、在显示前将视频帧转换为目标格式(例如OpenGL需要RGB)。
libswresample用于处理音频重采样、格式转换(如采样位数)和声道混合等操作。SwrContext, swr_alloc(), swr_convert()调整音频采样率(如44.1kHz转48kHz)、立体声转单声道、FLTP转S16。
libavdevice和多媒体设备交互的类库,使用这个库可以读取电脑(或其他设备上)的多媒体设备的数据,或输出数据到指定的多媒体设备上。AVInputFormat, AVOutputFormat, avdevice_register_all()从摄像头或麦克风采集数据、将渲染画面输出到指定窗口或屏幕。
libpostproc用于后期效果处理,主要用于提升视频质量,如去块效应(deblocking),修复编解码过程中产生的块效应。pp_get_context(), pp_postprocess()对低码率或压缩严重的视频进行后期增强,改善主观画质。

FFmpeg 的这些核心库就像一支分工明确的专业团队:

  • libavformat外交官,负责与各种文件格式和网络协议打交道。
  • libavcodec翻译官,负责编码和解码,即压缩和解压音视频数据。
  • libavfilter特效师,负责对原始素材进行各种加工和处理。
  • libavutil工具库,为整个团队提供各种基础支持。
  • libswscalelibswresample格式转换专家,分别负责视频和音频的格式转换。
  • libavdevice设备接口,负责与硬件设备连接。
  • libpostproc后期处理,负责一些画质增强工作。

FFmpeg 的工作流程涉及多个核心数据结构和 API 的协同。下图是一个典型的媒体文件转码处理流程,它展示了这些结构体和函数是如何串联起来的:

写入文件尾
上图展示了 FFmpeg 处理媒体的主要步骤和关键操作。接下来,我们详细了解流程中涉及的核心数据结构和 API。

📁 解复用与容器相关 (libavformat)

结构体/上下文主要用途描述关键成员/相关API
AVFormatContext媒体格式的上下文信息,是解复用/复用的核心结构,包含文件的全局信息。url: 文件路径或URL。 nb_streams: 流的数量。 streams: AVStream 指针数组。 duration: 文件总时长。 bit_rate: 平均比特率。 metadata: 元数据信息(如作者、标题)。
AVStream代表媒体文件中的一条流(如视频流、音频流、字幕流)。index: 流的索引。 codecpar: 指向 AVCodecParameters,存储流的编解码信息(如编码类型、分辨率、采样率)。 time_base: 该流的时间基,用于时间戳转换。 duration: 该流的时长。
AVInputFormat (Demuxer)描述输入容器格式(如MP4、FLV)。name: 格式名称。 long_name: 格式长名称。 read_probe: 探测文件格式的函数指针。 read_header: 读取文件头的函数指针。 read_packet: 读取数据包的函数指针。 read_seek: 跳转的函数指针。
AVOutputFormat (Muxer)描述输出容器格式name: 格式名称。 long_name: 格式长名称。 audio_codec: 默认的音频编解码器。 video_codec: 默认的视频编解码器。 write_header: 写入文件头的函数指针。 write_packet: 写入数据包的函数指针。 write_trailer: 写入文件尾的函数指针。
AVIOContext封装了低层I/O操作,支持文件、网络协议(如HTTP、RTMP)的读写。由FFmpeg内部管理,开发者通常通过 AVFormatContext 间接使用。

关键API (libavformat):

  • avformat_open_input(&fmt_ctx, filename, NULL, NULL): 打开输入文件,初始化 AVFormatContext
  • avformat_find_stream_info(fmt_ctx, NULL): 读取流信息,填充 AVFormatContext中的 streams 信息。
  • av_read_frame(fmt_ctx, &pkt): 读取一个数据包AVPacket)。
  • av_seek_frame(fmt_ctx, stream_index, timestamp, flags): 跳转到指定时间点
  • avformat_alloc_output_context2(&fmt_ctx, NULL, NULL, filename): 分配输出上下文,用于复用。
  • avio_open(&fmt_ctx->pb, filename, AVIO_FLAG_WRITE): 打开输出文件
  • avformat_write_header(fmt_ctx, NULL): 写入文件头
  • av_interleaved_write_frame(fmt_ctx, &pkt): 写入交错的数据包(保证音视频数据正确交织)。
  • av_write_trailer(fmt_ctx): 写入文件尾
  • avformat_close_input(&fmt_ctx): 关闭输入文件并释放资源

🔧 编解码相关 (libavcodec)

结构体/上下文主要用途描述关键成员/相关API
AVCodecContext编解码器的上下文,包含编解码所需的所有参数和信息。codec_type: 媒体类型(视频、音频等)。 codec: 指向 AVCodecbit_rate: 目标比特率。 width/height: 视频分辨率。 pix_fmt: 视频像素格式。 sample_rate: 音频采样率。 channel_layout: 音频声道布局。 sample_fmt: 音频采样格式。 time_base: 时间基。
AVCodec代表一个编解码器(如H.264编码器、AAC解码器)。name: 编解码器名称。 long_name: 编解码器描述名称。 type: 媒体类型。 id: 编解码器ID。 capabilities: 编解码器能力标志。
AVPacket存储压缩编码后的数据(如一个H.264 NAL单元,或一段AAC数据)。data: 指向数据缓冲区的指针。 size: 数据大小。 stream_index: 所属流的索引。 pts: 显示时间戳。 dts: 解码时间戳。 duration: 包持续时间。
AVFrame存储原始(未压缩)数据(如YUV视频帧,PCM音频帧)。data: 指向数据平面的指针数组(如Y, U, V分量)。 linesize: 每个数据平面的行大小(步长)。 width/height: 视频帧宽高。 nb_samples: 音频帧采样数。 format: 像素格式或采样格式。 pts: 显示时间戳。 sample_rate: 音频采样率。

关键API (libavcodec):

  • avcodec_find_decoder(codec_id)/ avcodec_find_encoder(codec_id): 根据ID查找编解码器
  • avcodec_alloc_context3(codec): 分配编解码器上下文
  • avcodec_parameters_to_context(dec_ctx, stream->codecpar): 从流中拷贝参数到编解码器上下文
  • avcodec_open2(codec_ctx, codec, NULL): 使用给定的编解码器初始化编解码器上下文
  • avcodec_send_packet(codec_ctx, pkt): 发送一个压缩数据包 (AVPacket) 给解码器。
  • avcodec_receive_frame(codec_ctx, frame): 从解码器接收一个解码后的帧 (AVFrame)
  • avcodec_send_frame(codec_ctx, frame): 发送一个原始帧 (AVFrame) 给编码器。
  • avcodec_receive_packet(codec_ctx, pkt): 从编码器接收一个编码后的数据包 (AVPacket)
  • av_packet_alloc(), av_packet_unref(), av_packet_free(): 分配、释放和取消引用 AVPacket
  • av_frame_alloc(), av_frame_unref(), av_frame_free(): 分配、释放和取消引用 AVFrame

🎨 处理与转换相关 (libswscale, libswresample, libavfilter)

结构体/上下文主要用途描述关键成员/相关API
SwsContext视频缩放和像素格式转换的上下文(来自libswscale)。通过 sws_getContext() 创建,由 sws_scale() 内部使用。
SwrContext音频重采样和格式转换的上下文(来自libswresample)。通过 swr_alloc()swr_alloc_set_opts() 创建,由 swr_convert() 内部使用。
AVFilterGraph, AVFilterContext滤镜图和滤镜上下文(来自libavfilter),用于构建复杂的滤镜流程。用于管理滤镜链和单个滤镜实例。

关键API:

  • sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, ...): 获取缩放/转换上下文
  • sws_scale(sws_ctx, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride): 执行视频缩放或像素格式转换
  • swr_alloc_set_opts(...): 分配并设置重采样上下文
  • swr_init(swr_ctx): 初始化重采样上下文
  • swr_convert(swr_ctx, &out_buf, out_samples, in_buf, in_samples): 执行音频重采样或格式转换
  • avfilter_graph_alloc(), avfilter_graph_create_filter(), avfilter_graph_parse_ptr(), avfilter_graph_config(): 用于构建和配置滤镜图

⚙️ 工具函数 (libavutil)

libavutil 提供了许多通用工具函数和宏,例如:

  • av_malloc(), av_free(): 内存分配与释放
  • av_log(): 日志输出
  • av_rescale_q(): 时间戳在不同时间基之间转换
  • av_gettime(): 获取当前时间

FFmpeg 也为用户提供了直接使用的命令行工具(Tools):

  • ffmpeg:这是最核心的命令行工具,用于转换音视频文件格式(转码)、进行剪辑、合并、提取、添加滤镜等各种操作。
  • ffplay:一个非常简单的媒体播放器,常用于快速预览媒体文件或测试。
  • ffprobe:用于分析媒体文件,显示其详细的流信息(如编解码器、分辨率、码率、时长等元数据)。
http://www.dtcms.com/a/391182.html

相关文章:

  • MySQL索引篇---B+树在索引中的工作原理
  • 强化学习训练-数据处理
  • VirtualBox为ubuntu系统设置共享文件夹
  • Python实战进阶》No.41: 使用 Streamlit 快速构建 ML 应用
  • Salesforce 执行顺序(Order of Execution)详解
  • Linux内核进程管理子系统有什么第五十七回 —— 进程主结构详解(53)
  • Vue 记账凭证模块组件
  • ORACLE-数据库闪回
  • 【Python】集合
  • 【Leetcode hot 100】437.路径总和 Ⅲ
  • 神经网络学习笔记16——高效卷积神经网络架构汇总(SqueezeNet、MobileNet、ShuffleNet、EfficientNet、GhostNet)
  • 解码阳光电源技术壁垒:以IPD和数字化驱动模块化创新的研发体系
  • ARM体系结构—架构—指令集—寄存器—工作模式
  • 自适应全变分模型的图像平滑去噪与边缘保留算法
  • 主流前端框架比较
  • 前端接口参数序列化
  • 精细调光,稳定驱动:AP5165B 在低压LED照明中的卓越表现
  • EasyGBS如何实现企业园区视频监控一体化管理?
  • Ledit 16.3 版图软件全面系统性教程
  • Linux的DTS配置信息
  • 线程池全面解析:核心原理、参数配置与实践指南
  • 【Linux】自定义协议——网络计算器实现
  • Ubuntu 安装的docker-compose拉取镜像失败问题处理办法
  • 第35篇:AI前沿:具身智能(Embodied AI)与通用人工智能(AGI)
  • LangChain 入门到精通企业项目实践之 LangChain 聊天模型
  • crush情感分析项目01
  • 免费插件分享 | Missing References Search
  • ECU OTA测试
  • Jenkins运维之路(Slave容器节点)
  • Amazon Lambda + API Gateway 实战,无服务器架构入门