DJI“视频流解码示例”:MediaCodec配置为null Surface问题

时间:2017-02-05 21:44:29

标签: android video surfaceview mediacodec dji-sdk

我正在研发面向无人机摄像机视图的实时增强可视化的Android移动应用程序(特别是我正在使用相对SDK的DJI Phantom 3 Professional)。 为了研究如何用外部视频流替换AR框架中的摄像机流,我正在尝试DJI演示“视频流解码示例”(https://developer.dji.com/mobile-sdk/documentation/sample-code/index.html)。

特别是,我试图通过在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);
            }

现在我的问题是,在第一种情况下(将Surface设置为MediaCodec)我可以计算每秒30帧的平均帧速率,在这种情况下(将Surface设置为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):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; METODO:decodeFrame() - 6

正如日志文件所示,dequeueInputBuffer()通常会返回负的inIndex值,并且某些帧无法输入到编解码器中,因为输入缓冲区不可用:这导致只有大约一半的帧将是正确解码。 我只在表面为空的情况下观察这个问题!怎么了?请给我一些建议。

1 个答案:

答案 0 :(得分:0)

dequeueInputBuffer返回负“索引”时,这些值实际上并不意味着被解释为索引而是被解释为元数据。请参阅dequeueInputBuffer ... if message.scan(/var1/).length > 1 errors.add :message, 'You must not repeat the word VAR1' end ... 并查看那些INFO *常量(例如MediaCodec.INFO_TRY_AGAIN_LATER,MediaCodec.INFO_OUTPUT_FORMAT_CHANGED等)。文档页面的顶部有一些关于如何处理这些内容的部分示例代码。