|
W S
Very strange, a value of 0 means it's NULL. Are you sure pVmr9 has been correctly initialized?
|
|
|
|
|
hi,
I am new to DirectShow and have encountered a problem. I am trying to implement the following filter graph to render avi video only.
source filter -> mpeg-1 stream splitter -> mpeg video decoder -> video renderer
I get correct output when i use "Capture Graph builder" and apply the "renderstream" function. I want to use "Filter Graph Manager" to implement the above filter graph and manually connect the filters (not using renderfile). The problem is that MPEG-1 Stream Splitter has two pins of media types AMMEDIA_Audio and AMMEDIA_Video. I just want to use the video output pin only. I don't know exactly how to enumerate the pin for this media type. I have tried enummediatypes in my program but it doesn't work. I think there is some problem in the way I have used it. Can anyone please correct the following program for me?
/****************************************************************************
Link -> 1)Strmiids.lib 2)Quartz.lib
Manually building a filter graph for playing an "AVI video" (not audio).
Source Filter -> MPEG-I Stream Splitter -> MPEG Video Decoder -> Video Renderer
*****************************************************************************/
#include <iostream.h>
#include <dshow.h>
void CheckFailure(HRESULT);
HRESULT GetUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);
/******************************************************************/
void main()
{
IGraphBuilder *pGraph=NULL;
IBaseFilter *pSource=NULL;
IBaseFilter *pmpegSplitter=NULL;
IBaseFilter *pmviddecoder=NULL;
IBaseFilter *pvidrenderer=NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
HRESULT hr;
IPin *InPin;
IPin *OutPin;
//initialize COM
CoInitialize(NULL);
// Create the filter graph manager and query for interfaces.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
cout<<"ERROR - Could not create the Filter Graph Manager."<<endl;
return;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
//STEP 1: Create filter instances
/*hr=CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pSource);
CheckFailure(hr);*/
hr=CoCreateInstance(CLSID_MPEG1Splitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pmpegSplitter);
CheckFailure(hr);
hr=CoCreateInstance(CLSID_CMpegVideoCodec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pmviddecoder);
CheckFailure(hr);
hr=CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pSource);
CheckFailure(hr);
//STEP 2: Add the filters
pGraph->AddSourceFilter(L"C:\\Badday.avi", L"Source", &pSource);
pGraph->AddFilter(pmpegSplitter, NULL);
pGraph->AddFilter(pmviddecoder, NULL);
pGraph->AddFilter(pvidrenderer, NULL);
//STEP 3: Query pins for connction
//1. find source output
hr = GetUnconnectedPin(pSource, PINDIR_OUTPUT, &OutPin);
//2. find mpegSplitter input
hr = GetUnconnectedPin(pmpegSplitter, PINDIR_INPUT, &InPin);
//connect 1 & 2
hr = pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
//3. find mpegSplitter output
// hr = GetUnconnectedPin(pmpegSplitter, PINDIR_OUTPUT, &OutPin);
IEnumPins *pEnum = 0;
IEnumMediaTypes *pmedia=NULL;
AM_MEDIA_TYPE *pmt=NULL;
hr = pmpegSplitter->EnumPins(&pEnum);
while (pEnum->Next(1, &OutPin, NULL) == S_OK)
{
// hr=OutPin->ConnectionMediaType(pmt);
hr=OutPin->EnumMediaTypes(&pmedia);
hr=pmedia->Next(1, &pmt, NULL);
PIN_DIRECTION ThisPinDir;
OutPin->QueryDirection(&ThisPinDir);
if (ThisPinDir == PINDIR_OUTPUT)
{
if(pmt->majortype == MEDIATYPE_Video)
{
pEnum->Release();
pmedia->Release();
break;
}
}
}
//4. find mpeg video decoder input
hr = GetUnconnectedPin(pmviddecoder, PINDIR_INPUT, &InPin);
//connect 3 & 4
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
//5. find mpeg video decoder output
hr = GetUnconnectedPin(pmviddecoder, PINDIR_OUTPUT, &OutPin);
//6. find video renderer input
hr = GetUnconnectedPin(pvidrenderer, PINDIR_INPUT, &InPin);
//connect 5 & 6
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
//STEP 4: Run the graph
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
}
//STEP : Release all resources
pGraph->Release();
pControl->Release();
pEvent->Release();
pSource->Release();
pmpegSplitter->Release();
pmviddecoder->Release();
pvidrenderer->Release();
CoUninitialize();
}
/******************************************************************/
HRESULT GetUnconnectedPin(
IBaseFilter *pFilter, // Pointer to the filter.
PIN_DIRECTION PinDir, // Direction of the pin to find.
IPin **ppPin) // Receives a pointer to the pin.
{
*ppPin = 0;
IEnumPins *pEnum = 0;
IPin *pPin = 0;
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr))
{
return hr;
}
while (pEnum->Next(1, &pPin, NULL) == S_OK)
{
PIN_DIRECTION ThisPinDir;
pPin->QueryDirection(&ThisPinDir);
if (ThisPinDir == PinDir)
{
IPin *pTmp = 0;
hr = pPin->ConnectedTo(&pTmp);
if (SUCCEEDED(hr)) // Already connected, not the pin we want.
{
pTmp->Release();
}
else // Unconnected, this is the pin we want.
{
pEnum->Release();
*ppPin = pPin;
return S_OK;
}
}
pPin->Release();
}
pEnum->Release();
// Did not find a matching pin.
return E_FAIL;
}
/******************************************************************/
void CheckFailure(HRESULT hr)
{
if(FAILED(hr))
exit(0);
}
|
|
|
|
|
Hi,
AVI and MPEG are different formats and you can not conclude the contents of a file with it's extension.
Considering video only, an MPEG-1 filter graph will *always* look like the following:
MPEG-1 File Source --> MPEG-1 Stream Splitter --> MPEG Video Decoder --> Video Renderer
An AVI filter graph will look *something* like this:
AVI File Source --> AVI Splitter --> AVI Decompresser --> Video Renderer
Now, the AVI decompressor component depends on the type of compression. If the file is in DivX format, a DivX decompressor would be inserted.
Since you are using an MPEG-1 splitter, I will assume you are rendering an MPEG.
The exception occurs because “pvidrenderer” has not been initialized. I will assume you’ve tried to initialize it, but have passed an incorrect variable’s name, because the following line does not make any sense:
hr=CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pSource);
Replace it with:
hr=CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pvidrenderer);
I am sending you a cleaner version of your code (with unnecessary code commented out).
Good luck!
|
|
|
|
|
Hi,
I use on my application the IVideoWindow interface but I want to change the code to use the Video Mixing Renderer filter. How can I switch on the full screen mode ?
Thanks,
Gabriel
|
|
|
|
|
From the SDK:
"The IVideoWindow interface sets properties on the video window. Applications can use it to set the window owner, the position and dimensions of the window, and other properties.
Note The IVMRWindowlessControl or IVMRWindowlessControl9 interface is now preferred over IVideoWindow. For more information, see Using Windowless Mode."
|
|
|
|
|
e:\down\codeproject\directshowvmr9_src\Form1.h(148) : error C2440: 'type cast' : cannot convert from 'System::EventHandler __gc *' to 'byte *'
Cannot convert a managed type to an unmanaged type
e:\down\codeproject\directshowvmr9_src\Form1.h(148) : error C3867: 'DirectShowVMR9::Form1::trackBarX1_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarX1_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(148) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(167) : error C3867: 'DirectShowVMR9::Form1::trackBarY1_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarY1_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(167) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(187) : error C3867: 'DirectShowVMR9::Form1::trackBarW1_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarW1_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(187) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(207) : error C3867: 'DirectShowVMR9::Form1::trackBarH1_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarH1_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(207) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(227) : error C3867: 'DirectShowVMR9::Form1::trackBarA1_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarA1_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(227) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(271) : error C3867: 'DirectShowVMR9::Form1::buttonStop_Click': function call missing argument list; use '&DirectShowVMR9::Form1::buttonStop_Click' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(271) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(282) : error C3867: 'DirectShowVMR9::Form1::buttonClose_Click': function call missing argument list; use '&DirectShowVMR9::Form1::buttonClose_Click' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(282) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(293) : error C3867: 'DirectShowVMR9::Form1::buttonPlay_Click': function call missing argument list; use '&DirectShowVMR9::Form1::buttonPlay_Click' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(293) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(303) : error C3867: 'DirectShowVMR9::Form1::buttonOpen_Click': function call missing argument list; use '&DirectShowVMR9::Form1::buttonOpen_Click' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(303) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(313) : error C3867: 'DirectShowVMR9::Form1::buttonPause_Click': function call missing argument list; use '&DirectShowVMR9::Form1::buttonPause_Click' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(313) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(325) : error C3867: 'DirectShowVMR9::Form1::trackBarA2_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarA2_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(325) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(345) : error C3867: 'DirectShowVMR9::Form1::trackBarH2_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarH2_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(345) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(365) : error C3867: 'DirectShowVMR9::Form1::trackBarW2_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarW2_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(365) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(384) : error C3867: 'DirectShowVMR9::Form1::trackBarY2_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarY2_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(384) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(403) : error C3867: 'DirectShowVMR9::Form1::trackBarX2_Scroll': function call missing argument list; use '&DirectShowVMR9::Form1::trackBarX2_Scroll' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(403) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
e:\down\codeproject\directshowvmr9_src\Form1.h(456) : error C3867: 'DirectShowVMR9::Form1::Form1_Load': function call missing argument list; use '&DirectShowVMR9::Form1::Form1_Load' to create a pointer to member
e:\down\codeproject\directshowvmr9_src\Form1.h(456) : error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s)
生成日志保存在“file://e:\down\codeproject\DirectShowVMR9_src\Debug\BuildLog.htm”
|
|
|
|
|
hi sameer,
Gr8 work man.
Can these interfaces b useful to me in mixing the text with video(like displaying subtitles). Can u suggest me some idea regarding this.
..JK
|
|
|
|
|
Thank you.
Well, first you draw your desired text on a bitmap. Then you can use the IVMRMixerBitmap9 Interface to blend that bitmap on any video.
The DirectX9 SDK has a good sample regarding this, it can be found in the following location:
(SDK root)\Samples\C++\DirectShow\VMR9\Text
An alternative solution can be found here:
http://www.gdcl.co.uk/overlay.htm[^]
Good luck!
|
|
|
|
|
W Salaam!
There aren't many DirectShow resources and the two you've mentioned have been the best I've been through. You must also walk-through the (simple) samples provided in the DirectX SDK. Thankfully, a kind person has made available a comprehensive list of DirectShow resources:
http://tmhare.mvps.org/links.htm[^]
|
|
|
|
|
Thanks for posting the great sample. It will be a good resource to learn from. Do you have a blog?
Ron
|
|
|
|
|
Thank you. No, I'm sorry, but I do not have a blog.
|
|
|
|
|
ingnore this
OnlythruGrace
|
|
|
|
|
Oh, I forgot. After I am done I would like to capture the rendered video to a file.
Do the VMR7 or VMR9 have output pins. Or does it require geting the DDraw surface and pull the video from there.
If so how do you keep the audio sinked.
I want to be able to edit just a section one of the embedded video streams, without having to reprocess the entire video.
So I need to capture, cut, reinsert and splice.
Peter
check out the liitle people att http://curems.no-ip.org/grace.html
OnlythruGrace
|
|
|
|
|
This looks like the Blender sample that some with the SDK.
I tried to compile that and got stuck with it not being able to open some 64 bit lib file. When I tweaked it so it could open. I got another error message saying I had a conflict between 32 and 64 bit modes.
I am sure I just did set up the paths corredctly.
With you code I am getting compiler errors with all the System::EventHandler calls.
when I comment these out just to see if it will run. I get a cannot open input file 'ddraw.dll' linker error LNK1181.
Any clues?
I have managed to implement most of this in VMR7 from some windowed sample I made windowless. Since I managed to get all the paths right on that I don't think it will take me much to convert to VMR9.
I am looking to make a production system so I am not certain that I even want VMR9 because it can't use the video port manager. I thaough this might help speed things up if the graphic card could do some decoding, incodeing and other filtering. All this is for a client.
For my own interest I have made some green screen video with C## and dot .NET framework. It is nice but no of my friends or prospective viewers want to download and install .NET on their home computers.
That is what brought me to doing it in C++. I have a free copy of C++ express. When It loadied your demo software it did some conversions, which weren't exactly correct.
Any help would uh.. Help.
Thanks
OnlythruGrace
|
|
|
|
|
hi,
I would like to know,
what I have to do, to play a video in loop.
I mean, how can I detect the end and restart again?
Thanx 4 all, your code has helped me so much.
|
|
|
|
|
Hello !
Thanks for your very useful articles !
Using this method, can you assume that both video are synchronized ? (using same encoding properties for both videos) ?
Thanks in advance
Thomas.P
|
|
|
|
|
Thank you for the encouragement.
Two videos, encoded with the same properties, may not always be synchronized when played, especially when the compression level is high (like MPEG4). Play the videos in Media Player and check out it's quality in the properties section: make sure there is no jitter/frames dropped while playback.
If the playback is smooth: zero jitter/dropped frames, then you may assume both videos are synchronized when mixed, i.e. Frame 214 of a video will be rendered on top of Frame 214 of another video.
I have not tried such an experiment, so please let me know of your results, thank you.
|
|
|
|
|
Hi,
This is a great article! Is there a way to stream the result? I want to add a compressor filter. After the video is compressed (for example with divx), I want to stream it over the internet.
Is this possible? If so, can you explain me how?
Thanks!
Geert
Want to spread the newest version of your software automatically for free? Use Updater!
Visit my website: www.gvhsoftware.org
|
|
|
|
|
Hi,
First of all, thank you! Well, VMR9 is a 'renderer' filter and not a 'transform' filter, so the results cannot be streamed to disk (or over the net).
But, VMR9 allows you to capture a bitmap of the mixed videos. Maybe if you capture a bitmap of every frame and convert it to video, then you can stream it over the internet.
This is what Screen Capture utilities do to save a screen (or portions of it) as AVI/WMV. A sample is available here[^].
Further information may be found here[^], under the "Can I create a movie from bitmaps?" section.
[Off the topic: I visited your website, it's impressive!]
-- modified at 18:09 Monday 7th August, 2006
|
|
|
|
|
Thank you for your (speedy) reply!
The only thing I want is to load video from a webcam, compress it and send it over the net (we can use LAN, so the filesize can be pretty big).
I used VMR before, so I was able to show the video in a preview window with the divx logo. I thought, the only thing left now is streaming. That was easier said than done.
Do you think I need to use VMR to implement what I want, or is the IVideoWindow enough?
Again, thank you for your help! It is very hard to find some good tutorials about DirectShow (and streaming) on the internet.
Geert
Want to spread the newest version of your software automatically for free? Use Updater!
Visit my website: www.gvhsoftware.org
|
|
|
|
|
I found your proposition interesting, surfed the net to find solutions. You are correct, finding streaming tutorials are not easy.
VMR or IVideoWindow will not help, as they render to the screen. You need to render to the internet, over TCP/IP perhaps. To accomplish this, you will need to replace the VideoRenderer filter with a filter that renders to the internet. Such a filter is not available in the DX SDK, and writing such a filter is not easy, but there are 3rd party solutions like:
http://www.leadtools.com/SDK/Multimedia/video-conferencing-sdk.htm[^]
|
|
|
|
|
Hi Sameer Ahmed,
Thanks for your research and interest. However, I cannot use any commercial products since it is a product for my school.
There should be a way to send data in a compressed way without expensive commercial products. I will search for the solution on the internet. When I find it (and I remember to do it), I will post the solution here.
Thanks again for your help so far!
Best regards,
Geert
Want to spread the newest version of your software automatically for free? Use Updater!
Visit my website: www.gvhsoftware.org
|
|
|
|
|
when i was running a program using dshow.h , an error in strmif.h (Generated IDL header file for streams interfaces) which is included in dshow.h occured saying missing semicolon at line 1024 , but i didn't find any error , i don't know what to do ? can any one send me a working strmif.h file ?
|
|
|
|
|
Open your project in Visual Studio.
Click the "Tools" and there the "Options" menu. In the now opened dialog click the "Directories" tab. You can see the include directories. Move the include directory of your DirectX to the top of the list. You should do the same with the lib files (see right combo box).
Your list should be something like:
Include FIles
C:\Program Files\Microsoft DirectX 9.0 SDK\Include
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE
Librray Files
C:\Program Files\Microsoft DirectX 9.0 SDK\Lib
C:\Program Files\Microsoft Visual Studio\VC98\LIB
C:\Program Files\Microsoft Visual Studio\VC98\MFC\LIB
Finally, perform a COMPLETE rebuild of your project.
|
|
|
|
|
could any one copy and paste the code for dshow.h here or attach dshow.h
|
|
|
|
|