[Ffmpeg-devel] ffmepg and SDL related
AJAY GAUTAM
ajaygautam1981
Wed Apr 25 08:36:31 CEST 2007
Hi All,
I am new for this forum as well as ffmpeg .
I have a problem::
I am getting screen height and width(e.g 320*240 or any size) from avcodec
,then i am creating SDL_CreateRGBSurface with the help of this screen height
and width ,but i want to change this height and width in 176*220,So can you
tell me how it is possible ? I tried to give hight and width as 176*220 but
it's not give the whole screen.
So how can i rescale the screen ??
And i want to draw this screen using GTK or GDK ,so how can i draw this
using GTK window(176*220)?
I am sending my test code ,please have a look upon it and help me.
/////************************************************************************************************************************************************************************************************////
//g++ test.c -lSDL -I/usr/include/SDL -lavcodec -lavformat
-I/usr/local/include/ffmpeg
#include "SDL.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include "GMidpCanvas.h"
#define FALSE 0
//============
SDL_Surface *screen;
guint16 *raw_pixels;
typedef struct
{
GtkWidget* pSoftkeys;
GtkWidget* Main_window;
GtkWidget* DrawingArea;
GdkGC* GC;
GdkDrawable *drawable;
}PlayMediaFileStruct;
on_darea_expose ();
PlayMediaFileStruct *PlayMediaFile;
//=========
int image_width;
int image_height;
GdkGC *gc;
unsigned char *buffer;
void swap_rgb24(unsigned char *mem, int n);
//swap the pixels before displying it as drivers will return in BGR format
void swap_rgb24(unsigned char *mem, int n)
{
unsigned char c;
unsigned char *p = mem;
unsigned int i = n ;
while (--i)
{
c = p[0];
p[0] = p[2];
p[2] = c;
p += 3;
}
}
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
//unsigned char *buffer;
int y;
uint8_t *pixel=NULL;
//unsigned char *pixel=NULL;
#if 0
// Open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write header to each file (it is format of header for ppm)
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; ydata[0]+y*pFrame->linesize[0], 1, width*3, pFile);
//-------------------
#endif
//pixel =(unsigned char *) malloc(width*height*3);
//SDL_LockSurface(screen);
pixel=(uint8_t*)screen->pixels;
for(y=0;ylinesize[0], pFrame->data[0]+y*pFrame->linesize[0], width*3);
}
#if 1
buffer = (unsigned char *)pixel;
swap_rgb24(buffer, height*width);
#endif
display(height,width);
//SDL_UnlockSurface(screen);
/*if( PlayMediaFile->Main_window != NULL)
{
CMidpCanvas_SetCameraMode(PlayMediaFile->Main_window, &buffer );
CMidpCanvas_Show( PlayMediaFile->Main_window );
} */
//SDL_UpdateRect(screen,0,0,0,0);//x,y,w,h are all 0 so it will update
entire screen.
//--------------------------
// Close file
//fclose(pFile);
}
//signal handler function
void signal_handler (int signum)
{
printf("\nSignal handler called to interupt the program.\n");
exit(1);
}
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;
//Handling CTRL-C signal.
signal(SIGINT, signal_handler);
gtk_init(&argc,&argv);
gdk_init(&argc,&argv);
gdk_rgb_init();
// gtk_main();
//*******************SDL code***********************
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Unable to initialize SDL: %s\n",
SDL_GetError());
return 1;
};
atexit(SDL_Quit);
//*************************************
// 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);
// Find the first video stream
videoStream=-1;
for(i=0; inb_streams; i++)
// if(pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO)
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;
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
PlayMediaFile = (PlayMediaFileStruct*)malloc(sizeof(PlayMediaFileStruct));
//PlayMediaFile->Main_window = CMidpCanvas_New (176, 220 );
PlayMediaFile->Main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_decorated(PlayMediaFile->Main_window,FALSE);
PlayMediaFile->DrawingArea = gtk_drawing_area_new();
gtk_drawing_area_size(PlayMediaFile->DrawingArea,176,220);
//****************************SDL API --------------
//screen =
SDL_SetVideoMode(pCodecCtx->width,pCodecCtx->height,24,SDL_NOFRAME);
//***************************************************
screen = SDL_CreateRGBSurface(SDL_NOFRAME,
pCodecCtx->width,pCodecCtx->height,24, 0xff000000, 0x00ff0000, 0x0000ff00,
0x000000ff);
//zoomSurface (screen, 0, 1, 1);
// 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= (uint8_t*)malloc(numBytes * sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in pFrameRGB
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
//Note : we can directly convert image into format PIX_FMT_BGR24 in that
case we dont need to call swap function manually.
image_width = pCodecCtx->width ;
image_height = pCodecCtx->height ;
// Read frames and save 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);
// Save the frame to disk as well as display it to SDL surface.
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,i++);
SDL_Delay(50);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
//gtk_main();
// Free the RGB image
free(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);
//=================
//SDL code
//SDL_Quit();
//gtk_main_quit();
//==============
return 0;
}
display(int height,int width)
{
gtk_container_add (GTK_CONTAINER (PlayMediaFile->Main_window),
(PlayMediaFile->DrawingArea)); // Put darea in windows.
gtk_signal_connect (GTK_OBJECT (PlayMediaFile->DrawingArea), "expose-event",
// Put RGB image in darea.
GTK_SIGNAL_FUNC (on_darea_expose), NULL);
gtk_drawing_area_size (GTK_DRAWING_AREA (PlayMediaFile->DrawingArea), 176,
220); // Set darea size.
gtk_widget_show_all (PlayMediaFile->Main_window); // Show windows in screen.
gtk_main();
}
on_darea_expose (GtkWidget *widget)
{
//PlayMediaFile->GC = gdk_gc_new (PlayMediaFile->drawable);
//if(!PlayMediaFile->GC)
gdk_draw_rgb_32_image
(widget->window,widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, 176,220,GDK_RGB_DITHER_MAX, buffer, 320*3);
gtk_main_quit();
}
Thanx & Regards
Ajay Gautam
More information about the ffmpeg-devel
mailing list