2016-04-11 14 views
0

USBのデバイスはレガートゲームのキャプチャです。 pictureBox1のストリーミングプレビューではデバイスからのビデオが表示されますが、pictureBox1から画像として保存できるのはピクセルではありません。私はどのように私はDirectShowを使用してストリーミングプレビューから画像/ビデオを保存することができるグラフにサンプルグラバーフィルターを追加できますか?

「実際に表示されていないウィンドウのショットをつかむための方法はありません。ウィンドウが完全に表示されていない場合は、それらのピクセルは、単に存在しません。」

もう一つの問題は、私ができることですレガートのゲームキャプチャデバイスをグラフェンディットで見つけることはできません。私もgraphedit plusを試しました。しかし、レガート装置はリストには存在しません。

これは、今私は、サンプルグラバで使用するには、このメソッドを追加しようとした私は、プレビューを作成し、pictureBox1

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using DirectShowLib; 
using DirectShowLib.BDA; 
using DirectShowLib.DES; 
using DirectShowLib.DMO; 
using DirectShowLib.Dvd; 
using DirectShowLib.MultimediaStreaming; 
using DirectShowLib.SBE; 
using System.Runtime.InteropServices; 
using System.Management; 
using System.IO; 
using System.Drawing.Imaging; 


namespace Youtube_Manager 
{ 

    public partial class Elgato_Video_Capture : Form 
    { 


     IFileSinkFilter sink; 

     IFilterGraph2 graph; 
     ICaptureGraphBuilder2 captureGraph; 
     System.Drawing.Size videoSize; 

     string error = ""; 
     List<Object> devices = new List<Object>(); 
     IMediaControl mediaControl; 

     public Elgato_Video_Capture() 
     { 
      InitializeComponent(); 



      if (comboBox1.Items.Count == 0) 
      { 
       for (int xx = 1; xx <= 8; xx++) 
       { 
        comboBox1.Items.Add(xx); 
       } 
      } 

      InitDevice(); 
      timer1.Start(); 
     } 

     IBaseFilter smartTeeFilter; 
     IPin outPin; 
     IPin inPin; 
     private void InitDevice() 
     { 
      try 
      { 
       //Set the video size to use for capture and recording 
       videoSize = new Size(827, 505);//1280, 720); 

       //Initialize filter graph and capture graph 
       graph = (IFilterGraph2)new FilterGraph(); 
       captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); 
       captureGraph.SetFiltergraph(graph); 
       //Create filter for Elgato 
       Guid elgatoGuid = new Guid("39F50F4C-99E1-464A-B6F9-D605B4FB5918"); 
       Type comType = Type.GetTypeFromCLSID(elgatoGuid); 
       IBaseFilter elgatoFilter = (IBaseFilter)Activator.CreateInstance(comType); 
       graph.AddFilter(elgatoFilter, "Elgato Video Capture Filter"); 

       //Create smart tee filter, add to graph, connect Elgato's video out to smart tee in 
       smartTeeFilter = (IBaseFilter)new SmartTee(); 

       graph.AddFilter(smartTeeFilter, "Smart Tee"); 
       outPin = GetPin(elgatoFilter, "Video"); 
       inPin = GetPin(smartTeeFilter, "Input"); 
       SetAndGetAllAvailableResolution(outPin); 
       graph.Connect(outPin, inPin); 


       //Create video renderer filter, add it to graph, connect smartTee Preview pin to video renderer's input pin 
       IBaseFilter videoRendererFilter = (IBaseFilter)new VideoRenderer(); 

       graph.AddFilter(videoRendererFilter, "Video Renderer"); 
       outPin = GetPin(smartTeeFilter, "Preview"); 

       inPin = GetPin(videoRendererFilter, "Input"); 
       graph.Connect(outPin, inPin); 

       // int hr = graph.Connect(outPin, inPin); ; 
       // DsError.ThrowExceptionForHR(hr); 

       captureGraph.SetOutputFileName(MediaSubType.Avi, @"e:\screenshots\test1.mp4", out smartTeeFilter, out sink); 

       //Render stream from video renderer 
       captureGraph.RenderStream(PinCategory.VideoPort, MediaType.Video, videoRendererFilter, null, null); 
       //Set the video preview to be the videoFeed panel 
       IVideoWindow vw = (IVideoWindow)graph; 
       vw.put_Owner(pictureBox1.Handle); 
       vw.put_MessageDrain(this.Handle); 
       vw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren); 
       vw.SetWindowPosition(0, 0, 827, 505); 

       //Start the preview 
       mediaControl = graph as IMediaControl; 
       mediaControl.Run(); 
      } 
      catch (Exception err) 
      { 
       error = err.ToString(); 
      } 
     } 

     IPin GetPin(IBaseFilter filter, string pinname) 
     { 
      IEnumPins epins; 
      int hr = filter.EnumPins(out epins); 
      checkHR(hr, "Can't enumerate pins"); 
      IntPtr fetched = Marshal.AllocCoTaskMem(4); 
      IPin[] pins = new IPin[1]; 
      while (epins.Next(1, pins, fetched) == 0) 
      { 
       PinInfo pinfo; 
       pins[0].QueryPinInfo(out pinfo); 
       bool found = (pinfo.name == pinname); 
       DsUtils.FreePinInfo(pinfo); 
       if (found) 
        return pins[0]; 
      } 
      checkHR(-1, "Pin not found"); 
      return null; 
     } 

     public void checkHR(int hr, string msg) 
     { 
      if (hr < 0) 
      { 
       MessageBox.Show(msg); 
       DsError.ThrowExceptionForHR(hr); 
      } 



     } 

     public void SetAndGetAllAvailableResolution(IPin VideoOutPin) 
     { 
      int hr = 0; 
      IAMStreamConfig streamConfig = (IAMStreamConfig)VideoOutPin; 
      AMMediaType searchmedia; 
      AMMediaType CorectvidFormat = new AMMediaType(); 
      IntPtr ptr; 
      int piCount, piSize; 
      hr = streamConfig.GetNumberOfCapabilities(out piCount, out piSize); 
      ptr = Marshal.AllocCoTaskMem(piSize); 
      for (int i = 0; i < piCount; i++) 
      { 
       hr = streamConfig.GetStreamCaps(i, out searchmedia, ptr); 
       VideoInfoHeader v = new VideoInfoHeader(); 

       Marshal.PtrToStructure(searchmedia.formatPtr, v); 
       if (i == 2)// 4 
       { 
        CorectvidFormat = searchmedia; 
       } 
      } 
      hr = streamConfig.SetFormat(CorectvidFormat); 

      IntPtr pmt = IntPtr.Zero; 
      AMMediaType mediaType = new AMMediaType(); 
      IAMStreamConfig streamConfig1 = (IAMStreamConfig)VideoOutPin; 
      hr = streamConfig1.GetFormat(out mediaType); 
      BitmapInfoHeader bmpih = new BitmapInfoHeader(); 
      Marshal.PtrToStructure(mediaType.formatPtr, bmpih); 
     } 
    } 
} 

でそれをストリーミングしてる方法です:

private void AddSampleGrabber(int hr, Guid elgatoguid, IFilterGraph2 pGraph) 
     { 
      //add SampleGrabber 
      IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(elgatoguid)); 
      hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber"); 
      checkHR(hr, "Can't add SampleGrabber to graph"); 
      //set callback 
      hr = ((ISampleGrabber)pSampleGrabber).SetCallback(new SampleGrabberCallback(), 0); 
      checkHR(hr, "Can't set callback."); 

      AMMediaType pmt = new AMMediaType(); 
      pmt.majorType = MediaType.Video; 
      pmt.subType = MediaSubType.YUY2; 
      pmt.formatType = FormatType.VideoInfo; 
      pmt.fixedSizeSamples = true; 
      pmt.formatSize = 88; 
      pmt.sampleSize = 614400; 
      pmt.temporalCompression = false; 
      VideoInfoHeader format = new VideoInfoHeader(); 
      format.SrcRect = new DsRect(); 
      format.TargetRect = new DsRect(); 
      format.BmiHeader = new BitmapInfoHeader(); 
      format.BmiHeader.Size = 40; 
      format.BmiHeader.Width = 640; 
      format.BmiHeader.Height = 480; 
      format.BmiHeader.Planes = 1; 
      format.BmiHeader.BitCount = 16; 
      format.BmiHeader.Compression = 844715353; 
      format.BmiHeader.ImageSize = 614400; 
      pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(format)); 
      Marshal.StructureToPtr(format, pmt.formatPtr, false); 
      hr = ((IAMStreamConfig)GetPin(smartTeeFilter, "Capture")).SetFormat(pmt); 
      DsUtils.FreeAMMediaType(pmt); 
      checkHR(hr, "Can't set format"); 

      //connect USB2.0 Camera and SampleGrabber 
      hr = pGraph.ConnectDirect(GetPin(smartTeeFilter, "Capture"), GetPin(pSampleGrabber, "Input"), null); 
      checkHR(hr, "Can't connect USB2.0 Camera and SampleGrabber"); 

      //render the video 
      hr = captureGraph.RenderStream(null, null, pSampleGrabber, null, null); 
      checkHR(hr, "Can't render video from grabber"); 

     } 

     class SampleGrabberCallback : ISampleGrabberCB 
     { 
      public SampleGrabberCallback() 
      { 
      } 

      public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen) 
      { 
       return 0; 
      } 

      public int SampleCB(double SampleTime, IMediaSample pSample) 
      { 
       if (pSample == null) return -1; 
       int len = pSample.GetActualDataLength(); 
       IntPtr pbuf; 
       if (pSample.GetPointer(out pbuf) == 0 && len > 0) 
       { 
        byte[] buf = new byte[len]; 
        Marshal.Copy(pbuf, buf, 0, len); 
        for (int i = 0; i < len; i += 2) 
         buf[i] = (byte)(255 - buf[i]); 
        Marshal.Copy(buf, 0, pbuf, len); 
       } 
       return 0; 
      } 
     } 

しかし、私は

hr = ((ISampleGrabber)pSampleGrabber).SetCallback(new SampleGrabberCallback(), 0); 

タイプ 'System .__ ComObject'のCOMオブジェクトをinterにキャストすることができません。フェイスタイプ 'DirectShowLib.ISampleGrabber'。この操作はIID '{6B652FFF-11FE-4FCE-92AD-0266B5D7C78F}'のインターフェイスのCOMコンポーネントのQueryInterface呼び出しが次のエラーで失敗したため失敗しました:このようなインターフェイスはサポートされていません(HRESULT:0x80004002(E_NOINTERFACE)例外)

私はまったくそれを使用していないと思います。 また、ストリーミングのイメージやビデオを後で(ハードディスクに保存する)使用する方法もわかりません。

答えて

0

pSampleGrabberのコードは意味をなさない。これは、Sample Grabber FilterインスタンスへのCOMポインタを想定しています。 ISampleGrabberを実装する他のフィルタはありません。ただし(E_NOINTERFACEはまさにこのことをあなたに伝えます!)あることを想定されていないものにビデオキャプチャフィルタをキャストしようとしている。

IBaseFilter pSampleGrabber = 
    (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(elgatoguid)); 

あなたはその後、サンプルグラバーインスタンスを作成し、ビデオキャプチャフィルタを追加する必要があり、その後、接続します二つ。グラバーの出力をレンダリングします。次にコールバックをグラバーインスタンスに関連付けます。

+0

ローマ様ありがとうございます。聞こえにくい音。やってみます。 –

+0

最初の手順でビデオキャプチャフィルタを追加する方法はまだ見つかりません。 Googleにしようとしたが見つかりませんでした。それはとても難しいですか? –

+0

キャプチャフィルタが作成され、最初に投稿されたコードスニペット( 'elgatoFilter'の周り)のグラフに追加されます。 –

関連する問題