Есть программа для захвата видео через DirectShow и отображение его в окне WPF в Image.
В Grabber создается эта WriteableBitmap и кадр передается в основное приложение.
Создается так:
private class Grabber : ISampleGrabberCB
{
private System.Windows.Media.Imaging.BitmapSource image = null;
// Callback method that receives a pointer to the sample buffer
public int BufferCB(double sampleTime, IntPtr buffer, int bufferLen)
{
if (parent.NewFrameWB != null)
{
// create new image
if (image == null)
image = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
(image as WriteableBitmap).Lock();
IntPtr dst_ptr = (image as WriteableBitmap).BackBuffer;
int dst_stride = (image as WriteableBitmap).BackBufferStride;
unsafe
{
switch(format)
{
case 2: //convert from YUY2 to ARGB
{
int src_stride = width * 2;
byte* dst = (byte*)dst_ptr.ToPointer();
byte* src = (byte*)buffer.ToPointer();
for (int y = 0; y < height; y++)
{
byte* dst_line = (byte*)dst;
Int16* src_line = (Int16*)src;
for (int x = 0; x < width; x++, src_line++, dst_line += 4)
{
Int16 val = *src_line;
*dst_line = 255; //A
*(dst_line + 1) = //R
*(dst_line + 2) = //G
*(dst_line + 3) = (byte)(val >> 8); //B
}
dst += dst_stride;
src += src_stride;
}
break;
}
}
(image as WriteableBitmap).AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height));
(image as WriteableBitmap).Unlock();
}
// notify parent
parent.OnNewFrame(image);
}
return 0;
}
}
В приложении пытаюсь обновить VideoWnd.Source (Image control):
При попытке доступа к image, который получен из BufferCB граббера, выдает исключение.
private void UpdateElement(BitmapSource image)
{
this.Dispatcher.Invoke(
new Action(() =>
{
//Тут все нормально
FrameCnt.Text = "Frames: " + nFrameCnt.ToString() + " FPS: " + capwnd.videosource.FramesReceived.ToString();
//Тут возникает исключение
int w = bitmap.PixelWidth;
//Тут возникает исключение
VideoWnd.Source = image;
}), System.Windows.Threading.DispatcherPriority.Normal);
}
В чем может быть проблема ?
С DirectShow у меня опыт обширный , а вот с WPF только начал.
Здравствуйте, B_A_D, Вы писали:
B_A>Есть программа для захвата видео через DirectShow и отображение его в окне WPF в Image.
1. exception.ToString()?
2. А
готовые решения пробовали?
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, B_A_D, Вы писали:
B_A>>Есть программа для захвата видео через DirectShow и отображение его в окне WPF в Image.
S>1. exception.ToString()?
S>2. А готовые решения пробовали?
1) "The calling thread cannot access this object because a different thread owns it." ВОт не понятно, как достучаться до него.
Кстати с System.Drawing.Bitmap вариант проходит, она саздается в граббере и передается в UI поток и через Invoke контрол Image
обновляется нормально. Не понимаю, в чем различие. Я хотел избавиться от лишних преобразований из Bitmap в BitmapSource.
2) Спасибо за ссылку, странно, как ее не нашел.
Здравствуйте, B_A_D, Вы писали:
B_A>1) "The calling thread cannot access this object because a different thread owns it." ВОт не понятно, как достучаться до него.
А вот и причина засора(с)
WriteableBitmap надо создавать в ui-потоке.
B_A>2) Спасибо за ссылку, странно, как ее не нашел.
Есть ещё 5-6 полудохлых проектов. То, что с ходу вспомнил/нагуглил:
http://wpfmediakit.codeplex.com/
http://videorendererelement.codeplex.com/
http://touchless.codeplex.com/
ну и
http://directshownet.sourceforge.net/ конечно (
топик по сабжу.).
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, B_A_D, Вы писали:
B_A>>1) "The calling thread cannot access this object because a different thread owns it." ВОт не понятно, как достучаться до него.
S>А вот и причина засора(с) WriteableBitmap надо создавать в ui-потоке.
Если создаю в UI потоке, то же самое исключение возникает уже в граббере при доступе к ней.
Как я уже писал, при работе с Bitmap, созданного в грабере такого не происходит при доступе
к этой Bitmap из UI потока через Dispatcher.Invoke.
Ладно, буду делать как в приведенной ссылке.