I had also problems with the sample grabber towards a null renderer , to be used for direct3d surfaces , this is how i solved the samplegrabber part in c# ( i use directshow.net and c#):
my sample grabber :
public class JMakerAviSampleDetector : ISampleGrabberCB
{
#region declare events
public event JDelegates.JSampleISample EventSampleCb;
public event JDelegates.JSampleBuffer EventBufferCb;
private bool pFirstTime;
#endregion
#region initialize
public JMakerAviSampleDetector()
{
pFirstTime = true;
}
#endregion
#region declare callback
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;
}
public int BufferCB(double sampleTime, IntPtr buffer, int bufferLen)
{
EventBufferCb(this, sampleTime, buffer, bufferLen);
return 0;
}
#endregion
private void ScanSampe(IMediaSample sample)
{
var hr = sample.IsDiscontinuity();
var isDicontinuity = (hr == 0);
Trace.WriteLine("Is discontinuity => " + isDicontinuity);
hr = sample.IsPreroll();
var isPreroll = (hr == 0);
Trace.WriteLine("Is preroll => " + isPreroll);
hr = sample.IsSyncPoint();
var isSyncPoint = (hr == 0);
Trace.WriteLine("Is syncpoint => " + isSyncPoint);
IntPtr bufferPointer;
hr = sample.GetPointer(out bufferPointer);
Trace.WriteLine(String.Format("Buffer-pointer => " + DsError.GetErrorText(hr) + " bufferpointer is at " + bufferPointer.ToInt32()));
var bufferSize = sample.GetSize();
Trace.WriteLine(string.Format("Buffer size is {0}", bufferSize));
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;
}
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));
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);
}
any my init :
Tracer.Write(this, "filtergraph connect pins");
var loutPin = DsFindPin.ByDirection(pGraphFilterSource, PinDirection.Output, 0);
var lInPin = DsFindPin.ByDirection(pGraphFilterSampleGrabber, PinDirection.Input, 0);
pHr = pGraphManager.Connect(loutPin, lInPin);
DsError.ThrowExceptionForHR(pHr);
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);
pHr = pGraphSampleGrabber.SetCallback(pGraphAviSampleDetector, 0);
pGraphAviSampleDetector.EventBufferCb += OnEventBufferCb;
pGraphAviSampleDetector.EventSampleCb += OnEventSampleCb;
}