Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing ISampleGrabberCB::SampleCB
    text
    copied!<p>Hi i'm trying to use the <code>ISampleGrabberCB::SampleCB</code> to get the images from a live preview just before they are shown within my form.</p> <p>I would like to be able to convert every new frame into a bitmap to be processed (e.g. scan + add watermark type image).</p> <p>Currently I am trying to do it in the following way:</p> <pre><code>int ISampleGrabberCB.SampleCB(double SampleTime, IMediaSample sample) { int hr; IntPtr buffer; AMMediaType mediaType; VideoInfoHeader videoInfo; int frameWidth; int frameHeight; int stride; int bufferLength; hr = sample.GetPointer(out buffer); DsError.ThrowExceptionForHR(hr); hr = sample.GetMediaType(out mediaType); DsError.ThrowExceptionForHR(hr); bufferLength = sample.GetSize(); try { videoInfo = new VideoInfoHeader(); Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); frameWidth = videoInfo.BmiHeader.Width; frameHeight = videoInfo.BmiHeader.Height; stride = frameWidth * (videoInfo.BmiHeader.BitCount / 8); CopyMemory(imageBuffer, buffer, bufferLength); Bitmap bitmapOfFrame = new Bitmap(frameWidth, frameHeight, stride, PixelFormat.Format24bppRgb, buffer); bitmapOfFrame.Save("C:\\Users\\...\\...\\...\\....jpg"); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return 0; } </code></pre> <p>This theoretically should get the media type which is then used to get the width, height and stride of the image which is then used to create the bitmap. The buffer is then obtained from the pointer of the IMediaSample.</p> <p>However this does not seem to work (I am presuming this as the bitmap never saves). So how would I go about converting every new frame into a bitmap?</p> <p>Additonal function where pins are set:</p> <pre><code>public void setupGraphForSampleGrabber(DsDevice webcamDevice, Control displayBox) { int hr; ISampleGrabber sampleGrabber = null; IPin capturePin = null; IPin samplePin = null; IPin renderPin = null; IBaseFilter captureFilter; filtergraph = new FilterGraph() as IFilterGraph2; try { //Add the webcam hr = filtergraph.AddSourceFilterForMoniker(webcamDevice.Mon, null, webcamDevice.Name, out captureFilter); DsError.ThrowExceptionForHR(hr); //Get the still pin stillPin = DsFindPin.ByCategory(captureFilter, PinCategory.Still, 0); if (stillPin == null) { stillPin = DsFindPin.ByCategory(captureFilter, PinCategory.Preview, 0); } if (stillPin == null) { IPin outputPin = null; IPin inputPin = null; //As there is still no still pin set this to null videoControl = null; // Add a splitter IBaseFilter smartTee = (IBaseFilter)new SmartTee(); try { hr = filtergraph.AddFilter(smartTee, "SmartTee"); DsError.ThrowExceptionForHR(hr); //Obtain the capture pin from the webcam and the input pin from the spliter and assign them to the outputPin and inputPin respectivly outputPin = DsFindPin.ByCategory(captureFilter, PinCategory.Capture, 0); inputPin = DsFindPin.ByDirection(smartTee, PinDirection.Input, 0); //Then connect both of them to the graph hr = filtergraph.Connect(outputPin, inputPin); DsError.ThrowExceptionForHR(hr); //Set the capture and still pins so we can use them with the rest of the program stillPin = DsFindPin.ByName(smartTee, "Preview"); capturePin = DsFindPin.ByName(smartTee, "Capture"); setParameters(outputPin); } //Release all the com objects to avoid problems as the program is to be used for extended periods finally { if (outputPin != null) { Marshal.ReleaseComObject(outputPin); } if (outputPin != inputPin) { Marshal.ReleaseComObject(inputPin); } if (outputPin != smartTee) { Marshal.ReleaseComObject(smartTee); } } } else { videoControl = captureFilter as IAMVideoControl; capturePin = DsFindPin.ByCategory(captureFilter, PinCategory.Capture, 0); setParameters(stillPin); } //Get interface sampleGrabber = new SampleGrabber() as ISampleGrabber; //Configure the samplegrabber IBaseFilter baseFilter = sampleGrabber as IBaseFilter; configureSampleGrabber(sampleGrabber); samplePin = DsFindPin.ByDirection(baseFilter, PinDirection.Input, 0); //Video Renderer IBaseFilter render = new VideoRendererDefault() as IBaseFilter; hr = filtergraph.AddFilter(render, "Renderer"); DsError.ThrowExceptionForHR(hr); renderPin = DsFindPin.ByDirection(render, PinDirection.Input, 0); //Add samplegrabber to graph hr = filtergraph.AddFilter(baseFilter, "SampleGrabber"); DsError.ThrowExceptionForHR(hr); if (videoControl == null) { //Connect still pin to samplegrabber hr = filtergraph.Connect(stillPin, samplePin); DsError.ThrowExceptionForHR(hr); //Connect capture pin to render hr = filtergraph.Connect(capturePin, renderPin); DsError.ThrowExceptionForHR(hr); } else { //Connect capture pin to render hr = filtergraph.Connect(capturePin, renderPin); DsError.ThrowExceptionForHR(hr); //Connect still pin to samplegrabber hr = filtergraph.Connect(stillPin, samplePin); DsError.ThrowExceptionForHR(hr); } //Get video properties saveVideoInfo(sampleGrabber); ConfigureVideoLocation(displayBox); //Run Graph IMediaControl mediaControl = filtergraph as IMediaControl; hr = mediaControl.Run(); DsError.ThrowExceptionForHR(hr); } finally { if (sampleGrabber != null) { Marshal.ReleaseComObject(sampleGrabber); sampleGrabber = null; } if (capturePin != null) { Marshal.ReleaseComObject(capturePin); capturePin = null; } if (renderPin != null) { Marshal.ReleaseComObject(renderPin); renderPin = null; } if (samplePin != null) { Marshal.ReleaseComObject(samplePin); samplePin = null; } } } </code></pre> <p>Furthermore I configure my samplegrabber like this:</p> <pre><code> public void configureSampleGrabber(ISampleGrabber sampleGrabber) { int hr; AMMediaType mediaType = new AMMediaType(); //Set the values for media type and format mediaType.majorType = MediaType.Video; mediaType.subType = MediaSubType.RGB24; mediaType.formatType = FormatType.VideoInfo; hr = sampleGrabber.SetMediaType(mediaType); DsError.ThrowExceptionForHR(hr); DsUtils.FreeAMMediaType(mediaType); mediaType = null; //Configure hr = sampleGrabber.SetCallback(this, 0); DsError.ThrowExceptionForHR(hr); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload