个人ffmpeg笔记(一)

环境安装

QT环境安装

  1. 运行qt…run安装

下载地址:https://download.qt.io/archive/qt/
下载地址:https://download.qt.io/archive/qt/5.12/5.12.10/

  1. sudo apt install --reinstall libxcb-xinerama0 解决xcb问题

  2. Ubuntu16.04打开Qt显示/home/user/.config/QtProject/qtcreator/qtversion.xml :Permission denied

    权限不够所导致,执⾏命令 sudo chown -R user:user ~/.config/ 即可解决

ffmpeg环境安装

apt安装:

sudo apt-get update
sudo apt-get install -y \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libsdl2-dev \
  libtool \
  libva-dev \
  libvdpau-dev \
  libvorbis-dev \
  libxcb1-dev \
  libxcb-shm0-dev \
  libxcb-xfixes0-dev \
  libfdk-aac-dev \
  libfaad-dev \
  pkg-config \
  texinfo \
  wget \
  zlib1g-dev

sudo apt-get install -y \
	nasm \
	yasm \
	libx264-dev \
	libx265-dev \
	libnuma-dev \
	libvpx-dev \
	libfdk-aac-dev \
	libmp3lame-dev \
	libopus-dev 

apt安装:

sudo apt install ffmpeg
vi  ~/.bashrc
export PATH="/usr/bin:$PATH"
source ~/.bashrc

源码安装:

一、创建目录
在home目录下创建
ffmpeg_sources:用于下载源文件
ffmpeg_build: 存储编译后的库文件
bin:存储二进制文件(ffmpeg,ffplay,ffprobe,X264,X265等)
cd ~
mkdir ffmpeg_sources ffmpeg_build bin

二、安装依赖
sudo apt-get update
sudo apt-get -y install \
autoconf \
automake \
build-essential \
cmake \
git-core \
libass-dev \
libfreetype6-dev \
libsdl2-dev \
libtool \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libxcb1-dev \
libxcb-shm0-dev \
libxcb-xfixes0-dev \
pkg-config \
texinfo \
wget \
zlib1g-dev

NASM使用源码进行安装
cd ~/ffmpeg_sources && \
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2 && \
tar xjvf nasm-2.14.02.tar.bz2 && \
cd nasm-2.14.02 && \
./autogen.sh && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" &&
\
make && \
make install

Yasm使用源码进行安装:
cd ~/ffmpeg_sources && \
wget -O yasm-1.3.0.tar.gz https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz && \
tar xzvf yasm-1.3.0.tar.gz && \
cd yasm-1.3.0 && \
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" && \
make && \
make install

libx264
H.264视频编码器。更多信息和使用范例参考H.264 Encoding Guide
要求编译ffmpeg时配置:--enable-gpl --enable-libx264.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C x264 pull 2> /dev/null || git clone --depth 1 https://gitee.com/ibaoger/x264.git && \
cd x264 && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" && \
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --enable-pic && \
PATH="$HOME/bin:$PATH" make && \
make install

libx265
H.265/HEVC 视频编码器, 更多信息和使用范例参考H.265 Encoding Guide。
要求编译ffmpeg时配置:--enable-gpl --enable-libx265.
使用源码进行编译:
sudo apt-get install mercurial libnuma-dev && \
cd ~/ffmpeg_sources && git clone https://gitee.com/mirrors_videolan/x265.git && \
cd x265/build/linux && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off ../../source && \
PATH="$HOME/bin:$PATH" make && \
make install

libvpx
VP8/VP9视频编解码器。 更多信息和使用范例参考VP9 Video Encoding Guide 。
要求编译ffmpeg时配置: --enable-libvpx.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C libvpx pull 2> /dev/null || git clone --depth 1 https://github.com/webmproject/libvpx.git && \
cd libvpx && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm --enable-pic && \
PATH="$HOME/bin:$PATH" make && \
make install

libfdk-aac
AAC音频编码器. 更多信息和使用范例参考AAC Audio Encoding Guide。
要求编译ffmpeg时配置:--enable-libfdk-aac ( 如果你已经配置了 --enable-gpl则需要加上--enablenonfree).
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C fdk-aac pull 2> /dev/null || git clone --depth 1 https://github.com/mstorsjo/fdk-aac && \
cd fdk-aac && \
autoreconf -fiv && \
./configure CFLAGS=-fPIC --prefix="$HOME/ffmpeg_build" && \
make && \
make install

libmp3lame
MP3音频编码器.
要求编译ffmpeg时配置:--enable-libmp3lame.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git clone --depth 1 https://gitee.com/qingfuliao/lame && \
cd lame && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-nasm --with-pic && \
PATH="$HOME/bin:$PATH" make && \
make install

libopus
Opus音频编解码器.
要求编译ffmpeg时配置:--enable-libopus.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C opus pull 2> /dev/null || git clone --depth 1 https://gitee.com/ttsu00/opus.git && \
cd opus && \
./autogen.sh && \
./configure --prefix="$HOME/ffmpeg_build" -with-pic&& \
make && \
make install

FFmpeg
cd ~/ffmpeg_sources && \
wget -O ffmpeg-4.2.1.tar.bz2 https://ffmpeg.org/releases/ffmpeg-4.2.1.tar.bz2 && \
tar xjvf ffmpeg-4.2.1.tar.bz2 && \
cd ffmpeg-4.2.1 && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" CFLAGS="-O3 -fPIC" ./configure \
--prefix="$HOME/ffmpeg_build" \
--pkg-config-flags="--static" \
--extra-cflags="-I$HOME/ffmpeg_build/include" \
--extra-ldflags="-L$HOME/ffmpeg_build/lib" \
--extra-libs="-lpthread -lm" \
--bindir="$HOME/bin" \
--enable-gpl \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-openssl \
--enable-pic \
--enable-shared \
--enable-nonfree \
--enable-debug=3 \
--disable-optimizations \
--disable-asm \
--disable-stripping && \
PATH="$HOME/bin:$PATH" make && \
make install && \
hash -r
然后重新登录系统或者在当前shell会话执行如下命令以识别新安装ffmpeg的位置:
source ~/.profile
现在已经完成编译和安装ffmpeg (also ffplay, ffprobe, lame, x264, & x265) 。该文档剩余章节主要讲如何更新和删除ffmepg。
编译完成后,ffmpeg_build ffmpeg_sources bin目录的大体情况

加入命令:
vi ~/.bashrc
export PATH="$PATH:/usr/local/bin"   这里需要写入正确路径
source ~/.bashrc

环境使用

Cmake
cmake_minimum_required(VERSION 3.10)
project(ffmpeg_test)

# 设置C标准
set(CMAKE_C_STANDARD 99)

# 查找FFmpeg库
find_package(PkgConfig REQUIRED)
pkg_check_modules(AVFORMAT REQUIRED libavformat)
pkg_check_modules(AVCODEC REQUIRED libavcodec)
pkg_check_modules(AVUTIL REQUIRED libavutil)
pkg_check_modules(AVDEVICE REQUIRED libavdevice)
pkg_check_modules(AVFILTER REQUIRED libavfilter)
pkg_check_modules(POSTPROC REQUIRED libpostproc)
pkg_check_modules(SWRESAMPLE REQUIRED libswresample)
pkg_check_modules(SWSCALE REQUIRED libswscale)

find_package(SDL2 REQUIRED)
link_libraries(SDL2)

# 包含FFmpeg头文件路径
include_directories(${AVFORMAT_INCLUDE_DIRS})
include_directories(${AVCODEC_INCLUDE_DIRS})
include_directories(${AVUTIL_INCLUDE_DIRS})
include_directories(${AVDEVICE_INCLUDE_DIRS})
include_directories(${AVFILTER_INCLUDE_DIRS})
include_directories(${POSTPROC_INCLUDE_DIRS})
include_directories(${SWRESAMPLE_INCLUDE_DIRS})
include_directories(${SWSCALE_INCLUDE_DIRS})

# 添加可执行文件
add_executable(ffmpeg_test main.cpp)

# 链接FFmpeg库
target_link_libraries(ffmpeg_muxmp4 ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES} ${AVUTIL_LIBRARIES} ${AVDEVICE_LIBRARIES} ${AVFILTER_LIBRARIES} ${POSTPROC_LIBRARIES} ${SWRESAMPLE_LIBRARIES}  ${SWSCALE_LIBRARIES} )

QT
CONFIG += link_pkgconfig
PKGCONFIG += sdl2

LIBS += -L/home/enpht/sdk/ffmpeg4/ffmpeg_build/lib/ -lavcodec -lavformat -lavutil -lswscale -lavfilter -lavdevice -lswresample -lfdk-aac
INCLUDEPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
DEPENDPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp \
    muxer.cpp \
    audioencoder.cpp \
    videoencoder.cpp \
    audioresampler.cpp

win32 {
INCLUDEPATH += $$PWD/ffmpeg-4.2.1-win32-dev/include
LIBS += $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib   \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/avcodec.lib    \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/avdevice.lib   \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/avfilter.lib   \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/avutil.lib     \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/postproc.lib   \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/swresample.lib \
        $$PWD/ffmpeg-4.2.1-win32-dev/lib/swscale.lib
}

linux{
INCLUDEPATH += /usr/include/x86_64-linux-gnu/libavcodec /usr/include/x86_64-linux-gnu/libavformat /usr/include/x86_64-linux-gnu/libavutil /usr/include/x86_64-linux-gnu/libswscale

LIBS += -lavcodec -lavformat -lavutil -lswscale

}

HEADERS += \
    muxer.h \
    audioencoder.h \
    videoencoder.h \
    audioresampler.h

源码编译:

下载源码:

mkdir ffmpeg && cd ffmpeg/
wget https://ffmpeg.org/releases/ffmpeg-4.3.1.tar.bz2
tar xvf ffmpeg-4.3.1.tar.bz2
cd ffmpeg-4.3.1/

配置:

./configure --enable-gpl \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libopus \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree

编译:

sudo make -j4 && sudo make install

测试:

ffmpeg -version

零声安装步骤参考:

https://www.yuque.com/linuxer/ffmcy9/pgx8mi

QT使用ffmpeg

pro文件:

TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += \
main.c
INCLUDEPATH += /home/lqf/ffmpeg_build/include

LIBS += /home/lqf/ffmpeg_build/lib/libavcodec.a \
/home/lqf/ffmpeg_build/lib/libavdevice.a \
/home/lqf/ffmpeg_build/lib/libavfilter.a \
/home/lqf/ffmpeg_build/lib/libavformat.a \
/home/lqf/ffmpeg_build/lib/libavutil.a \
/home/lqf/ffmpeg_build/lib/libswresample.a \
/home/lqf/ffmpeg_build/lib/libswscale.a

兼容多个平台:可以参考飞扬青云的playffmpeg

#如果用的是ffmpeg4内核请将ffmpeg3改成ffmpeg4,两种内核不兼容,头文件也不一样
DEFINES += ffmpeg4

#ffmpeg4则使用ffmpeg4的目录

contains(DEFINES, ffmpeg4) {
strPath = ffmpeg4
} else {
strPath = ffmpeg3
}

#表示64位的构建套件
contains(QT_ARCH, x86_64) {
strLib = winlib64
strInclude = include64
} else {
#由于Qt4不支持QT_ARCH所以会执行下面的
#如果用的64位的Qt4则需要自行修改

strLib = winlib
strInclude = include
}

#表示arm平台构建套件

contains(QT_ARCH, arm) {
strInclude = include
}

!android {
INCLUDEPATH += $$PWD/$$strPath/$$strInclude
}

win32 {
LIBS += -L$$PWD/$$strPath/$$strLib/ -lavcodec -lavfilter -lavformat -lswscale -lavutil -lswresample -lavdevice
}

#请自行替换

!android {
unix:!macx {
LIBS += -L$$PWD/linuxlib/ -lavfilter -lavformat -lavdevice -lavcodec -lswscale -lavutil -lswresample -lavdevice -lpthread -lm -lz -lrt -ldl
}}

#android系统
android {
INCLUDEPATH += $$PWD/androidlib/include
LIBS += -L$$PWD/androidlib/ -lavcodec -lavfilter -lavformat -lswscale -lavutil -lswresample
#将动态库文件一起打包
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavcodec.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavfilter.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavformat.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavutil.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libswresample.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libswscale.so
}

pkgconfig查找:

# 使用 pkg-config 查找 FFmpeg 4 的库
CONFIG += link_pkgconfig
PKGCONFIG += libavcodec libavformat libavutil libswscale

# 如果需要使用其他 FFmpeg 组件,可以添加它们
# PKGCONFIG += libavfilter libavdevice libavformat libswresample

# 添加包含目录
INCLUDEPATH += $$system(pkg-config --cflags-only-I libavcodec libavformat libavutil libswscale)

# 添加库目录
LIBS += $$system(pkg-config --libs libavcodec libavformat libavutil libswscale)

我的具体位置:

CONFIG += link_pkgconfig
PKGCONFIG += sdl2

LIBS += -L/home/enpht/sdk/ffmpeg4/ffmpeg_build/lib/ -lavcodec -lavformat -lavutil -lswscale -lavfilter -lavdevice -lswresample -lfdk-aac
INCLUDEPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
DEPENDPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include

头文件导入

//必须加以下内容,否则编译不能通过,为了兼容C和C99标准
#ifndef INT64_C
#define INT64_C
#define UINT64_C
#endif

//引入ffmpeg头文件
extern "C" {
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "libavutil/frame.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/ffversion.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h" 
#include "libswresample/swresample.h" 
#include "libavformat/avformat.h" 
#include "libavfilter/avfilter.h" 

#ifdef ffmpegdevice 
#include "libavdevice/avdevice.h" 
#endif

#ifndef gcc45 
#include "libavutil/hwcontext.h" 
//#include "libavutil/hwcontext_qsv.h" 
#endif 
}

ffmpeg命令行

主要命令参数:

命令参数内容命令参数内容
-version显示版本-bsfs显示可用比特流filter
-buildconf显示编译配置-protocols显示可用的协议
-formats显示可用格式 (muxers+demuxers)-filters显示可用的过滤器
-muxers显示可用复用器-pix_fmts显示可用的像素格式
-demuxers显示可用解复用器-layouts显示标准声道名称
-codecs显示可用编解码器 (decoders+encoders)-sample_fmts显示可用的音频采样 格式
-decoders显示可用解码器-colors显示可用的颜色名称
-encoders显示可用编码器

查看具体所支持的类型:

语法:

​ ffmepg -h type=name

比如:

​ ffmpeg -h muxer=flv
​ ffmpeg -h filter=atempo (atempo调整音频播放速率)
​ ffmpeg -h encoder=libx264

ffmpeg/ffplay/ffprobe3区别

◼ffmpeg:
Hyper fast Audio and Video encoder
超快音视频编码器(类似爱剪辑)
◼ffplay:
Simple media player简单媒体播放器
◼ffprobe:
Simple multimedia streams analyzer
简单多媒体流分析器

◼基本信息: ffmpeg -h
◼高级信息: ffmpeg -h long
◼所有信息: ffmpeg -h full

ffplay命令

播放命令
选项说明选项说明
q, ESC退出播放t循环切换字幕流
f全屏切换c循环切换节目
p, SPC暂停w循环切换过滤器或显 示模式
m静音切换s逐帧播放
9, 09减少音量, 0增加音量left/right向后/向前拖动10秒
/, */减少音量, *增加音量down/up向后/向前拖动1分钟
a循环切换音频流鼠标右键单击拖动与显示宽度对应 百分比的文件进行播 放
v循环切换视频流鼠标左键双击全屏切换
命令选项

◼ -x width 强制显示宽带。
◼ -y height 强制显示高度。
◼ -video_size size 帧尺寸 设置显示帧存储(WxH格式),仅适用于类似
原始YUV等没有包含帧大小(WxH)的视频。
比如: ffplay -pixel_format yuv420p -video_size 320x240 -framerate 5 yuv420p_320x240.yuv
◼ -pixel_format format 格式设置像素格式。
◼ -fs 以全屏模式启动。
◼ -an 禁用音频(不播放声音)
◼ -vn 禁用视频(不播放视频)
◼ -sn 禁用字幕(不显示字幕)
◼ -ss pos 根据设置的秒进行定位拖动,注意时间单位:比如’55’ 55seconds, ‘12:03:45’ ,12 hours, 03 minutes and 45 seconds, ‘23.189’ 23.189second
◼ -t duration 设置播放视频/音频长度,时间单位如 -ss选项

◼ -bytes 按字节进行定位拖动(0=off 1=on -1=auto)。
◼ -seek_interval interval 自定义左/右键定位拖动间隔(以秒为单位),默认值为10秒(代码没有看到实现)
◼ -nodisp 关闭图形化显示窗口,视频将不显示
◼ -noborder 无边框窗口
◼ -volume vol 设置起始音量。音量范围[0 ~100]
◼ -f fmt 强制使用设置的格式进行解析。比如-f s16le
◼ -window_title title 设置窗口标题(默认为输入文件名)
◼ -loop number 设置播放循环次数
◼ -showmode mode 设置显示模式,可用的模式值: 0 显示视频,1 显示音频波形, 2 显示音频频谱。缺省为0,如果视频不存在则自动选择2
◼ -vf filtergraph 设置视频滤镜
◼ -af filtergraph 设置音频滤镜

◼ -stats 打印多个回放统计信息,包括显示流持续时间,编解码器参数,流中的当前位置,以及音频/视频同步差值。默认情况下处于启用状态,要显式禁用它则需要指定-nostats。。
◼ -fast 非标准化规范的多媒体兼容优化。
◼ -genpts 生成pts。
◼ -sync type 同步类型 将主时钟设置为audio(type=audio), video(type=video)或external(type=ext),默认是audio为主时钟。
◼ -ast audio_stream_specifier 指定音频流索引,比如-ast 3,播放流索引为3的音频流
◼ -vst video_stream_specifier指定视频流索引,比如-vst 4,播放流索引为4的视频流
◼ -sst subtitle_stream_specifier 指定字幕流索引,比如-sst 5,播放流索引为5的字幕流
◼ -autoexit 视频播放完毕后退出。

◼ -exitonkeydown 键盘按下任何键退出播放
◼ -exitonmousedown 鼠标按下任何键退出播放
◼ -codec:media_specifier codec_name 强制使用设置的多媒体解码器,media_specifier可用值为a(音频), v(视频)和s字幕。比如-codec:v h264_qsv 强制视频采用h264_qsv解码
◼ -acodec codec_name 强制使用设置的音频解码器进行音频解码
◼ -vcodec codec_name 强制使用设置的视频解码器进行视频解码
◼ -scodec codec_name 强制使用设置的字幕解码器进行字幕解码
◼ -autorotate 根据文件元数据自动旋转视频。值为0或1 ,默认为1。
◼ -framedrop 如果视频不同步则丢弃视频帧。当主时钟非视频时钟时默认开启。若需禁用则使用 -noframedrop
◼ -infbuf 不限制输入缓冲区大小。尽可能快地从输入中读取尽可能多的数据。播放实时流时默认启用,如果未及时读取数据,则可能会丢弃数据。此选项将不限制缓冲区的大小。若需禁用则使用-noinfbuf

播放例子

◼ 播放本地文件
◼ ffplay -window_title “test time” -ss 2 -t 10 -autoexit test.mp4
◼ ffplay buweishui.mp3
◼ 播放网络流
◼ ffplay -window_title “rtmp stream”
rtmp://202.69.69.180:443/webcast/bshdlive-pc
◼ 强制解码器
◼ mpeg4解码器: ffplay -vcodec mpeg4 test.mp4
◼ h264解码器: ffplay -vcodec h264 test.mp4
◼ 禁用音频或视频
◼ 禁用音频: ffplay test.mp4 -an
◼ 禁用视频: ffplay test.mp4 -vn

◼ 播放YUV数据
◼ ffplay -pixel_format yuv420p -video_size 320x240 -framerate 5
yuv420p_320x240.yuv
◼ 播放RGB数据
◼ ffplay -pixel_format rgb24 -video_size 320x240 -i rgb24_320x240.rgb
◼ ffplay -pixel_format rgb24 -video_size 320x240 -framerate 5 -i rgb24_320x240.rgb
◼ 播放PCM数据
◼ ffplay -ar 48000 -ac 2 -f f32le 48000_2_f32le.pcm
-ar set audio sampling rate (in Hz) (from 0 to INT_MAX) (default 0)
-ac set number of audio channels (from 0 to INT_MAX) (default 0)

过滤器

◼ 视频旋转
ffplay -i test.mp4 -vf transpose=1
◼ 视频反转
ffplay test.mp4 -vf hflip
ffplay test.mp4 -vf vflip
◼ 视频旋转和反转
ffplay test.mp4 -vf hflip,transpose=1
◼ 音频变速播放
ffplay -i test.mp4 -af atempo=2
◼ 视频变速播放
ffplay -i test.mp4 -vf setpts=PTS/2
◼ 音视频同时变速
ffplay -i test.mp4 -vf setpts=PTS/2 -af atempo=2

ffmpeg命令

主要命令

◼ 主要参数:
-i 设定输入流
-f 设定输出格式(format)
-ss 开始时间
-t 时间长度

◼ 视频参数:
-vframes 设置要输出的视频帧数
-b 设定视频码率
-b:v 视频码率
-r 设定帧速率
-s 设定画面的宽与高
-vn 不处理视频
-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777
-vcodec 设定视频编解码器,如果用copy表示原始编解码数据必须被拷贝
-vf 视频过滤器

◼ 音频参数:
-aframes 设置要输出的音频帧数
-b:a 音频码率
-ar 设定采样率
-ac 设定声音的Channel数
-acodec 设定声音编解码器,如果用copy表示原始编解码数据必须被拷贝。
-an 不处理音频
-af 音频过滤器

例子
修改参数

◼ 修改mp4视频参数,并且转码265:

ffmpeg -i test.mp4 -vframes 300 -b:v 300k -r 30 -s 640x480 -aspect 16:9 -vcodec libx265 out1.mp4

◼ 提取音频:

ffmpeg -i test.mp4 -b:a 192k -ar 48000 -ac 2 -acodec libmp3lame -aframes 200 out2.mp3

◼ 保留封装格式
纯音频:ffmpeg -i test.mp4 -acodec copy -vn audio.mp4
纯视频:ffmpeg -i test.mp4 -vcodec copy -an video.mp4

提取音视频

◼ 提取视频
保留编码格式: ffmpeg -i test.mp4 -vcodec copy -an test_copy.h264
强制格式: ffmpeg -i test.mp4 -vcodec libx264 -an test.h264

◼ 提取音频
保留编码格式: ffmpeg -i test.mp4 -acodec copy -vn test.aac
强制格式: ffmpeg -i test.mp4 -acodec libmp3lame -vn test.mp3

提取YUV和PCM

◼ 提取YUV
提取3秒数据,分辨率和源视频一致
ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p yuv420p_orig.yuv
提取3秒数据,分辨率转为320x240
ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p -s 320x240 yuv420p_320x240.yuv

◼ 提取RGB
提取3秒数据,分辨率转为320x240
ffmpeg -i test.mp4 -t 3 -pix_fmt rgb24 -s 320x240 rgb24_320x240.rgb
RGB和YUV之间的转换
ffmpeg -s 320x240 -pix_fmt yuv420p -i yuv420p_320x240.yuv -pix_fmt rgb24 rgb24_320x240_2.rgb

◼ 提取PCM
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -f s16le 48000_2_s16le.pcm
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -sample_fmt s16 out_s16.wav
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -codec:a pcm_s16le out2_s16le.wav
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -f f32le 48000_2_f32le.pcm
ffmpeg -i test.mp4 -t 10 -vn -ar 48000 -ac 2 -f f32le 48000_2_f32le_2.pcm

转封装

◼ 保持编码格式:
ffmpeg -i test.mp4 -vcodec copy -acodec copy test_copy.ts
ffmpeg -i test.mp4 -codec copy test_copy2.ts

◼ 改变编码格式:
ffmpeg -i test.mp4 -vcodec libx265 -acodec libmp3lame out_h265_mp3.mkv

◼ 修改帧率:
ffmpeg -i test.mp4 -r 15 -codec copy output.mp4 (错误命令)
ffmpeg -i test.mp4 -r 15 output2.mp4

◼ 修改视频码率:
ffmpeg -i test.mp4 -b 400k output_b.mkv (此时音频也被重新编码)

◼ 修改视频码率:
ffmpeg -i test.mp4 -b:v 400k output_bv.mkv

◼ 修改音频码率:
ffmpeg -i test.mp4 -b:a 192k output_ba.mp4
如果不想重新编码video,需要加上-vcodec copy

◼ 修改音视频码率:
ffmpeg -i test.mp4 -b:v 400k -b:a 192k output_bva.mp4

◼ 修改视频分辨率:
ffmpeg -i test.mp4 -s 480x270 output_480x270.mp4

◼ 修改音频采样率:
ffmpeg -i test.mp4 -ar 44100 output_44100hz.mp4

裁剪

◼ 找三个不同的视频每个视频截取10秒内容
ffmpeg -i 沙海02.mp4 -ss 00:05:00 -t 10 -codec copy 1.mp4
ffmpeg -i 复仇者联盟3.mp4 -ss 00:05:00 -t 10 -codec copy 2.mp4
ffmpeg -i 红海行动.mp4 -ss 00:05:00 -t 10 -codec copy 3.mp4
如果音视频格式不统一则强制统一为 -vcodec libx264 -acodec aac

◼ 将上述1.mp4/2.mp4/3.mp4转成ts格式
ffmpeg -i 1.mp4 -codec copy -vbsf h264_mp4toannexb 1.ts
ffmpeg -i 2.mp4 -codec copy -vbsf h264_mp4toannexb 2.ts
ffmpeg -i 3.mp4 -codec copy -vbsf h264_mp4toannexb 3.ts

分离某些封装格式(例如MP4/FLV/MKV等)中的H.264的时候,需要首先写入
SPS和PPS,否则会导致分离出来的数据没有SPS、 PPS而无法播放。 H.264码流
的SPS和PPS信息存储在AVCodecContext结构体的extradata中。需要使用ffmpeg
中名称为“h264_mp4toannexb”的bitstream filter处理

◼ 转成flv格式
ffmpeg -i 1.mp4 -codec copy 1.flv
ffmpeg -i 2.mp4 -codec copy 2.flv
ffmpeg -i 3.mp4 -codec copy 3.flv

合并

◼ 以MP4格式进行拼接
方法1: ffmpeg -i “concat:1.mp4|2.mp4|3.mp4” -codec copy out_mp4.mp4
方法2: ffmpeg -f concat -i mp4list.txt -codec copy out_mp42.mp4
◼ 以TS格式进行拼接
方法1: ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out_ts.mp4
方法2: ffmpeg -f concat -i tslist.txt -codec copy out_ts2.mp4
◼ 以FLV格式进行拼接
方法1: ffmpeg -i “concat:1.flv|2.flv|3.flv” -codec copy out_flv.mp4
方法2: ffmpeg -f concat -i flvlist.txt -codec copy out_flv2.mp4
◼ 方法1只适用部分封装格式,比如TS
◼ 建议:
(1)使用方法2进行拼接
(2)转成TS格式再进行拼接

◼ 修改音频编码
ffmpeg -i 2.mp4 -vcodec copy -acodec ac3 -vbsf h264_mp4toannexb 2.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out1.mp4 结果第二段没有声音

◼ 修改音频采样率
ffmpeg -i 2.mp4 -vcodec copy -acodec aac -ar 96000 -vbsf h264_mp4toannexb 2.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out2.mp4 第二段播放异常

◼ 修改视频编码格式
ffmpeg -i 1.mp4 -acodec copy -vcodec libx265 1.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out3.mp4

◼ 修改视频分辨率
ffmpeg -i 1.mp4 -acodec copy -vcodec libx264 -s 800x472 -vbsf h264_mp4toannexb 1.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out4.mp4

◼ 注意:
◼ 把每个视频封装格式也统一为ts,拼接输出的时候再输出你需要的封装格
式,比如MP4
◼ 视频分辨率可以不同,但是编码格式需要统一
◼ 音频编码格式需要统一,音频参数(采样率/声道等)也需要统一

图片和视频互转

◼ 截取一张图片
ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.jpg
ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.bmp
-i 输入
-y 覆盖
-f 格式
image2 一种格式
-ss 起始值
-vframes 帧 如果大于1 那么 输出加%03d test%03d.jpg
-s 格式大小size

◼ 转换视频为图片(每帧一张图):
ffmpeg -i test.mp4 -t 5 -s 640x360 -r 15 frame%03d.jpg

◼ 图片转换为视频:
ffmpeg -f image2 -i frame%03d.jpg -r 25 video.mp4

◼ 从视频中生成GIF图片
ffmpeg -i test.mp4 -t 5 -r 1 image1.gif
ffmpeg -i test.mp4 -t 5 -r 25 -s 640x360 image2.gif

◼ 将 GIF 转化为 视频
ffmpeg -f gif -i image2.gif image2.mp4

屏幕录制

◼ 先安装dshow软件 Screen Capturer Recorder,
项目地址: https://sourceforge.net/projects/screencapturer/files/
然后查看可用设备名字: ffmpeg -list_devices true -f dshow -i dummy

◼ 录制视频(默认参数)
桌面: ffmpeg -f dshow -i video=“screen-capture-recorder” v-out.mp4
摄像头: ffmpeg -f dshow -i video=“Integrated Webcam” -y v-out2.flv (要根据自己摄像头名称)
◼ 录制声音(默认参数)
系统声音: ffmpeg -f dshow -i audio=“virtual-audio-capturer” a-out.aac
系统+麦克风声音: ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i audio=“virtual-audio-capturer” -filter_complex amix=inputs=2:duration=first:dropout_transition=2 a-out2.aac
◼ 同时录制声音和视频(默认参数)
ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i audio=“virtualaudio-capturer” -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=“screen-capture-recorder” -y av-out.flv

◼ 查看视频录制的可选参数
ffmpeg -f dshow -list_options true -i video=“screen-capture-recorder”

◼ 查看视频录制的可选参数
ffmpeg -f dshow -list_options true -i audio="virtual-audio-capturer“

指定参数录制:

◼ ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i
audio=“virtual-audio-capturer” -filter_complex
amix=inputs=2:duration=first:dropout_transition=2 -f dshow -video_size
1920x1080 -framerate 15 -pixel_format yuv420p -i video=“screen-capturerecorder” -vcodec h264_qsv -b:v 3M -y av-out.flv
◼ ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i
audio=“virtual-audio-capturer” -filter_complex
amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i
video=“screen-capture-recorder” -vcodec h264_qsv -b:v 3M -r 15 -y avout2.mp4
◼ ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i
audio=“virtual-audio-capturer” -filter_complex
amix=inputs=2:duration=first:dropout_transition=2 -f dshow -framerate 15
-pixel_format yuv420p -i video=“screen-capture-recorder” -vcodec
h264_qsv -b:v 3M -r 15 -y av-out3.mp4

推流

◼ 直播拉流
ffplay rtmp://server/live/streamName
ffmpeg -i rtmp://server/live/streamName -c copy dump.flv
对于不是rtmp的协议 -c copy要谨慎使用

◼ 可用地址
HKS: rtmp://live.hkstv.hk.lxdns.com/live/hks2
大熊兔(点播): rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
CCTV1高清: http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8
ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 -c copy cctv1.ts
ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 cctv1.flv
ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 -acodec aac -vcodec libx264
cctv1-2.flv
CCTV3高清: http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8
CCTV5高清: http://ivi.bupt.edu.cn/hls/cctv5hd.m3u8
CCTV5+高清: http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8
CCTV6高清: http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8

◼ 直播推流
ffmpeg -re -i out.mp4 -c copy flv rtmp://server/live/streamName
-re,表示按时间戳读取文件

◼ rtsp和rtmp推流

// rtsp推流(文件推流)
ffmpeg -re -i test.mp4 -rtsp_transport tcp -c copy -f rtsp rtsp://127.0.0.1:554/live/test

// rtsp推流(文件循环推流)
ffmpeg -re -stream_loop  -1  -i test.mp4 -rtsp_transport tcp -c copy -f rtsp rtsp://127.0.0.1:554/live/test

// rtmp推流(文件推流)
ffmpeg -re -i test.mp4 -vcodec h264_nvenc  -acodec aac -f flv  rtmp://192.168.1.3:1935/live/test

// rtmp推流(文件循环推流)
ffmpeg -re -stream_loop  -1 -i test.mp4 -vcodec h264  -acodec aac -f flv  rtmp://127.0.0.1:1935/live/test

SDL显示的API

SDL视频显示函数简介

• SDL_Init():初始化SDL系统

• SDL_CreateWindow():创建窗口SDL_Window

• SDL_CreateRenderer():创建渲染器SDL_Renderer

• SDL_CreateTexture():创建纹理SDL_Texture

• SDL_UpdateTexture():设置纹理的数据

• SDL_RenderCopy():将纹理的数据拷贝给渲染器

• SDL_RenderPresent():显示

• SDL_Delay():工具函数,用于延时。

• SDL_Quit():退出SDL系统

SDL中事件和多线程

SDL多线程

• 函数

• SDL_CreateThread():创建一个线程

• SDL_LockMutex(), SDL_UnlockMutex():互斥量操作

• 数据结构

• SDL_Thread:线程的句柄

SDL事件

• 函数

• SDL_WaitEvent():等待一个事件

• SDL_PushEvent():发送一个事件

• SDL_PumpEvents():将硬件设备产生的事件放入事件队列

• SDL_PeepEvents():从事件队列提取一个事件

• 数据结构

• SDL_Event:代表一个事件

ffmpeg的API

参考:FFmpeg架构全面分析 - Coder个人博客 - 博客园 (cnblogs.com)

整体框架

​ 1、AVUtil: 核心工具库,许多其他模块都会依赖该库做一些基本的音视频处理操作,如log信息、版本信息等。

2、AVFormat: 文件格式和协议库,封装了Protocol层和Demuxer、Muxer层。其中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。

3、AVCodec: 编解码库,封装了Codec库,AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,即支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x264编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块。默认不会添加libx264、libfdk_aac等三方库的,但可以插件形式添加,然后提供统一接口。

4、AVFilter: 提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。

5、AVDevice: 输入输出设备库,音/视频的输入输出需要确保该模块已经打开

6、SwrResample: 该模块可用于音频重采样,可以对数字音频进行声道数、数据格式、采样率、等多种基本信息的转换,同时支持音频通道布局转换与布局调整。

7、SWScale: 提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420p转换成YUYV,或者YUV转RGB等图像格式转换。

8、PostProc: 该模块可用于进行后期处理,当我们使用AVFilter的时 候需要打开该模块的开关,因为Filter中会使用到该模块的一些基础函数。

结构体以及关系

重要结构体

AVFormatContext 封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。

​ • iformat:输入媒体的AVInputFormat,比如指向AVInputFormat ff_flv_demuxer
​ • nb_streams:输入媒体的AVStream 个数
​ • streams:输入媒体的AVStream []数组
​ • duration:输入媒体的时长(以微秒为单位),计算方式可以参考av_dump_format()函数。
​ • bit_rate:输入媒体的码率

AVCodecContext 编码器上下文结构体

​ • codec:编解码器的AVCodec,比如指向AVCodec ff_aac_latm_decoder
​ • width, height:图像的宽高(只针对视频)
​ • pix_fmt:像素格式(只针对视频)
​ • sample_rate:采样率(只针对音频)
​ • channels:声道数(只针对音频)
​ • sample_fmt:采样格式(只针对音频)

AVCodecParameters 用于存储编码流的属性。在新版本中被设计来替代已废弃的 AVCodecContext
• codectype:编解码器类型,取值为AVMEDIATYPEVIDEO、AVMEDIATYPEAUDIO、 AVMEDIATYPE_SUBTITLE之一。
• codec_id:编解码器的ID,取值为枚举类型AVCodecID中的一种。
• codec_tag:编解码器标签。
• extradata:对于某些编码器(如H.264)需要额外的信息来解码,这些信息称为“extradata”。该成员变量保存了这些额外信息的地址。
• extradata_size:extradata所占用的字节数。
• format:音视频帧的像素或采样格式,例如对于视频来说,可以是AVPIXFMTYUV420P、AVPIXFMTNV12等等。对于音频来说,可以是AVSAMPLEFMTS16、AVSAMPLEFMTFLTP等等。
• bit_rate:比特率,用于描述音视频流的质量,单位为bps。
• bitspercoded_sample:每个编码的样本所占用的位数。
• bitsperraw_sample:每个采样的样本所占用的位数。
• profile:编解码器的协议等级。
• level:编解码器的协议等级。
• width:视频帧宽度。
• height:视频帧高度。
• sample_rate:音频采样率。
• channels:音频声道数。
• samplefmt:音频采样格式,例如AVSAMPLEFMTS16、AVSAMPLEFMT_FLTP等等。
• channellayout:音频声道布局,例如AVCHLAYOUTMONO、AVCHLAYOUT_STEREO等等。
• sampleaspectratio:音视频帧宽高比。
• fpsfirstnum:帧率分子。
• fpssecondnum:帧率分母。
• delay:编码器的编码时延。
• seek_preroll:如果需要进行关键帧的跳转,这个字段表示需要跳过的帧数。

AVStream 视频文件中每个视频(音频)流对应一个该结构体

​ • index:标识该视频/音频流
​ • id:流的ID,用于在文件格式中识别流。
​ • time_base:该流的时基, PTS*time_base=真正的时间(秒)
​ • avg_frame_rate: 该流的帧率
​ • duration:该视频/音频流长度
​ • codecpar:编解码器参数属性

AVPacket 存储一帧压缩编码数据

​ • pts:显示时间戳
​ • dts:解码时间戳
​ • data:压缩编码数据
​ • size:压缩编码数据大小
​ • pos:数据的偏移地址
​ • stream_index:所属的AVStream

AVFrame 存储一帧解码后像素(采样)数据

​ • data:解码后的图像像素数据(音频采样数据)
​ • linesize:对视频来说是图像中一行像素的大小;对音频来说是整个音频帧的大小
​ • width, height:图像的宽高(只针对视频)
​ • key_frame:是否为关键帧(只针对视频) 。
​ • pict_type:帧类型(只针对视频) 。例如I, P, B
​ • sample_rate:音频采样率(只针对音频)
​ • nb_samples:音频每通道采样数(只针对音频)
​ • pts:显示时间戳

AVCodec 每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体

​ • name:编解码器名称
​ • type:编解码器类型
​ • id:编解码器ID
​ • 一些编解码的接口函数,比如int (*decode)()

AVOutputFormatAVInputFormat ffmpeg内部使用

​ • name:封装格式名称
​ • extensions:封装格式的扩展名
​ • id:封装格式ID
​ • 一些封装格式处理的接口函数,比如read_packet()

AVCodecParameters

​ • codec_type:媒体类型,比如AVMEDIA_TYPE_VIDEO AVMEDIA_TYPE_AUDIO等
​ • codec_id:编解码器类型, 比如AV_CODEC_ID_H264 AV_CODEC_ID_AAC等。

AVDictionary

简单的key/value存储,经常使用AVDictionary设置或读取内部参数。声明如下,具体实现在libavutil模块中的dict.c/h,提供此结构体是为了与libav兼容,但它实现效率低下,在FFmpeg 4.1.3版本中已弃用(deprecated),推荐使用libavutil模块中的tree.c/h来替代

AVDictionary* dict = nullptr;

av_dict_set(&dict, “max_delay”, “100”, 0); // 设置

很多地方需要参数的时候都会使用。也可以自行打印:

AVDictionaryEntry* t = nullptr;

while (t = av_dict_get(dict , “”, t, AV_DICT_IGNORE_SUFFIX)) {
fprintf(stdout, “key: %s, value: %s\n”, t->key, t->value); // iterate over all entries in d
}

av_dict_free(&dict); // 释放

AVFilter 过滤器

const char *name; // overlay
const AVFilterPad *inputs;
const AVFilterPad *outputs;

AVFilterContext 过滤器上下文

AVFilterGraph 过滤器图,对整个过滤器进行管道拼接和管理

struct AVFilterGraph
{
AVFilterContext **filters;
unsigned nb_filters;
}

AVFilterLink 两个过滤器之间的连接

struct AVFilterLink
{
AVFilterContext *src;
AVFilterPad *srcpad;
AVFilterContext *dst;
AVFilterPad *dstpad;
struct AVFilterGraph *graph;

}

重要结构体关系
  1. AVFormatContext和AVInputFormat之间的关系

    AVFormatContext API调用
    AVInputFormat 主要是FFMPEG内部调用

  2. AVCodecContext和AVCodec之间的关系

    AVCodecContext 编码器上下文结构体

    AVCodec 每种视频(音频)编解码器

  3. AVFormatContext、AVStream和AVCodecContext之间的关系

  • AVFormatContext 是最顶层的结构,代表整个多媒体文件。

  • AVStreamAVFormatContext 的一部分,代表文件中的单个媒体流。

  • AVCodecContext 是与 AVStream 相关联的,代表单个媒体流的编解码器上下文。

  1. AVPacket和AVFrame之间的关系

    AVPacket是AVFrame编码后的数据。

  2. AVFilterContext,AVFilterGraph,和AVFilter的关系:

    AVFilter是具体的各个过滤器,有不同功能。AVFilterContext是各个AVFilter的上下文,用于后期拼接,以及参数设置,管理filter与外部的联系 。AVFilterGraph是整个过滤器管理器,类似gstreamer的插件管道,用于初始化和开启过滤器。

内存模型

内部使用AVBuffer保存数据,内部有一个引用计数来保证内存正确释放。

引用计数原理:

◼ 对于多个AVPacket共享同一个缓存空间, FFmpeg使用的引用计数的机制(reference-count) :

  • 初始化引用计数为0,只有真正分配AVBuffer的时候,引用计数初始化为1;
  • 当有新的Packet引用共享的缓存空间时, 就将引用计数+1;
  • 当释放了引用共享空间的Packet,就将引用计数-1;引用计数为0时,就释放掉引用的缓存空间AVBuffer。
  • AVFrame也是采用同样的机制。

所以,从现有的Packet拷贝一个新Packet的时候,有两种情况:
• ①两个Packet的buf引用的是同一数据缓存空间,这时候要注意数据缓存空间的释放问题;
• ②两个Packet的buf引用不同的数据缓存空间,每个Packet都有数据缓存空间的copy;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AVPacket:

函数说明
AVPacket *av_packet_alloc(void);分配AVPacket 这个时候和buffer没有关系
void av_packet_free(AVPacket **pkt);释放AVPacket 和_alloc对应
void av_init_packet(AVPacket *pkt);初始化AVPacket 只是单纯初始化pkt字段
int av_new_packet(AVPacket *pkt, int size);给AVPacket的buf分配内存, 引 用计数初始化为1
int av_packet_ref(AVPacket *dst, const AVPacket *src);增加引用计数
void av_packet_unref(AVPacket *pkt);减少引用计数
void av_packet_move_ref(AVPacket *dst, AVPacket *src);转移引用计数
AVPacket av_packet_clone(const AVPacket *src);等于 av_packet_alloc()+av_packet_ref()
int av_write_frame(AVFormatContext *s, AVPacket *pkt);顺序写帧。将编码数据包写入到多媒体容器格式中
void av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);交替写帧。用于视频和音频同时存在的场景
void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt);打印pts,dts,duration等信息

AVFrame:

函数说明
AVFrame *av_frame_alloc(void);分配AVFrame
void av_frame_free(AVFrame **frame);释放AVFrame
int av_frame_ref(AVFrame *dst, const AVFrame *src);增加引用计数
void av_frame_unref(AVFrame *frame);减少引用计数
void av_frame_move_ref(AVFrame *dst, AVFrame *src);转移引用计数
int av_frame_get_buffer(AVFrame *frame, int align);根据AVFrame分配内存
AVFrame *av_frame_clone(const AVFrame *src);等于 av_frame_alloc()+av_frame_ref()

播放器框架:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

函数用处

初始化

◼ av_register_all(): 注册所有组件,4.0已经弃用

◼ avdevice_register_all()对设备进行注册,比如V4L2等

◼ avformat_network_init();初始化网络库以及网络加密协议相关的库(比如openssl)

上下文相关

◼ avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec):将AVCodecContext结构体中码流参数拷⻉到AVCodecParameters结构体中 。

封装

◼ avformat_write_header(); 写媒体头
◼ av_write_frame/av_interleaved_write_frame: 写packet
◼ av_write_trailer():写媒体尾

◼ avformat_alloc_context();负责申请一个AVFormatContext结构的内存,并进行简单初始化
◼ avformat_free_context();释放该结构里的所有东西以及该结构本身
◼ avformat_close_input();关闭解复用器。关闭后就不再需要使用avformat_free_context 进行释放。
◼ avformat_open_input();打开输入视频文件
◼ avformat_find_stream_info(): 获取音视频文件信息
◼ av_read_frame(); 读取音视频包
◼ avformat_seek_file(); 定位文件
◼ av_seek_frame():定位文件,也可以移动播放位置

编码

◼ avcodec_register_all(); 注册所有可用的编解码器和格式。
◼ avcodec_find_encoder(); 根据ID创建编码器
◼ avcodec_find_encoder_by_name(); 根据名字查找并创建编码器
◼ avcodec_alloc_context3(); 分配并初始化 AVCodecContext 结构,存储编码器或解码器的参数
◼ avcodec_open2(); 打开指定的编码器或解码器,初始化它的上下文。需要在编码或解码前调用
◼ avcodec_send_frame(); 发送frame到编码器
◼ avcodec_receive_packet(); 接收编码后的packet
◼ av_rescale_q(); 改变时间基
◼ av_image_fill_arrays(); 填充图片数据
◼ avcodec_flush_buffers(); 用于清空编码器或解码器的缓冲区。这在处理流式数据时非常有用,比如在开始处理新的视频流时,确保先前的帧数据被清除
◼ avcodec_close(); 关闭
◼ avcodec_free_context();

解码

◼ avcodec_register_all(); 注册所有可用的编解码器和格式。
◼ avcodec_find_decoder(); 根据ID创建解码器
◼ avcodec_find_decoder_by_name(); 根据名字查找并创建编码器
◼ avcodec_alloc_context3(); 分配并初始化 AVCodecContext 结构,存储编码器或解码器的参数
◼ avcodec_open2(); 打开指定的编码器或解码器,初始化它的上下文。需要在编码或解码前调用
◼ avcodec_send_packet(); 发送packet到编码器
◼ avcodec_receive_frame(); 接收编码后的frame
◼ avcodec_flush_buffers(); 用于清空编码器或解码器的缓冲区。这在处理流式数据时非常有用,比如在开始处理新的视频流时,确保先前的帧数据被清除
◼ avcodec_close(); 关闭
◼ avcodec_free_context();

音频重采样

从uint_8 *data 的音频数据,转为AVFrame * 数据。

#include "libswresample/swresample.h"

重要结构体:SwrContext
◼ swr_alloc_set_opts(SwrContext *s , …); 根据设置的输出和输入的采样参数,创建上下文
◼ swr_convert(SwrContext *s, …); 重采样,根据上下文,将uint8_t *音频数据转换为AVFrame.data里面去。
◼ swr_init(SwrContext ctx); 初始化
◼ swr_free(SwrContext **ss);

过滤器
//#include <libavfilter/avfiltergraph.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>

◼ avfilter_register_all(); 注册过滤器
◼ avfilter_get_by_name(const char name); 根据名字创建过滤器
◼ av_buffersrc_add_frame(AVFilterContext ctx, AVFrame frame); 往源过滤器输入数据
◼ av_buffersink_get_frame(AVFilterContext ctx, AVFrame frame); 从终点过滤器中获取数据
◼ avfilter_graph_alloc(); 创建⼀个滤波器图实例 AVFilterGraph*
◼ avfilter_graph_parse2(); 根据 传递的字符串语法来创建一个或者多个滤镜上下文,多个滤镜会根据语法自动连接。同时会把新创建的滤镜上下文放进去滤镜容器。
◼ avfilter_graph_create_filter(…); 创建某个滤波器实例AVFilterContext(如果之前是空指针),设置参数并添加到AVFilterGraph中
◼ avfilter_graph_get_filter(); 根据名称获取 滤镜容器内部的某个滤镜上下文。
◼ avfilter_link(); 连接两个过滤器。从上一个过滤器的某个输出点,连接到下一个过滤器的某个输入点
◼ avfilter_graph_config(); 检查过滤器图,并且开启
◼ avfilter_graph_dump(); 将过滤器图导出txt
◼ avfilter_graph_free(); 释放内存,包括过滤器和上下文
◼ avfilter_init_str(); 使用提供的参数,初始化过滤器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/936795.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【网络】传输层协议UDP/TCP网络层IP数据链路层MACNAT详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.传输层协议 UDP 1.1 传输层 1.2 端口号 1.3 UDP 协议 1.3.1 UDP 协议端格式 1.3.2 UDP 的特点 1.3.3 面向数据报 1…

WordPress插件 Download-block-plugin下载按钮图标美化

WordPress插件 Download-block-plugin下载按钮图标美化

分布式 漏桶算法 总结

前言 相关系列 《分布式 & 目录》《分布式 & 漏桶算法 & 总结》《分布式 & 漏桶算法 & 问题》 概述 简介 LBA Leaky Bucket Algorithm 漏桶算法是一种流行于网络通信领域的流量控制/频率限制算法。漏桶算法的核心原理是通过一个概念上的“漏桶”来…

04面向对象篇(D4_OOT(D1_OOT - 面向对象测试))

目录 一、 面向对象影响测试 1. 封装性影响测试 2. 继承性影响测试 3. 多态性影响测试 二、 面向对象测试模型 三、 面向对象分析测试 1. 对象测试 2. 结构测试 3. 主题测试 4. 属性和实例关联测试 5. 服务和消息关联测试 四、面向对象设计测试 1. 对认定类测试 …

群控系统服务端开发模式-应用开发-前端操作记录功能展示

一、创建操作记录展示视图 在根目录下src文件夹下views文件夹下permission文件夹下创建token文件夹&#xff0c;在token文件夹下&#xff0c;新建index.vue文件&#xff0c;代码如下&#xff1a; <template><div class"app-container"><div class&qu…

【AIGC】如何高效使用ChatGPT挖掘AI最大潜能?26个Prompt提问秘诀帮你提升300%效率的!

还记得第一次使用ChatGPT时&#xff0c;那种既兴奋又困惑的心情吗&#xff1f;我是从一个对AI一知半解的普通用户&#xff0c;逐步成长为现在的“ChatGPT大神”。这一过程并非一蹴而就&#xff0c;而是通过不断的探索和实践&#xff0c;掌握了一系列高效使用的技巧。今天&#…

电容Q值、损耗角、应用

电容发热的主要原因&#xff1a;纹波电压 当电容两端施加纹波电压时&#xff0c;电容承受的是变化的电压&#xff0c;由于电容内部存在寄生电阻&#xff08;ESR&#xff09;和寄生电感&#xff08;ESL&#xff09;.因此电容会有能量损耗&#xff0c;从而产生热量&#xff0c;这…

适配器模式的理解和实践

在软件开发中&#xff0c;我们经常遇到需要将一个类的接口转换成客户端所期望的另一种接口的情况。这种接口不匹配问题会导致类之间的不兼容&#xff0c;使得原本可以协同工作的两个类无法在一起工作。为了解决这一问题&#xff0c;适配器模式&#xff08;Adapter Pattern&…

大数据分析案例-基于梯度提升决策树回归算法构建医疗保险费用预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

轩凯生物被警示,财务内控不规范,华泰证券又被处罚

作者&#xff1a;Tracy 来源&#xff1a;IPO魔女 11月21日&#xff0c;南京轩凯生物科技股份有限公司&#xff08;简称“轩凯生物”&#xff09;被交易所下达书面警示的自律监管函。同时其保荐机构华泰联合证券和会计师事务所天衡&#xff0c;均受到监管处罚。这是今年来&…

IoTDB 常见问题 QA 第二期

关于 IoTDB 的 Q&A IoTDB Q&A 第二期来啦~我们将定期汇总社区讨论频繁的问题&#xff0c;并展开进行详细回答&#xff0c;通过积累常见问题“小百科”&#xff0c;方便大家使用 IoTDB。 Q1&#xff1a;集群扩容方法 问题 问题1&#xff1a;当 IoTDB 集群的存储占用达到…

RT-DETR融合[CVPR2024]Starnet中的star block特征提取模块

RT-DETR使用教程&#xff1a; RT-DETR使用教程 RT-DETR改进汇总贴&#xff1a;RT-DETR更新汇总贴 《Rewrite the Stars》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/2403.19967 代码链接&#xff1a;https://github.com/ma-xu/Rewrite-the-Stars/tree/main 论…

Java web - 后端开发

一 Maven Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 Maven的作用

Unity学习笔记(二)如何制作角色动画

前言 本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记 创建一个角色 我们的目的是创建一个可移动、跳跃、冲刺等动作的角色 需要的组件&#xff1a;Rigidbody&#xff08;用于创建物理规则&#xff09;、Collider&#xff08;用于检测碰撞&am…

Pytest-Bdd-Playwright 系列教程(16):标准化JSON报告Gherkin格式命令行报告

Pytest-Bdd-Playwright 系列教程&#xff08;16&#xff09;&#xff1a;标准化JSON报告&Gherkin格式命令行报告 前言一、创建Feature文件二、创建步骤定义文件三、生成Cucumber格式的JSON报告四、使用Gherkin格式的命令行报告五、将BDD报告集成到Jenkins中总结 前言 在自动…

harbor镜像仓库搭建

Harbor简介 Harbor的发展背景和现状 Harbor项目起始于2014年左右,当时正值容器技术和微服务架构迅速崛起的时期。随着越来越多的企业开始采用容器化部署应用,对于私有镜像管理的需求也日益增长。传统的解决方案要么缺乏必要的企业级特性(如访问控制、安全性和可扩展性),…

Windows安装Jira

下载 Download Jira Data Center | Atlassian https://product-downloads.atlassian.com/software/jira/downloads/atlassian-jira-software-10.3.0-x64.exe 以管理员身份安装&#xff0c;否则弹出以下提醒 创建和配置MySQL数据库&#xff1a;参照 Connecting Jira applicat…

【企业微信自建应用-前端篇】企业微信自建应用开发流程详细介绍

前言 最近接到需求&#xff0c;需要我在企业微信端自建一个应用&#xff0c;用来接受PC端派发的工单&#xff0c;告警&#xff0c;公告等内容。 这里写一个帖子汇总一下我经历的全流程开发&#xff0c;当然这是基础的流程啊。因为功能要求也不高。后面如果开发更多的东西再补充…

[每周一更]-(第127期):Go新项目-Gin中使用超时中间件实战(11)

在项目不断迭代过程中&#xff0c;发现基础架构中&#xff0c;没有进行超时控制&#xff0c;有些接口由于网络延迟以及远程调用等情况存在请求时间过长的问题&#xff0c;消耗了资源&#xff0c;也降低了用户体验&#xff0c;这一讲我们聊下超时控制中间件&#xff0c;来完善我…

定时/延时任务-Kafka时间轮源码分析

文章目录 1. 概要2. TimingWheel2.1 核心参数2.2 添加任务2.3 推进时间 3. TimerTaskList3.1 添加节点3.2 删除节点3.3 刷新链表3.4 队列相关 4. 时间轮链表节点-TimerTaskEntry5. TimerTask6. Timer 和 SystemTimer - 设计降级逻辑7. 上层调用8. 小结 1. 概要 时间轮的文章&a…