【发布时间】: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