从 MediaCodec 将同一视频渲染到 2 个表面
Rendering same video to 2 Surfaces from a MediaCodec
MediaCodec 有 2 种操作方式:您可以传递一个 Surface 让它渲染,或者您读取输出缓冲区并自己将其绘制到屏幕上。
在第一种情况下,我通过一个表面:是否可以将相同的 MediaCodec 解码视频绘制到 2 个表面?
解码循环看起来像这样:
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
//Do nothing, the MediaCodec will automatically draw to our surface
//But how to draw to 2 surfaces?
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
要能够一次绘制到多个表面的唯一方法是使用 OpenGL。
如果你愿意,我可以给你一些建议。
首先,您需要一个由表面纹理支撑的表面。表面纹理是解码器将解码帧排队的地方,您可以从那里检索它。一旦表面纹理中的框架可用,您将使用 OpenGL(多个 EGLSurface(s) 连接到每个表面。您可以使用 eglCreateWindowSurface 创建这样的表面)。
连接表面和有效的 EGL 上下文后,只需使用 eglMakeCurrent 并传入您创建的 EGL 表面,每个绘制操作一个。所以 eglMakeCurrent 将允许您一次在一个表面上绘制,并且您可以为您拥有的每个表面执行此操作。您通常可以在 grafika
中找到其中一些示例
MediaCodec 有 2 种操作方式:您可以传递一个 Surface 让它渲染,或者您读取输出缓冲区并自己将其绘制到屏幕上。
在第一种情况下,我通过一个表面:是否可以将相同的 MediaCodec 解码视频绘制到 2 个表面?
解码循环看起来像这样:
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
//Do nothing, the MediaCodec will automatically draw to our surface
//But how to draw to 2 surfaces?
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
要能够一次绘制到多个表面的唯一方法是使用 OpenGL。
如果你愿意,我可以给你一些建议。
首先,您需要一个由表面纹理支撑的表面。表面纹理是解码器将解码帧排队的地方,您可以从那里检索它。一旦表面纹理中的框架可用,您将使用 OpenGL(多个 EGLSurface(s) 连接到每个表面。您可以使用 eglCreateWindowSurface 创建这样的表面)。
连接表面和有效的 EGL 上下文后,只需使用 eglMakeCurrent 并传入您创建的 EGL 表面,每个绘制操作一个。所以 eglMakeCurrent 将允许您一次在一个表面上绘制,并且您可以为您拥有的每个表面执行此操作。您通常可以在 grafika
中找到其中一些示例