Playing movie in texture

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
greetzyl
Posts: 7
Joined: Tue Mar 13, 2007 2:53 am

Re: Playing movie in texture

Post by greetzyl »

where can i find the .h file in your program?
like:
#include <dshow.h>
#include <mmstream.h>
#include <amstream.h>
#include <ddstream.h>
I am a students of china !weicame to china!
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

These are includes from the original Windows-only version. The includes are windows multimedia includes. Better use the latter version which requires ffmpeg library and includes.
iulian_dbc
Posts: 2
Joined: Thu Apr 19, 2007 11:09 am

VideoPlayer

Post by iulian_dbc »

Can you provide som hints on building the player with Visual Studio 2005?
iulian_dbc
Posts: 2
Joined: Thu Apr 19, 2007 11:09 am

Re: VideoPlayer

Post by iulian_dbc »

iulian_dbc wrote:Can you provide som hints on building the player with Visual Studio 2005?
Managed to compile with VC but i have some problems. The video using EDT_OPENGL is not clear. I see a series of lines and some movement but no actual image. The only rnderer this works with is EDT_SOFTWARE2 but i get performance mesages and video is a little slow. However FPS is good :(


regards,

iulian
Athrun
Posts: 2
Joined: Wed Nov 19, 2008 3:43 am

Post by Athrun »

HI, Thanks first.

I used your code, I run those code ,have no error,
but I see nothing in my screen.
I need your help.


Code: Select all

#include <dshow.h> 
#include <mmstream.h> 
#include <amstream.h> 
#include <ddstream.h> 
#include "irrlicht.h"

using namespace irr; 

using namespace core; 
using namespace scene; 
using namespace video; 
using namespace io; 
using namespace gui; 

static GUID MY_CLSID_AMMultiMediaStream={0x49C47CE5,0x9BA4,0x11D0,0x82,0x12,0x00,0xC0,0x4F,0xC3,0x2C,0x45}; 
static GUID MY_IID_IAMMultiMediaStream={0xBEBE595C,0x9A6F,0x11D0,0x8F,0xDE,0x00,0xC0,0x4F,0xD9,0x18,0x9D}; 
static GUID MY_MSPID_PrimaryVideo={0xA35FF56A,0x9FDA,0x11D0,0x8F,0xDF,0x00,0xC0,0x4F,0xD9,0x18,0x9D}; 
static GUID MY_IID_IDirectDrawMediaStream={0xF4104FCE,0x9A70,0x11D0,0x8F,0xDE,0x00,0xC0,0x4F,0xD9,0x18,0x9D};  
static GUID MY_MSPID_PrimaryAudio={0xA35FF56B,0x9FDA,0x11D0,0x8F,0xDF,0x00,0xC0,0x4F,0xD9,0x18,0x9D}; 

class TMovie 
{ 
	IAMMultiMediaStream*     pAMStream; 
	IMediaStream*            pPrimaryVidStream; 
	IDirectDrawMediaStream*  pDDStream; 
	IDirectDrawStreamSample* pSample; 
	IDirectDrawSurface*      pSurface; 
	RECT                     Movie_rect; 
	LONG                     MoviePitch; 
	void*                    MovieBuffer; 
	DWORD                    time; 
	DWORD                    oldtick; 
	BOOL                     flg; 

public:    
	TMovie() 
	{ 
		CoInitialize(0); 
		pAMStream         = 0; 
		pPrimaryVidStream = 0;  
		pDDStream         = 0;    
		pSample           = 0; 
		pSurface          = 0; 
		time              = 0; 
	} 

	~TMovie() 
	{ 
		pPrimaryVidStream->Release(); 
		pDDStream->Release(); 
		pSample->Release(); 
		pSurface->Release(); 
		pAMStream->Release(); 
		CoUninitialize(); 
	} 

	void LoadMovie(char* filename) 
	{ 
		WCHAR buf[512]; 
		MultiByteToWideChar(CP_ACP,0,filename,-1,buf,512); 
		CoCreateInstance(MY_CLSID_AMMultiMediaStream,0,1,MY_IID_IAMMultiMediaStream,(void**)&pAMStream); 
		pAMStream->Initialize((STREAM_TYPE) 0, 0, NULL); 
		pAMStream->AddMediaStream( 0, &MY_MSPID_PrimaryVideo, 0, NULL); 
		pAMStream->OpenFile(buf,4); 
		pAMStream->GetMediaStream( MY_MSPID_PrimaryVideo, &pPrimaryVidStream); 
		pPrimaryVidStream->QueryInterface(MY_IID_IDirectDrawMediaStream,(void**)&pDDStream); 
		pDDStream->CreateSample(0,0,0,&pSample); 
		pSample->GetSurface(&pSurface,&Movie_rect); 
		pAMStream->SetState((STREAM_STATE)1); 
	} 

	void NextMovieFrame() 
	{ 
		if(GetTickCount()-oldtick < time){flg = false ;return;} 
		oldtick = GetTickCount(); 
		flg = true; 
		pSample->Update( 0, NULL, NULL, 0); 
	} 

	int MovieWidth() { return (Movie_rect.right - Movie_rect.left);} 

	int MovieHeight() { return (Movie_rect.bottom - Movie_rect.top);}  

	void DrawMovie(int x,int y,ITexture* Buf) 
	{    
		void* pBits = Buf->lock(); 
		LONG  Pitch = Buf->getPitch();  
		DDSURFACEDESC  ddsd; 
		ddsd.dwSize=sizeof(DDSURFACEDESC); 
		pSurface->Lock( NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT , NULL); 
		int wmin=(Pitch<ddsd.lPitch)?Pitch:ddsd.lPitch; 
		for(int h=0; h<ddsd.dwHeight; h++) 
			memcpy((BYTE*)pBits+((y+h)*Pitch)+x*4,(BYTE*)ddsd.lpSurface+h*ddsd.lPitch,wmin); 
		pSurface->Unlock(NULL); 
		Buf->unlock(); 
	}  

	void SetMovieFPS(int fps) 
	{ 
		time = fps; 
	} 

	void MovieLock() 
	{ 
		DDSURFACEDESC  ddsd; 
		ddsd.dwSize=sizeof(DDSURFACEDESC); 
		pSurface->Lock( NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); 
		MoviePitch  = ddsd.lPitch; 
		MovieBuffer = ddsd.lpSurface; 
	}  

	void MovieUnlock() 
	{  
		pSurface->Unlock( NULL); 
	}              

	void Gray(int x1,int y1,int x2,int y2) 
	{ 
		if(!flg) return; 
		DWORD  clr; 
		LPBYTE buff; 
		for (int h=y1; h<y2; h++)    
			for (int w=x1; w<x2; w++) 
			{ 
				buff = (LPBYTE)MovieBuffer + w*4 + h*MoviePitch; 
				clr = (buff[0] + buff[1] + buff[2]) /3; 
				*(DWORD*)buff = RGB((BYTE)clr,(BYTE)clr,(BYTE)clr); 
			}    
	} 

	void Negative(int x1,int y1,int x2,int y2) 
	{ 
		if(!flg) return; 
		DWORD  clr; 
		LPBYTE buff; 
		for (int h=y1; h<y2; h++)    
			for (int w=x1; w<x2; w++) 
			{ 
				buff = (LPBYTE)MovieBuffer + w*4 + h*MoviePitch;  
				*(DWORD*)buff = RGB((BYTE)255-buff[0],(BYTE)255-buff[1],(BYTE)255-buff[2]); 
			}    
	}  

	void Intensity(float intnsty,int x1,int y1,int x2,int y2) 
	{ 
		if(!flg) return; 
		DWORD  clr; 
		LPBYTE buff; 
		for (int h=y1; h<y2; h++)    
			for (int w=x1; w<x2; w++) 
			{ 
				buff = (LPBYTE)MovieBuffer + w*4 + h*MoviePitch;  
				*(DWORD*)buff = RGB((BYTE)buff[0]/intnsty,(BYTE)buff[1]/intnsty,(BYTE)buff[2]/intnsty); 
			} 
	}          
};    

And the main:

Code: Select all

int main(int argc, char* argv[])
{
	IrrlichtDevice* device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(800, 600));
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();

	IAnimatedMesh* mesh = smgr->getMesh("../mesh_bin/Tris.MD2");//sydney.md2
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setMD2Animation ( scene::EMAT_STAND );
		node->setScale(core::vector3df(0.1f,0.1f,0.1f));
	}

	TMovie* movie = new TMovie; 
	movie->LoadMovie("../mesh_bin/lake.mpg"); 
	movie->SetMovieFPS(25); 

	ITexture* movTxtr; 
	driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT , TRUE); 
	driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, FALSE); 
	movTxtr = driver->addTexture(dimension2d<s32>(512,512),"imovie"); 

	smgr->addCameraSceneNode(0, vector3df(0,0,-20), vector3df(0,0,0));
	// 
	//smgr->addCameraSceneNodeFPS(0,100.0f,1200.f);


	while(device->run())
	{
		driver->beginScene(true, true, SColor(0,200,200,200));

		movie->NextMovieFrame();
		movie->MovieLock(); 
		movie->Gray(0,0,320,240) ;              
		movie->MovieUnlock(); 
		movie->DrawMovie(0,0,movTxtr); 

		smgr->drawAll();
		//guienv->drawAll();
		driver->endScene();
	}
	device->drop();

	return 0;
}
NotAnotherNun
Posts: 8
Joined: Fri Nov 21, 2008 1:10 am

Post by NotAnotherNun »

Hey there, I have been playing around with this code and several other peices of code for playing AVI files, but none have worked. It keeps telling me there is a problem with reading the file (in the gray subroutine) but refuses to show the code. Could someone create an MSVC project with all the code and the example code together because I can't make it work. Also, does the video file need to be in the media file, or can it be anywhere as long as its defined (i.e. D:/My Videos/20081123164536.avi)

Chris
stepan1117
Posts: 10
Joined: Sun Mar 08, 2009 12:41 pm

Post by stepan1117 »

Hi everyone, I really had to make this working, so I modified the previous code so it can work with the newest ffmpeg and under linux. Here are those two modified files:

videoPlayer.cpp

Code: Select all

#include "videoPlayer.h"

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;




//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
// Original code by: juliusctw
// Modified by Hansel
// Additional changes by stepan1117

// compile with:
// windows:
// g++ -o player cVideoPlayer.cpp -lavformat -lavcodec -lavutil -lz -I/c/code/iamar/irrlicht-1.2/include/ -L/c/code/iamar/irrlicht-1.2/bin/Win32-gcc/ -lIrrlicht
//
// linux:
// g++ -o player cVideoPlayer.cpp -lavformat -lavcodec -lavutil -lz -I../irrlicht/include/ -L../irrlicht -lIrrlicht -lGL -lGLU -lXxf86vm -lXext -lX11


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

cVideoPlayer::cVideoPlayer(irr::video::IVideoDriver *irrVideoDriver, irr::ITimer *timer)
        : IrrVideoDriver(irrVideoDriver), Timer(timer)
{
    IrrVideoDriver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
    IrrVideoDriver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
    // Register all formats and codecs
    av_register_all();

    state = stopped;
    streamOpen = false;
    actualFrame = 0;
    loop = false;
    replayCont = 0;
    seekFactor = 15;




}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

cVideoPlayer::cVideoPlayer(irr::video::IVideoDriver *irrVideoDriver, irr::ITimer *timer, char* filename, int desiredW, int desiredH)
        : IrrVideoDriver(irrVideoDriver), Timer(timer)
{
    IrrVideoDriver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
    IrrVideoDriver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
    // Register all formats and codecs
    av_register_all();

    this->desiredH = desiredH;
    this->desiredW = desiredW;

    if (! open(filename))
    {
        printf("problem opening movie");
        exit(1);
    }


    state = stopped;
    streamOpen = false;
    actualFrame = 0;
    loop = false;
    replayCont = 0;
    seekFactor = 15;


}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


cVideoPlayer::~cVideoPlayer()
{
    // Free the RGB image
    if (Buffer != NULL)
        delete [] Buffer;

    if (FrameRGB != NULL)
        av_free(FrameRGB);

    // Free the YUV frame
    if (Frame != NULL)
        av_free(Frame);

    // Close the codec
    if (CodecCtx != NULL)
        avcodec_close(CodecCtx);

    // Close the video file
    if (FormatCtx != NULL)
        av_close_input_file(FormatCtx);
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

void cVideoPlayer::changeResolution(int w, int h){

	if (desiredW != w || desiredH != h){

		std::cout << "Changing resolution from ["<< desiredW << "x" << desiredH << "] to [" << w << "x" << h << "]" << std::endl;

		desiredW = w;
		desiredH = h;

		delete [] Buffer;
		//av_free((AVPicture *)FrameRGB);

		NumBytes=avpicture_get_size(PIX_FMT_RGB32,
										desiredW,
										desiredH);

		Buffer=new uint8_t[NumBytes];

			// Assign appropriate parts of buffer to image planes in pFrameRGB
		avpicture_fill((AVPicture *)FrameRGB, Buffer, PIX_FMT_RGB32,
					desiredW, desiredH);
	}
}

bool cVideoPlayer::open(char *filename)
{
    actualFilename = filename;

    // Open video file
    if (av_open_input_file(&FormatCtx, filename, NULL, 0, NULL)!=0)
        return false; // Couldn't open file

    // Retrieve stream information
    if (av_find_stream_info(FormatCtx)<0)
        return false; // Couldn't find stream information

    // Dump information about file onto standard error
    dump_format(FormatCtx, 0, filename, false);

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



    // Get a pointer to the codec context for the video stream
    CodecCtx=FormatCtx->streams[VideoStream]->codec;

    // Get the seconds/frame of this video stream
    SecondsPerFrame = (double)FormatCtx->streams[VideoStream]->r_frame_rate.den / FormatCtx->streams[VideoStream]->r_frame_rate.num;
    printf("Duration:  %f", (double)FormatCtx->duration);

    printf("  seconds per frame: %f\n", SecondsPerFrame);

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

    // Inform the codec that we can handle truncated bitstreams -- i.e.,
    // bitstreams where frame boundaries can fall in the middle of packets
    if (Codec->capabilities & CODEC_CAP_TRUNCATED)
        CodecCtx->flags|=CODEC_FLAG_TRUNCATED;

    // Open codec
    if (avcodec_open(CodecCtx, Codec)<0)
        return false; // Could not open codec

    // Allocate video frame
    Frame=avcodec_alloc_frame();

    // Allocate an AVFrame structure
    FrameRGB=avcodec_alloc_frame();
    if (FrameRGB==NULL)
        return false;

    // Determine required buffer size and allocate buffer

//    desiredH = CodecCtx->height+100;
//    desiredW = CodecCtx->width+100;

    NumBytes=avpicture_get_size(PIX_FMT_RGB32,
                                desiredW,
                                desiredH);
    Buffer=new uint8_t[NumBytes];

    // Assign appropriate parts of buffer to image planes in pFrameRGB
    avpicture_fill((AVPicture *)FrameRGB, Buffer, PIX_FMT_RGB32,
    		desiredW, desiredH);


    // get the movie framerate
    framerate = FormatCtx->streams[VideoStream]->r_frame_rate.num;



    return true;
}



//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


bool cVideoPlayer::refresh()
{
	static struct SwsContext *img_convert_ctx;
	static int currentX = 0;
	static int currentY = 0;
	bool needResize = false;

	if (state == playing)
    {

    	if (Timer->getRealTime() - lastTime > (SecondsPerFrame*1000))
        {

        	if (GetNextFrame(FormatCtx, CodecCtx, VideoStream, Frame))
            {




        		if(img_convert_ctx == NULL) {
        			currentX = desiredW;
        			currentY = desiredH;

        			int w = CodecCtx->width;
         	        int h = CodecCtx->height;

            	          img_convert_ctx = sws_getContext(w, h,
											CodecCtx->pix_fmt,
            	                            desiredW, desiredH, PIX_FMT_RGB32, SWS_FAST_BILINEAR | SWS_CPU_CAPS_MMX2,
            	                            NULL, NULL, NULL);
            	          if(img_convert_ctx == NULL) {
            	        	  fprintf(stderr, "Cannot initialize the conversion context!\n");
            	        	  exit(1);
            	          }
            	 } else if (currentX != desiredW || currentY != desiredH){
            		 needResize = true;
            		 currentX = desiredW;
            		 currentY = desiredH;

            		 int w = CodecCtx->width;
					 int h = CodecCtx->height;

					 sws_freeContext(img_convert_ctx);
					 img_convert_ctx = NULL;

					 img_convert_ctx = sws_getContext(w, h,
										CodecCtx->pix_fmt,
										desiredW, desiredH, PIX_FMT_RGB32, SWS_FAST_BILINEAR | SWS_CPU_CAPS_MMX2,
										NULL, NULL, NULL);
					 if(img_convert_ctx == NULL) {
						  fprintf(stderr, "Cannot re-initialize the conversion context!\n");
						  exit(1);
					 }
            	 }



        		sws_scale(img_convert_ctx, Frame->data,
            	                  Frame->linesize, 0,
            	                  CodecCtx->height,
            	                  FrameRGB->data, FrameRGB->linesize);

                //printf("Replay Num.: %d  ::  Dumping Frame: %d  ::  FrameRate: %f\n", replayCont, actualFrame, framerate);

                // Dump the frame
                DumpFrame(FrameRGB, desiredW, desiredH, needResize);

                actualFrame++;
            }
            else
            {
                state = stopped;
                printf("->End\n");
            }

            lastTime = Timer->getRealTime();
        }
    }

    if (state == stopped)
    {
        actualFrame = 0;

        restartStream();

        // if looped then replay the movie
        if (loop)
        {
            replayCont ++;
            state = playing;
            streamOpen = true;
        }
    }
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

bool cVideoPlayer::isPlaying(){
	return (state == playing);
}

bool cVideoPlayer::play()
{
    if (state == stopped) replayCont++;
    state = playing;
    streamOpen = true;

    return true;
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


bool cVideoPlayer::stop()
{
    state = stopped;

    return true;
};


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

bool cVideoPlayer::pause()
{
    state = paused;

    return true;
};


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


bool cVideoPlayer::GetNextFrame(AVFormatContext *pFormatCtx,
                                AVCodecContext *pCodecCtx,
                                int videoStream,
                                AVFrame *pFrame)
{
    static AVPacket packet;
    static int      bytesRemaining=0;
    static uint8_t  *rawData;
    static bool     fFirstTime=true;
    int             bytesDecoded;
    int             frameFinished;



    // First time we're called, set packet.data to NULL to indicate it
    // doesn't have to be freed
    if (fFirstTime)
    {
        fFirstTime=false;
        packet.data=NULL;
    }

    // Decode packets until we have decoded a complete frame
    while (true)
    {
        // Work on the current packet until we have decoded all of it
        while (bytesRemaining > 0)
        {
            // Decode the next chunk of data
            bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
                                              &frameFinished, rawData, bytesRemaining);

            // Was there an error?
            if (bytesDecoded < 0)
            {
                fprintf(stderr, "Error while decoding frame\n");
                return false;
            }

            bytesRemaining-=bytesDecoded;
            rawData+=bytesDecoded;

            // Did we finish the current frame? Then we can return
            if (frameFinished)
                return true;
        }

        // Read the next packet, skipping all packets that aren't for this
        // stream
        do
        {
            // Free old packet
            if (packet.data!=NULL)
                av_free_packet(&packet);

            // Read new packet
            if (av_read_packet(pFormatCtx, &packet)<0)
                goto loop_exit;
        }
        while (packet.stream_index!=videoStream);

        bytesRemaining=packet.size;
        rawData=packet.data;
    }

loop_exit:

    // Decode the rest of the last frame
    bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                                      rawData, bytesRemaining);

    // Free last packet
    if (packet.data!=NULL)
        av_free_packet(&packet);

    return frameFinished!=0;
}



//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------



bool cVideoPlayer::DumpFrame(AVFrame *pFrame,
                             int width,
                             int height, bool needResize)
{
    static char first_time = 1;


    if (first_time)
    {
       CurrentImage = IrrVideoDriver->createImageFromData(irr::video::ECF_A8R8G8B8,
                       irr::core::dimension2d<irr::u32>(width, height),
                       pFrame->data[0],
                       true);
        first_time = 0;
        CurrentTexture = IrrVideoDriver->addTexture("movie", CurrentImage);

    }

    if (needResize){
    	IrrVideoDriver->removeTexture(CurrentTexture);

    	CurrentImage = IrrVideoDriver->createImageFromData(irr::video::ECF_A8R8G8B8,
    	                       irr::core::dimension2d<irr::u32>(width, height),
    	                       pFrame->data[0],
    	                       true);
        CurrentTexture = IrrVideoDriver->addTexture("movie", CurrentImage);
    }

    p = (s32*)CurrentTexture->lock ();
    pimage = (s32*)CurrentImage->lock ();


    for (int i = 0; i < width*height; i++) p[i] = pimage[i];

    // unlock de texture and the image
    CurrentTexture->unlock();
    CurrentImage->unlock();



    return true;

}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

irr::video::ITexture* cVideoPlayer::getVideoTexture()
{
    return CurrentTexture;
}



//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------



void cVideoPlayer::drawVideoTexture()
{
    // draw the texture
    if (state == playing)
    	IrrVideoDriver->draw2DImage(CurrentTexture, irr::core::position2d<irr::s32>(0,0),
                                irr::core::rect<irr::s32>(0,0,desiredW,desiredH), 0, irr::video::SColor(255,255,255,255), false);
}

//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


bool cVideoPlayer::restartStream()
{
    //Close stream
	// printf("GetNextFrame()\n");
	if ( FormatCtx && streamOpen)
    {
        streamOpen = false;

        if (av_open_input_file(&FormatCtx, actualFilename, NULL, 0, NULL)!=0) return false; // Couldn't open file
    }
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


void cVideoPlayer::setLoop(bool l)
{
    loop = l;
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


void cVideoPlayer::goToSecond(int numSecond)
{
    restartStream();

    state = manual;


    goToFrame((int)framerate*numSecond);
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------




bool cVideoPlayer::goToFrame(int numFrame)
{
    // seek the movie
    if (numFrame < seekFactor) av_seek_frame(FormatCtx, VideoStream, numFrame, AVSEEK_FLAG_ANY);
    else
    {
        av_seek_frame(FormatCtx, VideoStream, numFrame-seekFactor, AVSEEK_FLAG_ANY);

        // advance to the real selected frame
        for (int i = 0; i < seekFactor; i++) GetNextFrame(FormatCtx, CodecCtx, VideoStream, Frame);
    }

    actualFrame = numFrame;

    printf("Replay Num.: %d  ::  Dumping Frame: %d  ::  FrameRate: %f\n", replayCont, actualFrame, framerate);

    return true;
}



//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


float cVideoPlayer::getFrameRate()
{
    return framerate;
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

videoPlayer.h

Code: Select all

#ifndef __VIDEO_PLAYER_H__
#define __VIDEO_PLAYER_H__

// irrlicht includes
#include <irrlicht.h>

// ffmpeg includes
extern "C" {
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
#include <ffmpeg/swscale.h>
}

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;



class cVideoPlayer
{
private:

    irr::ITimer *Timer;
    irr::video::IVideoDriver *IrrVideoDriver;
    irr::video::IImage *CurrentImage;
    irr::video::ITexture *CurrentTexture;

    unsigned long lastTime;

    double SecondsPerFrame;

    AVFormatContext *FormatCtx;
    int             VideoStream;
    AVCodecContext  *CodecCtx;
    AVCodec         *Codec;
    AVFrame         *Frame;
    AVFrame         *FrameRGB;
    int             NumBytes;
    uint8_t         *Buffer;
    int 			desiredH;
    int 			desiredW;



    bool GetNextFrame(AVFormatContext *pFormatCtx,
                      AVCodecContext *pCodecCtx,
                      int videoStream,
                      AVFrame *pFrame);

    bool DumpFrame(AVFrame *pFrame, int width, int height, bool needResize);

    s32* p;
    s32* pimage;

    enum cState {playing, paused, stopped, manual};
    cState state;
    bool streamOpen;
    char* actualFilename;
    int actualFrame;
    bool loop;
    int replayCont;
    float framerate;
    int seekFactor;

public:
    // constructors
    cVideoPlayer(irr::video::IVideoDriver *irrVideoDriver,
                 irr::ITimer *timer);
    cVideoPlayer(irr::video::IVideoDriver *irrVideoDriver,
                 irr::ITimer *timer, char* filename, int desiredW, int desiredH);

    // destructor
    ~cVideoPlayer();

    void changeResolution(int w, int h);

    // functions to open, play, and stop the media
    bool open(char *filename);

    // refresh the video
    bool refresh();

    // play the video
    bool play();

    // stop the video
    bool stop();

    // pause the video
    bool pause();

    // get the video texture
    irr::video::ITexture* getVideoTexture();

    bool isPlaying();

    // draw the video texture
    void drawVideoTexture();
   
    // close the video stream
    bool restartStream();

    // set looped
    void setLoop(bool l);

    // go to selected second
    void goToSecond(int numSecond);

    // get selected frame
    bool goToFrame(int numFrame);

    // get the movie framerate
    float getFrameRate();

    // get the seek factor (15 by default)
    int getSeekFactor();

    // set the seek factor
    void setSeekFactor(int sf);
};

#endif
I am still beginner with Irrlicht, therefore I cannot guarantee that it is the best possible solution :)
Hope it will help smbdy...
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

Well i guess using a rendertargettexture, kicking the CurrentImage and replacing the loop "for (int i = 0; i < width*height; i++) p = pimage; " with a memcpy will increase the performance. There are some codereplication which indicates that there is place for some improvements :).
netpipe
Posts: 670
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

projecto

Post by netpipe »

http://www.mediafire.com/?xc9thbycexk

UPDATED : project with CB file LINUX
thanks for the good times.

Tecan
netpipe
Posts: 670
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

oops

Post by netpipe »

aparently its broken but runs fine. i tried with this movie http://www.gotfuturama.com/Multimedia/3 ... inking.avi its DIVX im not sure if its good/bad but it complained less than the others. hopefully someone can patch this up ;)
thespecial1
Posts: 135
Joined: Thu Oct 30, 2008 11:56 am
Location: UK
Contact:

almost working

Post by thespecial1 »

Hi Guys

i have been playin with the win/linux version of the wrapper for a week and have included ffmpeg sucessfully (tested with the avsample demo) and made my code run a movie, well almost.

currently i have a movie on the screen but whilst you can see it playing (openGL video mode), it is more like squiggly bars of colour rather than the movie. have tried mpg,divx,xvid all same output.

comparing to your code, i can see the part of the code that i am missing,
easy question:-

is the file "unistd.h" supposed to be from the MSYS\mingw\include\sys?? if i add this as an include path i get a host of errors along the lines of
"fatal error C1014: too many include files : depth = 1024",

If i leave "unistd.h" commented out it compiles fine and dandy but displays v.weird video, anyone shed any light state on this would be appreciated.

thanks
rob
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

It's rather unlikely that unistd will change the color planes. The problem is probably that you need a different byte order for your video stream. Just make sure you have the correct bit depth (16 or 32 in general), and that e.g. an ARGB mode needs to be represented in little endian u32 in Irrlicht (so it's actually an BGRA mode).
thespecial1
Posts: 135
Joined: Thu Oct 30, 2008 11:56 am
Location: UK
Contact:

Post by thespecial1 »

fair enuff, aslong as I definatly dont need that file, weirdly with no changes the same code plays video flawlessly at work but squiggly lines on my laptop, only real difference between the two is the laptop has ATI graphics and work is nvidia, strange..
altanis
Posts: 2
Joined: Mon Jul 06, 2009 6:33 pm

error while drawing...

Post by altanis »

Hi
On Irrlicht 1.5 I have an error in method DrawMovie:

Code: Select all

void DrawMovie(int x,int y,ITexture* Buf) 
            {    
                void* pBits = Buf->lock(); 
                LONG  Pitch = Buf->getPitch();  
                DDSURFACEDESC  ddsd; 
                ddsd.dwSize=sizeof(DDSURFACEDESC); 
                pSurface->Lock( NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT , NULL); 
                int wmin=(Pitch<ddsd.lPitch)?Pitch:ddsd.lPitch; 
                for(int h=0; h<ddsd.dwHeight; h++) 
                     memcpy((BYTE*)pBits+((y+h)*Pitch)+x*4,(BYTE*)ddsd.lpSurface+h*ddsd.lPitch,wmin); 
                pSurface->Unlock(NULL); 
                Buf->unlock(); 
           }
Access violation writing location 0x03d01000 in lines

Code: Select all

for(int h=0; h<ddsd.dwHeight; h++) 
                     memcpy((BYTE*)pBits+((y+h)*Pitch)+x*4,(BYTE*)ddsd.lpSurface+h*ddsd.lPitch,wmin); 
Does anyone know how to handle this?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, just ditch this movie player. It never worked correctly for all types of textures, so depending on your actual hardware it might run or not. Check for other players which do handle such issues.
Post Reply