Java 如何使ExtractMpegFramesTest中的saveFrame()方法更有效?
[编辑]按照fadden@suggestion重新格式化为问答格式 在saveFrame()方法中,有一个循环用于将RGBA重新排序为ARGB以进行位图png压缩(请参见下面该文件中的引号),如何对其进行优化Java 如何使ExtractMpegFramesTest中的saveFrame()方法更有效?,java,android,android-mediacodec,Java,Android,Android Mediacodec,[编辑]按照fadden@suggestion重新格式化为问答格式 在saveFrame()方法中,有一个循环用于将RGBA重新排序为ARGB以进行位图png压缩(请参见下面该文件中的引号),如何对其进行优化 //glReadPixels为我们提供了一个ByteBuffer,其中填充了本质上是大端RGBA的内容 //数据(即一个字节的红色,后跟一个字节的绿色…)。我们需要一个int[]填充 //使用少量的endian ARGB数据馈送到位图。 // //所以。。。我们将ByteBuffer设
//glReadPixels为我们提供了一个ByteBuffer,其中填充了本质上是大端RGBA的内容
//数据(即一个字节的红色,后跟一个字节的绿色…)。我们需要一个int[]填充
//使用少量的endian ARGB数据馈送到位图。
//
//所以。。。我们将ByteBuffer设置为little endian,这将使bulk缓冲区变为IntBuffer
//在大多数Android设备上,将()直接放入memcpy。我们的ints将保存ABGR数据。
//交换B和R得到ARGB。大容量get()大约需要30毫秒,另外
//颜色交换270ms。
for(int i=0;i 颜色[i]=(c&0xff00ff00)|((c&0x00ff0000)>>16)|((c&0x000000ff)[edit]按照fadden@suggestion重新格式化为问答格式
我想建议在FragmentShader中通过更改行来实现此转换
gl_FragColor = texture2D(sTexture, vTextureCoord);
进入
这是在GPU中对着色器的输出通道进行重新排序的有效快捷方式,也可以通过其他方式工作:.abgr
甚至.bggr
等等。事实证明,有一种更快的方法
使用@elmiguelao答案中的建议,我修改了片段着色器以进行像素交换。这允许我从saveFrame()中删除交换代码。由于我不再需要内存中像素的临时副本,我完全消除了int[]
缓冲区,从以下位置切换:
int[] colors = [... copy from mPixelBuf, swap ...]
Bitmap.createBitmap(colors, mWidth, mHeight, Bitmap.Config.ARGB_8888);
为此:
Bitmap bmp = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
bmp.copyPixelsFromBuffer(mPixelBuf);
当我这么做的时候,我所有的颜色都错了
结果是Bitmap#copyPixelsFromBuffer()
需要RGBA顺序的像素,而不是ARGB顺序的像素
已经使用了正确的格式。因此,通过这种方式,我避免了交换,避免了不必要的复制,根本不需要调整片段着色器。好主意!交换循环在Java.FWIW中不是特别快,我认为提供建议的“官方”方式是问:“我们如何制作saveFrame()方法提取mpegframestest more effective?”,然后回答您自己的问题。这样,鼓励其他人也提供自己的答案。请参阅。重新格式化,谢谢fadden!
Bitmap bmp = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
bmp.copyPixelsFromBuffer(mPixelBuf);