After failing many times trying to install opencv with ffmpeg support for reading and displaying frames from video, I gave up and tried to use ffmpeg and sdl libraries directly.

The code here reads frames from video using ffmpeg (taken from http://www.dranger.com/ffmpeg/tutorial01.html) , stores them in IplImages and then displays them using SDL (code taken from http://cone3d.gamedev.net/pdfs/GFXwithSDLPart1.pdf) . Both these libraries are present by default or can be installed without many problems in many OS’s.

#include
#include
#include “opencv/cv.h”
#include “SDL/SDL.h”
#include

#define NFRAMES 600

/////////////// FFMPEG PART ///////////////////////////////////////////////////

//code taken from http://www.dranger.com/ffmpeg/tutorial01.html
void rfv(char * file, IplImage ** frames) {
// tutorial01.c
// Code based on a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)
// Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1

// A small sample program that shows how to use libavformat and libavcodec to
// read video from a file.
//
// Use
//
// gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lz
//
// to build (assuming libavformat and libavcodec are correctly installed
// your system).
//
// Run using
//
// tutorial01 myvideofile.mpg
//
// to write the first five frames from “myvideofile.mpg” to disk in PPM
// format.

AVFormatContext *pFormatCtx;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
AVPacket packet;
int frameFinished;
int numBytes;
uint8_t *buffer;
int m = 0, n = 0, p = 0, count = 0;

// Register all formats and codecs
av_register_all();

// Open video file
if(av_open_input_file(&pFormatCtx, file, 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, file, 0); // Find the first video stream videoStream=-1; for(i=0; inb_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) {
fprintf(stderr, “Unsupported codec!\n”);
return -1; // Codec not found
}

// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0) return -1; // Could not open codec // 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 *)av_malloc(numBytes*sizeof(uint8_t));

// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);

//Read frames and store to IplImages
i=0;
unsigned char *ptr1, *ptr2;

while(av_read_frame(pFormatCtx, &packet)>=0 && count < NFRAMES) { // 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);

//store the frame in an IplImage
frames[count] =
cvCreateImage(cvSize(pCodecCtx->width, pCodecCtx->height), IPL_DEPTH_8U, 3);

for(m = 0; m < pCodecCtx->height; m++) {
ptr1 = pFrameRGB->data[0]+ m*pFrameRGB->linesize[0];

ptr2 = frames[count]->imageData + m*frames[count]->widthStep;

for(n = 0; n < 3*pCodecCtx->width; n++)

ptr2[n] = ptr1[n];

}
count++;
}
}

// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}

// Free the RGB image
av_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);

return 0;
}

/////////////// SDL PART ///////////////////////////////////////////////////

//code taken from http://cone3d.gamedev.net/pdfs/GFXwithSDLPart1.pdf
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B) {
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
switch (screen->format->BytesPerPixel) {
case 1: { // Assuming 8-bpp
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*bufp = color;
}
break;
case 2: { // Probably 15-bpp or 16-bpp
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp = color;
}
break;
case 3: { // Slow 24-bpp mode, usually not used
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
bufp[0] = color;
bufp[1] = color >> 8;
bufp[2] = color >> 16;
} else{
bufp[2] = color;
bufp[1] = color >> 8;
bufp[0] = color >> 16;
}
}
break;
case 4: { // Probably 32-bpp
Uint32 *bufp;
bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
*bufp = color;
}
break;
}
}

void Slock(SDL_Surface *screen) {
if ( SDL_MUSTLOCK(screen) ) {
if ( SDL_LockSurface(screen) < 0 ) { return; } } } void Sulock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } } void sdlinit(SDL_Surface **screen, IplImage * frame) { if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) { printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); *screen=SDL_SetVideoMode(frame->width,frame->height,0,SDL_HWSURFACE|SDL_DOUBLEBUF);

if ( *screen == NULL ) {
printf(“Unable to set video: %s\n”, SDL_GetError());
exit(1);
}
}

void draw(SDL_Surface *screen, IplImage ** frames) {
int x, y, i = 0, done = 0;

while(done == 0 && i < NFRAMES) { SDL_Event event; 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; } } } Slock(screen); for(y=0;yheight;y++) {
for(x=0;xwidth;x++) {
DrawPixel(screen, x,y,
frames[i]->imageData[ y*frames[i]->widthStep + x*3],
frames[i]->imageData[ y*frames[i]->widthStep + x*3 + 1],
frames[i]->imageData[ y*frames[i]->widthStep + x*3 + 2]);
}
}

Sulock(screen);
SDL_Flip(screen);

cvWaitKey(1000/24);

i++;
}
}

int main(int argc, char ** argv) {
//check if video file is supplied
if(argc < 2) { printf("Please provide a movie file\n"); return -1; } //read frames IplImage ** frames; frames=(IplImage **) malloc(sizeof(IplImage*)*NFRAMES); rfv(argv[1], frames); //initialize SDL SDL_Surface *screen; sdlinit(&screen,frames[0]); //do processing //draw draw(screen,frames); } [/sourcecode]

Advertisements