2017-02-05 55 views
-1

我正在開發面向無人機相機視圖的實時增強可視化的Android移動應用程序(具體而言,我正在研究DJI Phantom 3 Professional與相關的SDK)。 爲了研究如何用外部視頻流替換AR框架中的攝像機流,我正在嘗試DJI演示「視頻流解碼示例」(https://developer.dji.com/mobile-sdk/documentation/sample-code/index.html)。DJI「視頻流解碼示例」:MediaCodec配置爲空表面問題

特別是,我試圖通過在configure()方法中將Surface參數設置爲null來獲取來自MediaCodec的原始視頻數據。所以,我不需要讓MediaCodec渲染視頻流,但我想使用onYuvDataReceived()方法重定向每個輸出YUV幀。 所以我在MainActivity.java改變以下兩行代碼:

@Override 
      public void surfaceCreated(SurfaceHolder holder) { 

       DJIVideoStreamDecoder.getInstance().setYuvDataListener(MainActivity.this); 
      } 

      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

       DJIVideoStreamDecoder.getInstance().changeSurface(null); 
      } 

現在我的問題是,雖然在第一種情況下(與表面設置到MediaCodec)我可以指望30幀的平均幀速率在這種情況下(Surface設置爲空),平均幀速率大約爲每秒15-16個解碼幀(這可能會嚴重影響視頻渲染的質量!)。特別是,通過調試,我觀察到的問題是在以下部分:

 for (int i = 0; i < CODEC_DEQUEUE_INPUT_QUEUE_RETRY && inIndex < 0; i ++) { 
     //Log.i(TAGa,"FILE: DJIVideoStreamDecoder.java; CLASS: DJIVideoStreamDecoder; METODO: decodeFrame() -- 5"); //DEBUG 
     try { 
      Log.i(TAGa,"FILE: DJIVideoStreamDecoder.java; CLASS: DJIVideoStreamDecoder; METODO: decodeFrame() -- 6"); //DEBUG 

      inIndex = codec.dequeueInputBuffer(0); 
     } catch (IllegalStateException e) { 
      Log.i(TAGa,"FILE: DJIVideoStreamDecoder.java; CLASS: DJIVideoStreamDecoder; METODO: decodeFrame() -- 7"); //DEBUG 

      logd(TAGa, "decodeFrame: dequeue input: " + e); 
      codec.stop(); 
      codec.reset(); 
      initCodec(); 
      e.printStackTrace(); 
     } 
    } 

日誌文件: 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java ; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 1 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.112 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder。java的; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder; METODO:decodeFrame() - 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992):FILE:DJIVideoStreamDecoder.java; CLASS:DJIVideoStreamDecoder;方法方法:decodeFrame() - 6

作爲日誌文件顯示,經常dequeueInputBuffer()返回一個負inIndex值和一些幀不能被輸入到編解碼器,因爲不可用的輸入緩衝器:此導致只有大約一半的幀將被正確解碼。 我只在表面爲空的情況下觀察這個問題!怎麼了?請給我一些關於這方面的建議。

回答

0

dequeueInputBuffer返回負值「索引」時,這些值實際上並不是要解釋爲索引,而是解釋爲元數據。請參閱Android documentationdequeueInputBuffer並查看這些INFO *常量(例如,MediaCodec.INFO_TRY_AGAIN_LATER,MediaCodec.INFO_OUTPUT_FORMAT_CHANGED等)。文檔頁面的頂部部分有關於如何處理這些內容的部分示例代碼。