音视频学习(三十二):VP8和VP9

VP8

简介

  • 全称:Video Processing 8
  • 发布者:原 On2 Technologies(2010 被 Google 收购)
  • 定位开源视频压缩标准,主要竞争对手是 H.264
  • 应用
    • WebRTC 视频通信
    • HTML5 <video> 标签(WebM)
    • FFmpeg、SRS 支持
    • YouTube(早期使用)

VP8编解码

VP8 是一种基于块的混合视频编码标准,整体思路类似 H.264。

编码核心步骤:

  1. 帧划分为宏块(Macroblock):16x16 像素
  2. 帧间预测(Inter)或帧内预测(Intra)
  3. 残差计算 + 变换编码(DCT)
  4. 量化
  5. 熵编码(基于概率模型的熵编码)
  6. 输出比特流

帧结构

组成结构

VP8 的每一帧(Frame)主要包括两个部分:

  • 帧头(Frame Header)
  • 帧数据(Frame Data)

帧头

帧头是帧的起始部分,包含了控制解码器如何处理该帧的各种信息。VP8 的帧头长度可变,分为 关键帧非关键帧 两种情况:

共通帧头结构(Frame Tag, 3字节)

text 复制代码
0 1 2 3 4 5 6 7   8 9 10 11 12 13 14 15   16 17 18 19 20 21 22 23
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|I|P|  Version  |     Partition 0 Length (19 bits)   |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
  • I (1 bit): 关键帧标志。0 表示关键帧,1 表示非关键帧。

  • P (1 bit): 是否允许显示该帧(rarely used)。

  • Version (3 bits): 编码器版本号。

  • Partition Length (19 bits): 第一个分区(Partition 0)的长度。

关键帧附加信息(关键帧特有,附加 7 字节)

如果是关键帧(I=0),在上述 3 字节后再跟随:

text 复制代码
0x9D 0x01 0x2A  // Start code (固定标志)
2 字节: 宽度 + flags
2 字节: 高度 + flags

这部分包含图像的尺寸信息(宽度和高度)以及颜色空间标志(通常忽略)。

帧数据(Frame Partitions)

VP8 的帧数据采用分区结构(Partitioning),通常为:

  • Partition 0:包含帧的控制信息、宏块模式等。必须完整接收后才能解码其余分区。
  • Partition 1+:包含实际的宏块残差编码数据(Residual)。

分区结构如下:

mathematica 复制代码
[ Partition 0 ] [ Partition 1 ] [ Partition 2 ] ... [ Partition N ]

注意:

  • Partition 0 通常为熵编码的语法元素,像预测模式、分区信息。
  • Partition 1-N 是变换系数等实际视频数据。

简化结构图

mathematica 复制代码
VP8 Frame:
├── Frame Tag (3 bytes)
│   ├── Key Frame? (I bit)
│   └── Partition 0 Length
├── [If Key Frame]
│   ├── Start Code (0x9D012A)
│   ├── Width, Height
├── Partition 0 (mode, control info)
├── Partition 1+ (macroblock residuals)

VP8编码技术细节

宏块划分(Macroblock)

  • 每帧划分为 16x16 的宏块
  • 每个宏块支持:
    • 4x4、8x8、16x16 子块
    • 1-4 个运动矢量
    • 多种预测模式

帧内预测(Intra Prediction)

  • 预测方向(如 H.264 中的 Intra_4x4、Intra_16x16):
    • 水平预测、垂直预测、DC 预测等
  • 使用邻近像素估计当前块的值

帧间预测(Inter Prediction)

  • 使用参考帧(last/golden/altref)中对应块
  • 具备子像素运动估计(1/4 像素精度)

变换和量化

  • 使用 DCT(Discrete Cosine Transform)
    • 4x4 DCT、16x16 DCT
  • 残差值 DCT 后进行量化

熵编码(Entropy Coding)

  • Bool编码器(Boolean Arithmetic Coding)
    • 类似算术编码,但更轻量
  • 使用上下文建模(Context Modeling)

比特流结构

text 复制代码
+----------------------------------+
| 帧标志位 (Frame Tag)             |
|  - 帧类型(1bit)                  |
|  - 版本号(3bit)                  |
|  - 显示标志(1bit)                |
|  - 帧长度(19bit)                 |
+----------------------------------+
| 帧头部数据                       |
|  - 分辨率                        |
|  - 色彩空间                      |
|  - 参考帧标识                    |
|  - Loop Filter 参数              |
|  - Segment 参数                  |
+----------------------------------+
| 编码宏块数据                     |
+----------------------------------+

特点

特性 说明
宏块大小 固定 16x16
支持子块划分 支持
多参考帧 支持(Last, Golden, AltRef)
子像素精度 支持 1/4 像素
去块滤波器 内置
分辨率 无限制(理论上)
CABAC / CAVLC 无,使用 Bool 编码
B 帧 不支持
可扩展性 不支持 SVC(VP9 才支持)

源码结构(libvpx)

libvpx 项目概览

GitHub 地址https://github.com/webmproject/libvpx

bash 复制代码
libvpx/
├── build/                  # 构建系统(make, cmake等)
├── configure               # 自动配置脚本
├── examples/               # 示例代码(编码、解码、实时编码等)
├── test/                   # 单元测试
├── tools/                  # 工具,如 vpxdec/vpxenc 封装
├── vpx/                    # 公共接口
├── vpxdec/                 # 解码器主程序
├── vpxenc/                 # 编码器主程序
├── vp8/                    # ✅ VP8 专用核心代码目录
│   ├── common/             # 公共结构、宏块、DCT、IDCT等
│   ├── decoder/            # 解码器实现
│   ├── encoder/            # 编码器实现
│   └── wrapper/            # 封装接口(如 vpx_codec_iface_t)
└── vp9/                    # VP9 对应目录

核心目录说明

vp8/common/ --- 编解码公用模块

包含 VP8 的核心数据结构、算法实现:

文件/目录 功能
blockd.h 宏块(Macroblock)结构定义
entropymode.c/h 熵编码模式表
entropy.c/h Bool-based 熵编码实现
idctllm.c 快速 IDCT 实现
loopfilter.c/h 去块滤波器实现
mv.h 运动矢量定义
modecont.h 预测模式上下文表
treecoder.c Huffman 树解码辅助模块
onyxc_int.h 解码器内部数据结构
alloccommon.c 内存分配器
postproc.c 解码后处理滤波器
vp8/encoder/ --- 编码器实现
文件/目录 功能
onyx_if.c 编码器主入口,初始化、编码过程
encodeframe.c 帧编码主流程(帧内/帧间)
ratectrl.c 码率控制模块
rdopt.c RDO(率失真优化)核心
modecosts.c 模式代价估算
picklpf.c 去块滤波器参数选择
quantize.c 残差量化
motion_search.c 运动估计核心(Diamond、Hexagon)
variance.c SAD/SSD 误差计算
firstpass.c 首遍编码(为双遍做统计)
temporal_filter.c 临时帧过滤(可用于 AltRef)
vp8/decoder/ --- 解码器实现
文件/目录 功能
onyxd_if.c 解码器主流程
decodeframe.c 解码单帧流程
detokenize.c 熵编码解码器(Token -> 残差)
idct_blk.c IDCT 模块
reconinter.c 帧间重建
reconintra.c 帧内重建

vp8/wrapper/

对外接口(API)封装,实现 vpx_codec_iface_t 接口,供上层使用,比如 FFmpeg、WebRTC:

文件 功能
vp8_cx_iface.c VP8 编码器接口封装
vp8_dx_iface.c VP8 解码器接口封装

这些接口被 vpx_codec_*() 系列函数调用,如:

复制代码
c复制编辑vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, &cfg, 0);
vpx_codec_enc_init(&codec, &vpx_codec_vp8_cx_algo, &cfg, 0);

编码流程简析(VP8)

文件核心在 vp8/encoder/encodeframe.conyx_if.c

编码主流程:

c 复制代码
// onyx_if.c
vp8_get_compressed_data():
    -> encode_frame_to_data_rate()         // 编码主流程
       -> vp8cx_encode_frame()
          -> vp8_first_pass()              // 如果是两遍编码
          -> motion_estimation()
          -> mode decision / RDO
          -> DCT -> Quant -> Entropy encode
          -> loopfilter()

解码流程简析(VP8)

c 复制代码
c// onyxd_if.c
vp8_decode_frame():
    -> read frame header
    -> token parsing (detokenize.c)
    -> decode macroblocks (decodeframe.c)
    -> IDCT, loop filter, reconstruction

实用命令:libvpx 编码示例

bash 复制代码
# 编码 VP8 视频(libvpx 提供的工具)
vpxenc input.y4m --codec=vp8 --output=output.webm --threads=4 --target-bitrate=1000

# 解码 VP8 文件
vpxdec output.webm

VP9

简介

  • 发布者:Google(2013年开源)
  • 定位开放的高效视频压缩标准(H.265 竞争者)
  • 应用
    • YouTube(主流编码格式)
    • Chrome、Firefox、Edge、Android 原生支持
    • WebRTC(与 VP8 并存)
    • 支持 WebM 封装格式(.webm)

核心特性(相较于 VP8)

特性 VP8 VP9
参考帧 最多 3 帧 最多 8 帧
分区结构 固定 16x16 宏块 可递归划分至 4x4 子块
压缩效率 普通 提升约 30%-50%
运动估计精度 1/4 像素 支持至 1/8 像素
并行解码 支持有限 支持 Tile 并行解码
色彩空间 8-bit YUV 支持 10/12-bit、BT.2020 等
可扩展编码(SVC) 不支持 支持

帧结构

组成结构

一个 VP9 Frame(画面)主要由以下部分组成:

css 复制代码
[ Uncompressed Header ]
[ Compressed Header ]
[ Tile Data ]

Uncompressed Header(非压缩帧头)

非压缩帧头是 VP9 帧最前面的部分,不使用熵编码,含有控制信息。

主要字段说明:

字段名 位数(大致) 含义
Frame Marker 2 bits 固定值 0b10,用于标记 VP9 帧
Profile 2 bits 取值 0~3,表示 VP9 Profile(色深/采样)
Show Existing Frame 1 bit 是否显示已有帧
Frame Type 1 bit 关键帧(0)/非关键帧(1)
Show Frame 1 bit 是否显示该帧
Error Resilient 1 bit 错误恢复模式(影响帧间预测)
Intra Only 1 bit 仅帧内预测(只对非关键帧)
Reset Frame Context 2 bits 控制解码上下文的重置策略
Color Space 3 bits 颜色空间,如 BT.601/BT.709 等
Bit Depth 1 bit 8 / 10 / 12 bits
Frame Width / Height 32 bits 图像宽高信息
Render Width / Height 32 bits 显示宽高(可能不同于编码宽高)
Loop Filter Params 可变 循环滤波配置
Quantization Params 可变 量化参数
Segmentation Params 可变 分块质量控制参数
Tile Info 可变 瓦片划分信息(行数列数)

注意:关键帧会包含完整帧宽高和颜色信息;非关键帧可以引用之前帧的元数据。

Compressed Header(压缩帧头)

使用熵编码(基于上下文概率表)压缩,包含预测模式、运动矢量、块划分模式等控制信息。

包含内容:

  • 预测模式(帧内/帧间)
  • 块划分方式
  • 运动矢量参考索引(ref_frame_idx)
  • skip_flags
  • transform size 选择
  • DCT/ADST 类型选择
  • Token 语法表

这个部分决定了解码时如何还原帧。

Tile Data(图像数据部分)

VP9 使用 Tile(瓦片)结构进行并行解码,Tile 是按列分割的一块图像区域,具有独立编码结构。

Tile 特点:

  • 每个 Tile 可独立解码(适合多线程)
  • Tile 数据包括:
    • 残差系数(变换块)
    • skip 模式信息
    • CDF 熵码表更新
  • Tile 是 VP9 实际图像内容的主要组成部分

你可以认为一帧由多个 tile 按顺序拼成图像。

VP9 帧结构图示

bash 复制代码
┌──────────────────────────┐
│ Frame Marker (2 bits)    │
│ Profile (2 bits)         │
│ Show Frame / Keyframe    │
├──────────────────────────┤
│ Uncompressed Header      │
│  ├── Width / Height      │
│  ├── Color Space         │
│  ├── Loop Filter         │
│  └── Quant Params        │
├──────────────────────────┤
│ Compressed Header (熵编码)│
│  ├── Mode Info           │
│  ├── Motion Vectors      │
│  └── Token Partition     │
├──────────────────────────┤
│ Tile Data                │
│  ├── Tile 0              │
│  ├── Tile 1              │
│  └── Tile N              │
└──────────────────────────┘

关键帧 vs 非关键帧 区别

关键帧(Keyframe) 非关键帧(Inter Frame)
是否独立 否,需要参考前帧
包含信息 完整图像元信息 可复用前帧元信息
参考帧使用 多参考帧/双向预测
用途 场景切换、起始帧 正常视频传输帧

VP9编码技术细节

mathematica 复制代码
Raw Frame (YUV)
   ↓
Block Partitioning(分块)
   ↓
Prediction(预测:Intra / Inter)
   ↓
Transform(变换:DCT / ADST)
   ↓
Quantization(量化)
   ↓
Entropy Coding(上下文熵编码)
   ↓
Bitstream(VP9 Frame)

Superblock & Block Partitioning(超级块与分块)

Superblock
  • 固定大小 64x64 像素
  • VP9 使用 superblock 替代 VP8 的宏块(16x16)
分块模式
  • 每个 superblock 可递归划分为更小块(最大到 4x4)
  • 块划分支持 10 种模式,如:
diff 复制代码
64x64 → 32x32 → 16x16 → 8x8 → 4x4
+ 一些非对称划分(e.g. 32x16, 16x32)
优点
  • 允许更细粒度的局部控制(纹理复杂区域划小块,背景区域保大块)
  • 类似 HEVC 中 CU/PU/TU 的结构

Prediction(帧预测)

帧内预测(Intra Prediction)
  • 预测当前块的数据来自当前帧已解码区域
  • 支持 10 种帧内预测模式(DC、水平、垂直、方向模式等)
帧间预测(Inter Prediction)
  • 预测当前块来自于 参考帧
  • 参考帧支持:Last, Golden, AltRef(最多 3 个)
  • 支持:
    • 单向预测(Single Reference)
    • 双向预测(Compound Prediction)
    • 亚像素精度运动矢量(1/8 像素)
    • 运动矢量预测与补偿(MVP)
    • 全局运动建模(Global Motion)
优点
  • 相较 VP8,大幅提升运动估计准确度和压缩效率

Transform(变换)

VP9 使用 DCT/ADST 进行频域转换,压缩空间冗余。

Block Size 支持变换类型
4x4 DCT / ADST
8x8 DCT / ADST
16x16 DCT only
32x32 DCT only
64x64 DCT only

水平/垂直可用不同变换类型,混合变换提升适应性。

Quantization(量化)

  • 各个块的变换系数会进行量化压缩
  • 使用 自适应量化参数,支持 segmentation(每块不同 QP)
  • QP(量化参数)影响压缩率和质量:数值越大,压缩越强,画质越差

Loop Filters(环路滤波)

用于消除块边界伪影(blocking artifacts):

包括:

  • Deblocking Filter(去块效应)
  • Adaptive Loop Filter
  • Clamping Filter
  • CDEF / Sgrproj(在 AV1 中)

VP9 提供灵活的滤波控制参数,按块启用或关闭滤波器。

Segmentation(分段控制)

将图像划分为多个 segment,每个 segment 可设置不同参数:

  • QP(量化参数)
  • Loop filter 强度
  • 预测模式约束
  • 可用于 ROI 编码(重点区域更高质量)

Tile-based 并行处理

Tile 是图像按列划分的子区域(不是 macroblock)

  • 每个 tile 可独立解码
  • 支持并行编码(多线程)
  • Tile Size 可调节(编码效率 vs 并行效率)

好处:

  • 实时编码优化(尤其适用于 WebRTC)
  • 硬件友好,可并行硬解

Entropy Coding(熵编码)

使用 上下文自适应二进制算术编码(Context Adaptive Binary Arithmetic Coding, CABAC) 类似结构:

  • 每个语法元素使用概率模型编码
  • 多个上下文模型(如 skip_flag、mv、transform_size 等)
  • 兼容多参考帧、多块模式预测

VP9 Profiles & 色深支持

Profile Bit Depth 色度格式 用途
0 8-bit 4:2:0 WebM, YouTube 默认
1 8-bit 4:2:2 / 4:4:4 高质量视频
2 10/12-bit 4:2:0 HDR 视频
3 10/12-bit 4:2:2 / 4:4:4 专业场景

比特流结构

css 复制代码
[ Frame Header ]
[ Compressed Frame Data ]
    └── [ Tile Data ]
    └── [ Residual Data (Transformed & Quantized) ]
    └── [ Motion Vectors (for Inter Frames) ]
    └── [ Entropy-coded Data (Tokens) ]

特点

特性 VP9 H.264 H.265
压缩效率 很高
编码复杂度 很高
硬件支持 中(新设备支持) 普遍
授权成本 免费 付费 付费
多线程支持 好(Tile) 一般 优秀

源码结构(libvpx)

bash 复制代码
libvpx/
├── vp8/                    # VP8 编解码器实现
├── vp9/                    # VP9 编解码器实现 ✅ ← 重点
│   ├── encoder/            # VP9 编码器实现
│   ├── decoder/            # VP9 解码器实现
│   ├── common/             # 编码器 & 解码器共有的数据结构、工具函数
│   └── ...
├── build/                  # 构建脚本
├── test/                   # 单元测试代码
├── tools/                  # 命令行工具(vpxenc/vpxdec)
├── examples/               # 示例代码(使用 libvpx 编解码)
├── vpx/                    # 通用接口层
│   ├── vpx_encoder.h       # 编码器 API 入口
│   ├── vpx_decoder.h       # 解码器 API 入口
│   └── vpx_codec.h         # 通用编解码框架
└──

编码器核心结构(vp9/encoder/

文件名 功能
vp9_encoder.h/c 编码器核心控制接口
vp9_encodeframe.c 每帧编码主逻辑(块划分、预测、残差、熵编码)
vp9_ratectrl.c 码率控制模块(CBR/VBR)
vp9_pickmode.c 预测模式选择(Intra / Inter)
vp9_rdopt.c 率失真优化(Rate-Distortion)关键模块 ✅
vp9_quantize.c DCT 系数量化
vp9_tokenize.c 熵编码预处理(生成 token)
vp9_mcomp.c 运动估计(Motion Estimation)
vp9_segmentation.c 分段编码(不同 QP 区域)
vp9_skin_detection.c 人脸/肤色检测(可用于提升视觉质量)
vp9_aq_variance.c 自适应质量 AQ 策略
... 其他模块如 tile、滤波器、变换 等

解码器核心结构(vp9/decoder/

文件名 功能
vp9_decoder.h/c 解码器核心控制逻辑
vp9_decodeframe.c 解码主逻辑(解析帧头、构建帧)
vp9_dboolhuff.c 帧头解析 + 熵解码器
vp9_decodemv.c 解码运动矢量相关信息
vp9_detokenize.c 熵解码后的系数还原
vp9_reader.h 比特流解析器(BitReader)
... 变换、滤波、预测、Tile 重建等

通用模块(vp9/common/

文件名 功能
vp9_common.h 公共定义(帧类型、块大小等)
vp9_blockd.c/.h 块级数据结构、预测模式枚举
vp9_mv.h 运动矢量数据结构
vp9_entropy.c 熵编码上下文模型(上下文概率表)
vp9_loopfilter.c 去块滤波器(Deblocking Filter)
vp9_seg_common.c 分段结构解析
vp9_tile_common.c Tile 分区结构解析
vp9_pred_common.c 预测函数(帧内帧间)
vp9_inv_txfm.c 反变换(IDCT / IADST)

编码流程简析(VP9)

入口在 examples/vpxenc.c

  1. main() 中设置参数后调用:

    c 复制代码
    vpx_codec_enc_init()
  2. 使用 vpx_codec_encode() 编码一帧 YUV,会调用:

    c 复制代码
    vp9_get_cx_interface() → vp9_encode() → vp9_encode_frame()
  3. 编码流程深入到:

    • vp9_rd_pick_inter_mode_sb():选最优 Inter 模式
    • vp9_transform_block():DCT/ADST
    • vp9_quantize():量化
    • vp9_entropy_coding():熵编码 token
    • vp9_write_bitstream():写入 VP9 比特流

解码流程简析(VP9)

入口在 examples/vpxdec.c

  1. 初始化解码器 vpx_codec_dec_init()

  2. 调用 vpx_codec_decode() 解码 VP9 比特流

  3. 实际进入 VP9 解码器:

    c 复制代码
    vp9_get_dx_interface() → vp9_decode() → vp9_decode_frame()
  4. 解码流程:

    • vp9_read_frame_header()
    • vp9_decode_tiles():Tile 并行重建
    • vp9_loopfilter_frame():去块滤波
    • 输出 YUV 图像帧

FFMPEG推拉VP8/VP9

推流

推送 VP8 流(RTMP 协议)

bash 复制代码
ffmpeg -re -i input.mp4 -c:v libvpx -b:v 1M -c:a libopus -f flv rtmp://your-server-ip/live/stream_key
  • -re:以实时速度读取输入文件
  • -i input.mp4:输入文件(可以是 .mp4.y4m.avi 等)
  • -c:v libvpx:使用 VP8 编码器(libvpx)
  • -b:v 1M:设置视频比特率为 1Mbps
  • -c:a libopus:使用 Opus 编码器进行音频编码
  • -f flv:指定输出格式为 FLV(适用于 RTMP 流媒体)
  • rtmp://your-server-ip/live/stream_key:RTMP 流媒体服务器地址和流密钥

推送 VP9 流(RTMP 协议)

bash 复制代码
ffmpeg -re -i input.mp4 -c:v libvpx-vp9 -b:v 1M -c:a libopus -f flv rtmp://your-server-ip/live/stream_key
  • -c:v libvpx-vp9:使用 VP9 编码器(libvpx-vp9)
  • 其他参数与推送 VP8 流类似

拉流

拉取 VP8 流(RTMP 协议)

bash 复制代码
ffmpeg -i rtmp://your-server-ip/live/stream_key -c:v libvpx -c:a libopus output.webm
  • -i rtmp://your-server-ip/live/stream_key:指定 RTMP 流媒体源地址
  • -c:v libvpx:解码 VP8 视频流
  • -c:a libopus:解码音频流为 Opus 格式
  • output.webm:指定输出文件格式为 WebM

拉取 VP9 流(RTMP 协议)

bash 复制代码
ffmpeg -i rtmp://your-server-ip/live/stream_key -c:v libvpx-vp9 -c:a libopus output.webm
  • -c:v libvpx-vp9:解码 VP9 视频流
  • 其他参数与拉取 VP8 流类似

其他协议

推流至 RTSP 服务器(VP8/VP9)

bash 复制代码
ffmpeg -re -i input.mp4 -c:v libvpx -b:v 1M -c:a libopus -f rtsp rtsp://your-server-ip:port/stream
  • -f rtsp:设置 RTSP 协议输出
  • rtsp://your-server-ip:port/stream:指定 RTSP 流地址

拉取 RTSP 流(VP8/VP9)

bash 复制代码
ffmpeg -i rtsp://your-server-ip:port/stream -c:v libvpx -c:a libopus output.webm

拉取 HLS 流(VP8/VP9)

如果流源为 HLS(HTTP Live Streaming),可以使用以下命令来拉取 VP8 或 VP9 流:

bash 复制代码
ffmpeg -i http://your-server-ip/hls/stream.m3u8 -c:v libvpx -c:a libopus output.webm
  • -i http://your-server-ip/hls/stream.m3u8:指定 HLS 流的 M3U8 播放列表
  • output.webm:输出为 WebM 格式
相关推荐
救救孩子把4 小时前
换脸视频FaceFusion3.1.0-附整合包
音视频
爱趣五科技12 小时前
H5DS编辑器教程——企业级雪花特效开发指南
前端·安全·编辑器·音视频
1alisa15 小时前
OBS 录屏软件 for Mac 视频录制
macos·音视频
写代码的小王吧1 天前
【安全】Java幂等性校验解决重复点击(6种实现方式)
java·linux·开发语言·安全·web安全·网络安全·音视频
yunteng5211 天前
音视频(四)android编译
android·ffmpeg·音视频·x264·x265
zhuxian20091 天前
ffmpeg音频分析
ffmpeg·音视频
AI服务老曹1 天前
机器学习算法能够自动学习并使用不同条件下的变化趋势,确保预测结果的准确性的智慧地产开源了
运维·学习·开源·音视频
花落已飘1 天前
ffmpeg基础知识入门
ffmpeg·音视频