自写的samplegrabber过滤器和nullrenderer

自写的samplegrabber过滤器和nullrenderer

本文介绍了使用自写的samplegrabber过滤器和nullrenderer DirectShow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

描述:
为了从视频中获取指定的帧,我在winmobile和注册的dll上编写了一个示例获取器过滤器和null渲染器.在主程序中
,使用cocreateinstance方法正确创建了两个自写过滤器.但没有调用transform方法.

Descritpion:
In order to grab s specified frame from video,i wrote a sample grabber filter and null renderer on winmobile and registered dll.In main program
, two self-written filters are created rightly using cocreateinstance method. but transform method isn''t called.

typedef HRESULT (*SAMPLECALLBACK) (IMediaSample * pSample);

MIDL_INTERFACE("6B652FFF-11FE-4FCE-92AD-0266B5D7C78F")
IGrabberSample : public IUnknown
{
public:
	virtual HRESULT STDMETHODCALLTYPE SetAcceptedMediaType(
		const AM_MEDIA_TYPE *pType) = 0;
	virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType(
		AM_MEDIA_TYPE *pType) = 0;
	virtual HRESULT STDMETHODCALLTYPE SetCallback(
		SAMPLECALLBACK Callback) = 0;
};


class CSampleGrabber : public CTransInPlaceFilter,
	public IGrabberSample
{
private:
	BOOL m_bModifiesData;
protected:
	CMediaType m_mtAccept;
	SAMPLECALLBACK m_callback;
	CCritSec m_Lock; // serialize access to our data
	//BOOL IsReadOnly( ) { return !m_bModifiesData; }
	// PURE, override this to ensure we get 
	// connected with the right media type
	HRESULT CheckInputType( const CMediaType * pmt );
        //call callback function in this method
	HRESULT Transform( IMediaSample * pms );
public:

   CSampleGrabber( IUnknown * pOuter, HRESULT * phr, BOOL ModifiesData);
   static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
	// Expose ISampleGrabber
	STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
	DECLARE_IUNKNOWN;

	// IGrabberSample
	STDMETHODIMP SetAcceptedMediaType( const AM_MEDIA_TYPE * pmt );
	STDMETHODIMP GetConnectedMediaType( AM_MEDIA_TYPE * pmt );
	STDMETHODIMP SetCallback( SAMPLECALLBACK Callback );
};


问题:
构建过滤器图然后运行图之后-不调用transform方法.我想在transform函数中处理样本数据,但是我对这个问题并不理想.有人知道原因吗?您的建议将不胜感激.
谢谢您的关注!


Question:
After building filter graph and then running the graph - transform method isn''t called.I want to deal with sample data in transform function, but i have no ideal about the problem. does anybody know the reasons. Your advice will be much appreciated.
thank you for your attention!

推荐答案

my sample grabber :
    /// <summary>
    /// a callback handler for samples
    /// The ISampleGrabberCB interface provides callback methods for the ISampleGrabber::SetCallback method.
    /// If your application calls that method, it must implement this interface. For more information, see ISampleGrabber.
    /// http://msdn.microsoft.com/en-us/library/dd376985(VS.85).aspx
    /// </summary>
    public class JMakerAviSampleDetector : ISampleGrabberCB
    {
        #region declare events
        /// <summary>
        /// Occurs when [event sample cb].
        /// </summary>
        public event JDelegates.JSampleISample EventSampleCb;

        /// <summary>
        /// Occurs when [event buffer cb].
        /// </summary>
        public event JDelegates.JSampleBuffer EventBufferCb;

        private bool pFirstTime;
        #endregion

        #region initialize
        public JMakerAviSampleDetector()
        {
            pFirstTime = true;
        }
        #endregion

        #region declare callback
        /// <summary>
        /// Get the callback using a imediasample
        /// http://msdn.microsoft.com/en-us/library/dd376987(v=VS.85).aspx
        /// </summary>
        ///
        /// <param name="sampleTime">
        /// >Starting time of the sample, in seconds.
        /// </param>
        ///
        /// <param name="sample">
        /// Pointer to the IMediaSample interface of the sample.
        /// The IMediaSample interface sets and retrieves properties on media samples.
        /// A media sample is a COM object that contains a block of media data.
        /// Media samples support the use of shared memory buffers among filters.
        /// http://msdn.microsoft.com/en-us/library/dd407001(VS.85).aspx
        /// </param>
        ///
        /// <returns>
        /// Returns S_OK if successful, or an HRESULT error code otherwise.
        /// </returns>
        public int SampleCB(double sampleTime, IMediaSample sample)
        {
            if (pFirstTime)
            {
                 ScanSampe(sample);
            }
            else if (0 == sample.IsDiscontinuity())
            {
                ScanSampe(sample);
            }

            pFirstTime = false;
            EventSampleCb(this, sampleTime, sample);
            return 0;
        }

        /// <summary>
        /// Get the callback using a buffer .
        /// The BufferCB method is a callback method that receives a pointer to the sample buffer
        /// http://msdn.microsoft.com/en-us/library/dd376986(v=VS.85).aspx
        /// </summary>
        ///
        /// <param name="sampleTime">
        /// Starting time of the sample, in seconds.
        ///  </param>
        ///
        /// <param name="buffer">
        /// The buffer.Pointer to a buffer that contains the sample data.
        /// The format of the data depends on the media type of the Sample Grabber''s input pin.
        /// To get the media type, call ISampleGrabber::GetConnectedMediaType.
        /// </param>
        ///
        /// <param name="bufferLen">
        /// Length of the buffer pointed to by pBuffer, in bytes.
        /// </param>
        ///
        /// <returns>
        /// Returns S_OK if successful, or an HRESULT error code otherwise.
        /// </returns>
        ///
        /// <remarks>
        /// This method receives a pointer to the original sample data, not a copy
        /// </remarks>
        public int BufferCB(double sampleTime, IntPtr buffer, int bufferLen)
        {
            EventBufferCb(this, sampleTime, buffer, bufferLen);
            return 0;
        }
        #endregion

        private void ScanSampe(IMediaSample sample)
        {
            // Determine if this sample represents a break in the data stream.
            // A discontinuity occurs when a filter seeks to a different place in the stream, or when a filter drops samples for quality control.
            // A perfect way to checkup everyhting
            // Returns S_OK (=0) if the sample is a break in the data stream. Otherwise, returns S_FALSE (=1).
            var hr = sample.IsDiscontinuity();
            var isDicontinuity = (hr == 0);
            Trace.WriteLine("Is discontinuity => " + isDicontinuity);


            // Check if the sample is a preroll sample.
            // Preroll samples are processed but not displayed. They are located in the media stream before the displayable samples.
            // Returns S_OK (=0) if the sample is a preroll sample. Otherwise, returns S_FALSE (=1).
            hr = sample.IsPreroll();
            var isPreroll = (hr == 0);
            Trace.WriteLine("Is preroll => " + isPreroll);

            // Determine if the beginning of this sample is a synchronization point.
            // A filter can begin a stream at any synchronization point.
            // With some compression types, streaming can begin only at certain points in the stream; for example, on key frames.
            // If the bTemporalCompression member of the AM_MEDIA_TYPE structure is FALSE, all samples are synchronization points.
            // Returns S_OK (=0) if the sample is a synchronization point. Otherwise, returns S_FALSE (=1).
            hr = sample.IsSyncPoint();
            var isSyncPoint = (hr == 0);
            Trace.WriteLine("Is syncpoint => " + isSyncPoint);

            // Get the pointer to the media sample''s buffer.
            // The buffer memory is owned by the media sample object, and is automatically released when the media sample is destroyed.
            // The caller should not free or reallocate the buffer.
            // Returns S_OK if successful, or an HRESULT value indicating the cause of the error.
            IntPtr bufferPointer;
            hr = sample.GetPointer(out bufferPointer);
            Trace.WriteLine(String.Format("Buffer-pointer => " + DsError.GetErrorText(hr) + " bufferpointer is at " + bufferPointer.ToInt32()));

            // Retrieve the size of the buffer, in bytes.
            // The size does not include the prefix bytes, if any.
            var bufferSize = sample.GetSize();
            Trace.WriteLine(string.Format("Buffer size is {0}", bufferSize));

            // The GetActualDataLength method retrieves the length of the valid data in the buffer.
            var actualDataSize = sample.GetActualDataLength();
            Trace.WriteLine(string.Format("Actual data lenth is {0}", actualDataSize));

            if (isDicontinuity || isPreroll)
            {
                Trace.WriteLine(
                    "dropped sample , or a seek , or a preroll , we will not check mediatype or media-start/-end  ");
                return;

            }
            // Get media start and end time
            long timeStart;
            long timeEnd;
            hr = sample.GetMediaTime(out timeStart, out timeEnd);
            Trace.WriteLine(string.Format("GetMediaStart => {0} media start is {1} , media end is {2}", DsError.GetErrorText(hr) , timeStart , timeEnd));

            // Get the mediatype for the sample
            AMMediaType mediaType;
            hr = sample.GetMediaType(out mediaType);
            Trace.WriteLine(string.Format("GetMediaType => {0}",DsError.GetErrorText(hr) ));


        }
    }



和我的活动:



and my on event :

private void OnEventBufferCb(object sender,double sampleTime, IntPtr buffer, int bufferLength)
{
    RaiseSampleBufferChanged(sampleTime, buffer, bufferLength);
}



任何我的init:



any my init :

// voeg de null renderer toe
// **********************
Tracer.Write(this, "filtergraph connect pins");

// connect source-filter met samplegrabber filter
var loutPin = DsFindPin.ByDirection(pGraphFilterSource, PinDirection.Output, 0);
var lInPin = DsFindPin.ByDirection(pGraphFilterSampleGrabber, PinDirection.Input, 0);
pHr = pGraphManager.Connect(loutPin, lInPin);
DsError.ThrowExceptionForHR(pHr);

// connect samplegrabber-filter met null-filter
loutPin = DsFindPin.ByDirection(pGraphFilterSampleGrabber, PinDirection.Output, 0);
lInPin = DsFindPin.ByDirection(pGraphFilterNullRenderer, PinDirection.Input, 0);
pHr = pGraphManager.Connect(loutPin, lInPin);
DsError.ThrowExceptionForHR(pHr);

// **********************
Tracer.Write(this, "filtegraph configure filtergraph");
if (pGraphSampleGrabber.GetConnectedMediaType(pMediaType) == 0)
{
    pGraphAviSampleDetector = new JMakerAviSampleDetector();
    pHr = pGraphSampleGrabber.SetBufferSamples(true);
    DsError.ThrowExceptionForHR(pHr);
    pHr = pGraphSampleGrabber.SetOneShot(false);
    DsError.ThrowExceptionForHR(pHr);

    // when set to 0 , call SampleCB
    // when set to 1 , call BufferCB
    pHr = pGraphSampleGrabber.SetCallback(pGraphAviSampleDetector, 0);
    pGraphAviSampleDetector.EventBufferCb += OnEventBufferCb;
    pGraphAviSampleDetector.EventSampleCb += OnEventSampleCb;
}


这篇关于使用自写的samplegrabber过滤器和nullrenderer DirectShow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 08:43