2016-08-16 32 views
0

我想解碼h264流在Android上使用MediaCodec。memdiacodec解碼器工作在android 5.0但不是在Android 4.4

我用csd-0,csd-1來設置spspps這樣。

MediaFormat format = MediaFormat.createVideoFormat(MIME, WIDTH, HEIGHT); 
format.setByteBuffer("csd-0", sps); 
format.setByteBuffer("csd-1", pps); 

我配置解碼器輸出表面渲染輸出數據。

decoder.configure(format, surface, null, 0); 

然後,我剛開始一個線程來解碼我使用這個循環從網絡接收到的數據。

while (running) { 
    if (!isEOS) { 
     int inIndex = decoder.dequeueInputBuffer(10000); 
     if (inIndex >= 0) { 
      ByteBuffer buffer = inputBuffers[inIndex]; 
      byte[] data = getVideoPacket(); // native method that get data from network 
      buffer.put(data); 

      decoder.queueInputBuffer(inIndex, 0, data.length, 0L, 0); 
     } 
    } 

    int outIndex = decoder.dequeueOutputBuffer(info, 10000); 
    switch (outIndex) { 
     case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: 
      Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED"); 
      outputBuffers = decoder.getOutputBuffers(); 
      break; 
     case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: 
      Log.d("DecodeActivity", "New format " + decoder.getOutputFormat()); 
      MediaFormat format = decoder.getOutputFormat(); 
      break; 
     case MediaCodec.INFO_TRY_AGAIN_LATER: 
      Log.d("DecodeActivity", "dequeueOutputBuffer timed out!"); 
      break; 
     default: 
      ByteBuffer buffer = outputBuffers[outIndex]; 
      Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer); 

      decoder.releaseOutputBuffer(outIndex, true); // render 
      break; 
    } 

    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 
     Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM"); 
     break; 
    } 
} 

注意,我用0queueInputBuffer presentationTimestamp,因爲我得到的數據是從網絡套接字,我不知道如何計算相應的時間戳。

我得到了我想要的android 5.0(及以上版本),但是當我在android 4.4上運行這些代碼時,沒有任何東西出現在表面上(實際上我偶爾可以看到相同的圖片片段,但大多數時候,表面只是黑色)。

我試圖用從文件中提取的數據填充輸入緩衝區(使用MediaExtractor),並且它在Android 5.0和4.4上都能正常工作。

任何幫助將不勝感激。

回答

0

看來問題在於提取數據的方式。我曾經從本地層get數據:

public static native byte[] getVideoPacket(); 

,並從本地層到Java層現在我push數據:

env->CallVoidMethod(..., data); 

現在一切都只是工作。我不知道爲什麼,但這種方式適用於我。

相關問題