个人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-devsudo 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-devNASM使用源码进行安装
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 installYasm使用源码进行安装:
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 installlibx264
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 installlibx265
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 installlibvpx
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 installlibfdk-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 installlibmp3lame
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 installlibopus
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 installFFmpeg
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 += sdl2LIBS += -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 -= qtSOURCES += main.cpp \muxer.cpp \audioencoder.cpp \videoencoder.cpp \audioresampler.cppwin32 {
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/libswscaleLIBS += -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 -= qtSOURCES += \
main.c
INCLUDEPATH += /home/lqf/ffmpeg_build/includeLIBS += /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 += sdl2LIBS += -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(); 使用提供的参数,初始化过滤器

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaEE之多线程的风险以及如何避免

上文我们了解了单线程以及线程的一些基本常见方法&#xff0c;但是多线程在一些方面会存在安全问题&#xff0c;此文我们来为多线程的安全 保驾护航&#xff01;&#xff01; 详情请见下文 1. 多线程带来的风险——线程安全 1.1 观察线程不安全 /*** 使用两个线程&#xff0c…

LoViT: 用于手术阶段识别的长视频Transformer|文献速递-生成式模型与transformer在医学影像中的应用

Title 题目 LoViT: Long Video Transformer for surgical phase recognition LoViT: 用于手术阶段识别的长视频Transformer 01 文献速递介绍 快速发展的手术数据科学&#xff08;SDS&#xff09;领域旨在通过先进利用手术室&#xff08;OR&#xff09;内医疗设备采集的数据…

pika:适用于大数据量持久化的类redis组件|简介及安装(一)

文章目录 0. 引言1. pika简介2. pika安装3. pika设置开机自启4. pika主从搭建5. pika哨兵模式实现自动容灾总结 0. 引言 最近因为公司中用到pika组件&#xff0c;于是将研究过程和理解进行系统记录&#xff0c;以供后续参考。 1. pika简介 pika是360开发的一款国产类redis的…

LNMP和Discuz论坛

文章目录 LNMP和Discuz论坛1 LNMP搭建1.1 编译安装nginx服务1.1.1 编译安装1.1.2 添加到系统服务 1.2 编译安装MySQL服务1.2.1 准备工作1.2.2 编辑配置文件1.2.3 设置路径环境变量1.2.4 数据库初始化1.2.5 添加mysqld系统服务1.2.6 修改mysql的登录密码 1.3 编译安装PHP服务1.3…

Yocto 项目运行超出 BitBake 范围的内容

尽管 Yocto 项目依赖 BitBake 解析和调度元数据来完成构建&#xff0c;但在实际开发中&#xff0c;可能需要执行超出 BitBake 直接管理范围的任务。例如&#xff0c;调用外部脚本或工具完成一些特定的处理逻辑&#xff0c;如生成配置文件、执行硬件初始化脚本或调用第三方构建工…

SpringBoot+OSS文件(图片))上传

SpringBoot整合OSS实现文件上传 以前,文件上传到本地(服务器,磁盘),文件多,大,会影响服务器性能 如何解决? 使用文件服务器单独存储这些文件,例如商业版–>七牛云存储,阿里云OSS,腾讯云cos等等 也可以自己搭建文件服务器(FastDFS,minio) 0 过程中需要实名认证 … 1 开…

生产慎用之调试日志对空间矢量数据批量插入的性能影响-以MybatisPlus为例

目录 前言 一、一些缘由 1、性能分析 二、插入方式调整 1、批量插入的实现 2、MP的批量插入实现 3、日志的配置 三、默认处理方式 1、基础程序代码 2、执行情况 四、提升调试日志等级 1、在logback中进行设置 2、提升后的效果 五、总结 前言 在现代软件开发中&#xff0c;性能优…

SQL 在线格式化 - 加菲工具

SQL 在线格式化 打开网站 加菲工具 选择“SQL 在线格式化” 或者直接访问 https://www.orcc.online/tools/sql 输入sql&#xff0c;点击上方的格式化按钮即可 输入框得到格式化后的sql结果

汇编语言学习

文章目录 前言机器语言与机器指令汇编语言与汇编指令用汇编语言编写程序的工作过程注意事项 计算机组成指令和数据的表示计算机中的存储单元计算机中的总线三类总线X86 CPU性能一览 CPU对存储器的读写内存地址空间将各类存储器看作一个逻辑存储器 —— 统一编址内存地址空间的分…

MATLAB深度学习(七)——ResNet残差网络

一、ResNet网络 ResNet是深度残差网络的简称。其核心思想就是在&#xff0c;每两个网络层之间加入一个残差连接&#xff0c;缓解深层网络中的梯度消失问题 二、残差结构 在多层神经网络模型里&#xff0c;设想一个包含诺干层自网络&#xff0c;子网络的函数用H(x)来表示&#x…

【PHP】部署和发布PHP网站到IIS服务器

欢迎来到《小5讲堂》 这是《PHP》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言安装PHP稳定版本线程安全版解压使用 PHP配置配置文件扩展文件路径…

SSM 校园一卡通密钥管理系统 PF 于校园图书借阅管理的安全保障

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装校园一卡通密钥管理系统软件来发挥其高效地信息处理的作用&a…

TCP 2

文章目录 Tcp状态三次握手四次挥手理解TIME WAIT状态 如上就是TCP连接管理部分 流量控制滑动窗口快重传 延迟应答原理 捎带应答总结TCP拥塞控制拥塞控制的策略 -- 每台识别主机拥塞的机器都要做 面向字节流和粘包问题tcp连接异常进程终止机器重启机器掉电/网线断开 Tcp状态 建…

【操作系统】实验二:观察Linux,使用proc文件系统

实验二 观察Linux&#xff0c;使用proc文件系统 实验目的&#xff1a;学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat文件&#xff0c;计算并显示系统CPU占用率和用户态CPU占用率。&#xff08;编写一个程序使用/proc机制获得以及修改机器的各种资源参数。…

【密码学】AES算法

一、AES算法介绍&#xff1a; AES&#xff08;Advanced Encryption Standard&#xff09;算法是一种广泛使用的对称密钥加密&#xff0c;由美国国家标准与技术研究院&#xff08;NIST&#xff09;于2001年发布。 AES是一种分组密码&#xff0c;支持128位、192位和256位三种不同…

【学习笔记】目前市面中手持激光雷达设备及参数汇总

手持激光雷达设备介绍 手持激光雷达设备是一种利用激光时间飞行原理来测量物体距离并构建三维模型的便携式高科技产品。它通过发射激光束并分析反射回来的激光信号&#xff0c;能够精确地获取物体的三维结构信息。这种设备以其高精度、适应各种光照环境的能力和便携性&#xf…

探索 LeNet-5:卷积神经网络的先驱与手写数字识别传奇

一、引言 在当今深度学习技术蓬勃发展的时代&#xff0c;各种复杂而强大的神经网络架构不断涌现&#xff0c;如 ResNet、VGG、Transformer 等&#xff0c;它们在图像识别、自然语言处理、语音识别等众多领域都取得了令人瞩目的成果。然而&#xff0c;当我们回顾深度学习的发展历…

【数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;编写一个程序实现链栈的基本运算。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 初始化栈、销毁栈、判断栈是否为空、进栈、出栈、取栈…

【笔记】架构上篇Day6 法则四:为什么要顺应技术的生命周期?

法则四&#xff1a;为什么要顺应技术的生命周期&#xff1f; 简介&#xff1a;包含模块一 架构师的六大生存法则-法则四&#xff1a;为什么要顺应技术的生命周期&#xff1f;&法则四&#xff1a;架构设计中怎么判断和利用技术趋势&#xff1f; 2024-08-29 17:30:07 你好&am…

Security自定义逻辑认证(极简案例)

项目结构 config SecurityConfig package com.wunaiieq.tmp2024121105.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.password.NoOpPasswordEnco…