Adam Schiavone
Adam Schiavone

Reputation: 2452

Draw a frame of video as a GL_TEXTURE_RECTANGLE_EXT or GL_TEXTURE_2D

I'm working on a mac (objective-c) application that sends frames of video to Syphon.

As much as I would love to say that I have a starting point for this project, I've only gotten as far as some junk code and including OpenGL.framework, AVFoundation, and Syphon.framework in the project

I thought this question may have been helpful towards loading the video frame by frame, and this question about playing a video using OpenGL, but neither has really panned out.

I've been doing some research into AVFoundation and there seem to by multiple ways to load a video, but no way that I can see to load a singular frame

Here's my goal:

  1. Load a video into an application as a mov. (video will have constant frame rate)
  2. create a GL_TEXTURE_RECTANGLE_EXT or GL_TEXTURE_2D from frame n of a video file
  3. it must be able to accomplish 30fps minimum (frames selected and drawn in sequence)

If someone could recommend what direction to go in for this, that would give me a great direction to really start. I've really got no idea how to even accomplish goal 1, let alone goal 2.

Upvotes: 1

Views: 629

Answers (1)

vbrittes
vbrittes

Reputation: 200

I've implemented a similar application, but instead of a .mov, it loads a static image. I'd suggest getting an NSImage from a single frame. (don't know exactly how to do that)

And then, get a texture from the NSImage:

- (void)textureFromImage:(NSImage*)theImg textureName:(GLuint*)texName
{
    NSBitmapImageRep* bitmap = [NSBitmapImageRep alloc];
    int samplesPerPixel = 0;
    NSSize imgSize = [theImg size];

    [theImg lockFocus];
    [bitmap initWithFocusedViewRect:
                    NSMakeRect(0.0, 0.0, imgSize.width, imgSize.height)];
    [theImg unlockFocus];

    // Set proper unpacking row length for bitmap.
    glPixelStorei(GL_UNPACK_ROW_LENGTH, [bitmap pixelsWide]);

    // Set byte aligned unpacking (needed for 3 byte per pixel bitmaps).
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);

    // Generate a new texture name if one was not provided.
    if (*texName == 0)
        glGenTextures (1, texName);
    glBindTexture (GL_TEXTURE_RECTANGLE_EXT, *texName);

    // Non-mipmap filtering (redundant for texture_rectangle).
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER,  GL_LINEAR);
    samplesPerPixel = [bitmap samplesPerPixel];

    // Nonplanar, RGB 24 bit bitmap, or RGBA 32 bit bitmap.
    if(![bitmap isPlanar] &&
        (samplesPerPixel == 3 || samplesPerPixel == 4))
    {
        glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0,
            samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
            [bitmap pixelsWide],
            [bitmap pixelsHigh],
            0,
            samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
            GL_UNSIGNED_BYTE,
            [bitmap bitmapData]);
    }
    else
    {
        // Handle other bitmap formats.
    }

    // Clean up.
    [bitmap release];
}

The frame rate would be determined by an NSTimer running those actions.

If all of that doesn't works, take a look at this open source movie player( http://v002.info/plugins-sources/v002-movie-player-beta/ ), maybe this could help you to get a solution that's closer to the Syphon sample implementation. Good luck (:

Upvotes: 2

Related Questions