I’m working with some raw video and audio grabbers and needed a mechanism to view and hear it.
Web searching (of course) led me to
http://www.webkinesia.com/games/rawvideo.php
Eagerly I grabbed the code, fired up the rusty VS 2008 studio, downloaded the SDL (http://www.libsdl.org/download-1.2.php)
Built the code and NO windows opens, exits from the fopen() call. Opps back to the link to grab the sample video and rename to drop the .zip extension.
Well, that allows things to proceed BUT imagine my surprise when, NO screen output.
I had run into a learning curve with SDL. So, I modified the code to use a bltable screen. I also wished to share some of the lessons learned and provide some examples. I see several elements of confusion about some of the SDL 1.2 APIs.
At first, I was concerned about VS 2008 or being on Windows 7. So I grabbed the source and built it. Nice. Provided a .sln from VS 2005.
Build no errors, no warning.
Copied the debug build libs and dll into place and rebuild. Traced into the calls and was met with a compiler gotcha.
The this->hidden->screen_bmp was from a directx declaration (dx5video.h) NOT for the DIB stuff.
What(?).
Well, I went back to the SDL lib project. Added instrumentation, rebuit and looked at the class view. Everything looked fine. Aha. Client build versus lib build headers.
So, the lib appears to be ok.
Next I ruled out the possibility of a corrupt input file by downloading a different viewer. It played (with a little prompting) just great.
So, it’s NOT the lib, it’s NOT the file, What is wrong?
So I looked into the SDL docs to see if there was another way to do the same thing. Yep, use SDL_CreateRGBSurfaceFrom()!
So I modified the code to check for a cmd line arg and use a blt from our buffer
if ( argc > 1 && (strcmp(argv[1], “-blt”) == 0) ) {
//create our own in memory 'screen buffer - a DIB_Bitmap, non-hw
// char buf[ 320 * 240 * 3 ]; // this also works
// do NOT need to lock here, it's NOT 'in' a vid mem area 'yet'
fread( buf, 1, n, fp ); // fill up the buf
// Note : Pitch is a function of width and color depth, width is 320, depth is 24 bpp (3 bytes), 320 * 3 = 960
srcbmp = SDL_CreateRGBSurfaceFrom(buf, 320, 240, 24, 960,0,0,0,0 );
if( srcbmp->pixels != buf ) // check to make sure OUR buffer is used for the pixels
printf("Creation used a COPY of our data, NOT our buffer!\r\n");
while ( 1 ) {
//read data ( one frame of n bytes ) into buffer
while ( SDL_PollEvent(&sdlevent) ) ;
SDL_Delay ( 50 ); //50 ms per frame
SDL_BlitSurface( srcbmp, NULL, screen, NULL );
SDL_Flip(screen); // probably calls SDL_UpdateRect on WIn32, but on others it probably really flips the vid to hw memory
if ( SDL_MUSTLOCK( srcbmp ) )
SDL_LockSurface( srcbmp );
// ALWAYS use the provided buffer, as we NOT guaranteed 'where' in memory it is!
// IT should be buf pointer in Win32, but, on other platforms and depending upon hw, it's a 'maybe'
if ( fread ( srcbmp->pixels, 1, n, fp ) <= 0 )
break;
if ( SDL_MUSTLOCK( srcbmp ) )
SDL_UnlockSurface( srcbmp );
}
SDL_FreeSurface( srcbmp );
free( buf );
} else {
while( 1) …
Worked just fine! (had to tweak the pitch as I didn’t understand it at first)
So, what was wrong?
I went back and reviewed the original code. I slept on it (from 2 to 9), and it finally hit me!
We filled the buffer we allocated, BUT that’s NOT where the pixel buffer was located for the DIB_bitmap!!!
I did a trace through the code and sure enough, the video->pixels were set up in the CreateDib call, but JUST before we went into the loop,
we had a little piece of erroneous code…
screen->pixels = buf;
this points the screen pixels buffer to our allocated buffer, BUT the DIB had set the buffer in the create call
We ‘can’t’ fill a different buffer and expect it to be rendered. And it’s NOT.
So comment out the assignment, and change the fread from
if ( fread ( buf, 1, n, fp ) <= 0 )
to
if ( fread ( screen->pixels, 1, n, fp ) <= 0 )
Read INTO the alread created DIB pixels buffer!
Worked like a charm.
The War Craft short video is fairly nice in that small a format.
I’ll post the complete demo in a reply for easier access.
THanks SDL.org. This is NICE!
Looking forward to converting this to 1.3 for learning.
Enjoy