目录
- 参考
- 概述
- rav1e API介绍
1. 参考
2. 概述
rav1e是Mozilla/Xiph开发人员和许多志愿者开发的号称最安全、最快的AV1编码器。它使用rust编写,追求良好的速度、质量和可维护性。
3. rav1e API介绍
当前的API是围绕以下4个结构和1个枚举构建的[2]:
-
struct Frame
: 未压缩的原始视频数据。 -
struct Packet
:压缩的视频码流。 -
struct Config
: 编码器的配置。 -
struct Context
: 编码器的状态。 -
enum EncoderStatus
:Context
返回的fatal或者non-fatal的状态。
3.1 Config
Config的定义如下所示。
struct Config {
enc: EncoderConfig,
threads: usize,
}
- EncoderConfig存储所有对实际码流有影响的设置,而线程等设置则保存在外部。
let mut enc = EncoderConfig::with_speed_preset(speed);
enc.width = w;
enc.height = h;
enc.bit_depth = 8;
let cfg = Config { enc, threads: 0 };
Config的new_context方法
let cfg = Config { enc, threads: 0 };
let ctx: Context<u8> = cfg.new_context();
- 它产生一个新的编码Context。当
bit_depth
为8时,可以使用优化的u8
代码路径,否则必须使用u16
。
3.2 Context
它由Config::new_context
生成,它的实现细节是隐藏的。
Context
相关的方法可以分为基本方法(essential)、可选方法(optional)、便利方法(convenience)。
例如下面编码API:
// Essential API
pub fn send_frame<F>(&mut self, frame: F) -> Result<(), EncoderStatus>
where F: Into<Option<Arc<Frame<T>>>>, T: Pixel;
pub fn receive_packet(&mut self) -> Result<Packet<T>, EncoderStatus>;
- 编码器的工作原理是通过send_frame提供的每个
Frame
,通过receive_packet获取编码生成的Packet
。
下面是可选方法的示例,在某些场景下使用。
// Optional API
pub fn container_sequence_header(&mut self) -> Vec<u8>;
pub fn get_first_pass_data(&self) -> &FirstPassData;
- 根据容器格式的不同,AV1的序列头可以存储在extradata中。
container_sequence_header
生成预先格式化的数据,以方便地存储在mkv或mp4中。 -
rav1e
支持multi-pass编码,可以通过调用get_first_pass_data
获取第一趟编码的数据。
下面是遍历方法的示例,对已有方法的包装,方便使用者使用。
// Convenience shortcuts
pub fn new_frame(&self) -> Arc<Frame<T>>;
pub fn set_limit(&mut self, limit: u64);
pub fn flush(&mut self) {
-
new_frame()
:根据Context
中的维数和像素格式信息生成一个帧。 -
flush()
:在功能上相当于调用send_frame(None)
。 -
set_limit()
:在功能上相当于在limit
个帧发送到编码器后调用flush()。
3.3 工作流程
工作流程如下所示:
- 设置
- 创建并设置好
Config
。 - 调用
Config
的new_context
方法生成一个Context。
- 编码的循环
- 使用
receive_packet
尝试获取一个Packet
。 - 如果
receive_packet
返回EncoderStatus::NeedMoreData
,通过send_frame
给Context
发送一个Frame
。
- 编码结束
- 调用
flush()
将编码器中缓存的Frame
编码到最后一个Packet
。 - 调用
receive_packet
,直到返回EncoderStatus:: limitarrived
。