当前位置:   article > 正文

FFmpeg源码解析系列(一)目录和编译_ffmpeg 源码解析

ffmpeg 源码解析

引言

当我们欣赏一部电影、观看一段视频或者享受一首音乐时,很少有人会停下来思考这一切是如何呈现在我们眼前的。然而,在每一帧的画面、每一秒的声音背后,有着一个不可思议的技术世界
这个充满音视频的世界的核心之一,就是FFmpeg。FFmpeg是一个强大而复杂的多媒体处理工具,它为视频和音频编解码、流媒体传输、格式转换等提供了优秀的解决方案。在这个系列博客中,我们将深入探讨FFmpeg源码,解析它的工作原理。
后续将会每周更新一到两次,希望能得到你的关注,如果有看不懂的地方,一定是我表述的不够清楚,如果您能指出将是我莫大的荣幸。

概述

FFmpeg,全称"Fast Forward MPEG",是一个功能强大、开源的多媒体框架,它提供了广泛的音频和视频处理功能,使得多媒体数据的解码、编码、转换、封装以及流媒体传输变得更加容易。

随着数字媒体在我们日常生活中的普及,FFmpeg在多领域得到了广泛的应用。它可以用于:

  • 视频编辑和转码: 你可以使用FFmpeg来剪切、合并、转码、添加滤镜等,从而编辑和处理视频文件。这对于视频制作、后期制作以及视频分享平台非常重要。

  • 音频处理: FFmpeg不仅支持视频,还可以用于音频文件的处理,包括音频转码、剪切、合并以及添加效果。

  • 流媒体处理: FFmpeg支持各种网络协议和流媒体传输,使其成为在线直播、视频会议和实时音视频传输的理想工具。

  • 多格式支持: FFmpeg可以处理多种音视频编解码格式和容器格式,包括常见的MP4、MKV、AVI、以及H.264、AAC等流行的编码标准。

    在本系列博客中,我们将深入探讨FFmpeg的内部工作原理,从源代码级别理解其架构和功能。我们将解析其各个组件、编解码器、滤镜和功能,帮助你理解如何使用FFmpeg以及如何在自己的应用程序中集成它。此外,我们还会关注性能优化、安全性和最佳实践,以确保你能够有效地利用这一强大的多媒体处理工具。

ffmpeg源码路径

https://github.com/FFmpeg/FFmpeg

ffmpeg目录结构

FFmpeg 是一个开源多媒体框架,用于处理音频、视频和多媒体数据。其目录结构在不同版本中可能有细微的差异,但通常包含以下主要目录:

  1. doc: 这个目录包含关于 FFmpeg 的离线文档,包括开发文档、API 文档、示例等。在线文档可以访问 https://trac.ffmpeg.org/

  2. fftools: 这是一些用于测试和辅助工具的目录,如 ffmpeg 命令行工具的源代码以及一些其他小工具。

  3. libavcodec: 这个目录包含了 FFmpeg 的编解码库,用于处理各种音频和视频编解码器。

  4. libavformat: 实现流协议、封装格式以及基本的I/O访问。

  5. libavutil: 这个目录包含了一些通用的实用工具和功能,它们被不同部分的 FFmpeg 使用。

  6. libswscale: 这个库用于图像缩放和颜色空间转换。

  7. libswresample: 用于音频混音、重采样的库。

  8. libavdevice:提供一层采集设备和播放设备的抽象,包括一些特定设备相关的接口实现,比如sdl、opengl等

  9. libavfilter: 这是 FFmpeg 的滤镜库,允许你应用各种滤镜效果到音频和视频流。

  10. libpostproc: 这个库包含一些后处理滤镜,用于改善视频质量。

  11. compat: 兼容性代码,用于支持不同平台和系统。

  12. tests: 包含各种自动化测试脚本和测试数据,用于确保 FFmpeg 的正常运作。

  13. presets: 这里存储了一些编码器的预设配置文件,可以用于不同的编码任务。

  14. tools: 包含一些辅助工具,如 ffmpeg 用于命令行处理音视频, ffplay 用于媒体文件播放,ffprobe 用于媒体文件的简单分析

  15. build: 在这个目录下,你可以找到构建 FFmpeg 的脚本和相关文件。

这些目录包含了 FFmpeg 的核心组件和工具,帮助开发者处理多媒体数据、编码和解码各种多媒体格式,以及应用各种滤镜和效果。需要注意的是,具体的目录结构可能会因不同版本的 FFmpeg 而有所不同,但通常会包含上述核心组件。

ffmpeg编译流程

ffmpeg的编译流程很简单

先根据需要对ffmpeg进行配置,然后编译即可

配置

查看配置选项
./configure --help
  • 1
帮助选项(展示所有支持的编解码器、解复用器、协议等)
  --list-decoders          展示所有的解码器
  --list-encoders          展示所有的编码器
  --list-hwaccels          展示所有硬件加速器
  --list-demuxers          展示所有解复用器
  --list-muxers            展示所有复用器
  --list-parsers           展示所有解析器
  --list-protocols         展示所有协议
  --list-bsfs              展示所有比特流过滤器
  --list-indevs            展示所有的输入设备
  --list-outdevs           展示所有的输出设备
  --list-filters           展示所有的过滤器
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
标准选项(配置log输出路径、安装目录等,方括号内为默认路径)

  --logfile=FILE           将测试结果和输出记录到FILE文件中 [ffbuild/config.log]
  --disable-logging        禁止记录配置调试信息
  --fatal-warnings         如果生成任何配置警告,则失败
  --prefix=PREFIX          安装到PREFIX目录 [/usr/local]
  --bindir=DIR             将可执行文件安装到DIR目录 [PREFIX/bin]
  --datadir=DIR            将数据文件安装到DIR目录 [PREFIX/share/ffmpeg]
  --docdir=DIR             将文档安装到DIR目录 [PREFIX/share/doc/ffmpeg]
  --libdir=DIR             将库文件安装到DIR目录 [PREFIX/lib]
  --shlibdir=DIR           将共享库文件安装到DIR目录 [LIBDIR]
  --incdir=DIR             将包含文件安装到DIR目录 [PREFIX/include]
  --mandir=DIR             将手册页安装到DIR目录 [PREFIX/share/man]
  --pkgconfigdir=DIR       将pkg-config文件安装到DIR目录 [LIBDIR/pkgconfig]
  --enable-rpath           使用rpath以允许在动态链接器搜索路径之外的位置安装库(谨慎用)
  --install-name-dir=DIR   用于已安装目标的Darwin目录名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
开源选项
  --enable-gpl      允许使用GPL代码,生成的库和可执行文件将受GPL许可协议限制 [否]
  --enable-version3 将(L)GPL升级为版本3 [否]
  --enable-nonfree  允许使用非免费代码,生成的库和可执行文件将不可重新分发 [否]
  • 1
  • 2
  • 3
配置选项(尺寸优化、动态库静态库选择等)
  --disable-static         不构建静态库 [否]
  --enable-shared          构建共享库 [否]
  --enable-small           优化尺寸(注意不是优化速度)
  --disable-runtime-cpudetect 禁止在运行时检测CPU能力(生成较小的二进制文件)
  --enable-gray            启用完全灰度支持
  --disable-swscale-alpha  禁用swscale中的Alpha通道支持
  --disable-all            禁用构建组件、库和程序
  --disable-autodetect     禁用自动检测的外部库 [否]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
程序选项
  --disable-programs   不构建命令行程序
  --disable-ffmpeg     禁用ffmpeg的构建
  --disable-ffplay     禁用ffplay的构建
  --disable-ffprobe    禁用ffprobe的构建
  • 1
  • 2
  • 3
  • 4
文档选项
  --disable-doc            不构建文档
  --disable-htmlpages      不构建HTML文档页面
  --disable-manpages       不构建man文档页面
  --disable-podpages       不构建POD文档页面
  --disable-txtpages       不构建文本文档页面
  • 1
  • 2
  • 3
  • 4
  • 5
组件选项(组件裁剪、线程裁剪、优化裁剪等)
组件选项:
  --disable-avdevice       禁用libavdevice的构建
  --disable-avcodec        禁用libavcodec的构建
  --disable-avformat       禁用libavformat的构建
  --disable-swresample     禁用libswresample的构建
  --disable-swscale        禁用libswscale的构建
  --disable-postproc       禁用libpostproc的构建
  --disable-avfilter       禁用libavfilter的构建
  --enable-avresample      启用libavresample的构建(不推荐) [否]
  --disable-pthreads       禁用pthreads [自动检测]
  --disable-w32threads     禁用Win32线程 [自动检测]
  --disable-os2threads     禁用OS/2线程 [自动检测]
  --disable-network        禁用网络支持 [否]
  --disable-dct            禁用DCT代码
  --disable-dwt            禁用DWT代码
  --disable-error-resilience 禁用错误恢复代码
  --disable-lsp            禁用LSP代码
  --disable-lzo            禁用LZO解码器代码
  --disable-mdct           禁用MDCT代码
  --disable-rdft           禁用RDFT代码
  --disable-fft            禁用FFT代码
  --disable-faan           禁用浮点AAN(I)DCT代码
  --disable-pixelutils     禁用libavutil中的像素工具
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
独立功能选项(开关特定的组件类型,比如单独开关h264等)
单个组件选项:
  --disable-everything     禁用下面列出的所有组件
  --disable-encoder=NAME   禁用编码器NAME
  --enable-encoder=NAME    启用编码器NAME
  --disable-encoders       禁用所有编码器
  --disable-decoder=NAME   禁用解码器NAME
  --enable-decoder=NAME    启用解码器NAME
  --disable-decoders       禁用所有解码器
  --disable-hwaccel=NAME   禁用硬件加速器NAME
  --enable-hwaccel=NAME    启用硬件加速器NAME
  --disable-hwaccels       禁用所有硬件加速器
  --disable-muxer=NAME     禁用复用器NAME
  --enable-muxer=NAME      启用复用器NAME
  --disable-muxers         禁用所有复用器
  --disable-demuxer=NAME   禁用解复用器NAME
  --enable-demuxer=NAME    启用解复用器NAME
  --disable-demuxers       禁用所有解复用器
  --enable-parser=NAME     启用解析器NAME
  --disable-parser=NAME    禁用解析器NAME
  --disable-parsers        禁用所有解析器
  --enable-bsf=NAME        启用比特流过滤器NAME
  --disable-bsf=NAME       禁用比特流过滤器NAME
  --disable-bsfs           禁用所有比特流过滤器
  --enable-protocol=NAME   启用协议NAME
  --disable-protocol=NAME  禁用协议NAME
  --disable-protocols      禁用所有协议
  --enable-indev=NAME      启用输入设备NAME
  --disable-indev=NAME     禁用输入设备NAME
  --disable-indevs         禁用所有输入设备
  --enable-outdev=NAME     启用输出设备NAME
  --disable-outdev=NAME    禁用输出设备NAME
  --disable-outdevs        禁用所有输出设备
  --disable-devices        禁用所有设备
  --enable-filter=NAME     启用过滤器NAME
  --disable-filter=NAME    禁用过滤器NAME
  --disable-filters        禁用所有过滤器
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
外部库支持

使用以下任何开关将允许FFmpeg链接到相应的外部库。如果满足它们的所有其他依赖项并且它们没有被明确禁用,那么依赖于该库的所有组件将被启用。例如,–enable-libwavpack将启用与libwavpack的链接,并允许构建libwavpack编码器,除非使用–disable-encoder=libwavpack明确禁用它。

  • 请注意,只有系统库会自动检测。所有其他外部库必须显式启用。

  • 还请注意,以下帮助文本描述了库本身的目的,而不一定所有功能都一定可供FFmpeg使用。

第三方库比较多,不一一列举

  --disable-alsa   禁用ALSA支持 [自动检测]
  --disable-appkit 禁用苹果AppKit框架 [自动检测]
  --disable-avfoundation 禁用苹果AVFoundation框架 [自动检测]
  --enable-avisynth 启用读取AviSynth脚本文件 [否]
  --disable-bzlib 禁用bzlib [自动检测]
  --disable-coreimage 禁用苹果CoreImage框架 [自动检测]
  --enable-chromaprint 启用使用chromaprint进行音频指纹处理 [否]
  --enable-frei0r 启用frei0r视频滤镜 [否]
  --enable-gcrypt 启用gcrypt,用于rtmp(t)e支持,如果未使用openssl、librtmp或gmp [否]
  --enable-gmp 启用gmp,用于rtmp(t)e支持,如果未使用openssl或librtmp [否]
  --enable-gnutls 启用gnutls,用于https支持,如果未使用openssl、libtls或mbedtls [否]
  .
  .
  .
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

工具链选项(根据目标平台选择对应工具链)

编译选项:
  --arch=ARCH              选择体系结构 []
  --cpu=CPU                选择所需的最小CPU(影响指令选择,可能在旧的CPU上崩溃)
  --cross-prefix=PREFIX    使用PREFIX作为编译工具 []
  --progs-suffix=SUFFIX    程序名称后缀 []
  --enable-cross-compile   假定正在使用交叉编译器
  --sysroot=PATH           交叉构建树的根目录
  --sysinclude=PATH        交叉构建系统头文件的位置
  --target-os=OS           编译器目标的操作系统 []
  --target-exec=CMD        运行目标上可执行文件的命令
  --target-path=DIR        目标上构建目录的路径
  --target-samples=DIR     目标上样本目录的路径
  --tempprefix=PATH        强制固定的dir/prefix,而不是使用mktemp进行检查
  --toolchain=NAME         根据NAME设置工具默认值(gcc-asan、clang-asan、gcc-msan、clang-msan、gcc-tsan、clang-tsan、gcc-usan、clang-usan、valgrind-massif、valgrind-memcheck、msvc、icl、gcov、llvm-cov、hardened)
  --nm=NM                  使用nm工具NM [nm -g]
  --ar=AR                  使用存档工具AR [ar]
  --as=AS                  使用汇编程序AS []
  --ln_s=LN_S              使用符号链接工具LN_S [ln -s -f]
  --strip=STRIP            使用strip工具STRIP [strip]
  --windres=WINDRES        使用Windows资源编译器WINDRES [windres]
  --x86asmexe=EXE          使用兼容nasm的汇编程序EXE [nasm]
  --cc=CC                  使用C编译器CC [gcc]
  --cxx=CXX                使用C编译器CXX [g++]
  --objcc=OCC              使用ObjC编译器OCC [gcc]
  --dep-cc=DEPCC           使用依赖生成器DEPCC [gcc]
  --nvcc=NVCC              使用Nvidia CUDA编译器NVCC或clang []
  --ld=LD                  使用链接器LD []
  --pkg-config=PKGCONFIG   使用pkg-config工具PKGCONFIG [pkg-config]
  --pkg-config-flags=FLAGS 传递附加标志到pkgconf []
  --ranlib=RANLIB          使用ranlib RANLIB [ranlib]
  --doxygen=DOXYGEN        使用DOXYGEN生成API文档 [doxygen]
  --host-cc=HOSTCC         使用主机C编译器HOSTCC
  --host-cflags=HCFLAGS    在为主机编译时使用HCFLAGS
  --host-cppflags=HCPPFLAGS 在为主机编译时使用HCPPFLAGS
  --host-ld=HOSTLD         使用主机链接器HOSTLD
  --host-ldflags=HLDFLAGS  链接主机时使用HLDFLAGS
  --host-extralibs=HLIBS   链接主机时使用libs HLIBS
  --host-os=OS             编译器主机操作系统 []
  --extra-cflags=ECFLAGS   将ECFLAGS添加到CFLAGS []
  --extra-cxxflags=ECFLAGS 将ECFLAGS添加到CXXFLAGS []
  --extra-objcflags=FLAGS  将FLAGS添加到OBJCFLAGS []
  --extra-ldflags=ELDFLAGS 将ELDFLAGS添加到LDFLAGS []
  --extra-ldexeflags=ELDFLAGS 将ELDFLAGS添加到LDEXEFLAGS []
  --extra-ldsoflags=ELDFLAGS 将ELDFLAGS添加到LDSOFLAGS []
  --extra-libs=ELIBS       添加ELIBS []
  --extra-version=STRING   版本字符串后缀 []
  --optflags=OPTFLAGS      重写与优化相关的编译器标志
  --nvccflags=NVCCFLAGS    重写nvcc标志 []
  --build-suffix=SUFFIX    库名称后缀 []
  --enable-pic             构建位置无关的代码
  --enable-thumb           编译Thumb指令集
  --enable-lto             使用链接时优化
  --env="ENV=override"     覆盖环境变量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
专家选项(内存分配相关的配置,一般不用)
  --malloc-prefix=PREFIX    使用PREFIX作为malloc和相关名称的前缀
  --custom-allocator=NAME   使用支持的自定义分配器
  --disable-symver          禁用符号版本控制
  --enable-hardcoded-tables 使用硬编码的表格而不是运行时生成
  --disable-safe-bitstream-reader
                            禁用位读取器中的缓冲区边界检查(更快,但可能会崩溃)
  --sws-max-filter-size=N   swscale使用的最大滤波器大小 [256]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
优化选项(同样是专家选项,一般是针对目标平台汇编级别的优化)

涉及指令比较多,不一一列举

  --disable-asm            禁用所有汇编优化
  --disable-altivec        禁用AltiVec优化
  --disable-vsx            禁用VSX优化
  --disable-power8         禁用POWER8优化
  --disable-amd3dnow       禁用3DNow!优化
  --disable-amd3dnowext    禁用3DNow!扩展优化
  --disable-mmx            禁用MMX优化
  --disable-mmxext         禁用MMXEXT优化
  --disable-sse            禁用SSE优化
  --disable-sse2           禁用SSE2优化
  --disable-sse3           禁用SSE3优化
  --disable-ssse3          禁用SSSE3优化
。。。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
开发者选项(在开发或者调试FFmpeg时有用)
开发者选项:
  --disable-debug          禁用调试符号
  --enable-debug=LEVEL     设置调试级别 []
  --disable-optimizations  禁用编译器优化
  --enable-extra-warnings  启用更多的编译器警告
  --disable-stripping      禁用剥离可执行文件和共享库
  --assert-level=level     0(默认)、1或2,断言测试的数量,
                           2会导致运行时减速。
  --enable-memory-poisoning 使用任意数据填充堆中未初始化的分配空间
  --valgrind=VALGRIND      通过valgrind运行“make fate”测试以检测内存泄漏和错误,使用指定的valgrind二进制文件。不能与--target-exec组合使用
  --enable-ftrapv          捕获算术溢出
  --samples=PATH           用于FATE的测试样本位置,如果未设置,则在进行make时使用$FATE_SAMPLES。
  --enable-neon-clobber-test 检查NEON寄存器是否被覆盖(仅用于调试目的)
  --enable-xmm-clobber-test 检查XMM寄存器是否被覆盖(仅适用于Win64;仅用于调试目的)
  --enable-random          随机启用/禁用组件
  --disable-random
  --enable-random=LIST     随机启用/禁用特定组件或
  --disable-random=LIST    组件组。LIST是一个逗号分隔的列表
                           NAME[:PROB]条目,其中NAME是一个组件
                           (组)和与NAME相关联的概率
                           NAME的(默认为0.5)。
  --random-seed=VALUE      用于--enable/disable-random的种子值
  --disable-valgrind-backtrace 不在Valgrind下打印回溯
                           (仅适用于--disable-optimizations构建)
  --enable-ossfuzz         启用fuzzer工具的构建
  --libfuzzer=PATH         libfuzzer的路径
  --ignore-tests=TESTS     忽略结果的测试的逗号分隔列表(不带“fate-”前缀
                           在名称中)
  --enable-linux-perf      启用Linux性能监视器API

注意:对象文件在configure启动的地方构建。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

编译举例

cd ~/ffmpeg_sources && \
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \
tar xjvf ffmpeg-snapshot.tar.bz2 && \
cd ffmpeg && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./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" \
  --ld="g++" \
  --bindir="$HOME/bin" \
  --enable-gpl \
  --enable-gnutls \
  --enable-libaom \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libsvtav1 \
  --enable-libdav1d \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree && \
PATH="$HOME/bin:$PATH" make && \
make install && \
hash -r
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

总体来看,FFmpeg的编译系统比较庞大,它允许用户根据其需求和系统配置来构建自定义的多媒体处理工具。

它有以下优点

  1. 高度可定制性:FFmpeg的编译系统提供了大量的配置选项,允许用户根据其需求启用或禁用不同的组件、功能和编解码器。这使得它非常容易裁剪。

  2. 跨平台支持:FFmpeg的编译系统在各种操作系统上都能正常工作,包括Linux、macOS和Windows。并且在各个平台上提供了优化选项

尽管FFmpeg的编译系统具有众多优点,但也存在一些缺点:

  1. 依赖管理:在构建FFmpeg之前,需要安装各种外部依赖项,这可能会涉及到一些手动工作,尤其是在不同操作系统上。

  2. 配置选项繁多:FFmpeg的配置选项众多,有时会有重复或者让人感到困惑的地方。用户需要仔细阅读文档以理解每个选项的含义和作用。

总体而言,ffmpeg的编译尽管可能需要一些时间来学习和配置,但一旦掌握,它可以提供卓越的多媒体处理能力。对于那些需要定制多媒体处理工具的用户来说,FFmpeg编译系统是一个不可或缺的资源。

系列文章目录

  • FFmpeg目录和编译
  • 更新中…
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/901549
推荐阅读
相关标签
  

闽ICP备14008679号