使用AndroidFrameConverter将javacv Frame转换为Bitmap

时间:2016-06-15 05:52:25

标签: android bitmap ffmpeg javacv

我正在尝试使用javacv AndroidFrameConverter将大小为1280x720的帧转换为位图,并且转换需要很长时间。以下是转换的示例代码。

FrameGrabber grabber = new FFmpegFrameGrabber(videoUrl);
frame = grabber.grab();
AndroidFrameConverter converter = new AndroidFrameConverter();
Bitmap originalBitmap = converter.convert(frame);

有没有比这更快的其他解决方案?

2 个答案:

答案 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)

您可以根据需要使用此代码并更改过滤器。

?