快乐自己方便他人,以编写程序为乐趣(MIPS,ARM7/9/系列MCU,8051系列MCU,AVR系列MCU,C/C++/C#/VB/VBnet),以收集整理为主,原创为无
查看文章 |
转帖:DirectShow做一个简单的媒体文件播放器
2008年05月30日 星期五 14:55
作者:liguisen 附:CDXGraph.h和CDXGraph.cpp
//
// CDXGraph.h
//
#ifndef __H_CDXGraph__
#define __H_CDXGraph__
// Filter graph notification to the specified window
#define WM_GRAPHNOTIFY (WM_USER+20)
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"
#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)
{
if (!mGraph)
{
if (SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&mGraph)))
{
AddToObjectTable();
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;
}
RemoveFromObjectTable();
if (mGraph)
{
mGraph->Release();
mGraph = NULL;
}
}
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);
}
}
bool CDXGraph::SetDisplayWindow(HWND inWindow)
{
if (mVideoWindow)
{
// long lVisible;
// mVideoWindow->get_Visible(&lVisible);
// Hide the video window first
mVideoWindow->put_Visible(OAFALSE);
mVideoWindow->put_Owner((OAHWND)inWindow);
RECT windowRect;
::GetClientRect(inWindow, &windowRect);
mVideoWindow->put_Left(0);
mVideoWindow->put_Top(0);
mVideoWindow->put_Width(windowRect.right - windowRect.left);
mVideoWindow->put_Height(windowRect.bottom - windowRect.top);
mVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
mVideoWindow->put_MessageDrain((OAHWND) inWindow);
// Restore the video window
if (inWindow != NULL)
{
// mVideoWindow->put_Visible(lVisible);
mVideoWindow->put_Visible(OATRUE);
}
else
{
mVideoWindow->put_Visible(OAFALSE);
}
return true;
}
return false;
}
bool CDXGraph::ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight)
{
if (mVideoWindow)
{
long lVisible = OATRUE;
mVideoWindow->get_Visible(&lVisible);
// Hide the video window first
mVideoWindow->put_Visible(OAFALSE);
mVideoWindow->put_Left(inLeft);
mVideoWindow->put_Top(inTop);
mVideoWindow->put_Width(inWidth);
mVideoWindow->put_Height(inHeight);
// Restore the video window
mVideoWindow->put_Visible(lVisible);
return true;
}
return false;
}
bool CDXGraph::SetNotifyWindow(HWND inWindow)
{
if (mEvent)
{
mEvent->SetNotifyWindow((OAHWND)inWindow, WM_GRAPHNOTIFY, 0);
return true;
}
return false;
}
void CDXGraph::HandleEvent(WPARAM inWParam, LPARAM inLParam)
{
if (mEvent)
{
LONG eventCode = 0, eventParam1 = 0, eventParam2 = 0;
while (SUCCEEDED(mEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0)))
{
mEvent->FreeEventParams(eventCode, eventParam1, eventParam2);
switch (eventCode)
{
case EC_COMPLETE:
break;
case EC_USERABORT:
case EC_ERRORABORT:
break;
default:
break;
}
}
}
}
bool CDXGraph::Run(void)
{
if (mGraph && mMediaControl)
{
if (!IsRunning())
{
if (SUCCEEDED(mMediaControl->Run()))
{
return true;
}
}
else
{
return true;
}
}
return false;
}
bool CDXGraph::Stop(void)
{
if (mGraph && mMediaControl)
{
if (!IsStopped())
{
if (SUCCEEDED(mMediaControl->Stop()))
{
return true;
}
}
else
{
return true;
}
}
return false;
}
bool CDXGraph::Pause(void)
{
if (mGraph && mMediaControl)
{
if (!IsPaused())
{
if (SUCCEEDED(mMediaControl->Pause()))
{
return true;
}
}
else
{
return true;
}
}
return false;
}
bool CDXGraph::IsRunning(void)
{
if (mGraph && mMediaControl)
{
OAFilterState state = State_Stopped;
if (SUCCEEDED(mMediaControl->GetState(10, &state)))
{
return state == State_Running;
}
}
return false;
}
bool CDXGraph::IsStopped(void)
{
if (mGraph && mMediaControl)
{
OAFilterState state = State_Stopped;
if (SUCCEEDED(mMediaControl->GetState(10, &state)))
{
return state == State_Stopped;
}
}
return false;
}
bool CDXGraph::IsPaused(void)
{
if (mGraph && mMediaControl)
{
OAFilterState state = State_Stopped;
if (SUCCEEDED(mMediaControl->GetState(10, &state)))
{
return state == State_Paused;
}
}
return false;
}
|
最近读者: