背景:擴展客戶所有權
我已經連接Android的MediaCodec到FFmpeg的路複用爲各種格式不被支持MediaMuxer,包括通過.flv
容器rtmp://
輸出。這樣的流式複用器需要MediaCodec輸出緩衝器的更長,不可預知的所有權,因爲它們可以在任何數據包處理步驟上執行聯網I/O。對於我的視頻流,我使用配置爲Surface輸入的MediaCodec。爲了將多路複用與編碼分離,我通過一個Handler將MediaCodec的ByteBuffer輸出緩衝區排隊到我的muxer。
如果我將.flv
輸出複合到文件而非rtmp端點,所有的工作都非常出色。
問題:
當合併到rtmp://...
端點我發現我流應用始於上dequeueOutputBuffer()
呼籲eglSwapBuffers(mEGLDisplay, mEncodingEGLSurface)
阻止一次,我保留我的複用隊列甚至幾MediaCodec輸出緩衝器作爲MediaCodec似乎只能鎖定到4個輸出緩衝區。
任何技巧,以避免複製所有編碼器輸出MediaCodec#dequeueOutputBuffers
返回並立即呼籲releaseOutputBuffer(...)
?
我的項目的完整源代碼可在Github。具體而言,請參閱:
- AndroidEncoder.java:主要drainEncoder():與音頻和視頻編碼器之間共享行爲摘要編碼器類。將數據寫入
Muxer
實例。 - FFmpegMuxer.java:實現
Muxer
- CameraEncoder.java。將相機幀發送到爲視頻編碼配置的AndroidEncoder子類。
Systrace
下面是一些systrace輸出流的720p @ 2Mbps的視頻Zencoder。
解決
複製然後釋放MediaCodec編碼器輸出的ByteBuffers只要他們有空來解決問題,而顯著影響性能。我爲每個複用器軌道回收了ArrayDeque<ByteBuffer>
中的ByteBuffer副本,這限制了分配的數量。
感謝您的徹底解答! – dbro