Page 5 of 7

Posted: Tue Jun 26, 2007 2:03 pm
by jona vark
but there is no way to deny a user from having Nero installed..
Try uninstalling it and let us know what happens. I would be interested in finding out if it solves your problem too.

Posted: Tue Jun 26, 2007 4:03 pm
by ricardo_arango
I uninstalled it, and it solved the problem, but still, as I said, if I open the video in Media Player without setting the compatibility mode it works, but in my program it won't. And the only way it will work is checking the comptability mode.

I know that I could just say "Please check compatibility mode in the Decoder Options Dialog of XVid", but I am trying hard to avoid having to configure the user's PC for my app to work.

Is there's something in the direct show code snippet that can be implemented/extended for XVid to work without configuring?

Posted: Tue Jun 26, 2007 4:13 pm
by jona vark
I am afraid I can't answer your question as you are probably deeper into this than I am. I am glad that it works now for you but I agree it is problematic when you have to start telling users to remove other apps! I look forward to a solution if you find it and I'll post if I find one. Although this problem seems to be a Nero artifact. I don't think any program should have system wide reach like that, when it is not running.

FWIW I am not using XVID. I had this problem with WMV files so the Nero stuff affected quite a range of codecs.

Please post anything you find.

Here ya go: ... f183976989

Posted: Thu Jun 28, 2007 12:24 am
by ricardo_arango
OK, finally made XVid work...

I had to do a very fast course on DirectShow, because I didn't know anything about it.. but I somehow got it working, with a lot of help from bits of code from all over the net...
The real change is in the loadMovie method, which creates a source and grabber filter and connects them.
I adapted (and copied a good part of it) from an example in

So the updated method goes like this:

Code: Select all

void DirectShowMovieTexture::loadMovie(	const Ogre::String& moviePath, bool horizontalMirroring)
		HRESULT hr = S_OK;

		// Look for the video path
		Ogre::String path = "";
		Ogre::FileInfoListPtr results =  Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo("General", "*.avi");
		Ogre::FileInfoList::iterator itr = results->begin();
		while(itr != results->end())
			if((*itr).filename == moviePath)
				//path = (*itr).archive->getName() + "/" + (*itr).filename;
				path = (*itr).archive->getName() + (*itr).filename;
				//and so on
			itr ++;
			Ogre::String("[DSHOW] Couldn't find the video '" + moviePath+"'.");
			throw("[DSHOW] Couldn't find the video");

		// log it!
		Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::String("[DSHOW] Loading movie named '")+moviePath+"'.");

		// destroy previous movie objects (if any)

		// Create the graph builder
		hr = ::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
			IID_IGraphBuilder, reinterpret_cast<void**>(&dsdata->pGraph));
		if (FAILED(hr))	throw("Failed creating DirectShow objects!");

		// Create the Sample Grabber
		dsdata->pGrabberF = NULL;
		dsdata->pGrabber = NULL;
		hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
			IID_IBaseFilter, reinterpret_cast<void**>(&dsdata->pGrabberF));
		hr = dsdata->pGrabberF->QueryInterface(IID_ISampleGrabber,
		hr = dsdata->pGraph->AddFilter(dsdata->pGrabberF, L"SampleGrabber");

		// Set the media type
		ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
		mt.formattype = FORMAT_VideoInfo; 
		mt.majortype = MEDIATYPE_Video;
		mt.subtype = MEDIASUBTYPE_RGB24;	// only accept 24-bit bitmaps
		hr = dsdata->pGrabber->SetMediaType(&mt);

		// Create the src filter
		wchar_t archivo[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, path.c_str(), -1, archivo, MAX_PATH);
		hr = dsdata->pGraph->AddSourceFilter(archivo, L"Source", &dsdata->pSrcFilter);
		if(FAILED(hr)) throw("Unsupported media type!");

		// Connect the src and grabber
		hr = ConnectFilters(dsdata->pGraph, dsdata->pSrcFilter, dsdata->pGrabberF);

		// Create the NULL renderer and connect
		dsdata->pNullRenderer = NULL;
		hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
			IID_IBaseFilter, reinterpret_cast<void**>(&dsdata->pNullRenderer));
		hr = dsdata->pGraph->AddFilter(dsdata->pNullRenderer, L"NullRenderer");

		hr = ConnectFilters(dsdata->pGraph, dsdata->pGrabberF, dsdata->pNullRenderer);

		// set sampling options

		// Necessary interfaces for controlling
		dsdata->pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&dsdata->pControl));
		dsdata->pGraph->QueryInterface(IID_IMediaEvent, reinterpret_cast<void**>(&dsdata->pEvent));
		dsdata->pGraph->QueryInterface(IID_IMediaSeeking, reinterpret_cast<void**>(&dsdata->pSeeking));

		// Retrieve the actual media type
		ZeroMemory(&mt, sizeof(mt));
		hr = dsdata->pGrabber->GetConnectedMediaType(&mt);
		if (mt.formattype == FORMAT_VideoInfo) 
			vih = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
			throw("No video stream found!");

		vih = (VIDEOINFOHEADER*) mt.pbFormat;
		// microsoft's help version of free media type
		if (mt.cbFormat != 0)
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		if (mt.pUnk != NULL)
			mt.pUnk = NULL;

		// set some basic data

		// clean the texture, so that it's ready for rendering this video

I also had to modify the DirectShowData structure, and add a couple of helper functions straight from the CodeProject source:

Code: Select all

	namespace OgreUtils
	struct DirectShowData
		/// Graph object
		IGraphBuilder *pGraph;
		/// Media control object
		IMediaControl *pControl;
		/// Media event object
		//IMediaEvent *pEvent;
		/// Grabber filter
		IBaseFilter *pGrabberF;
		/// Grabber object
		ISampleGrabber *pGrabber;
		/// Interface for seeking object
		IMediaSeeking *pSeeking;
		/// Window interface
		/** Useful for some configuration
		IVideoWindow *pWindow;

		/// Video output width
		int nVideoWidth;
		/// Video output height
		int nVideoHeight;

		IBaseFilter *pSrcFilter;
		IBaseFilter *pNullRenderer;
		IMediaEventEx *pEvent;

	/// Util function for converting C strings to wide strings
	/** (as needed for path in directshow). */
	WCHAR* util_convertCStringToWString(const char* string);

	HRESULT GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin){
		IEnumPins  *pEnum;
		IPin       *pPin;
		while(pEnum->Next(1, &pPin, 0) == S_OK)
			if (PinDir == PinDirThis)
				*ppPin = pPin;
				return S_OK;
		return E_FAIL;  

	HRESULT ConnectFilters(IGraphBuilder *pGraph, IBaseFilter *pFirst, IBaseFilter *pSecond)
		IPin *pOut = NULL, *pIn = NULL;
		HRESULT hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
		if (FAILED(hr)) return hr;
		// The previous filter may have multiple outputs, so try each one!
		IEnumPins  *pEnum;
		while(pEnum->Next(1, &pOut, 0) == S_OK)
			if (PINDIR_OUTPUT == PinDirThis)
				hr = pGraph->Connect(pOut, pIn);
		return hr;
I also added an iterator that looks for videos with .avi extension declared in the "General" resource group, so all you have to do is place them in a directory, and add it to your resources.cfg file, or manually yo can do this before loading the video:

Ogre::String myDirPath = "../videos";
Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation(myDirPath , "FileSystem" );

I still have problems with the refreshing of the texture. It looks jagged sometimes. I mean, is not as smooth as a video in media player. I suppose it could be fixed by having two textures, one as a backbuffer....but I am only supposing not sure if that is the problem..
Any pointers on this I will gladly receive. Also is it possible to load the entire movie in memory so it plays smoother?

Another issue I found is that the texture size is declared when loading the system, but if you load a video that is larger than the texture it chops parts of the movie. So I think the best way is to create the texture when the movie size is known.

Posted: Thu Jun 28, 2007 12:36 am
by ricardo_arango
Wouldn't it be possible to copy rows of pixels, instead of doing one it by one? Or the whole frame?

Posted: Thu Jun 28, 2007 4:28 am
by syedhs

Err did you by any chance reading my past post in this thread? Because you are referring to the same article in the code project as mine :wink: Sorry for not replying earlier as I thought you can figure it out.

Posted: Thu Jun 28, 2007 4:59 am
by ricardo_arango
syedhs wrote:ricardo,

Err did you by any chance reading my past post in this thread? Because you are referring to the same article in the code project as mine :wink: Sorry for not replying earlier as I thought you can figure it out.
I read it but as no one replied to my posts I tought it didn't work for XVid.

But it works ... :D

Posted: Fri Jul 20, 2007 3:14 pm
by netocris

I'm trying to use the DirectShow code snippet in my application Ogre, but i have some errors in compilation.

d:\program files\microsoft sdks\windows\v6.0\include\comcat.h(158) : error C2146: syntax error : missing ';' before identifier 'IEnumGUID'
d:\program files\microsoft sdks\windows\v6.0\include\comcat.h(158) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
d:\program files\microsoft sdks\windows\v6.0\include\comcat.h(171) : error C2061: syntax error : identifier '__RPC__out_ecount_part'
d:\program files\microsoft sdks\windows\v6.0\include\comcat.h(172) : error C2059: syntax error : ')'
d:\program files\microsoft sdks\windows\v6.0\include\comcat.h(172) : fatal error C1903: unable to recover from previous error(s); stopping compilation

I have Windows Vista instaled in my computer and i had that instal the
Microsoft® Windows® Software Development Kit for Windows Vista™ and .NET Framework 3.0 Runtime Components, because the Dshow.h file is not instaled in my OS.

but i open comcat.h file and everything looks fine (I thing...)

Posted: Sun Jul 22, 2007 2:53 am
by ruichaves
Hi everyone!

What's wrong with my code:

Code: Select all

	mRoot		= Ogre::Root::getSingletonPtr();
	mSceneMgr	= mRoot->createSceneManager( Ogre::ST_GENERIC );
    mCamera		= mSceneMgr->createCamera( "MenuCamera" );
    mViewport	= mRoot->getAutoCreatedWindow()->addViewport( mCamera );
	//Para efeito de testes
	mViewport->setBackgroundColour( Ogre::ColourValue::White );

	dshowMovieTextureSystem = new OgreUtils::DirectShowMovieTexture(

	this->movieName = "./video/intro.wmv";
	this->dshowMovieTextureSystem->loadMovie(movieName); //load the movie
	this->materialName = "video";	
	if (!Ogre::MaterialManager::getSingleton().resourceExists(this->materialName))
		throw("Video Intro: Error, material doesn't exist!");
	this->mat = Ogre::MaterialManager::getSingleton().getByName(this->materialName);
	this->tex = mat->getTechnique(0)->getPass(0)->getTextureUnitState(0);
		Ogre::String("VIDEO loaded?: ") + Ogre::StringConverter::toString(this->tex->isLoaded()) );
	//this->tex->setTextureScale(1.0, 1.0);

	this->dshowMovieTextureSystem->playMovie(); //play the movie
I can't see the movie, but i listen the sound...

Posted: Thu Jul 26, 2007 3:26 pm
by ruichaves
I resolve the problem...

I didn't use the texture, then i didn't see the video, just listen the audio...


For those that have the same problem, just create a rectangle2d and add the material to the rectangle..

Code: Select all

// Create background rectangle covering the whole screen
	rect = new Rectangle2D(true);                               
	rect->setCorners(-1.0, 1.0, 1.0, -1.0);

	// Render the background before everything else

	// Use infinite AAB to always stay visible
	AxisAlignedBox aabInf;

	// Attach background to the scene
	node = mSceneMgr->getRootSceneNode()->createChildSceneNode("videoMaterial");
	node->attachObject(rect);  //apagar...

Posted: Thu Sep 06, 2007 6:59 pm
by rluck
is there a package somewhere with all of the updated code?

Posted: Thu Sep 13, 2007 4:41 pm
by nacsasoft
I tried to use the code , but linker mistakes came forward :

Code: Select all

main.obj : error LNK2001: unresolved external symbol "public: void __thiscall OgreUtils::DirectShowMovieTexture::updateMovieTexture(void)" (?updateMovieTexture@DirectShowMovieTexture@OgreUtils@@QAEXXZ)
main.obj : error LNK2001: unresolved external symbol "public: void __thiscall OgreUtils::DirectShowMovieTexture::playMovie(void)" (?playMovie@DirectShowMovieTexture@OgreUtils@@QAEXXZ)
main.obj : error LNK2001: unresolved external symbol "public: void __thiscall OgreUtils::DirectShowMovieTexture::loadMovie(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,bool)" (?loadMovie@DirectShowMovieTexture@OgreUtils@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall OgreUtils::DirectShowMovieTexture::DirectShowMovieTexture(int,int,bool)" (??0DirectShowMovieTexture@OgreUtils@@QAE@HH_N@Z)
..\..\bin\Release\The_Dead.exe : fatal error LNK1120: 4 unresolved externals
It Strmiids.lib is added to the library list !!
System : VS2005 EE SP1 , WinXP SP2 , Ogre 1.2 , Microsoft Platform SDK for Windows Server 2003 R2 , Microsoft DirectX SDK (June 2007) + Extras

Posted: Thu Sep 13, 2007 5:23 pm
by hmoraldo
Alll the updated code is in the wiki, excepting the last xvid modification (but I couldn't test it yet).

And for linking, did you add UtilsOgreDshow.cpp to your project? Only including the .h files won't work, as the builder needs to know that it needs to compile and link that cpp file too. I think that's your problem.

Posted: Thu Sep 13, 2007 6:02 pm
by nacsasoft
Ohh sorry !!!!!!!!
I forgot it UtilsOgreDshow.cpp to add a file to the project. :oops: :oops:
Thank you for the help !!!!

Already only so much the problem that the avi the opening of a file the program is frozen off.
May be that not good codec I compressed it ?

Posted: Fri Sep 14, 2007 2:40 am
by hmoraldo
nacsasoft wrote:Ohh sorry !!!!!!!!
I forgot it UtilsOgreDshow.cpp to add a file to the project. :oops: :oops:
Thank you for the help !!!!

Already only so much the problem that the avi the opening of a file the program is frozen off.
May be that not good codec I compressed it ?
Check with some standard video that you can see with the Windows Media Player with no problems. If you can do that, you shouldn't have problems with the code. If that's the case, then the problem is probably in how you use the library.

Posted: Tue Sep 18, 2007 5:21 pm
by wynnj
I've tried this and it works great for playing my xvid AVIs so far, but I cannot get WMVs to play correctly. They are really really laggy. Any idea why this is happening?

Posted: Sun Sep 23, 2007 5:27 pm
by Bino
Hi all,

I've had no trouble compiling and linking this together. However I am getting the following error message while running this code snippet in my Ogre.log

01:51:48: OGRE EXCEPTION(6:FileNotFoundException): Cannot locate resource DirectShowManualTexture in resource group General or any other group. in ResourceGroupManager::openResource at c:\cdev\cubedev\projects\echo\ogrenew\ogremain\src\ogreresourcegroupmanager.cpp (line 603)

I believe I've created the required libs and am using the code as documented.

I'm using Ogre Version 1.4.3 (Eihort) and things appear to be loading correctly as indicated in my log.

01:51:46: [DSHOW] Creating texture with dimensions 800x600.
01:51:46: [DSHOW] Loading movie named 'C:/h.avi'.
01:51:47: [DSHOW] -> This movie has dimensions: 624x352.

While in my application sound can be heard but white is rendered if I'm using DX and a weird black and yellow texture if using OpenGL.

Incase I've screwed up :P

I have this to initialize -

Code: Select all

dshowMovieTextureSystem = new OgreUtils::DirectShowMovieTexture(800, 600);
Ogre::String movieName="C:/h.avi";
And then per every frame (checking removed for brevity) -

Code: Select all

When checking if "DirectShowManualTexture" exists

Code: Select all

if (!Ogre::TextureManager::getSingleton().resourceExists("DirectShowManualTexture")) { ... }
I naturally find it's not there. I'm assuming this is the source of my troubles? However mTexture appears to be created correctly as I can inspect it in the debugger.

As pointed out by someone earlier the line -

Code: Select all

hr=dsdata->pGraph->RenderFile(filepath, NULL);
Does seem to cause problems. Stepping through the debugger it completely exits out of the application before I can read what the hr value is. My knowledge of Directshow is pretty lacking so I'm not sure why.

Hope my first post to these forums doesn't make me come across as useful as a glass hammer... But I'm out of ideas and\or I'm completely missing something obvious. :)



Posted: Mon Sep 24, 2007 3:20 pm
by hmoraldo
wynnj: there is nothing to do for video performance as we are playing the videos with the Direct Show player. Keep using the videos that play better or, if you want to advance more, check earlier in this thread as a solution for another codec was discussed, if I remember it well.

Bino: you seem to have two different problems: the texture isn't being created, and maybe you have a problem with render. First try solving the problem with the texture. This could be a problem with some change in the Ogre compatibility when changing versions from Dagon to Eihort, as this code was written for Dagon if I remember well. Maybe some slight change makes it work again in Eihort.

As I didn't receive other comments about this code not working in Eihort, it could be something else too. One thing is that the texture code assignment should be done after loadMovie, not once per frame; but that shouldn't produce that error there. Please check your initialization code is executed always _before_ the "every frame" code (that is: the every frame code shouldn't be executed ever before init).

Hope this helps...

Posted: Wed Sep 26, 2007 4:26 am
by Bino
Hi hmoraldo,

I tried a few slight changes but wasn't quite sure where to start. Made a few changes to the Ogre::TextureManager::getSingleton().createManual( in the DirectShowMovieTexture constuctor.

- Specifically added the texture DirectShowManualTexture to the "General" group
- Specified a depth of 1
- Changed usage to Ogre::TU_DYNAMIC_WRITE_ONLY
- Even created the texture from my function and passed that in as a parameter.

No luck. Any other ideas on things to change?

I'm absolutely positive that the initialization code is executed before the "every frame" code. (Pasted below).

It seems like Ogre just seems to "lose" the created DirectShowManualTexture texture. I had Kojack take a look at it and he was equally puzzled. (Kojack is my lecturer at uni).

I did some debugging output to see if the DirectShowManualTexture exists. On the very first call of the "every frame" code, it doesn't exist and then afterwards it does. I even tried just running the "every frame" code when it does (apparently) exist and still no luck.

Any other ideas would be much appreciated but I understand you not wanting to worry about this weird problem :)

Here's the code. I've tried it with a variety of formats that all work in Windows Media Player. The all exhibit the same problem.

Playground is a simple test level loaded from an oFusion created .osm file.
screenMaterial is a material attached to a cube.
Update is a function that gets called once per frame.

Code: Select all

#include "PlayGround.h"
#include "conio.h"
#include "ConcaveTrimesh.h"
#include "OIDs.h"
#include "Util.h"
#include "ArenaSceneCallback.h"
#include <EObjectManagerOgre.h>
#include <EObjectOgre.h>
#include "Match.h"

PlayGround::PlayGround(string osmLevelFile, Ogre::SceneManager* pSceneMgr, Ogre::RenderWindow *pRenderWindow, EObjectManagerOgre *m) : Arena(osmLevelFile, pSceneMgr, pRenderWindow, m)
	dshowMovieTextureSystem = new OgreUtils::DirectShowMovieTexture(800, 600);

	Ogre::String movieName="C:/Vid.mpeg";

       delete dshowMovieTextureSystem;

void PlayGround::Update(f32 deltaT)
	Ogre::String materialName="screenMaterial";

Posted: Thu Sep 27, 2007 12:51 am
by hmoraldo
Well, a good first test could be to see if you get the same problem with Dagon version of Ogre. If so, we know the video code needs to be ported to Eihort.

Also, the right way to use the code would be:

Code: Select all

   Ogre::String movieName="C:/Vid.mpeg";
That is, you only need to set the texture once, and not once per frame.

Best regards,

Posted: Sat Sep 29, 2007 3:59 pm
by Bino
Was just about to port the application to Dagon and thought I'd try your changes. It works! Thank you very much!

Don't quite understand why that would cause the problem.

Once again, thanks! :)


Posted: Wed Oct 10, 2007 11:43 am
by HappyHoward

It seems this is a bug outside of the video code. When I let Ogre automatically create a window through mRoot->initialise(true, "MainWin"); the bug disappears. It still doesn't render anything while another program is active but it starts rendering again as soon as I click on the Ogre app. That is the expected behaviour I assume.


Hi. first of all thanks to hmoraldo (and other contributors) for the code!

I have a strange bug though. Normally everything works just fine, but if I click on a window of another program before the video starts to play the rendering stops working. The sound still plays, but nothing is rendered on screen. The video normally plays before the player starts the game. I can even start the game and it seems to work ok, except nothing more is rendered on the screen.

It would be interresting for me if anyone could test if you have the same bug.

OBS this error only shows up when using Direct3D, OpenGL works 100%!

Posted: Wed Oct 24, 2007 5:08 pm
by stowelly
The Nero bug is definitly an issue

i have Nero 7 and have spent the last 2 days wondering why my program randomly exits.... uninstalling nero fixed this

how can i work around this? as im sure distributing my game to people is going to be hard, especially convincing people to uninstall nero lol

Posted: Thu Oct 25, 2007 1:33 am
by hmoraldo
Sorry for not replying here in a while...

Maybe you can try using a specific codec (ie ogg) that you are sure Nero isn't going to use?

Posted: Thu Oct 25, 2007 9:45 am
by stowelly
hmm thats the thing, the only videos ive been able to get to play in this so far are wmv files.

saying that i doint think i have a ogg codec installed, how easy would it be to package one with the game? would ogre pickup a codec just from it being in the project directory?