我正在开发一个 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 值,并且某些帧无法输入到编解码器中,因为没有可用的输入缓冲区:这导致只有大约一半的帧将被正确解码。我只在表面为空的情况下观察到这个问题!怎么了?请给我一些建议。