鴻蒙OS 視頻編解碼開發(fā)指導

2020-09-18 14:10 更新

場景介紹

視頻編解碼的主要工作是將視頻進行編碼和解碼。

接口說明

接口名 功能描述
createDecoder() 創(chuàng)建解碼器Codec實例。
createEncoder() 創(chuàng)建編碼器Codec實例。
registerCodecListener(ICodecListener listener) 注冊偵聽器用來異步接收編碼或解碼后的數(shù)據(jù)。
setSource(Source source, TrackInfo trackInfo) 根據(jù)解碼器的源軌道信息設置數(shù)據(jù)源,對于編碼器trackInfo無效。
setSourceFormat(Format format) 編碼器的管道模式下,設置編碼器編碼格式。
setCodecFormat(Format format) 普通模式設置編/解碼器參數(shù)。
setVideoSurface(Surface surface) 設置解碼器的Surface。
getAvailableBuffer(long timeout) 普通模式獲取可用ByteBuffer。
writeBuffer(ByteBuffer buffer, BufferInfo info) 推送源數(shù)據(jù)給Codec。
getBufferFormat(ByteBuffer buffer) 獲取輸出Buffer數(shù)據(jù)格式。
start() 啟動編/解碼。
stop() 停止編/解碼。
release() 釋放所有資源。

普通模式開發(fā)步驟

在普通模式下進行編解碼,應用必須持續(xù)地傳輸數(shù)據(jù)到 Codec 實例。

編碼的具體開發(fā)步驟如下

  1. 創(chuàng)建編碼 Codec 實例,可調(diào)用 createEncoder() 創(chuàng)建。

   final Codec encoder = Codec.createEncoder();

  1. 構(gòu)造數(shù)據(jù)源格式,并設置給 Codec 實例,調(diào)用 setCodecFormat(),代碼示例如下:

   Format fmt = new Format();
   fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
   fmt.putIntValue(Format.WIDTH, 1920);
   fmt.putIntValue(Format.HEIGHT, 1080);
   fmt.putIntValue(Format.BIT_RATE, 392000);
   fmt.putIntValue(Format.FRAME_RATE, 30);
   fmt.putIntValue(Format.FRAME_INTERVAL, -1);
   codec.setCodecFormat(fmt);

  1. 如果需要編碼過程中,檢測是否讀取到 Buffer 數(shù)據(jù)以及是否發(fā)生異常,可以構(gòu)造 ICodecListener, ICodecListener 需要實現(xiàn)兩個方法,實現(xiàn)讀到 Buffer 數(shù)據(jù)時、編碼發(fā)生異常時做相應的操作。舉例中讀到 buffer 時,獲取 buffer 的 format 格式,異常時拋出運行時異常,代碼示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 調(diào)用 start() 方法開始編碼。

  1. 調(diào)用 getAvailableBuffer() 取到一個可用的 ByteBuffer,把數(shù)據(jù)填入 ByteBuffer 里,然后再調(diào)用 writeBuffer() 把 ByteBuffer 寫入編碼器實例。

  1. 調(diào)用 stop() 方法停止編碼。

  1. 編碼任務結(jié)束后,調(diào)用 release() 釋放資源。

解碼的具體開發(fā)步驟如下:

  1. 創(chuàng)建解碼 Codec 實例,可調(diào)用 createDecoder() 創(chuàng)建。

  1. 構(gòu)造數(shù)據(jù)源格式,并設置給 Codec 實例,調(diào)用 setCodecFormat(),代碼示例如下:

   Format fmt = new Format();
   fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
   fmt.putIntValue(Format.WIDTH, 1920);
   fmt.putIntValue(Format.HEIGHT, 1080);
   fmt.putIntValue(Format.BIT_RATE, 392000);
   fmt.putIntValue(Format.FRAME_RATE, 30);
   fmt.putIntValue(Format.FRAME_INTERVAL, -1);
   codec.setCodecFormat(fmt);

  1. (可選)如果需要解碼過程中,檢測是否讀取到 Buffer 數(shù)據(jù)以及是否發(fā)生異常,可以構(gòu)造 ICodecListener,ICodecListener 需要實現(xiàn)兩個方法,實現(xiàn)讀到 Buffer 數(shù)據(jù)時、解碼發(fā)生異常時做相應的操作。舉例中讀到 buffer 時,獲取 buffer 的 format 格式,異常時拋出運行時異常,代碼示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 調(diào)用 start() 方法開始解碼。

  1. 調(diào)用 getAvailableBuffer 取到一個可用的 ByteBuffer,把數(shù)據(jù)填入 ByteBuffer 里,然后再調(diào)用 writeBuffer 把 ByteBuffer 寫入解碼器實例。

  1. 調(diào)用 stop() 方法停止解碼。

  1. 解碼任務結(jié)束后,調(diào)用 release() 釋放資源。

管道模式開發(fā)步驟

管道模式下應用只需要調(diào)用 Source 類的 setSource() 方法,數(shù)據(jù)會自動解析并傳輸給 Codec 實例。管道模式編碼支持視頻流編碼和音頻流編碼。

編碼的具體開發(fā)步驟如下:

  1. 調(diào)用 createEncoder() 創(chuàng)建編碼 Codec 實例。

  1. 調(diào)用 setSource() 設置數(shù)據(jù)源,支持設定文件路徑或者文件 File Descriptor。

  1. 構(gòu)造數(shù)據(jù)源格式或者從 Extractor 中讀取數(shù)據(jù)源格式,并設置給 Codec 實例,調(diào)用 setSourceFormat(),構(gòu)造數(shù)據(jù)原格式代碼示例如下:

   Format fmt = new Format();
   fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
   fmt.putIntValue(Format.WIDTH, 1920);
   fmt.putIntValue(Format.HEIGHT, 1080);
   fmt.putIntValue(Format.BIT_RATE, 392000);
   fmt.putIntValue(Format.FRAME_RATE, 30);
   fmt.putIntValue(Format.FRAME_INTERVAL, -1);
   codec.setSourceFormat(fmt);

  1. (可選)如果需要編碼過程中,檢測是否讀取到 Buffer 數(shù)據(jù)以及是否發(fā)生異常,可以構(gòu)造 ICodecListener,ICodecListener 需要實現(xiàn)兩個方法,實現(xiàn)讀到 Buffer 數(shù)據(jù)時、編碼發(fā)生異常時做相應的操作。舉例中讀到 buffer 時,獲取 buffer 的 format 格式,異常時拋出運行時異常,代碼示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 調(diào)用 start() 方法開始編碼。

  1. 調(diào)用 stop() 方法停止編碼。

  1. 編碼任務結(jié)束后,調(diào)用 release() 釋放資源。

解碼的具體開發(fā)步驟如下:

  1. 調(diào)用 createDecoder()創(chuàng)建解碼 Codec 實例。

  1. 調(diào)用 setSource()設置數(shù)據(jù)源,支持設定文件路徑或者文件 File Descriptor。

  1. (可選)如果需要解碼過程中,檢測是否讀取到 Buffer數(shù)據(jù)以及是否發(fā)生異常,可以構(gòu)造 ICodecListener,ICodecListener 需要實現(xiàn)兩個方法,實現(xiàn)讀到 Buffer 數(shù)據(jù)時、解碼發(fā)生異常時做相應的操作。舉例中讀到 buffer 時,獲取 buffer 的 format 格式,異常時拋出運行時異常,代碼示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 調(diào)用 start() 方法開始解碼。

  1. 調(diào)用 stop() 方法停止解碼。

  1. 解碼任務結(jié)束后,調(diào)用 release() 釋放資源。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號