2013-10-08 36 views
7

已經演示瞭如何像CameraPreview一樣feed MediaCodec with Surface input,但在提交到MediaCodec之前是否有緩衝此輸入的實際方法?對MediaCodec的緩衝表面輸入

以我experiments,銀河的Nexus經歷不可接受的打嗝在使用CameraToMpegTest.java

直接,同步編碼方法當使用MediaCodecbyte[]ByteBuffer輸入產生音頻/視頻流,我們就可以提交未編碼數據到ExecutorService或類似的隊列進行處理,以確保不丟幀,即使設備在我們應用程序的控制之外出現CPU使用率峯值。但是,由於執行color format conversion between Android's Camera and MediaCodec的要求,這種方法對於高分辨率的實時視頻是不現實的。

思想

  1. 有沒有辦法養活與EGL14.eglCopyBuffers(EGLDisplay d, EGLSurface s, NativePixmapType p)MediaCodec創建NativePixmapType

  2. Android的任何人都可以評論Camera和MediaCodec之間的ByteBuffer格式是否協調路線圖嗎?

+0

那麼,您是否在將幀傳遞給MediaCodec的輸入時找到解決打嗝的方法?在我的情況下,當將MediaCodec提供給MediaMuxer時,我將緩衝MediaCodec的輸出。但是在調用swapBuffers()來提供MediaMuxer的輸入時,我遇到了打嗝。 – Petrakeas

回答

3

你真的不想複製數據。分配存儲並複製大量數據可能需要足夠長的時間來殺死幀速率。這通常會排除byte []和ByteBuffer []解決方案,即使您不必進行U/V平面交換。

通過系統移動數據的最有效方式是使用Surface。訣竅是Surface不是緩衝區,它是一個queue of buffers的接口。緩衝區通過引用傳遞;當unlockCanvasAndPost()時,你實際上將當前緩衝區放置到消費者的隊列中,這通常是在不同的進程中。

沒有公共機制來創建新緩衝區並將其添加到隊列使用的集合中,或者從隊列中提取緩衝區,所以您無法在側面實現DIY緩衝區方案。沒有公共接口來更改池中緩衝區的數量。

知道是什麼導致了打嗝是有用的。用於分析此類問題的Android工具是systrace,可用於Android 4.1+(docsexamplebigflake example)。如果您可以確定CPU負載的來源,或者確定它不是CPU,而是讓一些代碼糾結在一起,那麼您可能會有一個解決方案,比向Surface添加更多緩衝區要容易得多。

+0

偉大的建議! Systrace真的幫了忙。是否可以嵌套'Trace'段落?我似乎無法獲得以家長身份開始和結束的片段。 – dbro

+0

它應該工作。我嘗試了一個簡單的例子(在onCreate()中的兩個'beginSection()'調用不同的位置,最後兩個'endSection()'調用),並得到了我的預期。 – fadden

+0

我在試圖從設備上的h264 TS文件或UDP上流式傳輸視頻時,在平板電腦上看到了「打嗝」(實時相機饋送或從服務器流式傳輸H264 TS)4.1.2(我認爲是Galaxy Note 10.1 ,它不在我面前)打嗝,並且總是返回BufferInfo。大小爲0(我們已經把我們的最小sdk提高到了18(4.3),因爲當編碼解碼器的CTS進入時)......但是,聯想瑜伽10 @ 4.3在回放過程中有嚴重的口吃...這似乎是因爲輸入緩衝區很少可用... – PapaWhiskey