陆其明吧 关注:196贴子:6,658
  • 8回复贴,共1

《DirectShow实务精选》把您的FilterQQSource例子改写了一下,在Re

只看楼主收藏回复

《DirectShow实务精选》把您的FilterQQSource例子改写了一下,在Render出错了???
估计是CheckMediaType(), GetMediaType()除了问题, 因为是推模式的源Filter,所以不能去Render MPEG1的文件,所以我改成了AVi,但是还是不行,麻烦给指导指导!!!
谢谢啦。。。
代码如下
//
#include <atlbase.h>//CComptr模板定义
#include <streams.h>//DS接口,基类接口
#include <qedit.h>
#include <wmsdk.h>
#include <dshowasf.h>
//////////////////////////////////////////////////////////////////////////
#include <streams.h>
//
#include <streams.h>           // quartz, includes windows
#include "stdio.h"
#pragma warning(disable: 4511 4512)
#include <measure.h>           // performance measurement (MSR_)
#include <initguid.h>
#if (1100 > _MSC_VER)
#include <olectlid.h>
#else
#include <olectl.h>
#endif
//
//////////////////////////////////////////////////////////////////////////
DEFINE_GUID(CLSID_QQSourceXX,
             0x1f201828, 0x4385, 0x4178, 0xa0, 0xf0, 0x8c, 0x45, 0x81, 0x62, 0x2, 0x87);
// {76C90120-D6E9-4cdd-8163-466B950BB133}
DEFINE_GUID(CLSID_QQSourcePropXX,
             0xb4daedaa, 0x8182, 0x488d, 0xbb, 0x4e, 0x32, 0xf9, 0xa5, 0x88, 0x49, 0xee);
// {8C2172BD-442A-467b-8DF5-E02454A0AEC1}
DEFINE_GUID(IID_IQQSourcexx,
             0x134d4289, 0xb361, 0x43d0, 0xaa, 0x2c, 0xd4, 0x45, 0xf, 0xab, 0xab, 0xbc);
//
class CQQOutPin;
class CFilterQQSource : public CSource
, public IFileSourceFilter
{
private:
     CFilterQQSource(LPUNKNOWN lpunk, HRESULT *phr);
     ~CFilterQQSource();
    
public:
     // The only allowed way to create Bouncing balls!
     static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
     DECLARE_IUNKNOWN;
     // Basic COM - used here to reveal our own interfaces
     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
    
     // you need to supply these to access the pins from the enumerator
     // and for default Stop and Pause/Run activation.
     virtual int GetPinCount();
     virtual CBasePin *GetPin(int n);
     STDMETHODIMP FindPin(LPCWSTR Id, IPin ** ppPin);
    
     // --- ISpecifyPropertyPages methods ---
     STDMETHODIMP GetPages(CAUUID *pPages);
    



1楼2010-03-01 22:43回复
         // --- IFileSourceFilter methods ---
         STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt);
         STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName, AM_MEDIA_TYPE *pmt);    
        
         // --- IQQSource methods ---
    //     STDMETHODIMP CanChangeSource(void);
        
    protected:
         CQQOutPin * OutPin() {return (CQQOutPin *)m_paStreams[0];};
    };
    //
    class CQQOutPin : public CSourceStream
    , public CSourceSeeking
    {
         friend class CFilterQQSource;
        
    protected:
         CFilterQQSource *         mFilter;//针里面含有此 Source Filter
         char                     mFilePath[MAX_PATH];
         CMediaType                 mPreferred;
         FILE *                     m_fp;
         long                     mHeaderSize;
         long                     mFrameSize;
         long                     mTotalFrames;
        
         CCritSec                 mSharedState;
         REFERENCE_TIME             mLastSampleTime;
         REFERENCE_TIME             mSampleDuration;
        
    public:
         BOOL SetFileSource(const char * inFile);
         void GetFileSource(char * outFile);
         HRESULT SetMediaType(const CMediaType *pMediaType)
         {
             HRESULT hr = CSourceStream::SetMediaType(pMediaType);
             return hr;
         }
    public:
         CQQOutPin(HRESULT *phr, CFilterQQSource * pFilter, LPCWSTR pPinName);
         ~CQQOutPin();
        
         STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
         {
             if (IID_IMediaSeeking == riid)
    


    2楼2010-03-01 22:43
    回复
               {
                   return CSourceSeeking::QueryInterface(riid, ppv);
               }
               else
               {
                   return CSourceStream::QueryInterface(riid,ppv);
               }
           };                                                          
           STDMETHODIMP_(ULONG) AddRef()
           {                             
               return CSourceStream::AddRef();                            
           };                                                              
           STDMETHODIMP_(ULONG) Release()
           {                            
               return CSourceStream::Release();                               
           };
           // Basic COM - used here to reveal our own interfaces
           STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
          
          
           STDMETHODIMP QueryId(LPWSTR * Id);
           // Pure methods
           virtual HRESULT FillBuffer(IMediaSample * pSample);
           virtual HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties);
           virtual HRESULT CheckMediaType(const CMediaType * inMediatype);
          
           virtual HRESULT Active(void);
      


      3楼2010-03-01 22:43
      回复
             HRESULT GetMediaType(int iPosition, CMediaType *pmt);//
            
             // Quality control notifications sent to us
        //    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
            
             // IMediaSeeking
             virtual HRESULT ChangeStart();
             virtual HRESULT ChangeStop();
             virtual HRESULT ChangeRate();
             virtual HRESULT OnThreadCreate(void);
             virtual HRESULT OnThreadStartPlay(void);
             void UpdateFromSeek(void);
        };
        const AMOVIESETUP_MEDIATYPE sudPinTypes =
        {
             &MEDIATYPE_Stream,             // Major type
             &MEDIASUBTYPE_NULL            // Minor type
        };
        const AMOVIESETUP_PIN psudPins[] =
        {
            {
                 L"Output",           // String pin name
                 FALSE,               // Is it rendered
                 TRUE,                // Is it an output
                 FALSE,               // Allowed none
                 FALSE,               // Allowed many
                 &CLSID_NULL,         // Connects to filter
                 L"Input",            // Connects to pin
                 1,                   // Number of types
                 &sudPinTypes         // The pin details
             }
        };
        const AMOVIESETUP_FILTER sudFilter =
        {
             &CLSID_QQSourceXX,           // Filter CLSID
             L"QQ Source",              // Filter name
             MERIT_DO_NOT_USE,          // Its merit
             1,                         // Number of pins
        


        4楼2010-03-01 22:43
        回复
               psudPins                   // Pin details
          };
          // List of class IDs and creator functions for the class factory. This
          // provides the link between the OLE entry point in the DLL and an object
          // being created. The class factory will call the static CreateInstance
          CFactoryTemplate g_Templates[] =
          {
               {
                   L"QQ Source",
                   &CLSID_QQSourceXX,
                   CFilterQQSource::CreateInstance,
                   NULL,
                   &sudFilter
               }
          };
          int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
          // ----------------------------------------------------------------------------
          //             Filter implementation
          // ----------------------------------------------------------------------------
          CFilterQQSource::CFilterQQSource(LPUNKNOWN lpunk, HRESULT *phr) :
          CSource(NAME("QQ Source"), lpunk, CLSID_QQSourceXX)
          {
               CQQOutPin * outStream = new CQQOutPin(phr, this, L"Output");
               if (outStream == NULL)
               {
                   *phr = E_OUTOFMEMORY;    
               }
          }
          CFilterQQSource::~CFilterQQSource()
          {
          }
          CUnknown * WINAPI CFilterQQSource::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
          {
               CFilterQQSource *pNewObject = new CFilterQQSource(punk, phr);
               if (pNewObject == NULL)
               {
                   *phr = E_OUTOFMEMORY;
               }
               return pNewObject;
          }
          //
          // Basic COM - used here to reveal our own interfaces
          STDMETHODIMP CFilterQQSource::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
          {
               CheckPointer(ppv, E_POINTER);
              
               if (riid == IID_IFileSourceFilter)
               {
                   return GetInterface((IFileSourceFilter *) this, ppv);
               }
               else
               {
                   return CSource::NonDelegatingQueryInterface(riid, ppv);
               }
          }
          int CFilterQQSource::GetPinCount()
          {
               return 1;
          }
          CBasePin * CFilterQQSource::GetPin(int n)
          {
               if (n == 0)
               {
                   return m_paStreams[0];    
          


          5楼2010-03-01 22:43
          回复
                 }
                 return NULL;
            }
            STDMETHODIMP CFilterQQSource::FindPin(LPCWSTR Id, IPin ** ppPin)
            {
                 return CBaseFilter::FindPin(Id, ppPin);
            }
            // --- IFileSourceFilter methods ---
            STDMETHODIMP CFilterQQSource::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt)
            {
                 char szAnsi[MAX_PATH];
                 WideCharToMultiByte(CP_ACP, 0, pszFileName, -1, szAnsi, MAX_PATH, NULL, NULL);
                 if (OutPin()->SetFileSource(szAnsi))
                 {
                     return NOERROR;
                 }
                 return E_FAIL;
            }
            STDMETHODIMP CFilterQQSource::GetCurFile(LPOLESTR *ppszFileName, AM_MEDIA_TYPE *pmt)
            {
                 char szAnsi[MAX_PATH];
                 OutPin()->GetFileSource(szAnsi);
                 DWORD n = sizeof(WCHAR) * (1 + strlen(szAnsi));
                 *ppszFileName = (LPOLESTR) CoTaskMemAlloc( n );
                 if (*ppszFileName != NULL)
                 {
                     WCHAR    szwFile[MAX_PATH];
                     MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, szwFile, MAX_PATH);
                     CopyMemory(*ppszFileName, szwFile, n);
                 }
                 return NOERROR;
            }
            ///////////////////////////////////
            extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
            BOOL APIENTRY DllMain(HANDLE hModule,
                                   DWORD   dwReason,
                                   LPVOID lpReserved)
            {
                 return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
            }
            STDAPI
            DllRegisterServer()
            {
                 return AMovieDllRegisterServer2( TRUE );
            }
            STDAPI
            DllUnregisterServer()
            {
                 return AMovieDllRegisterServer2( FALSE );
            }
            //
            /////
            CQQOutPin::CQQOutPin(HRESULT *phr, CFilterQQSource * pFilter, LPCWSTR pPinName) :
            CSourceStream(NAME("QQ Stream"), phr, pFilter, pPinName),
            CSourceSeeking("MediaSeeking", NULL, phr, pFilter->pStateLock())
            {
                 mFilter       = pFilter;
                 m_fp          = NULL;
                 mHeaderSize   = 0;
                 mFrameSize    = 0;
                 mTotalFrames = 0;
                 strcpy(mFilePath, "");
                 mPreferred.InitMediaType();
            


            6楼2010-03-01 22:43
            回复

                   mLastSampleTime = 0;
                   mSampleDuration = 0;
                   CSourceSeeking::m_rtStart     = 0;
                   CSourceSeeking::m_rtStop      = 1 * UNITS;
                   CSourceSeeking::m_rtDuration = 1 * UNITS;
              }
                 
              CQQOutPin::~CQQOutPin()
              {
                   CAutoLock    lock(&mSharedState);
                   if (m_fp)
                   {
                       fclose(m_fp);
                       m_fp = NULL;
                   }
              }
              STDMETHODIMP CQQOutPin::QueryId(LPWSTR * Id)
              {
                   return CBaseOutputPin::QueryId(Id);
              }
              STDMETHODIMP CQQOutPin::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
              {
                   CheckPointer(ppv,E_POINTER);
                  
                   if (riid == IID_IMediaSeeking)
                   {
                       return GetInterface((IMediaSeeking *) this , ppv);
                   }
                   else
                   {
                       return CSourceStream::NonDelegatingQueryInterface(riid, ppv);
                   }
              }
              HRESULT CQQOutPin::FillBuffer(IMediaSample * pSample)
              {
                   CAutoLock    lock(&mSharedState);
                  
                   BYTE * pData = NULL;
                   pSample->GetPointer(&pData);
                   long bytes = fread(pData, 1, mFrameSize, m_fp);
                   if (bytes<=0)
                   {
                       return S_FALSE;
                   }
                   return S_OK;
              }
              HRESULT CQQOutPin::DecideBufferSize(IMemAllocator *pAlloc,
                                                   ALLOCATOR_PROPERTIES *pProperties)
              {
                   CAutoLock   filterLock(m_pFilter->pStateLock());
                   ASSERT(pAlloc);
                   ASSERT(pProperties);
                   HRESULT hr = NOERROR;
                   VIDEOINFO *pvi = (VIDEOINFO *) m_mt.Format();
                   pProperties->cBuffers = 1;
                   pProperties->cbBuffer = pvi->bmiHeader.biSizeImage;
                   ASSERT(pProperties->cbBuffer);
                   ALLOCATOR_PROPERTIES Actual;
                   hr = pAlloc->SetProperties(pProperties, &Actual);
                   if (FAILED(hr)) {
              


              7楼2010-03-01 22:43
              回复
                         return hr;
                     }
                     // Is this allocator unsuitable
                     if (Actual.cbBuffer < pProperties->cbBuffer) {
                         return E_FAIL;
                     }
                     ASSERT( Actual.cBuffers == 1 );
                     return NOERROR;
                }
                HRESULT CQQOutPin::Active(void)
                {
                     if (m_fp)
                     {
                         CAutoLock    lock(&mSharedState);
                         fseek(m_fp, mHeaderSize, SEEK_SET);
                     }
                     return CSourceStream::Active();
                }
                HRESULT CQQOutPin::CheckMediaType(const CMediaType * inMediatype)
                {
                     if (inMediatype->majortype==MEDIATYPE_Stream && inMediatype->subtype==MEDIASUBTYPE_Avi)
                     {
                         return S_OK;
                     }
                     return S_FALSE;
                }
                HRESULT CQQOutPin::GetMediaType(int iPosition, CMediaType *pmt)//得为pmt开辟空间
                {
                     if (iPosition < 0) {
                         return E_INVALIDARG;
                     }
                     if (iPosition > 0) {
                         return VFW_S_NO_MORE_ITEMS;
                     }
                    
                     pmt->majortype=MEDIATYPE_Stream;
                     pmt->subtype=MEDIASUBTYPE_Avi;
                     return S_OK;    
                }
                HRESULT CQQOutPin::ChangeStart()
                {
                     UpdateFromSeek();
                     return NOERROR;
                }
                HRESULT CQQOutPin::ChangeStop()
                {
                     return NOERROR;
                }
                HRESULT CQQOutPin::ChangeRate()
                {
                     return NOERROR;
                }
                HRESULT CQQOutPin::OnThreadCreate(void)
                {
                     CAutoLock    lock(&mSharedState);
                //     mLastSampleTime = 0;
                     return NOERROR;
                }
                HRESULT CQQOutPin::OnThreadStartPlay(void)
                {
                //     return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
                     return NOERROR;
                }
                void CQQOutPin::UpdateFromSeek(void)
                {
                     if (ThreadExists())
                     {
                         DeliverBeginFlush();
                         Stop();
                         DeliverEndFlush();
                         Run();
                     }
                }
                BOOL CQQOutPin::SetFileSource(const char * inFile)
                {
                     CAutoLock    lock(&mSharedState);
                     strcpy(mFilePath, inFile);
                     if (m_fp)
                     {
                         fclose(m_fp);
                         m_fp = NULL;
                     }
                     m_fp = fopen(mFilePath, "rb");
                     return TRUE;
                }
                void CQQOutPin::GetFileSource(char * outFile)
                {
                     strcpy(outFile, mFilePath);
                }
                //


                8楼2010-03-01 22:43
                回复
                  有没有例子调用这个接口的?CUnknown * WINAPI CFilterQQSource::CreateInstance(LPUNKNOWN punk, HRESULT *phr)这个接口怎么在项目里面写参数的意义


                  9楼2018-04-29 18:41
                  回复