• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Link66

Play video files in SDL?

8 posts in this topic

Hi, I want some help... When I want to play a video file in my SDL code, what format is easiest to use. We are making a simple 2D-game in SDL for Windows and now it's time to do an intro. And we want to use a video file. But what format to use? avi,mpeg,mov,wmv? And does anyone know any example code or a tutorial? Thanks! Link
0

Share this post


Link to post
Share on other sites
SMPEG is the MPEG animation player used by SDLBasic and it seems to be the only one for SDL. I tend to stay away from Windows-only file formats like .WMV since there's no way to port them to another platform without converting the files first. BTW: Why are you limiting yourself to Windows only when SDL will work on practically any operating system?
0

Share this post


Link to post
Share on other sites
Once again Drew your attention to the needs of the forums are spot on. Great job. My only suggestion is to make a simple mpeg player that can pause, slow down, rewind and fast forward. Not that the documentation to do so isn't elsewhere but you know how lazy some of us are here and our aversion to using search engines.[wink]

Thanks again :)
0

Share this post


Link to post
Share on other sites
Nice tutorial, Drew.
I ran into the LGPL FFMPEG project, which unlike SMPEG is under active development and supports a whole bunch of modern codecs.
While there is no direct support for SDL, there is a nice tutorial for the API. The tutorial includes code for decoding video into RGB images, from which you can create SDL surface with SDL_CreateRGBSurfaceFrom.
If I get some free time, I might give it a try.

EDIT: I just found out that the FFMPEG project includes a program called ffplay, which is an SDL based video player. It seems to use SDL_DisplayYUVOverlay to output the video frame to the screen.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by evillive2
Once again Drew your attention to the needs of the forums are spot on. Great job. My only suggestion is to make a simple mpeg player that can pause, slow down, rewind and fast forward. Not that the documentation to do so isn't elsewhere but you know how lazy some of us are here and our aversion to using search engines.[wink]


By popular demand, here is a quick little wrapper that wraps most of all the needed functionality of SMPEG. It's everything in a header file, just so it's easy to work with and modify at first. Undoubtly it's not 100% complete or the best it could be, but it's definitly enough if you want to start easily working with MPEG files in SDL.

SDL_Movie.h

class SDL_Movie
{
private:
// Surface for the main screen
SDL_Surface *screen;

// Surface for the movie
SDL_Surface *movieSurface;

// Holds the movie information
SMPEG_Info movieInfo;

// Load the movie
SMPEG *movie;

// The max we can scale by
int MaxScaleX;
int MaxScaleY;
int MaxScale;

// Locations on screen to draw at
int X, Y;

void DrawIMG(SDL_Surface *img, SDL_Surface *dst, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, dst, &dest);
}

public:
SDL_Movie()
{
MaxScaleX = MaxScaleY = MaxScale = 1;

screen = 0;
movieSurface = 0;
movie = 0;
X = Y = 0;
}

// Free our movie
~SDL_Movie()
{
Stop();
SMPEG_delete( movie );
movie = 0;
SDL_FreeSurface( movieSurface );
movieSurface = 0;
}

void ClearScreen()
{
SDL_FillRect( movieSurface, 0, 0 );
}

// Set's the volume on a scale of 0 - 100
void SetVolume( int vol )
{
SMPEG_setvolume( movie, vol );
}

// Scale the movie by the desired factors
void Scale( int w, int h )
{
// Prevent a divide by 0
if( w == 0 )
w = 1;
if( h == 0 )
h = 1;

SMPEG_scaleXY( movie, w, h );
#ifdef _DEBUG
CheckErrors();
#endif
}

// Scale the movie by the desired factor
void ScaleBy( int factor )
{
// Prevent a divide by 0
if( factor == 0 )
factor = 1;
// Make sure we don't scale larger than the surface size
if( factor > MaxScale )
factor = MaxScale;

SMPEG_scale( movie, factor );
#ifdef _DEBUG
CheckErrors();
#endif
}

// Sets the region of the video to be shown
void SetDisplayRegion( int x, int y, int w, int h )
{
SMPEG_setdisplayregion( movie, x, y, w, h );
#ifdef _DEBUG
CheckErrors();
#endif
}

// Set the position that the movie should be drawn at on the screen
void SetPosition( int x, int y )
{
X = x;
Y = y;
}

// Check for any errors
void CheckErrors()
{
char* error = SMPEG_error( movie );
if( error )
printf( "Error: %s\n", error );
}

// Load the movie
void Load( const char* fileName, SDL_Surface* s, int maxscalex = 1, int maxscaley = 1 )
{
MaxScaleX = maxscalex;
MaxScaleY = maxscaley;

// Limit how much we can scale by
MaxScale = (maxscalex > maxscaley ? maxscaley : maxscalex);

// Assign the screen surface
screen = s;

// Load the movie and store the information about it
movie = SMPEG_new( fileName, &movieInfo, true );

#ifdef _DEBUG
CheckErrors();
#endif

// Create a temporary surface to render the movie to
SDL_Surface *tempSurface2 = SDL_CreateRGBSurface( SDL_SWSURFACE, movieInfo.width * MaxScaleX, movieInfo.height * MaxScaleY, 32, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask );

// Now make a surface optimized for the main screen
movieSurface = SDL_DisplayFormat( tempSurface2 );

// Free the temporary surface
SDL_FreeSurface( tempSurface2 );

// Set the surface to draw to
SMPEG_setdisplay( movie, movieSurface, 0, 0 );

#ifdef _DEBUG
CheckErrors();
#endif

// Set the display region
SMPEG_setdisplayregion( movie, 0, 0, movieInfo.width, movieInfo.height );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Set the looping of hte movie
void SetLoop( int val )
{
SMPEG_loop( movie, val );
#ifdef _DEBUG
CheckErrors();
#endif
}

// Play the movie
void Play()
{
SMPEG_play( movie );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Pause the movie
void Pause()
{
SMPEG_pause( movie );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Stops the movie, but keeps current position
void Stop()
{
SMPEG_stop( movie );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Rewind the movie back to 0:00:00
void Rewind()
{
SMPEG_rewind( movie );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Seek a number of bytes into the movie
void Seek( int bytes )
{
SMPEG_seek( movie, bytes );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Skip a number of seconds
void Skip( float seconds )
{
SMPEG_skip( movie, seconds );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Render some frame of the movie
void RenderFrame( int frame )
{
SMPEG_renderFrame( movie, frame );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Render the final frame of the movie
void RenderFinal()
{
SMPEG_renderFinal( movie, movieSurface, 0, 0 );

#ifdef _DEBUG
CheckErrors();
#endif
}

// Draw the movie surface to the main screen at x, y
void DisplayAt( int x, int y )
{
DrawIMG( movieSurface, screen, x, y );
}

// Draw the movie surface to the main screen at x, y
void Display()
{
DrawIMG( movieSurface, screen, X, Y );
}

// Return the current info for the movie
SMPEG_Info GetInfo()
{
SMPEG_getinfo( movie, &movieInfo );
return movieInfo;
}

// Get the current status of the movie, can be SMPEG_ERROR = -1, SMPEG_STOPPED, SMPEG_PLAYING
SMPEGstatus GetStatus()
{
return SMPEG_status(movie);
}
};



Here is the Main.cpp file that demonstrates using the class, it's very straight forward as well.

// Header file for SDL
#include "SDL.h"

// This is the header file for the library
#include "smpeg.h"

// Link in the needed libraries
#pragma comment( lib, "sdlmain.lib")
#pragma comment( lib, "sdl.lib")
#pragma comment( lib, "smpeg.lib")

#include "SDL_Movie.h"

int main( int argc, char *argv[] )
{
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
{
printf("Unable to init SDL: %s\n", SDL_GetError());
return -1;
}
atexit(SDL_Quit);

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 32, SDL_HWSURFACE );
if ( screen == NULL )
{
printf("Unable to set 640x480 video: %s\n", SDL_GetError());
return -1;
}

// The movie variable
SDL_Movie mov1;

// Load the specified file and draw it to the 'screen' surface
// In this case, we are allowed to scale the X and Y dimensions by 2 maximually
mov1.Load( "demo.mpg", screen, 2, 2 );

// Set the display at
//mov1.SetPosition( 100, 100 );

// Scale the movie by 2
mov1.ScaleBy( 2 );

// Event variable
SDL_Event event;

// Loop flag
int done = 0;

// Key structure
Uint8* keys;

while(done == 0)
{
// Simple event loop
while ( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT ) { done = 1; }

if ( event.type == SDL_KEYDOWN )
{
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
}
}

// Update key states
keys = SDL_GetKeyState( 0 );

// Play
if( keys[SDLK_p] )
{
mov1.Play();
keys[SDLK_p] = 0;
}

// Pause
if( keys[SDLK_a] )
{
mov1.Pause();
keys[SDLK_a] = 0;
}

// Stop
if( keys[SDLK_s] )
{
mov1.Stop();

// If we stop, we want to start from the beginning again
mov1.Rewind();

// Clear the movie surface so it's no longer showing the last frame
mov1.ClearScreen();

keys[SDLK_s] = 0;
}

// Rewind
if( keys[SDLK_r] )
{
mov1.Rewind();
keys[SDLK_r] = 0;
}

// NOTE: DOES NOT WORK
if( keys[SDLK_LEFT] )
{
// Still trying to figure this one out, how to go backwards
mov1.Skip( -.5 );
keys[SDLK_LEFT] = 0;
}

// Skip forward .5 seconds in the movie
if( keys[SDLK_RIGHT] )
{
mov1.Skip( .5 );
keys[SDLK_RIGHT] = 0;
}

// Clear the main screen (might not want to have in a game)
SDL_FillRect( screen, 0, 0 );

// Display the movie at the internal location (setposition)
if( mov1.GetStatus() == SMPEG_PLAYING )
mov1.Display();

// Display the movie at a specified location
//mov1.DisplayAt( 0, 0 );

// Flip the main screen
SDL_Flip( screen );
}

return 0;
}



So basically, if you look though the key inputs, there is play, pause, stop, rewind, seek forward, and no seek backward yet because it doesn't seem to work. Bare minimal to work with this class is as follows:

// Create a movie variable
SDL_Movie mov1;
// Load a movie file, set the surface it should be rendered to
mov1.Load( "demo.mpg", screen );
// Start playback (only needs to be called once, NOT once per frame)
mov1.Play();
// Finally draw the movie (called every frame)
mov1.Display();

And that's a wrap. I will probabally improive upon this a lot more and put it into a second tutorial when I next get time. This is just to get something out there for any interested, feel free to make your modifications as needed [wink]. So if there's any other requests with that project, just let me know!



Peregrin, that's a great find! The main problem I see with using SMPEG now is that it is under GLP, so you do have to release all your soruce code, which for something like E4E, it's not a bad thing, but if you wanted to make a game, then you'd not want to. If you don't beat me to it, I'll also take a look into using that program with SDL as well, for a LPGL alternative with more modern codecs would be great! [smile]
0

Share this post


Link to post
Share on other sites
Drew Benton is my idol! Seriously, where do you find the time to be this helpful? I have about 2-3 hours to myself a night and I get to read a bit here on the forums then go to bed so I can function at work the next day. My hat is off to you sir.
0

Share this post


Link to post
Share on other sites
Xcuse me, Where can I download this SMPEG to play MPEG in SDL?
I need this. I currently work on game SDL development.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0