Проблема с обновлением WPF Image из WriteableBitmap
От: B_A_D Израиль  
Дата: 14.07.11 06:58
Оценка:
Есть программа для захвата видео через 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 только начал.
Re: Проблема с обновлением WPF Image из WriteableBitmap
От: Sinix  
Дата: 14.07.11 07:20
Оценка: 2 (1)
Здравствуйте, B_A_D, Вы писали:

B_A>Есть программа для захвата видео через DirectShow и отображение его в окне WPF в Image.


1. exception.ToString()?

2. А готовые решения пробовали?
Re[2]: Проблема с обновлением WPF Image из WriteableBitmap
От: B_A_D Израиль  
Дата: 14.07.11 12:35
Оценка:
Здравствуйте, 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) Спасибо за ссылку, странно, как ее не нашел.
Re[3]: Проблема с обновлением WPF Image из WriteableBitmap
От: Sinix  
Дата: 14.07.11 13:00
Оценка:
Здравствуйте, 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/ конечно (топик по сабжу.).
Re[4]: Проблема с обновлением WPF Image из WriteableBitmap
От: B_A_D Израиль  
Дата: 15.07.11 05:10
Оценка: +1
Здравствуйте, 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.

Ладно, буду делать как в приведенной ссылке.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.