【问题标题】:DJI "Video Stream Decoding Sample" : MediaCodec configured with null Surface issueDJI“视频流解码示例”:MediaCodec 配置为 null Surface 问题
【发布时间】:2017-06-22 19:09:51
【问题描述】:

我正在开发一款面向无人机摄像头视图实时增强可视化的 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): 文件: 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.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;类:DJIVideoStreamDecoder; METODO: decodeFrame() -- 6

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

【问题讨论】:

    标签: android video surfaceview android-mediacodec dji-sdk


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 2019-06-21
      • 2014-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多