Waiting for the end of media
The previous sample showed how to playback a MPEG file. However, it used MessageBox to block execution. Using MessageBox is not so practical. In this page, I will show a way to block execution until the media file playback reaches an end. Please note that error handling codes are omitted to keep the sample code simple.
Waiting for an end
You can use WaitForCompletion in IMediaEvent, to wait for the media file to end. WaitForCompletion is a blocking method. The first argument of WaitForCompletion is a timeout value. For example, if you put "2" as the first argument, WaitForCompetion will block for maximum of 2 seconds. If you use "-1" as the first argument, WaitForCompletion will wait forever until the playback reaches an end.
Sample code
The following sample code shows how to use WaitForCompletion.
#include <stdio.h>
#include <dshow.h>
// change here
#define FILENAME L"c:\\DXSDK\\Samples\\Media\\butterfly.mpg"
int
main()
{
IGraphBuilder *pGraphBuilder;
IMediaControl *pMediaControl;
IMediaEvent *pMediaEvent;
long eventCode;
CoInitialize(NULL);
CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC,
IID_IGraphBuilder,
(LPVOID *)&pGraphBuilder);
pGraphBuilder->QueryInterface(IID_IMediaControl,
(LPVOID *)&pMediaControl);
pGraphBuilder->QueryInterface(IID_IMediaEvent,
(LPVOID *)&pMediaEvent);
pMediaControl->RenderFile(FILENAME);
pMediaControl->Run();
// The first argument is timeout value.
// If you change the "-1" part into "2",
// WaitForCompletion will timeout after 2 seconds.
pMediaEvent->WaitForCompletion(-1, &eventCode);
switch (eventCode) {
case 0:
printf("timeout\n");
break;
case EC_COMPLETE:
printf("complete\n");
break;
case EC_ERRORABORT:
printf("errorabort\n");
break;
case EC_USERABORT:
printf("userabort\n");
break;
}
pMediaControl->Release();
pGraphBuilder->Release();
CoUninitialize();
return 0;
}
WaitForCompletion is a blocking method. Therefore, if you want to do something else while playing the MPEG file, you would have to create a new thread.
You can also use GetState() in IMediaEvent instead of using WaitForCompletion. You can create a busy loop that lookup the state of the Graph using GetState().
Using a window event to notify the end of playback is another option. This might be the best way if you are using MFC, etc.