2014-01-23 57 views
0

我正在使用以下代碼準備硬件解碼器。我期望outputBufferIndex爲-1,然後是MediaCodec.INFO_OUTPUT_FORMAT_CHANGED。在通知格式改變之前,它不應該> = 0。在某些設備中解碼h.264時未調用MediaCodec.INFO_OUTPUT_FORMAT_CHANGED

我測試了25個不同設備中的代碼,其中7個從未返回INFO_OUTPUT_FORMAT_CHANGED。當我得到outputBufferIndex> = 0時,mediaCodec.getOutputFormat()返回IllegalStateException。我不知道是否所有設備都沒有工作的巧合是Android 4.2.2與OMX.qcom.video.decoder.avc解碼器。

for (int i = 0; i < videoExtractor.getTrackCount(); i++) { 
    MediaFormat mediaFormat = videoExtractor.getTrackFormat(i); 
    String mime = mediaFormat.getString(MediaFormat.KEY_MIME); 
    if (mime.startsWith("video/")) { 
     videoExtractor.selectTrack(i); 
     videoCodec = MediaCodec.createDecoderByType(mediaFormat.getString(MediaFormat.KEY_MIME)); 
     videoCodec.configure(mediaFormat, null, null, 0); 
     videoCodec.start(); 
    } 
} 
ByteBuffer[] videoInputBuffers = videoCodec.getInputBuffers(); 
while (true) { 
    int sampleTrackIndex = videoExtractor.getSampleTrackIndex(); 
    if (sampleTrackIndex == -1) { 
     break; 
    } else { // decode video 
     int inputBufferIndex = videoCodec.dequeueInputBuffer(0); 
     if (inputBufferIndex >= 0) { 
      int bytesRead = videoExtractor.readSampleData(videoInputBuffers[inputBufferIndex], 0); 
      if (bytesRead >= 0) { 
       videoCodec.queueInputBuffer(inputBufferIndex, 0, bytesRead, 
         videoExtractor.getSampleTime(), 0); 
       videoExtractor.advance(); 
      } 
     } 
     MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo(); 
     int outputBufferIndex = videoCodec.dequeueOutputBuffer(videoBufferInfo, 0); 
     if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 
      MediaFormat format = videoCodec.getOutputFormat(); 
      Log.w("video format changed: " + videoCodec.getOutputFormat()); 
      //do something... 
      break; 
     } else if (outputBufferIndex >= 0) { 
      //not supposed to happen! 
     } 
    } 
} 

非常感謝您的線索和幫助!

回答

0

在Android 4.3中,向CTS添加了一組MediaCodec測試。如果您查看doEncodeDecodeVideoFromBuffer()EncodeDecodeTest中的工作方式,則可以看到它在任何數據之前都會得到INFO_OUTPUT_FORMAT_CHANGED結果。如果它沒有得到它,當它試圖獲取顏色格式時,調用checkFrame()將失敗。在Android 4.3之前,沒有測試,任何行爲都是可能的。

話雖如此,我不記得看到在(基於高通公司)的Nexus 4

這種行爲在任何情況下,我不知道有多少這實際上阻止你,除非你'能夠解碼Qualcomm使用的專有緩衝區佈局。你可以在checkFrame()中看到它在看到OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka時踢出的功能。將輸出發送到Surface可能是一個可行的替代方案,具體取決於您的選擇。

大部分MediaCodec代碼在bigflakeGrafika目標API 18(Android 4.3),因爲那是行爲變得更加可預測的時候。 (可用的表面輸入和MediaMuxer也是巨大的價值。)

+0

是的,我做了很多努力轉換專有的yuv格式,如QCOM_COLOR_FormatYUV420XXX和COLOR_TI_FormatYUV420XXX到I420。不是隻調用INFO_OUTPUT_FORMAT_CHANGED,而是當outputBufferIndex> = 0時不更新mediaFormat。更糟糕的是,當我釋放輸出緩衝區時程序掛起。我試過谷歌的軟件編解碼器,當我在這些設備上進行MediaCodec.configure時,它會掛起,而它在其他設備上完美工作。我檢查了csd-0和csd-1,這是正確的。 –