2011-06-15 15 views
9

Estoy intentando capturar 720p de una a blackmagic intensity pro cards usando la última SDK (junio de 2011) en windows7 64x y con C# + VS 2010 express.blackmagic SDK en C#

he compilado y ejecutado con éxito un programa que captura fotogramas en YUV, sin embargo, la captura se detiene después de 56 fotogramas (la función de devolución de llamada deja de llamarse). Me pregunto si me está perdiendo algo simple aquí. especialmente dado que casi estoy allí, obtengo marcos con el contenido correcto con el tamaño correcto, etc., pero solo por un breve tiempo.

también alguna otra información que pueda ser relevante:

  • si desconecto el captura de la cámara no se detiene
  • también he intentado esto en 1080i y PAL y lo mismo sucede
  • lo mismo sucede incluso si la función VideoInputFrameArrived está vacía (es decir, con sólo un contador de tramas en ella)

aquí es el código:


public partial class MainWindow : Window , IDeckLinkInputCallback 
{ 
    private IDeckLinkIterator _deckLinkIterator; 
    private List<IDeckLink>  _deckLinkList = new List<IDeckLink>(); 
    private IDeckLink   _currentDevice=null; 
    private IDeckLinkInput  _deckLinkInput = null; 

    private int _width=1280; 
    private int _height=720; 

    private WriteableBitmap _writeableBitmap =null; 

    IntPtr _tempRGBData; 
    byte[] _tempRGBDataBytes; 

    DispatcherTimer _timer = new DispatcherTimer(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    Random _random = new Random(); 

    void _timer_Tick(object sender, EventArgs e) 
    { 
     _random.NextBytes(_tempRGBDataBytes); 

     _writeableBitmap.WritePixels(new Int32Rect(0, 0, _width, _height),_tempRGBData, _height * _width * 3, _width * 3); 
    } 


    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     _writeableBitmap = new WriteableBitmap(_width, _height, 72, 27, PixelFormats.Bgr24, null); 
     _captureImage.Source = _writeableBitmap; 

     _tempRGBData = Marshal.AllocHGlobal(3 * _width * _height * Marshal.SizeOf(typeof(byte))); 
     _tempRGBDataBytes = new byte[3 * _width * _height]; 
     _deckLinkIterator = new CDeckLinkIterator(); 


     IDeckLink dl=null; 
     while(true) 
     { 
      _deckLinkIterator.Next(out dl); 

      if(dl==null) 
      { 
       break; 
      } 
      else 
      { 
       _deckLinkList.Add(dl); 
      } 
     } 

     foreach (IDeckLink device in _deckLinkList) 
     { 
      String name; 
      device.GetModelName(out name); 
      Console.WriteLine("" + name); 
     } 

     _currentDevice = _deckLinkList[1]; 
     _deckLinkInput = (IDeckLinkInput)_currentDevice; 

     uint frameCount=0; 
     _deckLinkInput.GetAvailableVideoFrameCount(out frameCount); 

     Console.WriteLine("available frame count: " + frameCount); 

     IDeckLinkDisplayModeIterator displayIterator=null; 
     _deckLinkInput.GetDisplayModeIterator(out displayIterator); 


     _BMDDisplayModeSupport displayModeSupport; 
     IDeckLinkDisplayMode displayMode=null; 

     _BMDDisplayMode setDisplayMode  = _BMDDisplayMode.bmdModeHD720p50; 
     _BMDPixelFormat setPixelFormat  = _BMDPixelFormat.bmdFormat8BitYUV; 
     _BMDVideoInputFlags setInputFlag = _BMDVideoInputFlags.bmdVideoInputFlagDefault; 

     _deckLinkInput.DoesSupportVideoMode(setDisplayMode, setPixelFormat, setInputFlag, out displayModeSupport, out displayMode); 


     try 
     { 
      //_deckLinkInput.DisableAudioInput(); 
      _deckLinkInput.EnableVideoInput(setDisplayMode, setPixelFormat, setInputFlag); 

     } 
     catch (Exception em) 
     { 
      Console.WriteLine("deck link init failed: " + em.Message); 
     } 

     _deckLinkInput.SetCallback(this); 


     Console.WriteLine("done!"); 

     _timer.Interval = TimeSpan.FromSeconds(1f/30f); 
     _timer.Tick += new EventHandler(_timer_Tick); 
     _timer.Start(); 
    } 


    int frameCount = 0; 

    public void VideoInputFrameArrived(IDeckLinkVideoInputFrame video, IDeckLinkAudioInputPacket audio) 
    { 

     //get image data 
     IntPtr pData; 
     video.GetBytes(out pData); 



     //keeping it simple so just counting frames - this gets called 56 times then stops 
     Console.WriteLine("video frame arrived!! " + frameCount); 
     frameCount++; 

    } 

    public void VideoInputFormatChanged(_BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode displayMode, _BMDDetectedVideoInputFormatFlags flags) 
    { 
     Console.WriteLine("video format changed!!"); 
    } 

    //start stream 
    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     _deckLinkInput.StartStreams(); 

    } 

    //stop stream 
    private void button2_Click(object sender, RoutedEventArgs e) 
    { 
     _deckLinkInput.StopStreams(); 

    } 

    private void button4_Click(object sender, RoutedEventArgs e) 
    { 
     _deckLinkInput.PauseStreams(); 
    } 

    private void button3_Click(object sender, RoutedEventArgs e) 
    { 
     _deckLinkInput.FlushStreams(); 
    } 
} 
+0

vídeo. GetBytes() huele a pescado. Seguramente tiene que decirle al dispositivo que ha terminado de usar el marco devuelto. –

+0

sí, por supuesto. lo dejé en blanco. el problema es que la función que está dentro (la devolución de llamada) deja de llamarse después de un tiempo. –

+0

Claro, se detiene cuando se queda sin memoria. Esta API es demasiado oscura, póngase en contacto con el proveedor para obtener asistencia. –

Respuesta

9

he logrado resolver este problema con la ayuda de soporte técnico blackmagic

la solución es insertar esta línea al final de la función de devolución de llamada:

System.Runtime.InteropServices.Marshal.ReleaseComObject(video);