[SDL] displaying decoded video frame on sdl surface

sanjay kumar gupta sanjay417 at rediffmail.com
Mon Feb 19 11:03:24 PST 2007


Hi, 
 I am getting decoded video frames in PIX_FMT_RGB24 format & I can save these video frames in files successfully.
I have created the SDL window and I want to put these video frames on the SDL window i tried doing this  but crashing. Code is given below.
can you please suggest the necessary changes to do in this code to render this decoded video frame data to sdl window. Thanks in advance. 
=================================
#include <avcodec.h>
#include <avformat.h>
#include <stdio.h>
#include <SDL.h>
#include <stdlib.h>
//SDL variables
SDL_Surface *screen;

void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
    FILE *pFile;
    char szFilename[32];
    int  y;

    // Open file
    sprintf(szFilename, "frame%d.ppm", iFrame);
    pFile=fopen(szFilename, "wb");
    if(pFile==NULL)
        return;
    // Write header
    fprintf(pFile, "P6\n%d %d\n255\n", width, height);

    // Write pixel data
    for(y=0; y<height; y++)
        fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
//=========================display the frame on SDL window.
	//display this buffer on the sdl window
    screen->pixels = pFrame->data[0];//pointing to video frame data.
	//display it on the screen
	SDL_UpdateRect(screen,0,0,0,0); 
	//????????????? it is crashing here.
//===========================================================
    // Close file
    fclose(pFile);
}

int main(int argc, char *argv[])
{
    AVFormatContext *pFormatCtx;
    int             i, videoStream;
    AVCodecContext  *pCodecCtx;
    AVCodec         *pCodec;
    AVFrame         *pFrame; 
    AVFrame         *pFrameRGB;
    AVPacket        packet;
    int             frameFinished;
    int             numBytes;
    uint8_t         *buffer;

    // Register all formats and codecs
    av_register_all();

    // Open video file
    if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
        return -1; // Couldn't open file

    // Retrieve stream information
    if(av_find_stream_info(pFormatCtx)<0)
        return -1; // Couldn't find stream information

    // Dump information about file onto standard error
    dump_format(pFormatCtx, 0, argv[1], false);

//-----------
	/* Initialize SDL's video system and check for errors */
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
               printf("Unable to initialize SDL: %s\n",
                      SDL_GetError());
               return 1;
    };
	 /* Make sure SDL_Quit gets called when the
     * program exits! */
    atexit(SDL_Quit);
    /* Attempt to set a 640x480 video mode */
    screen = SDL_SetVideoMode(640,480,16,SDL_FULLSCREEN);
    if (screen == NULL) {
        printf("Unable to set video mode: %s\n",
               SDL_GetError());
        return 1;
    };
//---------

    // Find the first video stream
    videoStream=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++)
        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
        {
            videoStream=i;
            break;
        }
    if(videoStream==-1)
        return -1; // Didn't find a video stream

    // Get a pointer to the codec context for the video stream
    pCodecCtx=pFormatCtx->streams[videoStream]->codec;

    // Find the decoder for the video stream
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
        return -1; // Codec not found

    // Open codec
    if(avcodec_open(pCodecCtx, pCodec)<0)
        return -1; // Could not open codec

    // Hack to correct wrong frame rates that seem to be generated by some 
    // codecs
    if(pCodecCtx->time_base.den>1000 && pCodecCtx->time_base.num==1)
		pCodecCtx->time_base.num=1000;

    // Allocate video frame
    pFrame=avcodec_alloc_frame();

    // Allocate an AVFrame structure
    pFrameRGB=avcodec_alloc_frame();
    if(pFrameRGB==NULL)
        return -1;

    // Determine required buffer size and allocate buffer
    numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
    buffer=new uint8_t[numBytes];

    // Assign appropriate parts of buffer to image planes in pFrameRGB
    avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
        pCodecCtx->width, pCodecCtx->height);

    // Read frames and save first five frames to disk
    i=0;
    while(av_read_frame(pFormatCtx, &packet)>=0)
    {
        // Is this a packet from the video stream?
        if(packet.stream_index==videoStream)
        {
            // Decode video frame
            avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, 
                packet.data, packet.size);

            // Did we get a video frame?
            if(frameFinished)
            {
                // Convert the image from its native format to RGB
                img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, 
                    (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, 
                    pCodecCtx->height);

                // Show the frames to sdl window.
                   SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++);
            }
        }

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
    }
    // Free the RGB image
    delete [] buffer;
    av_free(pFrameRGB);

    // Free the YUV frame
    av_free(pFrame);
    // Close the codec
    avcodec_close(pCodecCtx);
    // Close the video file
    av_close_input_file(pFormatCtx);
    return 0;
}
==============
regards,
sanjay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070219/def440da/attachment-0001.htm 


More information about the SDL mailing list