none
NV12 raw video data rendering DirectShow source filer development for local playback

    Pergunta

  • Hello,

    I have developed DirectShow source filter for NV12 raw video data playback by configuring GetMediatype, DecideBuffersize, Fill buffer ,Load, Getcurfile ... functions. Filter is registered successfully.

    While checking through GraphEdit, i am getting error of filter is not connected/suitable output to render the pin.

    I am not able to render NV12 raw video data.

    Can anybody suggest how can I resolve this problem?

    Please suggest me the process for developing source filter for playback of raw NV12 data?

     

    sexta-feira, 16 de setembro de 2011 03:04

Todas as Respostas

  • You need to debug your code, check error codes you might be seeing, check sequence of calls you are getting, exceptions. DirectShow is nothing special from this point of view.  You have PushSource samples in SDK as an example of a filter that does work.
    http://alax.info/blog/tag/directshow
    sexta-feira, 16 de setembro de 2011 13:51
  • Thanks for your response.

    I have gone through PushSource sample before it. but still I am getting the same error as

    Sorry,  the filter graph can not render to this pin.

    No combinations of filter could be found to render the stream.(Return code : 0x80040218)

    However, I have configured

    /*********** GetMediaType ***********/
    HRESULT CRawSourceFilterPin::GetMediaType(CMediaType *pMediaType)
    {
        CAutoLock cAutoLock(m_pFilter->pStateLock());

        CheckPointer(pMediaType, E_POINTER);

        // If the bitmap files were not loaded, just fail here.
        if (!m_pRawSource->m_bFilesLoaded)
            return E_FAIL;

        pMediaType->InitMediaType();
        pMediaType->SetType(&MEDIATYPE_Video);
        pMediaType->SetSubtype(&MEDIASUBTYPE_NV12);
        pMediaType->SetFormatType(&FORMAT_VideoInfo2);
        pMediaType->SetTemporalCompression(FALSE);
        pMediaType->bFixedSizeSamples = true;
        //pMediaType->bTemporalCompression = FALSE;

        VIDEOINFOHEADER2* pvi = (VIDEOINFOHEADER2*)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER2));
        ZeroMemory(pvi, sizeof(VIDEOINFOHEADER2));

        pMediaType->cbFormat = sizeof(VIDEOINFOHEADER2);
        pMediaType->pbFormat = (BYTE *)pvi;

        pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pvi->bmiHeader.biBitCount = 12;
        pvi->bmiHeader.biHeight = m_pRawSource->m_stRawInfo.ui32Height;
        pvi->bmiHeader.biWidth = m_pRawSource->m_stRawInfo.ui32Width;
        pvi->bmiHeader.biSizeImage = m_pRawSource->m_stRawInfo.ui32Framesize;
        pvi->bmiHeader.biCompression = '21VN';
        pvi->bmiHeader.biPlanes = 1;
        pvi->bmiHeader.biClrImportant = 0;
        //pvi->bmiHeader.biWidth = ((((pvi->bmiHeader.biWidth * pvi->bmiHeader.biBitCount) + 31) & ~31) >> 3);
        //pvi->bmiHeader.biWidth = pvi->bmiHeader.biWidth * 3;

    //SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.

    //SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle

    //pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage);

    //DbgOutString(TEXT("GetMediaType returned S_OK\r\n"));

        RECT rct = {0, 0, m_pRawSource->m_stRawInfo.ui32Width, m_pRawSource->m_stRawInfo.ui32Height};
        pvi->rcSource = rct;
        pvi->rcTarget = rct;


        pvi->dwBitRate = 335127272;
        pvi->AvgTimePerFrame = (REFERENCE_TIME)(m_pRawSource->m_stRawInfo.dFrameDuration * 10000000);
        pvi->dwInterlaceFlags = AMINTERLACE_IsInterlaced;
        pvi->dwPictAspectRatioX = 16;
        pvi->dwPictAspectRatioY = 9;   
           
        return S_OK;
    }

    class CRawSourceFilterPin : public CSourceStream,
                                public CSourceSeeking
    {
    protected:
           
        BOOL m_bZeroMemory;                 // Do we need to clear the buffer?
        CRefTime m_rtSampleTime;            // The time stamp for each sample
       
        CCritSec m_cSharedState;            // Protects our internal state
        CImageDisplay m_Display;            // Figures out our media type for us

        CRawSourceFilter *m_pRawSource;
        BOOL m_bFilesLoaded;
        REFERENCE_TIME m_rtFrameLength;

    public:

        CRawSourceFilterPin(HRESULT *phr, CSource *pFilter, LPUNKNOWN pUnk);
        ~CRawSourceFilterPin();
        STDMETHODIMP NonDelegatingQueryInterface( REFIID riid, void ** ppv );

        // Override the version that offers exactly one media type
        HRESULT GetMediaType(CMediaType *pMediaType);
        HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest);
        HRESULT FillBuffer(IMediaSample *pSample);   

        // CSourceSeeking   
        HRESULT ChangeStart( );
        HRESULT ChangeStop( );
        HRESULT ChangeRate( );

        // Quality control
        // Not implemented because we aren't going in real time.
        // If the file-writing filter slows the graph down, we just do nothing, which means
        // wait until we're unblocked. No frames are ever dropped.
        STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q)
        {
            return E_NOTIMPL;
        }   

        CCritSec  m_Lock;
        UINT32 m_iFrameNumber;                // To track where we are in the file
    };

    class CRawSourceFilter : public CSource,
                             public IFileSourceFilter,
                             public IConfigureRawSource
    {
        friend class CRawSourceFilterPin;
    public:

        DECLARE_IUNKNOWN;
        static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);

        // Reveals IRawSourceFilter and ISpecifyPropertyPages
        STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);

        // Implements the IFileSourceFilter interface
        STDMETHODIMP Load(LPCOLESTR pszFileName,const AM_MEDIA_TYPE *pmt);
        STDMETHODIMP GetCurFile(LPOLESTR * ppszFileName,AM_MEDIA_TYPE *pmt);

        //IConfigureRawSource Interface
        BOOL SetVideoParams(UINT8 ui8Format, UINT32 ui32Height, UINT32 ui32Width, FLOAT FPS);

        void SeekToNewPosition(LONGLONG llStart);   
       
        stRawInfo m_stRawInfo;
    private:

        // Constructor
        CRawSourceFilter(LPUNKNOWN punk, HRESULT *phr);
        ~CRawSourceFilter();
        HRESULT ReadFrame(BYTE *, UINT32 *);
        CRawSourceFilterPin *m_pPin;
        HANDLE   m_hFile;
        LPOLESTR m_pFileName;   
        BOOL m_bFilesLoaded;   
        BOOL bDuringInit;
        REFERENCE_TIME m_rtStart;
        REFERENCE_TIME m_rtStop;
        UINT8 m_ui8RawHeadetType;
        UINT8 m_ui8ExtraData[128];
        UINT8 m_ui8ExtraDataSize;

        CCritSec m_RawSourceFilterLock;         // Private play critical section
    };

     

    can anybody suggest how to resolve this problem and whether this configuration of CRawSourceFilterPin::GetMediaType is correct or not ?

    Please suggest the process of developing source filter for playback of NV12 data?

     

     

    terça-feira, 20 de setembro de 2011 08:43
  • What debugging have you done? Did you step through your CheckMediaType to make sure execution reaches there, and you are not rejecting your own media type?
    http://alax.info/blog/tag/directshow
    terça-feira, 20 de setembro de 2011 14:41
  • What OS are you using? From what I read, NV12 is the prefered format for EVR in Windows 7 but XP does not seem to have handlers or converters for NV12. For example I have been trying to use the Intel H264 decoder in an directshow app but it only outputs NV12 and wont connect to anything in Win XP. I've written an NV12 to RGB24 converter filter which seems to help. (Am also trying to get it to handle YUY2 and RGB32 to work better with VMR7 and VMR9 but thats turning out to be remarkably difficult - buts that another story).

    Al Chisholm

    terça-feira, 21 de fevereiro de 2012 16:37