想得到DSHOW的IMediaSample接口的数据,如何做?

解决方案 »

  1.   

    IMediaSample如何与IGraphBuilder等建立关联?
      

  2.   

    IMediaSample如何与IGraphBuilder、IMediaControl等建立关联?播放功能已经实现,现在想得到数据研究一下。
      

  3.   

    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;
    }
      

  4.   

    看来是我对IMediaSample的作用的理解有错误。我本来的是意思是想实现音乐播放时,可以显示声音的波形。本来以为可以用IMediaSample来实现,看来是不对啦!请问各位DX,如何实现此功能?