c#中的blackmagic SDK

时间:2011-06-15 09:54:33

标签: c# sdk video-capture

我试图在Windows7 64x和C#+ VS 2010 express上使用最新的SDK(2011年6月)从一张blackmagic强度专业卡中捕获720p。

我已经成功编译并运行了一个在YUV捕获帧的程序,但是在56帧之后捕获停止(回调函数停止被调用)。我想知道我是否遗漏了一些简单的东西?特别是考虑到我几乎就在那里 - 我得到的帧数正确,尺寸正确,但只有很短的时间。

还有一些可能相关的其他信息:

  • 如果我拔掉相机捕捉不停止
  • 我也尝试过1080i和PAL,同样的事情发生了
  • 即使VideoInputFrameArrived函数为空(即只有一个帧计数器),也会发生同样的事情。

这是代码:


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

1 个答案:

答案 0 :(得分:9)

我已经设法在blackmagic技术支持的帮助下解决了这个问题

解决方案是在回调函数的末尾插入此行:

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