我在我的应用程序中实现了SurfaceTexture.OnFrameAvailableListener接口,因此我可以将视频帧用作OpenGL纹理.所有设置都应该设置它并且它完美地工作但是onFrameAvailable(SurfaceTexture surfaceTexture)在几秒钟后停止被调用,有效且看似冻结了OpenGL中的视频,因为没有通过SurfaceTexture.updateTextImage上传新的纹理数据.
我在onFrameAvailable中设置一个标志来从GL线程执行updateTextImage调用,并且仅在需要时.目前我在每次绘制调用时都将标志设置为true,因此在跳过onFrameAvailable检查时,每帧都会上传视频纹理数据.像这样,一切都像它应该运行但似乎效率低,因为如果它仍然是相同的(电影帧),则不需要上传新的纹理数据.
AFAIK没有内存泄漏,logcat没有显示任何错误.此外,媒体播放器设置为循环,但问题发生在单个运行完成之前.
什么会导致onFrameAvailable在几秒钟后不再被调用?
zin*_*gle 13
我在某些设备上遇到了同样的问题.找到了解决方案并想到我会分享.基本上它是@ user2254894建议的,除了因为计数器可以被2个不同的线程改变所以最好使用2个不同的vars.这是一些示例代码:
private int _updateTexImageCounter = 0;
private int _updateTexImageCompare = 0;
Run Code Online (Sandbox Code Playgroud)
和onFrameAvailable()很简单.
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture)
{
// increment every time a new frame is avail
_updateTexImageCounter++;
}
Run Code Online (Sandbox Code Playgroud)
然后在您的GL更新中,您将执行以下操作...
public void update()
{
.... create texture... etc.
..
// compare _updateTexImageCompare and _updateTexImageCounter
if( _surfaceTexture!=null && _updateTexImageCompare != _updateTexImageCounter )
{
// loop and call updateTexImage() for each time the onFrameAvailable() method was called below.
while(_updateTexImageCompare != _updateTexImageCounter) {
_surfaceTexture.updateTexImage();
_surfaceTexture.getTransformMatrix(x);
_updateTexImageCompare++; // increment the compare value until it's the same as _updateTexImageCounter
}
}
}
Run Code Online (Sandbox Code Playgroud)
这对我有用.如果有更好的方法,请告诉我.
小智 12
我刚刚看到了类似的问题,并对其进行了调试.我和你一样,有一个布尔标志,表示准备好使用一个(或多个!)帧.
当我在一对OpenGL帧之间收到两个相机帧时(可能是因为我的OpenGL重绘处理太慢),问题就出现了.这意味着我将布尔标志设置了两次.但是,我只读了一次这个帧数据,似乎updateTexImage实现了某种排队功能.
用挂起的相机帧的整数计数器替换布尔标志解决了我的问题.也许这对你也有用吗?
(我怀疑这比只是每帧调用updateTexImage更有效.至少在我的代码中,OpenGL帧非常罕见(1-2%)需要足够长的时间才能跨越两个相机帧.)
| 归档时间: |
|
| 查看次数: |
5319 次 |
| 最近记录: |