2017-02-05 29 views
-1

Я работаю над мобильным приложением Android, ориентированным на визуализацию камеры в режиме реального времени (в частности, я работаю над DJI Phantom 3 Professional с относительным SDK). Чтобы изучить, как заменить поток камеры в моей структуре AR внешним видеопотоком, я пытаюсь продемонстрировать демоверсию DJI «Пример декодирования видеопотока» (https://developer.dji.com/mobile-sdk/documentation/sample-code/index.html).DJI «Пример декодирования видеопотока»: MediaCodec с нулевой ошибкой Поверхностная проблема

В частности, я пытаюсь получить необработанные видеоданные, поступающие из MediaCodec, просто установив параметр Surface равным null в методе configure(). Таким образом, мне не нужно позволять MediaCodec визуализировать видеопоток, но я бы хотел перенаправить каждый выходной кадр YUV с помощью метода onUuvDataReceived(). Так что я изменил в 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 кадров в секунду (в этом случае (с Поверхностью установлено значение null) средняя частота кадров составляет около 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): Файл: DJIVideoStreamDecoder.java ; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 1 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.112 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.Ява; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; METODO: decodeFrame() - 6 02-05 21: 42: 58.122 I/DJIVideoStreamDecoder (27992): ФАЙЛ: DJIVideoStreamDecoder.java; КЛАСС: DJIVideoStreamDecoder; Metodo: decodeFrame() - 6

В качестве файла журнала показывает, часто dequeueInputBuffer() возвращает отрицательное значение inIndex и некоторые кадры не могут быть введены в кодек, потому что не доступен входной буфер: этот приводит к тому, что только около половины кадров будет правильно декодировано. Я наблюдаю эту проблему только в случае, когда поверхность равна нулю! Что не так? Пожалуйста, дайте мне несколько советов по этому поводу.

ответ

0

Когда dequeueInputBuffer возвращает отрицательные «индексы», эти значения на самом деле не должны интерпретироваться как индексы, а вместо этого в качестве метаданных. См. Android documentation для dequeueInputBuffer и проверьте эти INFO * константы (например, MediaCodec.INFO_TRY_AGAIN_LATER, MediaCodec.INFO_OUTPUT_FORMAT_CHANGED и т. Д.). В верхней части страницы документации содержится некоторый частичный пример кода о том, как обращаться с ними.