-1

我正在开发一个 Android 移动应用程序,该应用程序面向无人机摄像头视图的实时增强可视化(特别是我正在开发带有相关 SDK 的 DJI Phantom 3 Professional)。为了研究如何用外部视频流替换我的 AR 框架中的摄像头流,我正在尝试 DJI 演示“视频流解码示例”(https://developer.dji.com/mobile-sdk/documentation/示例代码/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 设置为空)平均帧速率约为 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;方法: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.java; 类:DJIVideoStreamDecoder;METODO: decodeFrame() -- 6 02-05 21:42:58.122 I/DJIVideoStreamDecoder(27992): 文件: DJIVideoStreamDecoder.java; 班级:DJIVideoStream解码器;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 DJIVideoStreamDecoder.java; 类:DJIVideoStreamDecoder;METODO: decodeFrame() -- 6 DJIVideoStreamDecoder.java; 类:DJIVideoStreamDecoder;METODO: decodeFrame() -- 6

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

4

1 回答 1

0

dequeueInputBuffer返回负“索引”时,这些值实际上并不意味着被解释为索引,而是被解释为元数据。请参阅Android 文档并查看dequeueInputBuffer这些 INFO* 常量(例如 MediaCodec.INFO_TRY_AGAIN_LATER、MediaCodec.INFO_OUTPUT_FORMAT_CHANGED 等)。文档页面的顶部有一些关于如何处理这些的部分示例代码。

于 2017-02-09T21:40:32.190 回答