本文的代码下载地址:GitHub,编译环境是Qt5.15.2跟MSVC2019_64bit。 跟 读取文件内容 相关的结构体如下: 1,AVPacket,一个管理压缩后的媒体数据的结构,它本身不包含压缩的媒体数据,而是通过data指针指向媒体数据。 这里面的媒体数据通常是一帧视频的数据,或者一帧音频的数据。但是也有一些特殊情况,这个AVPacket的data是空的,只有sidedata的数据。sidedata是一些附加信息。 跟 读取文件内容 相关的函数如下: 1,av_packet_alloc,初始化一个 AV...
本文的代码下载地址:GitHub,编译环境是Qt5.15.2跟MSVC2019_64bit。 跟解码相关的结构体如下: 1,AVCodecContext,这个结构体可以是 编码器 的上下文,也可以是 解码器 的上下文,两者使用的是同一种数据结构。 2,AVCodec,编解码信息。 3,AVCodecParameters,编解码参数。 4,AVPacket ,数据包(已编码压缩),这里面的数据通常是一帧视频的数据,或者一帧音频的数据。AVPacket 他本身是没有编码数据的,他只是管理编...
本文的代码下载地址:GitHub,编译环境是Qt5.15.2跟MSVC2019_64bit。 注意事项,需要配置install参数,才能把 juren-30s.mp4 跟相关的FFmpegDLL文件会拷贝到调试目录,配置install的参数如下: 跟编码相关的结构体如下: 1,AVCodecContext,这个结构体可以是 编码器 的上下文,也可以是 解码器 的上下文,两者使用的是同一种数据结构。 2,AVCodec,编解码信息。 3,AVCodecParameters,编解码参数。 4...
编码器(encode)的参数也是分为 通用部分 跟 私有部分。通用部分是指大部分编码器都有的属性,例如码率就是通用的。通用部分的参数是在 avcodec_options 变量里面的,如下: 也可以通过 ffmpeg.exe-h>t.txt 来查看通用部分,如下: 编码器私有部分的参数可以通过以下命令查询: ffmpeg.exe-hdecoder=libx264ffmpeg.exe-hencoder=libx264 无论是通用还是私有属性,都是使用 AVDictionar...
本文介绍如何使用FFmpeg的API函数 avio_open2 打开一个输出文件,然后用 av_interleaved_write_frame 来把编码器输出的 AVPacket 保存进去文件。 本文的代码下载地址:GitHub,编译环境是Qt5.15.2跟MSVC2019_64bit。 与输出相关的API函数如下: 1,avformat_alloc_output_context2,申请一个输出文件上下文,这个函数会生成 AVFormatContext 2,avfor...
FFmpeg项目里面输出日志信息的函数是 av_log,使用 av_log 函数可以在二次开发的时候,比较方便地做一些跟踪跟记录,可以把 av_log 作为 printf 函数的替代品。 av_log 函数的定义如下: /Sendthespecifiedmessagetothelogifthelevelislessthanorequaltothecurrentav_log_level.Bydefault,allloggingmessagesaresenttost...
大部分开源项目都会封装一下错误码,FFmpeg也不例外。FFmpeg对错误码以及相关的API函数的定义是在 libavutil/error.h 里面的,如下: defineFFERRTAG(a,b,c,d)(-(int)MKTAG(a,b,c,d))defineAVERROR_BSF_NOT_FOUNDFFERRTAG(0xF8,'B','S','F')///<BitstreamfilternotfounddefineAVERROR_BUGFFERRTAG('B','U','G','!')///<Internalbug,alsoseeAVERROR...
FFmpeg是一个C语言的项目,C语言标准库的功能比较简陋,所以很多东西都要自己写,造轮子。FFmpeg 已经造了不少轮子,AVString 就是其中一个轮子,用 AVString 函数库,可以使字符串处理更加方便。 AVString 函数库的代码在 libavutil/avstring.h 里面,本文选取一些常用的函数来讲解。 1,av_strstart(),检查 str 字符串是不是以 pfx 开头的,如果是,返回...
在前面的文章《如何设置解复用器参数》跟《如何设置编码器参数》中,我们学习了如何用 AVDictionary 来设置解复用器,编码器的参数。 但是还有另一种方法也可以设置各种数据结构的参数,那就是用 AVOptions 的方式。 AVOptions 相关的API函数,都在 libavutil/opt.h 里面,本文会选取一部分API函数来做讲解。 本文的代码下载地址:GitHub,编译环境是Qt5.15.2跟MSVC2019_64bit。 上图中,我设置了两个属性...
AVPixFmtDescriptor 是FFmpeg里面描述像素格式具体信息的一个结构,这个结构其实非常常用,像素怎么存储,排列的,都描述在这个 AVPixFmtDescriptor 结构里面。 下面来详细讲解一下这个结构体,定义在 pixdesc.h 文件里面。 typedefstructAVPixFmtDescriptor{constcharname;uint8_tnb_components;uint8_tlog2_chroma_w;uint8_tlog2_chroma_h;uint64_tflags;AVCo...
FFmpeg采用了FilterGraph的模型来管理整个数据流的处理,参与数据处理的各个功能模块叫做Filter(滤镜)。 普通的用户在使用音视频剪辑软件的时候,会把滤镜这个词理解为app上提供的一些特效,例如变场,镜像,加水印等等。 但是在FFmpeg音视频开发领域,Filter(滤镜)是指对音视频数据的处理,包括裁剪,转换采样率格式,转换封装格式等等,这些很简单的功能,在FFmpeg里面也是一个Filter。 所以,你可以把Filter(滤镜)看成是一个大杂烩,有很多功能,这些功能都是用来对音频或者视频的数据进行处理。 各个Filter会在FilterGraph中按照一定的顺序连接起来,...
FFmpeg的滤镜API其实有3种调用方法,我个人觉得他是3种用法,如下: 1,用 avfilter_graph_create_filter 一个一个地创建滤镜(AVFilterContext),然后用 avfilter_link 函数把各个滤镜的输入输出连接起来,这种方式比较灵活,但是非常繁琐。 2,下面的命令定义了一个滤镜字符串 "[0:v]scale=iw/2:ih/2" ,直接使用 avfilter_graph_parse2 来解析这个字符串。avfilter_g...
本文介绍split滤镜的用法以及 avfilter_link 函数的具体用法。 本文的代码下载地址:GitHub,编译环境是Qt5.15.2跟MSVC2019_64bit。 上下文这个词读起来不太通顺,context 这个单词我后面把它翻译成实例吧,滤镜实例。 之前在 scale-1 项目留了一个问题,就是 avfilter_link 函数的第二第四个参数的作用是什么。 avfilter_link 函数的定义如下: intavfilter_link(AVF...
前面介绍FFmpeg滤镜的文章,其实埋了一个坑,滤镜实例有输入跟输出。但是往buffer滤镜实例输入的AVFrame不是无限的,总会有读完文件的一刻。从buffersink滤镜实例输出的AVFrame也不是无限的,总会有刷完的一刻。 没有AVFrame可以输入了,怎么处理?没有AVFrame可以刷出来了,又怎么处理? 这就是本文的重点,本文会通过overlay滤镜来写一个小demo 本文用overlay滤镜实现一个往视频里面加logo水印图片的例子,代码下载地址:GitHub 初始化跟创建滤镜实例跟容器的代码如下: 这次我初始化的时候,在字符串里面写了两个buffer,然后我只需...
视频的 format 滤镜是一个非常常用的滤镜,用来转换图像的格式,例如可以把 AV_PIX_FMT_YUV420P 转成 AV_PIX_FMT_RGB24。 我们可以用以下命令查询format滤镜支持的参数: ffmpeg-hide_banner1-hfilter=format 从上图可以看到,只有一个参数 pix_fmts,但是这个 pix_fmts 这个参数的 value 是一个列表。列表里面可以只有一种图像格式,也可以有多种...
前面介绍了FFmpeg的 format 视频格式滤镜,那很显然,音频也会有一个格式滤镜,用来转换音频采样格式,调整采样率或者声道布局。 音频的格式滤镜叫 aformat,前面加了个 a 而已。 这是FFmpeg整个开源项目的命名习惯,不仅仅是格式滤镜,还有 buffer 滤镜与 abuffer 滤镜,这两个分别是视频,音频的入口滤镜。而出口滤镜是 buffersink 与 abuffersink。 总之,如果你遇到一个视...
sws_scale() 是 libswscale 库里面一个非常常用的函数,它的功能如下: 1,对图像的大小进行缩放。 2,转换图像格式跟颜色空间,例如把 YUYV422 转成 RGB24 。 3,转换像素格式的存储布局,例如把 YUYV422 转成 YUV420P ,YUYV422 是 packed 的布局,YUV3个分量是一起存储在 data[0] 里面的。而...
在做音频处理的时候,我们有时候需要调整音频流的采样率或者采样格式,可能是喇叭不支持48000采样率,所以需要降低到44100采样了.也可能因为各种业务原因,需要调整采样率,采样格式,或者声道布局。 FFmpeg提供了 swr_convert() 函数来实现上面的功能。 需要注意的是,调整采样率,是不会影响音频流的播放时长的,原来是10分钟的音频文件,你调高或者降低采样率,它还是10分钟的播放时长。 不过 swr_convert() 是支持调整播放时长的,这个后面说。 下面通过一个代码实例演示 swr_convert()...
在做音视频数据分析的时候,经常会遇到这样的需求,每隔5分钟抽取一帧数据进行分析。 在做播放器开发的时候,也会遇到这种情况,就是拖动进度条跳转到某个位置进行播放。 如果直接用 av_read_frame() 不断读数据,读到第5分钟的 AVPacket 才开始处理,其他读出来的 AVPacket 丢弃,这样做会带来非常大的磁盘IO。 其实上面两种场景,都可以用同一个函数解决,那就是 avformat_seek_file(),这个函数类似于 Linux 的 ...
ffmpeg 支持从网络流或者本地文件读取数据,然后拿去丢给解码器解码,但是有一种特殊情况,就是数据不是从网络来的,也不在本地文件里面,而是在某块内存里面的。 这时候 av_read_frame() 函数怎样才能从内存把 AVPacket 读出来呢? FFmpeg的开发者一早就考虑到这个问题了,所以他们提供了一个自定义 avio 的功能。利用这个功能,你可以自定义封装层的输入函数,也可以自定义封装层的输出函数。 没错,输出你也可以输出到一块内存里面,而不是保存到本地文件。 本文的代码下载地址...