Samusaaron3
Samusaaron3

Reputation: 532

Drawing Video Frames in OpenGL on Android

I'm currently working on a system which displays video frames (as bitmaps) via OpenGL ES 1.0 on Android. My issue is that I have not been able to get more than about 10 fps.

After doing some testing, I've determined that one of the biggest bottlenecks is the need for the bitmap to have its width and height both be a power of 2. A 640x480 video has to be scaled up to 1024x1024, for example. Without the scaling, I've been able to get about 40-50fps, but the texture just appears white, which does me no good.

I know that OpenGL ES 2.0 supports using non-power of two textures, but I have no experience with shaders / anything else new in 2.0

Is there any way I can get around this issue? How do other video plays get such good performance in comparison to what I have? I have included some code for reference.

private Bitmap makePowerOfTwo(Bitmap bitmap)
{
    // If one of the bitmap's resolutions is not a power of two
    if(!isPowerOfTwo(bitmap.getWidth()) || !isPowerOfTwo(bitmap.getHeight()))
    {
        int newWidth = nextPowerOfTwo(bitmap.getWidth());
        int newHeight = nextPowerOfTwo(bitmap.getHeight());

        // Generate a new bitmap which has the needed padding
        return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
    }
    else
    {
        return bitmap;
    }
}

private static boolean isPowerOfTwo(int num)
{
    // Check if a bitwise and of the number and itself minus one is zero
    return (num & (num - 1)) == 0;
}

private static int nextPowerOfTwo(int num)
{
    if(num <= 0)
    {
        return 0;
    }

    int nextPowerOfTwo = 1;

    while(nextPowerOfTwo < num)
    {
        nextPowerOfTwo <<= 1; // Bitwise shift left one bit
    }

    return nextPowerOfTwo;
}

Upvotes: 2

Views: 1479

Answers (1)

Tim
Tim

Reputation: 35933

Just because a texture has to be a power of two, doesn't mean that your data has to be a power of two.

You're free to create a 1024x1024 (or 1024x512) texture during initialization with glTexImage, fill in the lower 640x480 with your bitmap data with glTexSubImage, and then display the lower 640x480 of the texture with some intelligent texcoords (0,0) to (640/1024, 480/1024). The remainder of the texture will just contain empty space that's never seen.

Upvotes: 5

Related Questions