if i now call SetRate(0.5) e.g. only the first video to the filter graph
plays with 50% all others continue with normal speed.
Why is this?
Please help me!!
What does your graph look like?
How are you obtaining IMediaSeeking?
Where is your code snippet?
What types of files are you playing?
See the tips below for writing an effective post.
--
Please read this before replying:
1. Dshow & posting help: http://tmhare.mvps.org/help.htm
2. Trim & respond inline (please don't top post or snip everything)
3. Benefit others: follow up if you are helped or you found a solution
i created an instance of the Filter Graph Manager
created an instance of the VMR9 filter
added the VMR9 filter to the Graph Manager
got a pointer to the IVMRFilterConfig9 interface
made sure VMR9 is in windowless mode
set the number of streams
got a pointer to the IVMRWindowlessControl9 interface
specified the container window that the video should be clipped to
queried interface for IVMRMixerControl, IMediaControl and IMediaEvent
then i open the files, one after anoterher like this
hr = pGraph->RenderFile(fileName, NULL);
hr = pControl->StopWhenReady();
hr = pMix->SetAlpha(numStreams, 0.5);
pControl->Run() starts all movies at the same time,
BUT: hr = g_pSeek->SetRate(0.25); only works with the first video loaded
into the graph,
all others play
with normal speed
one (or maybe both of)
g_pSeek->GetPositions(&g_loopStartPos,&g_loopEndPos);
g_pSeek->SetPositions(&g_loopStartPos,AM_SEEKING_AbsolutePositioning,
&g_loopEndPos,AM_SEEKING_AbsolutePositioning);
also does not work, when loaded more than one video into the graph
Please help me finding out why g_pSeek does not work for multiple videos at
the same time ?
"The March Hare [MVP]" <ph...@ndsm.maps> schrieb im Newsbeitrag
news:fp6np8518bjx$.1lsmxkhldh1h9$.dlg@40tude.net...
> oh, i already wrote that information twice, and i even didnt get any answer.
Why didn't you say so in your original post?
> maybe now i first got some attention here...
Not from me unless you can follow the simple requests below.
The problem with top posting is that you have ignored the most important
question I asked as well as at least one other one. Easy to do when you
top post.
> Please help me finding out why g_pSeek does not work for
> multiple videos at the same time ?
If I am not mistaken, the VMR9 passes the seeking command
upstream only from pin 0. The usage scenario for the VMR(9)
is to render the main stream on pin 0 and substreams on all
other pins, all coming from the same source, in which case
everything would seek as expected. With multiple independent
sources, only the first one will seek. You can work around
this by enumerating the VMR's input pins and seeking on each
pin's upstream peer (skipping pin 0 since it's already taken
care of by the VMR itself).
--
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
thank you so much !!! im shure this will help, dont know exactly now how to
solve this, but the information itself saves my day :)
thanks a lot !
"Alessandro Angeli" <nob...@nowhere.in.the.net> schrieb im Newsbeitrag
news:eRAAK7YF...@TK2MSFTNGP02.phx.gbl...
at the moment i render the movies this way:
// Open the main movie
hr = pGraph->RenderFile(fileName, NULL);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during RenderFile
for pGraph ( Original Video File )");
}
else{
hr = pControl->StopWhenReady();
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
StopWhenReady for pControl ( Original Video File )");
}
hr = pMix->SetAlpha(numStreams, 1.0);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during SetAlpha
for pMix ( Original Video File )");
}
numStreams ++;
}
// Open the xy Avi File
hr =
pGraph->RenderFile(L"E:\\Projekte\\Firma\\Projekt_ET_Analysis\\Samples\\xyAviFile.avi",
NULL);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during RenderFile
for pGraph ( xyAviFile )");
rBxyView.EnableWindow(false);
}
else{
hr = pControl->StopWhenReady();
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
StopWhenReady for pControl ( xyAviFile )");
}
hr = pMix->SetAlpha(numStreams, 0.5);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during SetAlpha
for pMix ( xyAviFile )");
}
numStreams++;
rBxyView.EnableWindow(true);
rBxyView.SetCheck(true);
}
// Open the sarcades Avi File
hr =
pGraph->RenderFile(L"E:\\Projekte\\Firma\\Projekt_ET_Analysis\\Samples\\sarcadesAviFile.avi",
NULL);
if (FAILED(hr))
{
rBsarcades.EnableWindow(false);
rTaStatusPlayer.SetWindowText("Status: An error occured during RenderFile
for pGraph ( sarcadesAviFile )");
}
else{
hr = pControl->StopWhenReady();
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
StopWhenReady for pControl ( sarcadesAviFile )");
}
hr = pMix->SetAlpha(numStreams, 0.5);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during SetAlpha
for pMix ( sarcadesAviFile )");
}
numStreams++;
rBsarcades.EnableWindow(true);
rBsarcades.SetCheck(true);
}
// Open the heatmap Avi File
hr =
pGraph->RenderFile(L"E:\\Projekte\\Firma\\Projekt_ET_Analysis\\Samples\\heatmapAviFile.avi",
NULL);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during RenderFile
for pGraph ( heatmapAviFile )");
rBheatmap.EnableWindow(false);
}
else{
hr = pControl->StopWhenReady();
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
StopWhenReady for pControl ( heatmapAviFile )");
}
hr = pMix->SetAlpha(numStreams, 0.5);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during SetAlpha
for pMix ( heatmapAviFile )");
}
numStreams++;
rBheatmap.EnableWindow(true);
rBheatmap.SetCheck(true);
}
// Open the timebubbles Avi File
hr =
pGraph->RenderFile(L"E:\\Projekte\\Firma\\Projekt_ET_Analysis\\Samples\\bubblesAviFile.avi",
NULL);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during RenderFile
for pGraph ( bubblesAviFile )");
rBtimeBubbles.EnableWindow(false);
}
else{
hr = pControl->StopWhenReady();
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
StopWhenReady for pControl ( bubblesAviFile )");
}
hr = pMix->SetAlpha(numStreams, 0.5);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during SetAlpha
for pMix ( bubblesAviFile )");
}
numStreams++;
rBtimeBubbles.EnableWindow(true);
rBtimeBubbles.SetCheck(true);
}
hr = pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *)&pVideo);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
QueryInterface for IVideoWindow");
}
hr = pGraph->QueryInterface(IID_IMediaSeeking, (void**)&g_pSeek);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
QueryInterface for IMediaSeeking");
}
where do i connect now these pins ??? (because, pControl->Run() - runs all
videos at once)
only g_pSeek->SetRate(0.5) - only sets the rate for the first video.
as already mentioned i have no samples folders in my sdk, so is it possible
someone helps me to fix that problem ?
"Alessandro Angeli" <nob...@nowhere.in.the.net> schrieb im Newsbeitrag
news:eRAAK7YF...@TK2MSFTNGP02.phx.gbl...
> ok its me once again...
> how exactly can i do that ?
[...]
I guess pMix is a reference to IVMRMixerControl9? If it is,
QI that for IBaseFilter, otherwise call pGraph->EnumFilter()
and enumerate the filters until one of then returns
CLSID_VideoMixingRenderer9 from IBaseFilter::GetClassID().
Then call IBaseFilter::EnumPins() to enumerate the pins. Get
each pin's peer using IPin::ConnectedTo() and query it for
IMediaSeeking.
i render all 5 videos after another,
now i run my app.
it plays all videos on the right spot of the main window (all overlapped,
appear as 1 video)
but no setrate() possible (only the first video continues 50% speed, all
others stop, and begin at 0 playing normal speed)
now i remove following lines of code:
// CONFIGURE the VMR9
// MEDIA SIZE
LONG Width;
LONG Height;
LONG ARWidth;
LONG ARHeight;
hr = pWC->GetNativeVideoSize(&Width, &Height, &ARWidth, &ARHeight);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
GetNativeVideoSize for pWC");
}
RECT mediaRect;
mediaRect.left = 0;
mediaRect.top = 0;
mediaRect.right = Width;
mediaRect.bottom = Height;
RECT wndRect;
wndRect.left = 10;
wndRect.top = 10;
wndRect.right = 730;
wndRect.bottom = 586;
pWC->SetVideoPosition(&mediaRect, &wndRect);
if (FAILED(hr))
{
rTaStatusPlayer.SetWindowText("Status: An error occured during
SetVideoPosition for pWC");
}
the result is: i have 5 different windows in addirion to my mainwindow, each
with 1 video in it.
but now, when i use setrate, all videos play with 50% speed, and also my
loop works for all videos,
but i have 5 seperate windows, and i want to clip them to my main window as
shown above...
then it does not work anymore...
My problem is, i dont know exactly where to enumerate for pins, and maybe
also not, how to render more videos at the same time
because, the Multiplayer Example calls BuildAndRender:
There are following steps:
// first, check that file exists
// create graph
// create and add VMR9
// configure VMR9
// if wizard is provided, set VMR to the renderless code and attach to the
wizard
// set VMR to the renderless mode
// try to render media source
*1)
// ok, all is rendered, now get MediaControl, MediaSeeking and continue
where exactly should i render more videos in my application?
at *1) render media for every movie (the way i do it right now)
or do all steps each time i like to add a new movie ?
thank you all for attention and helping me.
"Alessandro Angeli" <nob...@nowhere.in.the.net> schrieb im Newsbeitrag
news:%23FxFMPy...@TK2MSFTNGP04.phx.gbl...
> it plays all videos on the right spot of the main window
> (all overlapped, appear as 1 video)
You are not positioning the streams with
IVMRMixerControl9::SetOutputRect().
> but no setrate() possible (only the first video continues
> 50% speed, all others stop, and begin at 0 playing normal
> speed)
You are still not seeking each stream individually.
> the result is: i have 5 different windows in addirion to
> my mainwindow, each with 1 video in it.
> but now, when i use setrate, all videos play with 50%
> speed, and also my loop works for all videos,
That's because now you have 1 renderer per stream instead of
1 renderer for all streams.
> but i have 5 seperate windows, and i want to clip them to
> my main window as shown above...
Nothing prevents you from making the separate windows
children of your main window and positioning them correctly.
To build the graph:
1. create the graph
2. create the VMR9
3. add the VMR9 to the graph
4. (optional) set the rendering mode
(IVMRFilterConfig9::SetRenderingMode(), defaults to
VMR9Mode_Windowed)
5. activate mixing mode (by setting the number of streams,
IVMRFilterConfig9::SetNumberOfStreams())
6. (optional) set the rendering prefs
(IVMRFilterConfig9::SetRenderingPrefs())
7. connect the inputs (e.g. call IGraphBuilder::RenderFile()
several times)
8. position the streams (IVMRMixerControl9::SetOutputRect())
9. (optional) configure the mixer (IVMRMixerControl9)
To seek:
1. pause the graph and wait for the graph to transition to
the paused state
2. call IMediaSeeking::SetRate() on the graph
3. call IBaseFilter::EnumPins() on the VMR9
4. call IEnumPins::Skip(1) (you do not need to seek pin 0)
5. call IEnumPins::Next(1,,NULL) until it returns S_FALSE
6. for each pin returned by IEnumPins::Next(), get its peer
(IPin::ConnectedTo())
7. if the peer is not NULL (that it IPin::ConnectedTo()
returned S_OK instead of VFW_E_NOT_CONNECTED), get
IMediaSeeking from the peer
8. if the peer supports IMediaSeeking, call
IMediaSeeking::SetRate() on it
9. run the graph
> You are not positioning the streams with
> IVMRMixerControl9::SetOutputRect().
I was positioning my streams with:
pConfig->SetRenderingMode(VMR9Mode_Windowless);
pVmr->QueryInterface(IID_IVMRWindowlessControl9, (void**)&pWC);
pWC->SetVideoClippingWindow(g_hDlg);
pWC->GetNativeVideoSize(&Width, &Height, &ARWidth, &ARHeight);
pWC->SetVideoPosition(&mediaRect, &wndRect);
My Problem with IVMRMixerControl9::SetOutputRect() according to your 9
steps, is
that the movies are still in a seperate window, but i want the movies played
in my main window.
So is it possible to clip the movies on the main window with
IVMRMixerControl9::SetOutputRect()
or was my way to show the movies on the main window already ok ?
> To seek:
> 1. pause the graph and wait for the graph to transition to the paused
> state
> 2. call IMediaSeeking::SetRate() on the graph
> 3. call IBaseFilter::EnumPins() on the VMR9
> 4. call IEnumPins::Skip(1) (you do not need to seek pin 0)
> 5. call IEnumPins::Next(1,,NULL) until it returns S_FALSE
> 6. for each pin returned by IEnumPins::Next(), get its peer
> (IPin::ConnectedTo())
> 7. if the peer is not NULL (that it IPin::ConnectedTo() returned S_OK
> instead of VFW_E_NOT_CONNECTED), get IMediaSeeking from the peer
> 8. if the peer supports IMediaSeeking, call IMediaSeeking::SetRate() on it
> 9. run the graph
Thank you, that's what i am looking for.
i'm still about to implement this, thank you so far !
Peter
Thats what i've got now,
//1
HRESULT hr = S_OK;
OAFilterState state;
hr = pControl->Pause();
state = State_Running;
while( State_Paused != state && SUCCEEDED(hr))
{
hr = pControl->GetState(100, &state);
Sleep(100);
}
//2
hr = g_pSeek->SetRate(0.5);
//3
hr = pVmr->EnumPins( &pEnum );
//4
hr = pEnum->Skip(1);
//5
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
IPin *pConnectedPin;
//6
hr = pPin->ConnectedTo( &pConnectedPin );
//7
if( SUCCEEDED(hr) && pConnectedPin )
{
//8
DWORD pCapabilities = AM_SEEKING_CanSeekForwards;
hr = g_pSeek->GetCapabilities( &pCapabilities );
if(SUCCEEDED(hr))
{
AfxMessageBox("Can Seek Forwards");
hr = g_pSeek->SetRate(0.5);
}
}
}
//9
hr = pControl->Run();
Thats what i got so far, but still the same result (only pin0 with 50%
speed - all others 100% )
i do get a AfxMessageBox("Can Seek Forwards") for every movie i have, but it
dos not play 50%
what have i done wrong ?
>> You are not positioning the streams with
>> IVMRMixerControl9::SetOutputRect().
>
> I was positioning my streams with:
>
> pConfig->SetRenderingMode(VMR9Mode_Windowless);
> pVmr->QueryInterface(IID_IVMRWindowlessControl9,
> (void**)&pWC); pWC->SetVideoClippingWindow(g_hDlg);
> pWC->GetNativeVideoSize(&Width, &Height, &ARWidth,
> &ARHeight); pWC->SetVideoPosition(&mediaRect, &wndRect);
>
> My Problem with IVMRMixerControl9::SetOutputRect()
> according to your 9 steps, is
> that the movies are still in a seperate window, but i
> want the movies played in my main window.
>
> So is it possible to clip the movies on the main window
> with IVMRMixerControl9::SetOutputRect()
> or was my way to show the movies on the main window
> already ok ?
IVMRWindowlessControl9 controls the position of the
composited image while IVMRMixerControl9 controls the
position of each stream in the composition rectangle.
You need to make a choice:
1. render all streams using one VMR9 (requires manual
seeking, the streams must be positioned in the single VMR9
using IVMRMixerControl9)
2. render each stream using its own VMR9 (seeking works by
itself, no need to position the streams inside their own
VMR9s)
A. use the VMR9 in windowless mode (the VMR9's composited
image is positioned using IVMRWindowlessControl9)
B. use the VMR9 in windowed mode (the VMR9's composited
image is positioned using IVideoWindow)
It looks to me like you started the thread asking about 1A
while you are actually doing 2B (if you have windows, you
are not using windowless mode, at least not on any VMR9
instance but the first one).
> You need to make a choice:
>
> 1. render all streams using one VMR9 (requires manual seeking, the streams
> must be positioned in the single VMR9 using IVMRMixerControl9)
>
> 2. render each stream using its own VMR9 (seeking works by itself, no need
> to position the streams inside their own VMR9s)
>
> A. use the VMR9 in windowless mode (the VMR9's composited image is
> positioned using IVMRWindowlessControl9)
>
> B. use the VMR9 in windowed mode (the VMR9's composited image is
> positioned using IVideoWindow)
>
> It looks to me like you started the thread asking about 1A while you are
> actually doing 2B (if you have windows, you are not using windowless mode,
> at least not on any VMR9 instance but the first one).
The problem is, i did not know what to do exactly, i only read the
documentation, and tried to build my own code.
After implementing, i realized, that it did not work as i supposed.
There i was making Number 1A - which still does not work
Then you have gave me a hint (30.10.2007) how to solve the problem
There it is still Number 1 because you said:
> 7. connect the inputs (e.g. call IGraphBuilder::RenderFile() several
> times)
Thats what i did before and still do.
but my result now (only by calling PLAY() ) is that i have my
mainapp(mediaplayer)
and after pressing play, the movie openes in a new seperate window
the only difference is, in my old version i had a new window for each movie,
now i have only one new window playing all movies.
Now while i was implementing your way, i was asking, how to, not open the
movies
in a new window, but playing them in my mainapp(mediaplayer)
Maybe i missunderstood your way, or did something wrong, so the result does
not
fit with your thoughts. Thats why i was asking again :(
At the moment i don't care how to reach my goal, essential i will reach in
some day...
>> 7. if the peer is not NULL (that it IPin::ConnectedTo()
>> returned S_OK instead of VFW_E_NOT_CONNECTED), get
>> IMediaSeeking from the peer 8. if the peer supports
>> IMediaSeeking, call
>> IMediaSeeking::SetRate() on it
[...]
> DWORD pCapabilities = AM_SEEKING_CanSeekForwards;
> hr = g_pSeek->GetCapabilities( &pCapabilities );
> if(SUCCEEDED(hr))
> {
>
> AfxMessageBox("Can Seek Forwards");
> hr = g_pSeek->SetRate(0.5);
>
> }
[...]
> Thats what i got so far, but still the same result (only
> pin0 with 50% speed - all others 100% )
> i do get a AfxMessageBox("Can Seek Forwards") for every
> movie i have, but it dos not play 50%
> what have i done wrong ?
You are skipping step #7:
pConnectedPin->QueryInterface(IID_IMediaSeeking,&pPinSeeking);
pPinSeeking->SetRate();
(you need to check for errors of course).
Also, there is no point in calling GetCapabilities().
> You are skipping step #7:
>
> pConnectedPin->QueryInterface(IID_IMediaSeeking,&pPinSeeking);
> pPinSeeking->SetRate();
THANK YOU SO MUCH ... that was missing, now IT WORKS
i have now restored my old code, where i have rendered my videos,
and exchanged it with your steps 1-9 to build the graph with my old version
Without any changing (except your steps 1-9 to seek) it also works, all
movies played overlapped, and with 50% speed.
i feel awful about asking again, but now there is following effect.
After pressing the 50% button, video number 0 plays 50% immediatly,
all others continue normal speed for about 1 second, then they pause,
wait until video 0 gets to their position, and then all together play with
50%
Is this the normal way it works, or have i still find out some bugs in my
code ?
And thank you once again for helping me so far. I am very grateful.
Peter
> After pressing the 50% button, video number 0 plays 50%
> immediatly, all others continue normal speed for about 1
> second, then
> they pause, wait until video 0 gets to their position, and
> then all
> together play with 50%
>
> Is this the normal way it works, or have i still find out
> some bugs in my code ?
This is simply a hack, so it has some issues I overlooked.
Modify it this way:
- replace step 1 with:
1a. stop the graph (stopping is synchronous so no need to
wait)
1b. get the current position from the graph
(IMediaSeeking::GetCurrentPosition())
- replace step 8 with:
8a. set the current position on the peer
(IMediaSeeking::SetPositions(¤t,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning))
8b. change the rate on the peer
- replace step 9 with:
9a. run the graph
9b. if run returns S_FALSE, wait for the graph to enter the
running state (since now you are transitioning from stopped,
running may not be synchronous)
> And thank you once again for helping me so far. I am very
> grateful.
You're welcome.