用MediaCodec實現多段視音訊的擷取與拼接

2021-07-30 03:26:08 字數 1542 閱讀 8588

視音訊編輯中,對多段**素材進行擷取和拼接是非常常見的操作。擷取和拼接實際上是對**檔案資料重新進行組合的過程。

要實現這些功能,就需要對**檔案進行編譯碼操作,即先解碼要處理的**檔案資料,然後再按照某種規則對這些資料進行編碼,以生成我們所需的目標。

android提供的mediacodec及其相關類為我們提供了所需的方法,這些類主要包括:mediacodec、mediaextractor、mediamuxer、mediaformat。

mediacodec用於建立視音訊編解碼器,通過它可以對視音訊資料進行編譯碼操作,它是編譯碼功能的核心類。

mediaextractor相當於乙個reader,它用於讀取**檔案,並提取出其中的視音訊資料。

mediamuxer相當於乙個writer,它用於將記憶體中的視音訊資料寫到檔案中。

主要邏輯如下,關鍵是三處執行緒同步的地方,具體原因稍後解釋。

再來了解一下這幾個類的「脾氣」。

一般用mediacodec建立編解碼器時,使用的都是createdecoderbytype方法,但在用三星pad(api level 18, android version 4.3)除錯時發現,呼叫該方法建立音訊編碼器時會出錯。故改為使用createbycodecname("omx.sec.aac.enc")建立音訊編碼器。估計這是乙個api bug。

configure decoder時,第乙個格式引數要與源的格式相同,這裡可以先通過extractor將源的格式讀出來,再直接傳給configure方法。configure encoder時,需設定幾個必要的引數,具體請參考官方說明。

當把全部要處理的資料灌給編解碼器後,使用queueinputbuffer(inputbufindex,0, 0, 0l, mediacodec.buffer_flag_end_of_stream)方法來通知編解碼器結束工作。之後,在outputbuffer的bufferinfo中,將攜帶這個標誌,通過判斷是否有這個標誌,我們就可以斷定資料是否都已處理完成,以進行後續操作。再之後,dequeueoutputbuffer的返回都將是info_try_again_later。當然,如果你自己有辦法在outputbuffer中判斷資料是否灌完,也可以不使用此標誌。

當資料灌完後,要使用releaseoutputbuffer,把緩衝區釋放掉。否則,你會發現queueinputbuffer總是返回-1,因為沒有空閒的緩衝區了。

需要注意的是,不能在啟動完編解碼器後,立即呼叫getoutputformat企圖addtrack,而應該在dequeueoutputbuffer後的info_output_format_changed中呼叫,否則會出錯。

當所有的writesampledata完成後,不要忘記呼叫stop和release,否則寫出的檔案也會有問題。

最後還要注意,這幾個類中,時間單位都是微秒,不要搞錯了。

轉至部落格無原始碼,後期將原始碼補上。

多段線性函式

我們容易證明,fmin是乙個非嚴格單峰函式。對於乙個xi,隨著y的增大,它的貢獻先是乙個減量,再是乙個為0的常量,最後是乙個增量。隨著y的增大,fmin的增量應該是增量和減減量和。因為每乙個都是由增量變成減量,因此fmin的增量越來越大,所以fmin單峰。因為平板的存在,fmin只能算是非嚴格單峰函...

AutoCad 修改多段線

對於用 pline 命令建立多段線物件,使用者可使用 pedit 命令來進行修改。該命令呼叫方式為 工具欄 modify ii 修改 ii 選單 modify 修改 object 物件 polyline 多段線 命令列 pedit 或別名pe 呼叫該命令後,系統首先提示使用者選擇多段線 pedit ...

資料的多段儲存

舉例說明8086如何用多個段儲存資料 說明 定義多個段和我們以前講的定義 段一樣,只是段名不同而已。程式中有多個段如何訪問這些資料呢,以及如何知道這些資料時 段還是資料段或者堆疊段呢,段名就相當於乙個錶號,它代表段位址,所以就通過mov ax,data 標號 然後將這個ax傳給ds,那就是資料段,傳...