0

i developed in windows application in C#.NET4.0 with Directshow Lib,for recording video using webcam.during video recording i put an overlay text by grabing frame in BufferCB and put my overlay bitmap on frame.

This application with overlay is working fine. but after some days overlay text is not coming so i tried to identify the problem then i realise that BufferCB not getting call. SetCallback() function is returning 0 means not error in it.Then why BufferCB is not getting Call?

Edit

Button click code for starting recording,config samplegrabber get video size info etc.

private void button1_Click(object sender, EventArgs e)
    {

        jpg.RotateFlip(RotateFlipType.RotateNoneFlipY);
        //jpgdata = jpg.LockBits(new Rectangle(0, 0, jpg.Width, jpg.Height), ImageLockMode.ReadWrite, jpg.PixelFormat);
        AvailableAudioInputDevices = new List<DsDevice>();
        DsDevice[] audioInputDevices = DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDevice);
        AvailableAudioInputDevices.AddRange(audioInputDevices);

        AvailableVideoInputDevices = new List<DsDevice>();
        DsDevice[] videoInputDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
        AvailableVideoInputDevices.AddRange(videoInputDevices);

        Graph = (IFilterGraph2)new FilterGraph();
        captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();

        hr = captureGraph.SetFiltergraph(Graph);
        DsError.ThrowExceptionForHR(hr);

        hr = captureGraph.SetOutputFileName(MediaSubType.Asf, "qwe.wmv", out pMux, out pFilter);
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.AddSourceFilterForMoniker(AvailableAudioInputDevices.First().Mon, null, AvailableAudioInputDevices.First().Name, out capFilter);
        DsError.ThrowExceptionForHR(hr);

        //ConfigProfileFromFile(pMux, "b.prx");

        hr = captureGraph.RenderStream(PinCategory.Capture, MediaType.Audio, capFilter, null, pMux);
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.AddSourceFilterForMoniker(AvailableVideoInputDevices.First().Mon, null, AvailableVideoInputDevices.First().Name, out capFilter);
        DsError.ThrowExceptionForHR(hr);
        #region code for init. preview window and sample grabber
        mediaControl = (IMediaControl)Graph;
        mediaEventEx = (IMediaEventEx)Graph;
        mediaEventEx.SetNotifyWindow(pic.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);
        IBaseFilter vmr9preview = null;
        vmr9preview = (IBaseFilter)new VideoMixingRenderer9();
        hr = Graph.AddFilter(vmr9preview, "VMR9");
        DsError.ThrowExceptionForHR(hr);
        IVMRFilterConfig9 vmr9Config = (IVMRFilterConfig9)vmr9preview;
        vmr9Config.SetRenderingMode(VMR9Mode.Windowless);
        vmr9Config.SetNumberOfStreams(1);
        vmr9Control = (IVMRWindowlessControl9)vmr9preview;
        vmr9Control.SetVideoClippingWindow(pic.Handle);
        vmr9Control.SetAspectRatioMode(VMR9AspectRatioMode.None);
        var srcRect = new DsRect();
        var dstRect = new DsRect(pic.ClientRectangle);
        int arWidth, arHeight;
        vmr9Control.GetNativeVideoSize(out srcRect.right, out srcRect.bottom, out arWidth, out arHeight);
        vmr9Control.SetVideoPosition(srcRect, dstRect);
        sampGrabber = new SampleGrabber() as ISampleGrabber;
        #endregion

        #region code for get video info and config sample grabber
        IPin iPinOutSource = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);
        // Configure the sample grabber
        IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter;
        ConfigureSampleGrabber(sampGrabber);
        iPinInFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);
        iPinOutFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0);

        // Add the frame grabber to the graph
        hr = Graph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.Connect(iPinOutSource, iPinInFilter);
        DsError.ThrowExceptionForHR(hr);

        // Get the default video renderer
        ibfRenderer = (IBaseFilter)new VideoRendererDefault();

        // Add it to the graph
        hr = Graph.AddFilter(ibfRenderer, "Ds.NET VideoRendererDefault");
        DsError.ThrowExceptionForHR(hr);
        iPinInDest = DsFindPin.ByDirection(ibfRenderer, PinDirection.Input, 0);

        // Connect the graph.  Many other filters automatically get added here
        hr = Graph.Connect(iPinOutFilter, iPinInDest);
        DsError.ThrowExceptionForHR(hr);
        SaveSizeInfo(sampGrabber);
        hr = Graph.RemoveFilter(baseGrabFlt);
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.Disconnect(iPinOutSource);
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.RemoveFilter(ibfRenderer);
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.Disconnect(iPinInDest);
        DsError.ThrowExceptionForHR(hr);
        #endregion
        ConfigProfileFromFile(pMux, "b.prx");

        hr = Graph.AddFilter(capFilter, "VMR9");
        DsError.ThrowExceptionForHR(hr);

        hr = Graph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
        DsError.ThrowExceptionForHR(hr);

        hr = captureGraph.RenderStream(PinCategory.Preview, MediaType.Video, capFilter, null, vmr9preview);
        DsError.ThrowExceptionForHR(hr);
        hr = captureGraph.RenderStream(PinCategory.Capture, MediaType.Video, capFilter, null, pMux);
        DsError.ThrowExceptionForHR(hr);


        m_mediaCtrl = Graph as IMediaControl;
        SetupBitmap();
        m_mediaCtrl.Run();
        //timer1.Start();             
    }

Config Sample Grabber method

private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
    {
        int hr;
        AMMediaType media = new AMMediaType();

        // Set the media type to Video/RBG24
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.RGB24;
        media.formatType = FormatType.VideoInfo;
        hr = sampGrabber.SetMediaType(media);
        DsError.ThrowExceptionForHR(hr);

        DsUtils.FreeAMMediaType(media);
        media = null;

        // Configure the samplegrabber
        hr = sampGrabber.SetCallback(this, 1);
        DsError.ThrowExceptionForHR(hr);
    }

BufferCB and SampleCB

 int ISampleGrabberCB.SampleCB(double SampleTime, IMediaSample pSample)
    {
        Marshal.ReleaseComObject(pSample);
        return 0;
    }

    [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
    static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);
    /// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
    int ISampleGrabberCB.BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
    {    
        CopyMemory(pBuffer, bmpData.Scan0, bmpData.Stride*20);
        return 0;
    }
Amogh
  • 4,453
  • 11
  • 45
  • 106
  • And your code is? A cleaner way to overlay is `SampleCB`, not `BufferCB`. – Roman R. Sep 28 '12 at 11:02
  • Hey Roman, i edited my question with code.currently i m looking to my code and come to know one intresting thing.if i connect Logitech webcam then bufferCB is get called and overlay text is coming but if i connect intex or Iball webcam than BufferCB is not geting call on Arrival of frame.Why? – Amogh Sep 28 '12 at 11:45
  • @RomanR. i tried with SampleCB also but it doesn't get call when i chnage the webcam. – Amogh Sep 29 '12 at 07:12
  • Did you have a chance to check what real topology you are getting after all connection is done? – Roman R. Oct 01 '12 at 05:42
  • [Loading a Graph From an External Process](http://msdn.microsoft.com/en-us/library/windows/desktop/dd390650%28v=vs.85%29.aspx) + [How can I reverse engineer a DirectShow graph?](http://stackoverflow.com/questions/27832/how-can-i-reverse-engineer-a-directshow-graph) – Roman R. Oct 04 '12 at 06:18
  • @RomanR. hello sir now i can able load a graph. here is [link](http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/42f61936-c023-4873-a777-b5b61aa0c070) can you u guide me further? – Amogh Nov 17 '12 at 07:26

0 Answers0