欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > FFmpeg视频处理入门级教程

FFmpeg视频处理入门级教程

2025/2/27 4:33:19 来源:https://blog.csdn.net/evm_doc/article/details/145822006  浏览:    关键词:FFmpeg视频处理入门级教程

在这里插入图片描述

一、FFmpeg常规处理流程

初始化上下文
打开媒体文件
查找流信息
获取视频流索引
获取解码器
打开解码器
循环读取数据包
是否视频流?
解码数据包
处理解码帧
释放资源

文字说明:

  1. 初始化容器格式和编解码器
  2. 打开输入文件建立连接
  3. 解析媒体流信息(时长/分辨率/编码格式等)
  4. 遍历找到视频流索引
  5. 根据编码器ID查找对应解码器
  6. 初始化并配置解码器上下文
  7. 循环读取压缩数据包
  8. 判断数据包类型并解码视频帧
  9. 对原始帧进行格式转换或处理
  10. 释放所有分配的资源

二、FFmpeg核心模块解析

2.1 模块预览

FFmpeg由多个功能模块组成,以下是8个核心模块的详细说明:

模块名称功能描述典型应用场景
libavcodec编解码库,包含主流音视频编码器的实现H.264解码、MP3编码、音频重采样
libavformat封装/解封装库,处理多媒体容器格式(MP4/MKV/FLV等)解析MP4文件头信息、将H.264流封装为TS格式
libavutil基础工具库,提供通用数据结构、数学运算等基础功能时间戳计算、内存管理、日志输出
libswscale图像处理库,实现色彩空间转换和图像缩放YUV420转RGB24、4K视频缩放到1080p
libavfilter滤镜处理库,支持多路视频流的复杂滤镜处理添加水印、视频画中画、音频混音
libavdevice设备访问库,支持采集显示设备数据摄像头抓取画面、屏幕录制、音频采集卡输入
libswresample音频重采样库,处理音频格式转换48kHz转44.1kHz、单声道转立体声、PCM格式转换
libpostproc后处理库,提供视频后期效果处理视频去块效应、MPEG视频补偿

模块依赖关系:

avformat → avcodec → avutil
avfilter → avformat
swscale/swresample → avutil

2.2 部分模块说明详解:

libavcodec 工作机理

输入编码数据
解析帧头信息
初始化解码器
空间分配
熵解码
反量化
反变换
运动补偿
输出YUV帧

libavfilter 处理链示例

// 创建滤镜图:视频缩放+叠加水印
filter_graph = avfilter_graph_alloc();
avfilter_graph_create_filter(&buffer_src_ctx, "输入源");
avfilter_graph_create_filter(&scale_filter, "scale=640:480");
avfilter_graph_create_filter(&overlay_filter, "overlay=10:10");
avfilter_graph_create_filter(&buffer_sink_ctx, "输出端");// 连接滤镜节点
avfilter_link(buffer_src_ctx, 0, scale_filter, 0);
avfilter_link(scale_filter, 0, overlay_filter, 0);
avfilter_link(overlay_filter, 0, buffer_sink_ctx, 0);

模块选择原则

  1. 文件操作:优先使用avformat
  2. 编解码处理:使用avcodec
  3. 图像处理:使用swscale或avfilter
  4. 实时流采集:配合avdevice使用

三、核心API函数说明

函数名称功能描述关键参数说明
av_register_all()注册所有封装格式与编解码器(新版本已弃用)无参数
avformat_open_input()打开媒体文件并初始化AVFormatContextps: 上下文指针地址
url: 文件路径
fmt: 强制指定格式(可NULL)
avformat_find_stream_info()获取媒体流详细信息ic: 上下文指针
options: 额外选项(通常NULL)
avcodec_find_decoder()根据编码ID查找解码器id: 编码格式ID(如AV_CODEC_ID_H264)
avcodec_open2()打开解码器avctx: 解码器上下文
codec: 解码器指针
options: 额外参数
av_read_frame()读取媒体文件中的数据包s: 上下文指针
pkt: 输出的数据包
avcodec_send_packet()发送压缩数据到解码器avctx: 解码器上下文
avpkt: 输入数据包
avcodec_receive_frame()从解码器获取解码后的帧avctx: 解码器上下文
frame: 输出的原始帧
sws_getContext()初始化图像缩放转换上下文参数包含源/目标分辨率、格式等图像特征
sws_scale()执行像素格式转换和缩放sws_ctx: 转换上下文
srcSlice: 源数据指针

四、视频解码显示实战

实现一个ffmpeg读取视频文件,并使用opencv进行显示的例子。

4.1 实现流程图

初始化FFmpeg
打开视频文件
获取视频流信息
定位视频流索引
配置解码器
初始化SWS转换上下文
循环读取帧
解码完成?
读取数据包
是视频包?
发送到解码器
接收解码帧
转换为RGB格式
OpenCV显示
释放资源

4.2 完整实现代码

#include <opencv2/opencv.hpp>
extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}int main() {// 初始化FFmpegavformat_network_init();AVFormatContext* fmt_ctx = NULL;// 打开输入文件if(avformat_open_input(&fmt_ctx, "test.mp4", NULL, NULL) != 0){printf("无法打开文件\n");return -1;}// 获取流信息if(avformat_find_stream_info(fmt_ctx, NULL) < 0){printf("无法获取流信息\n");return -1;}// 查找视频流索引int video_stream = -1;for(int i=0; i<fmt_ctx->nb_streams; i++){if(fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){video_stream = i;break;}}// 获取解码器参数AVCodecParameters* codec_par = fmt_ctx->streams[video_stream]->codecpar;const AVCodec* decoder = avcodec_find_decoder(codec_par->codec_id);// 初始化解码器上下文AVCodecContext* codec_ctx = avcodec_alloc_context3(decoder);avcodec_parameters_to_context(codec_ctx, codec_par);avcodec_open2(codec_ctx, decoder, NULL);// 准备转换上下文(YUV->RGB)SwsContext* sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,codec_ctx->width, codec_ctx->height, AV_PIX_FMT_RGB24,SWS_BILINEAR, NULL, NULL, NULL);// 准备帧结构AVFrame* frame = av_frame_alloc();AVFrame* rgb_frame = av_frame_alloc();uint8_t* buffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1));av_image_fill_arrays(rgb_frame->data, rgb_frame->linesize, buffer, AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1);AVPacket pkt;while(av_read_frame(fmt_ctx, &pkt) >= 0){if(pkt.stream_index == video_stream){// 发送到解码器avcodec_send_packet(codec_ctx, &pkt);// 接收解码帧while(avcodec_receive_frame(codec_ctx, frame) == 0){// 格式转换sws_scale(sws_ctx, (const uint8_t* const*)frame->data, frame->linesize,0, codec_ctx->height,rgb_frame->data, rgb_frame->linesize);// OpenCV显示cv::Mat img(codec_ctx->height, codec_ctx->width, CV_8UC3, rgb_frame->data[0]);cv::imshow("Video", img);cv::waitKey(1);}}av_packet_unref(&pkt);}// 释放资源av_frame_free(&frame);av_frame_free(&rgb_frame);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);sws_freeContext(sws_ctx);return 0;
}

4.3 关键代码解析

  1. 图像转换配置:
sws_ctx = sws_getContext(   // 创建转换器实例srcW, srcH, srcFormat,  // 源图像参数dstW, dstH, dstFormat,  // 目标图像参数flags,                  // 缩放算法选择...);                   // 其他可选参数
  1. OpenCV显示核心:
cv::Mat img(height, width,        // 创建Mat对象CV_8UC3,                      // 数据类型:8位无符号3通道rgb_frame->data[0],           // RGB数据首地址rgb_frame->linesize[0]);      // 每行字节数(步长)
  1. 解码循环逻辑:
while(av_read_frame() >=0){       // 读取压缩包if(视频流){avcodec_send_packet();    // 送入解码队列while(avcodec_receive_frame() ==0){ // 获取解码帧// 处理帧数据}}av_packet_unref();            // 必须释放数据包
}

五、常见问题处理

  1. 颜色显示异常:检查像素格式转换参数(AV_PIX_FMT_RGB24)
  2. 无法打开文件:检查文件路径和FFmpeg的协议支持
  3. 内存泄漏:确保每个av_malloc都有对应的av_free
  4. 花屏现象:检查解码器是否成功初始化,数据包是否完整

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词