2016-10-10 121 views
0

我試圖捕捉到Android的views爲位圖,並將其保存爲.mp4檔案高通公司的AVC編碼器。輸入緩衝區編碼通過Android的MediaCodec

我使用MediaCodec來編碼位圖,MediaMuxer將它們複合到.mp4中。

使用YUV420p彩色格式我期望MediaCodec的輸入緩衝區大小爲resWidth * resHeight * 1.5,但Qualcomm的OMX.qcom.video.encoder.avc給了我更多(不管我選擇什麼樣的分辨率)。我相信它希望我在輸入字節流中進行一些調整,但我不知道如何找出它期望我做什麼。

這是當我使用了高通的編解碼器緊緊地包在在Nexus 7(2013)輸入緩衝器我的數據我得到什麼:https://www.youtube.com/watch?v=JqJD5R8DiC8

而這個視頻是由同樣的應用進行運行在Nexus 10上(編解碼器OMX.Exynos.AVC.Encoder ):https://www.youtube.com/watch?v=90RDXAibAZI

所以看起來亮度平面是在錯誤的視頻好吧,但所發生的事情與色度平面是一個謎給我。

我準備最少(2類)工作的代碼示例暴露出這個問題:https://github.com/eeprojects/MediaCodecExample

可以得到上面所示的視頻只是通過運行這個程序(如果您的設備採用了高通的編解碼器會出現相同的假象)。

回答

1

有在緩衝器存儲YUV 420的多種方式;您需要檢查您選擇的單個像素格式。 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PlanarMediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar實際上是相同的,簡稱爲平面或I420,而其他的,MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar,MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanarMediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar稱爲半平面或NV12。

在semiplanar,你不必爲U和V分離的平面,但你必須有對交錯的U,V的一個單一的平面。

請參閱 https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java(第925-949行)的示例,瞭解如何填充半平面格式的緩衝區。

+0

再次感謝您的幫助。但是如果編解碼器支持'CodecCapabilities.COLOR_FormatYUV420Flexible'怎麼辦?文檔說它可以是平面或半平面的。您還可以在嘗試爲儘可能多的編解碼器提供支持的同時,指出一些我可能陷入的陷阱嗎? –

+1

如果編解碼器支持'CodecCapabilities.COLOR_FormatYUV420Flexible'和你選擇了它,它允許編碼器內部挑就是了取其格式(只要它可以被描述爲一個靈活的YUV420格式)。如果你使用這個,你需要使用'MediaCodec.getInputImage'來獲得緩衝區的描述(而不是舊的'getInputBuffers()'或'getInputBuffer()')。然後,你有三個直接的'ByteBuffers'用於每個平面,而一個通用的行和像素跨度來描述如何填充它。 – mstorsjo

+1

即使靈活的YUV 420格式確實允許非常瘋狂的格式,但我認爲它實際上實際上將是平面和半平面,而且它們仍然會通過正常的像素格式曝光。因此,如果您關心支持舊版本,那麼按照您的方式進行操作並不會有太大的損失(我還沒有看到過不支持平面或半平面輸入的設備,因爲這是CTS測試的結果也需要!)。 – mstorsjo