2013-04-17 41 views
1

我有sony handycam連接到Easycap USB 2.0,我使用DirectShowLib-2005進行圖像捕獲。捕獲類的源代碼如下:DirectShowLib-2005 easycap USB 2.0接口與索尼handycam圖像捕獲問題

public Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, Control hControl) 
    { 
     Pic_Control = hControl; 

     DsDevice [] capDevices; 

     // Get the collection of video devices 
     capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); 

     if (iDeviceNum + 1 > capDevices.Length) 
     { 
      throw new Exception("No video capture devices found at that index!"); 
     } 

     try 
     { 
      // Set up the capture graph 
      SetupGraph(capDevices[iDeviceNum], iWidth, iHeight, iBPP, hControl); 

      // tell the callback to ignore new images 
      m_PictureReady = new ManualResetEvent(false); 
     } 
     catch 
     { 
      Dispose(); 
      throw; 
     } 
    } 


    private void SetupGraph(DsDevice dev, int iWidth, int iHeight, short iBPP, Control hControl) 
    { 
     int hr; 

     ISampleGrabber sampGrabber = null; 
     IBaseFilter capFilter = null; 
     IPin pCaptureOut = null; 
     IPin pSampleIn = null; 
     IPin pRenderIn = null; 

     // Get the graphbuilder object 
     m_FilterGraph = new FilterGraph() as IFilterGraph2; 

     try 
     { 

      m_rot = new DsROTEntry(m_FilterGraph); 

      // add the video input device 
      hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); 
      DsError.ThrowExceptionForHR(hr); 

      // Find the still pin 
      m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); 

      // Didn't find one. Is there a preview pin? 
      if (m_pinStill == null) 
      { 
       m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); 
      } 

      // Still haven't found one. Need to put a splitter in so we have 
      // one stream to capture the bitmap from, and one to display. Ok, we 
      // don't *have* to do it that way, but we are going to anyway. 
      if (m_pinStill == null) 
      { 
       IPin pRaw = null; 
       IPin pSmart = null; 

       // There is no still pin 
       m_VidControl = null; 

       // Add a splitter 
       IBaseFilter iSmartTee = (IBaseFilter)new SmartTee(); 

       try 
       { 
        hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee"); 
        DsError.ThrowExceptionForHR(hr); 

        // Find the find the capture pin from the video device and the 
        // input pin for the splitter, and connnect them 
        pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); 
        pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0); 

        hr = m_FilterGraph.Connect(pRaw, pSmart); 
        DsError.ThrowExceptionForHR(hr); 

        // Now set the capture and still pins (from the splitter) 
        m_pinStill = DsFindPin.ByName(iSmartTee, "Preview"); 
        pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture"); 

        // If any of the default config items are set, perform the config 
        // on the actual video device (rather than the splitter) 
        if (iHeight + iWidth + iBPP > 0) 
        { 
         SetConfigParms(pRaw, iWidth, iHeight, iBPP); 
        } 
       } 
       finally 
       { 
        if (pRaw != null) 
        { 
         Marshal.ReleaseComObject(pRaw); 
        } 
        if (pRaw != pSmart) 
        { 
         Marshal.ReleaseComObject(pSmart); 
        } 
        if (pRaw != iSmartTee) 
        { 
         Marshal.ReleaseComObject(iSmartTee); 
        } 
       } 
      } 
      else 
      { 
       // Get a control pointer (used in Click()) 
       m_VidControl = capFilter as IAMVideoControl; 

       pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); 

       // If any of the default config items are set 
       if (iHeight + iWidth + iBPP > 0) 
       { 
        SetConfigParms(m_pinStill, iWidth, iHeight, iBPP); 
       } 
      } 

      // Get the SampleGrabber interface 
      sampGrabber = new SampleGrabber() as ISampleGrabber; 

      // Configure the sample grabber 
      IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; 
      ConfigureSampleGrabber(sampGrabber); 
      pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); 

      // Get the default video renderer 
      IBaseFilter pRenderer = new VideoRendererDefault() as IBaseFilter; 
      hr = m_FilterGraph.AddFilter(pRenderer, "Renderer"); 
      DsError.ThrowExceptionForHR(hr); 

      pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); 

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

      if (m_VidControl == null) 
      { 
       // Connect the Still pin to the sample grabber 
       hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); 
       DsError.ThrowExceptionForHR(hr); 

       // Connect the capture pin to the renderer 
       hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); 
       DsError.ThrowExceptionForHR(hr); 
      } 
      else 
      { 
       // Connect the capture pin to the renderer 
       hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); 
       DsError.ThrowExceptionForHR(hr); 

       // Connect the Still pin to the sample grabber 
       hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); 
       DsError.ThrowExceptionForHR(hr); 
      } 

      // Learn the video properties 
      SaveSizeInfo(sampGrabber); 
      ConfigVideoWindow(hControl); 

      // Start the graph 
      IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; 
      hr = mediaCtrl.Run(); 
      DsError.ThrowExceptionForHR(hr); 
     } 
     finally 
     { 
      if (sampGrabber != null) 
      { 
       Marshal.ReleaseComObject(sampGrabber); 
       sampGrabber = null; 
      } 
      if (pCaptureOut != null) 
      { 
       Marshal.ReleaseComObject(pCaptureOut); 
       pCaptureOut = null; 
      } 
      if (pRenderIn != null) 
      { 
       Marshal.ReleaseComObject(pRenderIn); 
       pRenderIn = null; 
      } 
      if (pSampleIn != null) 
      { 
       Marshal.ReleaseComObject(pSampleIn); 
       pSampleIn = null; 
      } 
     } 
    } 

    private void SaveSizeInfo(ISampleGrabber sampGrabber) 
    { 
     int hr; 

     // Get the media type from the SampleGrabber 
     AMMediaType media = new AMMediaType(); 

     hr = sampGrabber.GetConnectedMediaType(media); 
     DsError.ThrowExceptionForHR(hr); 

     if((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero)) 
     { 
      throw new NotSupportedException("Unknown Grabber Media Format"); 
     } 

     // Grab the size info 
     VideoInfoHeader videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); 
     m_videoWidth = videoInfoHeader.BmiHeader.Width; 
     m_videoHeight = videoInfoHeader.BmiHeader.Height; 
     m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount/8); 

     DsUtils.FreeAMMediaType(media); 
     media = null; 
    } 


    private void ConfigVideoWindow(Control hControl) 
    { 
     int hr; 

     IVideoWindow ivw = m_FilterGraph as IVideoWindow; 

     // Set the parent 
     hr = ivw.put_Owner(hControl.Handle); 
     DsError.ThrowExceptionForHR(hr); 

     // Turn off captions, etc 
     hr = ivw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings); 
     DsError.ThrowExceptionForHR(hr); 

     // Yes, make it visible 
     hr = ivw.put_Visible(OABool.True); 
     DsError.ThrowExceptionForHR(hr); 

     // Move to upper left corner 
     Rectangle rc = hControl.ClientRectangle; 
     hr = ivw.SetWindowPosition(0, 0, rc.Right, rc.Bottom); 
     DsError.ThrowExceptionForHR(hr); 
    } 

    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); 
    } 


    private void SetConfigParms(IPin pStill, int iWidth, int iHeight, short iBPP) 
    { 
     int hr; 
     AMMediaType media; 
     VideoInfoHeader v; 

     IAMStreamConfig videoStreamConfig = pStill as IAMStreamConfig; 

     // Get the existing format block 
     hr = videoStreamConfig.GetFormat(out media); 
     DsError.ThrowExceptionForHR(hr); 

     try 
     { 
      // copy out the videoinfoheader 
      v = new VideoInfoHeader(); 
      Marshal.PtrToStructure(media.formatPtr, v); 

      // if overriding the width, set the width 
      if (iWidth > 0) 
      { 
       v.BmiHeader.Width = iWidth; 
      } 

      // if overriding the Height, set the Height 
      if (iHeight > 0) 
      { 
       v.BmiHeader.Height = iHeight; 
      } 

      // if overriding the bits per pixel 
      if (iBPP > 0) 
      { 
       v.BmiHeader.BitCount = iBPP; 
      } 

      // Copy the media structure back 
      Marshal.StructureToPtr(v, media.formatPtr, false); 

      // Set the new format 
      hr = videoStreamConfig.SetFormat(media); 
      DsError.ThrowExceptionForHR(hr); 
     } 
     finally 
     { 
      DsUtils.FreeAMMediaType(media); 
      media = null; 
     } 
    } 

的代碼投擲在該行的異常: HR = mediaCtrl.Run();

hr的返回的值是-2147023729

由於這種圖像捕獲的不工作。有人可以幫我解決這個錯誤嗎?

回答