我正在尝试显示通过网络接收的帧流并将它们显示给TextureView。我的管道如下:
以下是只要app正在运行,pullFromQueue线程的回调就会保持活动状态。 byte []帧是已知宽度和高度的NV21格式帧。
@DebugLog
private void pullFromQueueMethod() {
try {
long start = System.currentTimeMillis();
byte frame[] = framesQueue.take();
}
从这里开始,我想使用OpenGL来改变亮度,对比度并将着色器应用于各个帧。性能是我最关心的,因此我不能将byte []转换为Bitmap然后显示到SurfaceView。我试过这个,在Nexus 5上使用768x576帧需要将近50ms。
令人惊讶的是,我无法在任何地方找到相同的例子。所有示例都使用Camera或MediaPlayer内置函数将其预览指向表面/纹理。例如:camera.setPreviewTexture(surfaceTexture);
。这将输出链接到SurfaceTexture,因此您永远不必处理显示单个帧(从不必处理字节数组)。
到目前为止我的尝试:
在StackOverflow上看到this回答。它建议使用Grafika的createImageTexture()
。收到纹理句柄后,如何将其传递给SurfaceTexture并不断更新?以下是我到目前为止实施的部分代码:
public class CameraActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
int textureId = -1;
SurfaceTexture surfaceTexture;
TextureView textureView;
...
protected void onCreate(Bundle savedInstanceState) {
textureView = new TextureView(this);
textureView.setSurfaceTextureListener(this);
}
private void pullFromQueueMethod() {
try {
long start = System.currentTimeMillis();
byte frame[] = framesQueue.take();
if (textureId == -1){
textureId = GlUtil.createImageTexture(frame);
surfaceTexture = new SurfaceTexture(textureId);
textureView.setSurfaceTexture(surfaceTexture);
} else {
GlUtil.updateImageTexture(textureId); // self defined method that doesn't create a new texture, but calls GLES20.glTexImage2D() to update that texture
}
surfaceTexture.updateTexImage();
/* What do I do from here? Is this the right approach? */
}
}
总结一下。我真正需要的只是一种显示帧流(字节数组)的有效方式。我如何实现这一目标?