DSHOW的IMediaSample接口如何使用

icesoft2000 2008-09-03 04:20:58
想得到DSHOW的IMediaSample接口的数据,如何做?
...全文
617 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
icesoft2000 2008-09-08
  • 打赏
  • 举报
回复
看来是我对IMediaSample的作用的理解有错误。

我本来的是意思是想实现音乐播放时,可以显示声音的波形。本来以为可以用IMediaSample来实现,看来是不对啦!

请问各位DX,如何实现此功能?
vocanicy 2008-09-05
  • 打赏
  • 举报
回复
ISampleGrabberCB回调接口中的SampleCB函数
HRESULT SampleCB(
double SampleTime,
IMediaSample *pSample
);


#include <windows.h>
#include <streams.h>
#include <stdio.h>
#include <atlbase.h>
#include <qedit.h>
int GrabBitmaps(TCHAR * szFile);
HRESULT GetPin(IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin);
IPin * GetInPin ( IBaseFilter *pFilter, int Num );
IPin * GetOutPin( IBaseFilter *pFilter, int Num );
class CSampleGrabberCB : public ISampleGrabberCB {
public:
STDMETHODIMP_(ULONG) AddRef() { return 2; }
STDMETHODIMP_(ULONG) Release() { return 1; }
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) {
CheckPointer(ppv,E_POINTER);
if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) {
*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
return NOERROR;
}
return E_NOINTERFACE;
}

STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ) {return 0;}
STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize ) {
_tprintf(TEXT("Found a sample at %f s\t[%ld]\r\n"), SampleTime , BufferSize );
return 0;
}
}
int _tmain(int argc, TCHAR* argv[]) {
if( argc != 2 || !argv || !argv[1] ) {
_tprintf( TEXT("GrabBitmaps: You must specify a media filename!\r\n") );
_tprintf( TEXT("Usage: GrabBitmaps Filename\r\n"));
return 0;
}
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// Read the filename from the command line
TCHAR szFile[MAX_PATH];
_tcsncpy(szFile, argv[1], MAX_PATH-1);
szFile[MAX_PATH-1] = 0; // Null-terminate
int nSuccess = GrabBitmaps(szFile);
CoUninitialize();
return nSuccess;
}
int GrabBitmaps(TCHAR * szFile ) {
USES_CONVERSION;
CComPtr< ISampleGrabber > pGrabber;
CComPtr< IBaseFilter > pSource;
CComPtr< IGraphBuilder > pGraph;
CComPtr< IVideoWindow > pVideoWindow;
HRESULT hr;
if (!szFile) return -1;
_tprintf(TEXT("Grabbing bitmaps from %s.\r\n"), szFile);

// Create the sample grabber
pGrabber.CoCreateInstance( CLSID_SampleGrabber );
if( !pGrabber ) {
_tprintf( TEXT("Could not create CLSID_SampleGrabber\r\n") );
return -1;
}
CComQIPtr<IBaseFilter, &IID_IBaseFilter> pGrabberBase(pGrabber);

// Create the file reader
pSource.CoCreateInstance(CLSID_AsyncReader);
if (!pSource) {
_tprintf( TEXT("Could not create source filter\r\n") );
return -1;
}

// Create the graph
pGraph.CoCreateInstance(CLSID_FilterGraph);
if( !pGraph ) {
_tprintf( TEXT("Could not not create the graph\r\n") );
return -1;
}

// Put them in the graph
hr = pGraph->AddFilter( pSource, L"Source" );
hr = pGraph->AddFilter( pGrabberBase, L"Grabber" );
// Load the source
CComQIPtr<IFileSourceFilter, &IID_IFileSourceFilter> pLoad(pSource);
hr = pLoad->Load( T2W( szFile ), NULL );
if (FAILED(hr)) {
_tprintf( TEXT("Could not load the media file\r\n") );
return -1;
}
CMediaType GrabType;
GrabType.SetType(&MEDIATYPE_Audio);
GrabType.SetSubtype(&MEDIASUBTYPE_PCM);
GrabType.SetFormatType(&FORMAT_WaveFormatEx);
hr = pGrabber->SetMediaType(&GrabType);
// Get the output pin and the input pin
CComPtr< IPin > pSourcePin;
CComPtr< IPin > pGrabPin;
pSourcePin = GetOutPin( pSource, 0 );
pGrabPin = GetInPin( pGrabberBase, 0 );
// ... and connect them
hr = pGraph->Connect( pSourcePin, pGrabPin );
if( FAILED( hr ) ) {
_tprintf( TEXT("Could not connect source filter to grabber\r\n") );
return -1;
}
CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 );
hr = pGraph->Render( pGrabOutPin );
if( FAILED( hr ) ) {
_tprintf( TEXT("Could not render grabber output pin\r\n") );
return -1;
}

// Don't buffer the samples as they pass through
hr = pGrabber->SetBufferSamples( FALSE );
// Only grab one at a time, stop stream after grabbing one sample
hr = pGrabber->SetOneShot(FALSE);
// Set the callback, so we can grab the one sample
CSampleGrabberCB CB;
hr = pGrabber->SetCallback(&CB, 1);
// Keep a useless clock from being instantiated....
CComQIPtr<IMediaFilter, &IID_IMediaFilter> pFilter(pGraph);
hr = pFilter->SetSyncSource(NULL);
if (FAILED(hr)) printf("SetNoClock: Failed to set sync source! hr=0x%x\n", hr);
CComQIPtr<IVideoWindow, &IID_IVideoWindow> pWindow(pGraph);
if (pWindow) hr = pWindow->put_AutoShow(OAFALSE);
// activate the threads
CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
hr = pControl->Run( );
// wait for the graph to settle
CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
long EvCode = 0;
hr = pEvent->WaitForCompletion( INFINITE, &EvCode );

_tprintf(TEXT("Sample grabbing complete.\r\n"));
return 0;
}

HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin) {
CComPtr< IEnumPins > pEnum;
*ppPin = NULL;
HRESULT hr = pFilter->EnumPins(&pEnum);
if(FAILED(hr)) return hr;
ULONG ulFound;
IPin *pPin;
hr = E_FAIL;
while (S_OK == pEnum->Next(1, &pPin, &ulFound)) {
PIN_DIRECTION pindir = (PIN_DIRECTION)3;
pPin->QueryDirection(&pindir);
if (pindir == dirrequired) {
if (iNum == 0) {
*ppPin = pPin; // Return the pin's interface
hr = S_OK; // Found requested pin, so clear error
break;
}
iNum--;
}
pPin->Release();
}
return hr;
}
IPin * GetInPin( IBaseFilter * pFilter, int nPin ) {
CComPtr<IPin> pComPin=0;
GetPin(pFilter, PINDIR_INPUT, nPin, &pComPin);
return pComPin;
}
IPin * GetOutPin( IBaseFilter * pFilter, int nPin ) {
CComPtr<IPin> pComPin=0;
GetPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin);
return pComPin;
}
icesoft2000 2008-09-05
  • 打赏
  • 举报
回复
IMediaSample如何与IGraphBuilder、IMediaControl等建立关联?

播放功能已经实现,现在想得到数据研究一下。
icesoft2000 2008-09-05
  • 打赏
  • 举报
回复
IMediaSample如何与IGraphBuilder等建立关联?
ouyh12345 2008-09-04
  • 打赏
  • 举报
回复
IMediaSample::GetPointer

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧