I am trying to create simple application (WPF Application Using C#)
I want to display the VideoFrame Comes from My camera through UltraStudio SDI in My Application
I've got the VideoFrame But I have a problem, When I am trying to Draw My Video frame Using IntPtr as Follow:
_writeable.WritePixels(new Int32Rect(0, 0, _width, _height), _tempRGBData, _height * _width * 3, _width * 3);
The Following Exception is thrown
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I will post my Code With My Question and I am waiting your Answers
I'm Using C# and Decklink in WPF Application
thank you in advance...
the Code as follow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DeckLinkAPI;
using System.Windows.Threading;
using System.Runtime.InteropServices;
namespace WpfApplication1
{
public partial class MainWindow : Window, IDeckLinkInputCallback
{
private IDeckLinkIterator _deckLinkIterator;
private List<IDeckLink> _deckLinkList = new List<IDeckLink>();
private IDeckLink _currentDevice = null;
private IDeckLinkInput _deckLinkInput = null;
IDeckLinkOutput _deckLinkOutput = null;
private IDeckLinkScreenPreviewCallback screenPreviewCallback;
private IDeckLinkVideoInputFrame video = null;
private int _width = 1280;
private int _height = 720;
private WriteableBitmap _writeableBitmap = null;
IntPtr _tempRGBData;
DispatcherTimer _timer = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
}
void _timer_Tick(object sender, EventArgs e)
{
_writeableBitmap.Lock();
unsafe
{
_writeableBitmap.WritePixels(new Int32Rect(0, 0, _width, _height), _tempRGBData, _height * _width * 3, _width * 3);
}
_writeableBitmap.Unlock();
}
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)));
_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[0];
string displayName;
_currentDevice.GetDisplayName(out displayName);
_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.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;
#region callbacks
public void VideoInputFormatChanged(_BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode newDisplayMode, _BMDDetectedVideoInputFormatFlags detectedSignalFlags)
{
Console.WriteLine("video format changed!!");
}
public void VideoInputFrameArrived(IDeckLinkVideoInputFrame videoFrame, IDeckLinkAudioInputPacket audioPacket)
{
IntPtr pData;
videoFrame.GetBytes(out pData);
_tempRGBData = pData;
Console.WriteLine("video frame arrived!! " + frameCount);
frameCount++;
}
#endregion
private void Button_Click(object sender, RoutedEventArgs e)
{
_deckLinkInput.StartStreams();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
_deckLinkInput.StopStreams();
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
_deckLinkInput.PauseStreams();
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
_deckLinkInput.FlushStreams();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
}
}
}
and XAML Code as Follow:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="886.3" Width="916" Loaded="Window_Loaded">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="65,51,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="208,51,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="368,51,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="535,51,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_3"/>
<Image Name="_captureImage" HorizontalAlignment="Left" Height="408" Margin="31,96,0,0" VerticalAlignment="Top" Width="848"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="680,45,0,0" VerticalAlignment="Top" Width="184" Name="label1"/>
</Grid>
</Window>
What I have tried:
I am trying to draw my videoFrame Using WriteableBitmap
thank you