AV1編碼器rav1e的API使用

目錄

  1. 參考
  2. 概述
  3. rav1e API介紹

1. 參考

2. 概述

rav1e是Mozilla/Xiph開發(fā)人員和許多志愿者開發(fā)的號稱最安全、最快的AV1編碼器。它使用rust編寫,追求良好的速度、質量和可維護性。

3. rav1e API介紹

當前的API是圍繞以下4個結構和1個枚舉構建的[2]:

  • struct Frame: 未壓縮的原始視頻數(shù)據(jù)。
  • struct Packet:壓縮的視頻碼流。
  • struct Config: 編碼器的配置。
  • struct Context: 編碼器的狀態(tài)。
  • enum EncoderStatus: Context返回的fatal或者non-fatal的狀態(tài)。

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();
  • 它產(chǎn)生一個新的編碼Context。當bit_depth為8時,可以使用優(yōu)化的u8代碼路徑,否則必須使用u16

3.2 Context

它由Config::new_context生成,它的實現(xiàn)細節(jié)是隱藏的。

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;
  • 根據(jù)容器格式的不同,AV1的序列頭可以存儲在extradata中。container_sequence_header生成預先格式化的數(shù)據(jù),以方便地存儲在mkv或mp4中。
  • rav1e支持multi-pass編碼,可以通過調用get_first_pass_data獲取第一趟編碼的數(shù)據(jù)。

下面是遍歷方法的示例,對已有方法的包裝,方便使用者使用。

// 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():根據(jù)Context中的維數(shù)和像素格式信息生成一個幀。
  • flush():在功能上相當于調用send_frame(None)
  • set_limit():在功能上相當于在limit個幀發(fā)送到編碼器后調用flush()。

3.3 工作流程

工作流程如下所示:

  1. 設置
  • 創(chuàng)建并設置好Config。
  • 調用Confignew_context方法生成一個Context。
  1. 編碼的循環(huán)
  • 使用receive_packet嘗試獲取一個Packet。
  • 如果receive_packet返回EncoderStatus::NeedMoreData,通過send_frameContext發(fā)送一個Frame
  1. 編碼結束
  • 調用flush()將編碼器中緩存的Frame編碼到最后一個Packet。
  • 調用receive_packet,直到返回EncoderStatus:: limitarrived。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容