//
// CDXGraph.h
//
#ifndef __H_CDXGraph__
#define __H_CDXGraph__
// Filter graph notification to the specified window
#define WM_GRAPHNOTIFY (WM_USER+20)
#include "Dshow.h"
#include "amstream.h"
#include "Qedit.h"
class CDXGraph
{
private:
IGraphBuilder * mGraph;
IMediaControl * mMediaControl;
IMediaEventEx * mEvent;
IBasicVideo * mBasicVideo;
IBasicAudio * mBasicAudio;
IVideoWindow * mVideoWindow;
IMediaSeeking * mSeeking;
DWORD mObjectTableEntry;
public:
CDXGraph();
virtual ~CDXGraph();
public:
virtual bool Create(void);
virtual void Release(void);
virtual bool Attach(IGraphBuilder * inGraphBuilder);
IGraphBuilder * GetGraph(void); // Not outstanding reference count
IMediaEventEx * GetEventHandle(void);
bool ConnectFilters(IPin * inOutputPin, IPin * inInputPin, const AM_MEDIA_TYPE * inMediaType = 0);
void DisconnectFilters(IPin * inOutputPin);
bool SetDisplayWindow(HWND inWindow);
bool SetNotifyWindow(HWND inWindow);
bool ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight);
void HandleEvent(WPARAM inWParam, LPARAM inLParam);
bool Run(void); // Control filter graph
bool Stop(void);
bool Pause(void);
bool IsRunning(void); // Filter graph status
bool IsStopped(void);
bool IsPaused(void);
bool SetFullScreen(BOOL inEnabled);
bool GetFullScreen(void);
// IMediaSeeking
bool GetCurrentPosition(double * outPosition);
bool GetStopPosition(double * outPosition);
bool SetCurrentPosition(double inPosition);
bool SetStartStopPosition(double inStart, double inStop);
bool GetDuration(double * outDuration);
bool SetPlaybackRate(double inRate);
// Attention: range from -10000 to 0, and 0 is FULL_VOLUME.
bool SetAudioVolume(long inVolume);
long GetAudioVolume(void);
// Attention: range from -10000(left) to 10000(right), and 0 is both.
bool SetAudioBalance(long inBalance);
long GetAudioBalance(void);
bool RenderFile(const char * inFile);
bool SnapshotBitmap(const char * outFile);
private:
void AddToObjectTable(void) ;
void RemoveFromObjectTable(void);
bool QueryInterfaces(void);
};
#endif // __H_CDXGraph__
//
// CDXGraph.cpp
//
#include "stdafx.h"
//#include "streams.h"
#include "CDXGraph.h"
#include "vfw.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////////////////
CDXGraph::CDXGraph()
{
mGraph = NULL;
mMediaControl = NULL;
mEvent = NULL;
mBasicVideo = NULL;
mBasicAudio = NULL;
mVideoWindow = NULL;
mSeeking = NULL;
mObjectTableEntry = 0;
}
CDXGraph::~CDXGraph()
{
Release();
}
bool CDXGraph::Create(void)
{
CoInitialize(NULL);
if (!mGraph)
{
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&mGraph);
if (SUCCEEDED(hr))
{
#ifdef _DEBUG
AddToObjectTable();
#endif
return QueryInterfaces();
}
mGraph = 0;
}
return false;
}
bool CDXGraph::QueryInterfaces(void)
{
if (mGraph)
{
HRESULT hr = NOERROR;
hr |= mGraph->QueryInterface(IID_IMediaControl, (void **)&mMediaControl);
hr |= mGraph->QueryInterface(IID_IMediaEventEx, (void **)&mEvent);
hr |= mGraph->QueryInterface(IID_IBasicVideo, (void **)&mBasicVideo);
hr |= mGraph->QueryInterface(IID_IBasicAudio, (void **)&mBasicAudio);
hr |= mGraph->QueryInterface(IID_IVideoWindow, (void **)&mVideoWindow);
hr |= mGraph->QueryInterface(IID_IMediaSeeking, (void **)&mSeeking);
if (mSeeking)
{
mSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
}
return SUCCEEDED(hr);
}
return false;
}
void CDXGraph::Release(void)
{
if (mSeeking)
{
mSeeking->Release();
mSeeking = NULL;
}
if (mMediaControl)
{
mMediaControl->Release();
mMediaControl = NULL;
}
if (mEvent)
{
mEvent->Release();
mEvent = NULL;
}
if (mBasicVideo)
{
mBasicVideo->Release();
mBasicVideo = NULL;
}
if (mBasicAudio)
{
mBasicAudio->Release();
mBasicAudio = NULL;
}
if (mVideoWindow)
{
mVideoWindow->put_Visible(OAFALSE);
mVideoWindow->put_MessageDrain((OAHWND)NULL);
mVideoWindow->put_Owner(OAHWND(0));
mVideoWindow->Release();
mVideoWindow = NULL;
}
#ifdef _DEBUG
RemoveFromObjectTable();
#endif
if (mGraph)
{
mGraph->Release();
mGraph = NULL;
}
CoUninitialize();
}
bool CDXGraph::Attach(IGraphBuilder * inGraphBuilder)
{
Release();
if (inGraphBuilder)
{
inGraphBuilder->AddRef();
mGraph = inGraphBuilder;
AddToObjectTable();
return QueryInterfaces();
}
return true;
}
IGraphBuilder * CDXGraph::GetGraph(void)
{
return mGraph;
}
IMediaEventEx * CDXGraph::GetEventHandle(void)
{
return mEvent;
}
// Connect filter from the upstream output pin to the downstream input pin
bool CDXGraph::ConnectFilters(IPin * inOutputPin, IPin * inInputPin,
const AM_MEDIA_TYPE * inMediaType)
{
if (mGraph && inOutputPin && inInputPin)
{
HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType);
return SUCCEEDED(hr) ? true : false;
}
return false;
}
void CDXGraph::DisconnectFilters(IPin * inOutputPin)
{
if (mGraph && inOutputPin)
{
HRESULT hr = mGraph->Disconnect(inOutputPin);
}
}