2016-06-15 117 views
0

我正在使用mediacodec解碼samsung S6,android 5.1.1上的h264流,發現輸入緩衝區mediacodec必須以「0001」開頭(並且不需要設置pps,sps) ,否則ACodec會報告錯誤。mediacodec解碼h264流限制

我也嘗試使用mediaextractor來播放mp4文件,它工作正常,但mediacodec的緩衝區不是以「0001」開頭的。

我不知道爲什麼decodec h264流有這樣的限制,目前我需要分析來自socket的流,並將數據分成小包(每個包以0001開頭),然後將它們提供給mediacodec,但這是低效的。

MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1024, 1024); 
+0

MediaCodec在NAL單元上運行。它需要啓動前綴。比照http://stackoverflow.com/questions/1685494/what-does-this-h264-nal-header-mean – fadden

回答

0

一些具體的解碼器也能夠在「MP4」的格式(與不同種類的起始碼)的解碼H264的NAL單元,但不是所有的設備保證。

如果三星的MediaExtractor版本知道他們自己的解碼器可以處理它,那麼它可能會以這種格式返回它。至少有一個先例,三星與MediaExtractor的版本做了同樣的,非標準的事情,並帶有時間戳,參見例如。 https://code.google.com/p/android/issues/detail?id=74356

(有MediaExtractor返回數據,只有當前設備的解碼器可以處理是錯誤的IMO,但是,因爲人們可能想使用MediaExtractor讀取文件,但通過網絡發送壓縮數據到另一個設備解碼,並在這些情況下,以非標準格式返回數據是錯誤的。)作爲fadden寫道,儘管MediaCodec運行在完整的NAL單元上,所以您需要以這種格式提供數據(即使您認爲它感覺效率低下)。如果您通過套接字接收數據的格式並不容易獲取此信息(關於幀邊界),那麼這就是您協議格式的問題(例如,實現RTP接收並不容易!),而不是MediaCodec本身 - 它是這是一個非常常見的限制,需要在解碼之前擁有全幀,而不是在有全幀之前才能提供隨機塊。除非你自己實施它是低效的,否則這不應該是低效率的。

0

一般來說,android會爲每個輸入指定nal個單位。對於某些設備,我發現在h264的媒體格式上設置csd-0/1的功能不一致。但是,如果您將每個參數集作爲輸入緩衝區提供,則媒體編解碼器會將其作爲格式更改進行提取。

int outputBufferIndex = NativeDecoder.DequeueOutputBuffer (info, 1000); 
if (outputBufferIndex == (int)MediaCodec.InfoOutputFormatChanged) { 
    Console.WriteLine ("Format changed: {0}", NativeDecoder.OutputFormat); 
} else if (outputBufferIndex >= 0) { 
    CodecOutputBufferAvailable (NativeDecoder, outputBufferIndex, info); 
} 

還要注意它是強制性的Nexus和其他一些三星設備的設置:

formatDescription.SetInteger(MediaFormat.KeyWidth, SelectedPalette.Value.Width); 
formatDescription.SetInteger(MediaFormat.KeyHeight, SelectedPalette.Value.Height); 
formatDescription.SetInteger(MediaFormat.KeyMaxInputSize, SelectedPalette.Value.Width * SelectedPalette.Value.Height); 

我很幸運,在我的情況,我可以查詢這些決議。但是,您可以從SPS和PPS nal單元手動解析分辨率。

//注意我在這裏使用Xamarin。但電話和事情幾乎相同。我相當確定在iOS VideoToolbox Xamarin Wrapper中存在錯誤,所以是的。請記住,如果您曾考慮Xamarin進行視頻解碼。它適用於任何事物,但稍微更加自定義或低級的事物。