我正在尝试使用javacv AndroidFrameConverter将大小为1280x720的帧转换为位图,并且转换需要很长时间。以下是转换的示例代码。
FrameGrabber grabber = new FFmpegFrameGrabber(videoUrl);
frame = grabber.grab();
AndroidFrameConverter converter = new AndroidFrameConverter();
Bitmap originalBitmap = converter.convert(frame);
有没有比这更快的其他解决方案?
答案 0 :(得分:2)
Frame
返回的 FrameGrabber.grab()
是javacv特定的,Bitmap
是特定于Android的,我怀疑两者之间有更快的转换方法,因为他们彼此不认识并且两者都是针对自己的使用进行了优化,他们无法优化两种数据格式之间的转换过程。
您正在移动1280 * 720 * 4字节,每帧大约3.6 MB,这对于移动设备来说非常重要,尤其是考虑到内存分配。
我怀疑你会找到另一个转换工具而不用javacv替换其他东西 - 无法想象一个专门用于将javacv的Frame
转换为Android Bitmap
以替换内置方法的工具。
此外,AndroidFrameConverter.convert()
已经非常聪明 - 它只是第一次创建Bitmap
,或者如果规范已经改变(如大小等),那么只需复制字节。
幸运的是,它有能力重复一次创建的Bitmap
实例,FFmpegFrameGrabber
也有这种能力,所以在第一次运行时,他们将创建每个适当的对象,但是从第二帧开始应该重用他们拥有的对象 - 这样至少不会发生不必要的内存分配,从而导致移动设备的性能下降。这意味着平均转换许多帧应该比仅转换一帧更快 - 只是不要为每个帧创建抓取器和转换器的新实例。
可以使用GPU进行并行化 - 手动创建Bitmap
,分区Frame
的缓冲区并并行设置Bitmap
的像素。我从来没有做过类似的事情,所以不能真正评论更多。请记住,并行算法有自己的开销,并不总是比顺序算法快。而且我不确定GPU编程是如何便携的。使用CPU进行并行化不值得尝试 - 有多少核心拥有当前设备? 4?开销应该超过收益。
答案 1 :(得分:1)
您可以根据需要使用此代码并更改过滤器。
?