blackmagic SDK in c#

morishuz picture morishuz · Jun 15, 2011 · Viewed 11.4k times · Source

i am attempting to capture 720p from one a blackmagic intensity pro cards using the newest SDK (june 2011) on windows7 64x and with C# + VS 2010 express.

i have successfully compiled and run a program that captures frames at YUV however, capture stops after 56 frames (the callback function stops being called). i am wondering if i am missing something simple here? especially given that i am almost there - i get frames with the correct content at the correct size etc but only for a brief time.

also some other information that may be relevant:

  • if i unplug the camera capture does not stop
  • i have also tried this at 1080i and PAL and the same happens
  • same thing happens even if the VideoInputFrameArrived function is empty (i.e. with just a frame counter in it)

here is the code:


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

Answer

morishuz picture morishuz · Jun 23, 2011

i've managed to solved this problem with the help of blackmagic tech support

the solution is to insert this line at the end of the callback function:

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