王朝网络
分享
 
 
 

使用directShow播放mpeg的基类

王朝vc·作者佚名  2006-01-09
宽屏版  字体: |||超大  

//

// 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);

}

}

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;

}

bool CDXGraph::SetFullScreen(BOOL inEnabled)

{

if (mVideoWindow)

{

HRESULT hr = mVideoWindow->put_FullScreenMode(inEnabled ? OATRUE : OAFALSE);

return SUCCEEDED(hr);

}

return false;

}

bool CDXGraph::GetFullScreen(void)

{

if (mVideoWindow)

{

long fullScreenMode = OAFALSE;

mVideoWindow->get_FullScreenMode(&fullScreenMode);

return (fullScreenMode == OATRUE);

}

return false;

}

// IMediaSeeking features

bool CDXGraph::GetCurrentPosition(double * outPosition)

{

if (mSeeking)

{

__int64 position = 0;

if (SUCCEEDED(mSeeking->GetCurrentPosition(&position)))

{

*outPosition = ((double)position) / 10000000.;

return true;

}

}

return false;

}

bool CDXGraph::GetStopPosition(double * outPosition)

{

if (mSeeking)

{

__int64 position = 0;

if (SUCCEEDED(mSeeking->GetStopPosition(&position)))

{

*outPosition = ((double)position) / 10000000.;

return true;

}

}

return false;

}

bool CDXGraph::SetCurrentPosition(double inPosition)

{

if (mSeeking)

{

__int64 one = 10000000;

__int64 position = (__int64)(one * inPosition);

HRESULT hr = mSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,

0, AM_SEEKING_NoPositioning);

return SUCCEEDED(hr);

}

return false;

}

bool CDXGraph::SetStartStopPosition(double inStart, double inStop)

{

if (mSeeking)

{

__int64 one = 10000000;

__int64 startPos = (__int64)(one * inStart);

__int64 stopPos = (__int64)(one * inStop);

HRESULT hr = mSeeking->SetPositions(&startPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,

&stopPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame);

return SUCCEEDED(hr);

}

return false;

}

bool CDXGraph::GetDuration(double * outDuration)

{

if (mSeeking)

{

__int64 length = 0;

if (SUCCEEDED(mSeeking->GetDuration(&length)))

{

*outDuration = ((double)length) / 10000000.;

return true;

}

}

return false;

}

bool CDXGraph::SetPlaybackRate(double inRate)

{

if (mSeeking)

{

if (SUCCEEDED(mSeeking->SetRate(inRate)))

{

return true;

}

}

return false;

}

// Attention: range from -10000 to 0, and 0 is FULL_VOLUME.

bool CDXGraph::SetAudioVolume(long inVolume)

{

if (mBasicAudio)

{

HRESULT hr = mBasicAudio->put_Volume(inVolume);

return SUCCEEDED(hr);

}

return false;

}

long CDXGraph::GetAudioVolume(void)

{

long volume = 0;

if (mBasicAudio)

{

mBasicAudio->get_Volume(&volume);

}

return volume;

}

// Attention: range from -10000(left) to 10000(right), and 0 is both.

bool CDXGraph::SetAudioBalance(long inBalance)

{

if (mBasicAudio)

{

HRESULT hr = mBasicAudio->put_Balance(inBalance);

return SUCCEEDED(hr);

}

return false;

}

long CDXGraph::GetAudioBalance(void)

{

long balance = 0;

if (mBasicAudio)

{

mBasicAudio->get_Balance(&balance);

}

return balance;

}

bool CDXGraph::RenderFile(const char * inFile)

{

if (mGraph)

{

WCHAR szFilePath[MAX_PATH];

MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);

if (SUCCEEDED(mGraph->RenderFile(szFilePath, NULL)))

{

return true;

}

}

return false;

}

bool CDXGraph::SnapshotBitmap(const char * outFile)

{

if (mBasicVideo)

{

long bitmapSize = 0;

if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0)))

{

bool pass = false;

unsigned char * buffer = new unsigned char[bitmapSize];

if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, (long *)buffer)))

{

BITMAPFILEHEADER hdr;

LPBITMAPINFOHEADER lpbi;

lpbi = (LPBITMAPINFOHEADER)buffer;

int nColors = 1 << lpbi->biBitCount;

if (nColors > 256)

nColors = 0;

hdr.bfType = ((WORD) ('M' << 8) | 'B'); //always is "BM"

hdr.bfSize = bitmapSize + sizeof( hdr );

hdr.bfReserved1 = 0;

hdr.bfReserved2 = 0;

hdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + lpbi->biSize +

nColors * sizeof(RGBQUAD));

CFile bitmapFile(outFile, CFile::modeReadWrite | CFile::modeCreate | CFile::typeBinary);

bitmapFile.Write(&hdr, sizeof(BITMAPFILEHEADER));

bitmapFile.Write(buffer, bitmapSize);

bitmapFile.Close();

pass = true;

}

delete [] buffer;

return pass;

}

}

return false;

}

//////////////////////// For GraphEdit Dubug purpose /////////////////////////////

void CDXGraph::AddToObjectTable(void)

{

IMoniker * pMoniker = 0;

IRunningObjectTable * objectTable = 0;

if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))

{

WCHAR wsz[256];

wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)mGraph, GetCurrentProcessId());

HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);

if (SUCCEEDED(hr))

{

hr = objectTable->Register(0, mGraph, pMoniker, &mObjectTableEntry);

pMoniker->Release();

}

objectTable->Release();

}

}

void CDXGraph::RemoveFromObjectTable(void)

{

IRunningObjectTable * objectTable = 0;

if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))

{

objectTable->Revoke(mObjectTableEntry);

objectTable->Release();

mObjectTableEntry = 0;

}

}

使用例子

void CMpegImageDlg::OnOpenButton()

{

// TODO: Add your control notification handler code here

CString strFilter =

"MPEG File (*.mpg;*.mpeg)|*.mpg;*.mpeg|"

"AVI File (*.avi)|*.avi|"

"Mp3 File (*.mp3)|*.mp3|"

"Wave File (*.wav)|*.wav|"

"All Files (*.*)|*.*|";

CFileDialog dlgOpen(TRUE, NULL, NULL, OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,

strFilter, this);

if (IDOK == dlgOpen.DoModal())

{

CString strSourceFile = dlgOpen.GetPathName();

// Rebuild the file playback filter graph

CMpegImageDlg::CreateGraph(strSourceFile);

GetDlgItem(ID_OPEN_BUTTON)->EnableWindow(FALSE);

GetDlgItem(ID_PLAY_BUTTON)->EnableWindow(TRUE);

}

}

void CMpegImageDlg::CreateGraph(const CString& strSourceFile)

{

CMpegImageDlg::DestroyGraph();

m_FilterGraph = new CDXGraph();

if (m_FilterGraph->Create())

{

// Render the source clip

m_FilterGraph->RenderFile(strSourceFile);

// Set video window and notification window

m_FilterGraph->SetDisplayWindow(m_VideoWindow.GetSafeHwnd());

m_FilterGraph->SetNotifyWindow(this->GetSafeHwnd());

// Show the first frame

m_FilterGraph->Pause();

}

}

void CMpegImageDlg::DestroyGraph(void)

{

if(m_FilterGraph)

{

// Stop the filter graph first

m_FilterGraph->Stop();

m_FilterGraph->SetNotifyWindow(NULL);

delete m_FilterGraph;

m_FilterGraph = NULL;

}

}

void CMpegImageDlg::OnPlayButton()

{

// TODO: Add your control notification handler code here

if (m_FilterGraph)

{

GetDlgItem(ID_PLAY_BUTTON)->EnableWindow(FALSE);

GetDlgItem(ID_IMAGE_BUTTON)->EnableWindow(TRUE);

m_FilterGraph->Run();

// Start a timer

if (m_SliderTimer == 0)

{

m_SliderTimer = SetTimer(SLIDER_TIMER, 100, NULL);

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有