FFmpeg笔记

本文详细介绍了FFmpeg的组成结构,包括libavcodec、libavutil等组件,并讲解了环境部署、shared版exe程序的使用及命令参数。重点探讨了dev版ffmpeg播放视频的流程,如解协议、解封装、解码、音视频同步等步骤,以及常用API的使用,如av_register_all、avcodec_find_decoder等。同时,文章列举了多个关键的FFmpeg结构体,如AVFormatContext、AVStream和AVCodecContext等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ffmpeg是一个开源的音视频编解码工具,很多音视频播放器和转码器都将其作为内核。

ffmpeg的组成结构

  • libavcodec encoding/decoding library
  • libavutil common utility library
  • libavformat I/O and muxing/demuxing library
  • libavfilter graph-based frame editing library
  • libavdevice special devices muxing/demuxing library
  • libswscale color conversion and scaling library
  • libswresample audio resampling, format conversion and mixing
  • libpostproc post processing library

环境部署

ffmpeg官网提供三个不同版本的下载,

版本介绍总结
static包含了三个体积较大的exe:ffmpeg.exe、ffplay.exe和ffprobe.exe,所有dll已经编译到exe中去了产品化的东西,小型项目直接使用
shared也包含了这三个exe,体积更小,运行时动态调用dll链接库产品化的东西,适用于大型项目
dev包含的是lib包和头文件适用于开发使用

从官网上下载dev版本,然后将include目录添加到项目的包含目录中,lib目录添加到项目的库文件目录中,将几个lib文件的名字添加到编译器的输入中。

shared版exe程序的使用

常见使用命令参数

如果仅仅想实现功能上的快速开发,可以直接调用exe

  • ffmpeg是用来转码的
  • ffplay是用来播放的
  • ffprobe是用来查看文件格式的
参数选项解释总结
-i filename输入文件可以输入多个
-y当输出文件已经存在时,是否执行覆盖缺省时,文件已存在会触发异常
-ss start_time -to end_time截取时间时间的格式既可以是xx:xx:xx也可以是浮点数xxx.xxx
-ss start_time -t duration截取时间
-r fps设置视频的帧率
-vcodec codec强制使用codec编解码方式codec可以设置为copy
-b bitrate设置比特率,缺省200kb/s

踩坑记录:
音视频混流时,音频文件必须在视频文件前面

dev版ffmpeg播放视频的流程

[外链图片转存失败(img-fGgcSEzA-1562145982594)(FC05DC45CAB842A4BCB1FB31D48E1227)]

播放一个视频的全部流程:

  • 解协议:如果视频数据是通过网络传输,那么第一步就是解协议。解协议将流媒体协议的数据,解析为标准的相应的封装格式数据。常见的解协议有HTTP,RTMP,或是MMS等等
  • 解封装demux:将封装格式数据(e.g. MKV)中的视频压缩数据(e.g. H.264)和音频压缩数据(e.g. AAC)分离开,这个过程中不涉及编码和解码。将读取一个媒体文件,然后将其拆分为数据块(data chunk)
  • 解码:就是将视频/音频压缩编码数据,解码成为非压缩的视频/音频原始数据
  • 音视频同步:播放一个视频的最后一步就是音视频同步。这个过程将根据解封装模块处理过程中获取到的参数信息,同步解码出来的视频和音频数据,并将视频音频数据送至系统的显卡和声卡播放出来

除此之外,在处理完视频帧后,

  • 音视频编码:将视频像素数据(RGB,YUV等)压缩成为视频码流,将音频采样数据(PCM等)压缩成为音频码流,从而降低音视频的数据量

常用API(根据原官方文档做了个性化翻译,具体以官方文档为准)

av_register_all 注册所有组件
打开和关闭视频

int avformat_open_input(AVFormatContext **ptr, const char * filename, AVInputFormat *fmt, AVDictionary **options)

打开一个媒体文件,将格式上下文保存在ptr指向的结构体中

  • fmt forces file format if not NULL.
  • options 附加的选项,可以为NULL
  • 函数执行成功,返回大于等于0的值

void avformat_close_input(AVFormatContex ** s)

关闭一个打开的AVFormatContext

寻找流信息,获取帧信息

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary ** options)

读取媒体文件的packets来获取流信息,成功时返回值大于等于0

int av_read_frame(AVFormatContext * s, AVPacket * pkt)

读取流中的下一帧,只返回的只是文件存储的东西,可能对解码器是无效的一帧

如果pkt->buf是NULL,那么直到下一个av_read_frame()或者直到avformat_open_input,当前packet都是有效的
对于视频来说packet只包含一帧,但是对于音频来说,如果每帧的大小是已知的,那么包含的是帧数,如果大小是变量,那么包含一帧。

int av_parse_video_size(int * width_ptr, int * height_ptr, const char * str)

解析str,并将解析得到的长度和宽度保存在height_ptr和width_ptr中

缩放视频

struct SwsContext * sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter * srcFilter, SwsFilter * dstFilter, const double * param)

部署和运行SwsContext

  • srcW/srcH/srcFormat 原图片的宽度、高度和格式
  • dstW/dstH/dstFormat 目标图片的宽度、高度和格式
  • flags 指定使用哪种算法和选项来重缩放
  • param 额外的参数

int sws_scale(struct SwsContext * c, const uint8_t * const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t * const dst[], const int dstStride[])

在srcSlice中缩放图像切片

  • c 使用sws_getContext()创建的缩放上下文
  • srcSlice 包含指向原切片指针的数组
  • srcStride 包含原图像步长的数组
  • srcSliceY
  • srcSliceH
  • dst
  • dstStride

返回输出切片的高度

void sws_freeContext(struct SwsContext * swsContext)

释放

avcodec_find_decoder 找到解码器
avcodec_open2 打开解码器
av_read_frame 读取帧
avcodec_decode_video2 开始解码

常用的结构体

在这里插入图片描述

1. AVFormatContext类

格式化IO上下文,在使用FFMPEG进行开发的时候,AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数。它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体

属性:

  1. AVStream** AVFormatContext::streams

包含文件中所有流的一个列表,在解封装demux的时候,创建方法有两种:avformat_open_input()和av_read_frame();在mux的时候,在avformat_writer_header()前通过用户创建

  1. unsigned int AVFormatContext::nb_streams

AVFormatContext.streams中元素的个数

  1. int AVFormatContext::ctx_flags

标记符号流属性

  1. int64_t AVFormatContext::start_time

组成部分中第一个帧的位置

  1. int64_t AVFormatContext::duration

流的时长

  1. int64_t AVFormatContext::bit_rate

码率bit/s

  1. int64_t AVFormatContext::packet_size
2. AVInputFormat

每种封装格式例如FLV\MKV\MP4\AVI对应一个该结构体

3. AVStream 每个视频流、音频流对应一个结构体
  1. int index stream index in AVFormatContext
  2. int id
  3. void* priv_data
  4. AVRational time_base
  5. int64_t start_time
  6. int64_t duration
  7. int64_t nb_frames 当前流中的帧数
  8. int disposition
  9. AVCodecParameters * codecpar
4. AVCodecContext 编解码上下文结构体
5. AVCodec|每种视频/音频编解码器例如H.264解码器对应一个该结构体
6. AVPacket|存储一帧压缩编码数据
7. AVFrame|存储一帧解码后像素/采样数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值