问题描述
描述:
为了从视频中获取指定的帧,我在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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!