我们如何才能使ExtractMpegFramesTest中的saveFrame()方法更有效?

时间:2014-02-07 17:46:55

标签: java android mediacodec

[edit]在fadden @ suggestion之后重新格式化为问答格式。

ExtractMpegFramesTest_egl14.java.txt方法saveFrame()中,有一个循环用于将RGBA重新排序为ARGB以进行位图png压缩(请参阅下面的文件引用),如何优化?

// glReadPixels gives us a ByteBuffer filled with what is essentially big-endian RGBA
// data (i.e. a byte of red, followed by a byte of green...).  We need an int[] filled
// with little-endian ARGB data to feed to Bitmap.
//

...

// So... we set the ByteBuffer to little-endian, which should turn the bulk IntBuffer
// get() into a straight memcpy on most Android devices.  Our ints will hold ABGR data.
// Swapping B and R gives us ARGB.  We need about 30ms for the bulk get(), and another
// 270ms for the color swap.

...

for (int i = 0; i < pixelCount; i++) {
    int c = colors[i];
    colors[i] = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16);
}

2 个答案:

答案 0 :(得分:3)

事实证明,这是一种更快的方法。

使用@ 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顺序。来自glReadPixels()的值已经采用正确的格式。因此,通过这种方式,我避免交换,避免不必要的副本,并且根本不需要调整片段着色器。

答案 1 :(得分:2)

[edit]在fadden @ suggestion

之后重新格式化为问答格式

我想建议通过更改行

在FragmentShader中进行此转换
gl_FragColor = texture2D(sTexture, vTextureCoord);

gl_FragColor = texture2D(sTexture, vTextureCoord).argb;

这是在GPU中重新排序着色器输出通道的有效快捷方式,它也可以以其他方式工作:.abgr甚至.bggr等。