c# RTSP播放器

來源:互聯網
上載者:User

標籤:

ONVIF ODM在onvif領域裡名氣很大,是一款開源的NVC實現。其實現採用了c# c++ F#。項目很大,也很複雜。最近研究了一下,自己調用其類庫寫了一個c#版的RTSP的播放器。難度不大。但要明白其中原理,還需要多研究研究ODM源碼。

 

 

 

目前痛點在於解碼過程,BGR轉為RGB排列,兼顧效率使用了unsafe  指標。對於不是專門搞映像的,還是需要慢慢理解。

        private void DecoderFrame(Bitmap bitmap, VideoBuffer videoBuffer, PlaybackStatistics statistics)        {            try            {                using (var md = videoBuffer.Lock())                {                    Rectangle rect = new Rectangle(0, 0, videoBuffer.width, videoBuffer.height);                    //將位元影像鎖定到記憶體中                    BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);                    //BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);                    //擷取掃描寬度,例如1280*3=3840 1280為寬度即1280個像素點,每個像素有R\G\B三種,3位元組                    bitmapData.Stride = videoBuffer.stride;                    byte[] buffer = new byte[videoBuffer.size];                    //將md中資料copy到數組buffer                    Marshal.Copy(md.value.scan0Ptr, buffer, 0, videoBuffer.size);                    //將buffer中資料copy到bitmapData                    Marshal.Copy(buffer, 0, bitmapData.Scan0, w * h * 3);                    //迴圈處理 ,將BGR轉換為RGB排列                    //http://blog.csdn.net/lulu831110/article/details/4820377                    unsafe                    {                        byte* ptr = (byte*)(bitmapData.Scan0);                        for (int i = 0; i < bitmapData.Height; i++)                        {                            for (int j = 0; j < bitmapData.Width; j++)                            {                                //將B和R對調,即第一個和第三個對調                                byte B = *ptr;//B的值                                byte R = *(ptr + 2);//R的值                                //對調                                *ptr = R;                                *(ptr + 2) = B;                                ptr += 3;                            }                            /*                             * 表示跨過無用的地區,跳過這些多餘的位元組,讓指標指向下一行,                             * 其原因是映像資料在記憶體中儲存時是按4位元組對齊的,                             * 具體解釋如下:假設有一張圖片寬度為6,                             * 假設是Format24bppRgb格式的(每像素3位元組,在以下的討論中,除非特別說明,                             * 否則Bitmap都被認為是24位RGB)。顯然,每一行需要6*3=18個位元組儲存。                             * 對於Bitmap就是如此。                             * 但對於BitmapData,雖然data.Width還是等於image.Width,                             * 但大概是出於顯示效能的考慮,                             * 每行的實際的位元組數將變成大於等於它的那個離它最近的4的整倍數,                             * 此時的實際位元組數就是Stride。就此例而言,18不是4的整倍數,                             * 而比18大的離18最近的4的倍數是20,所以這個data.Stride = 20。                             * 顯然,當寬度本身就是4的倍數時,bitmapData.Stride = image.Width * 3。                             *                              * |-------Stride-------------|                             * |-------Width----------|    |                             *  Scan0:                             *  BGR BGR BGR BGR BGR BGR XX                             *  BGR BGR BGR BGR BGR BGR XX                             *  BGR BGR BGR BGR BGR BGR XX                             *                              * 首先用data.Scan0找到第0個像素的第0個分量的地址,                             * 這個地址指向的是個byte類型,所以當時定義為byte* ptr。                             * 行掃描時,在當前指標位置(不妨看成當前像素的第0個顏色分量)                             * 連續取出三個值(3個原色分量。                             * 注意,0 1 2代表的次序是B G R。在取指標指向的值時,                             * 貌似p[n]和p += n再取p[0]是等價的),然後下移3個位置(ptr += 3,                             * 看成指到下一個像素的第0個顏色分量)。做過Bitmap.Width次操作後,                             * 就到達了Bitmap.Width * 3的位置,                             * 應該要跳過圖中標記為X的位元組了(共有Stride - Width * 3個位元組),                             * 代碼中就是 ptr += dataIn.Stride - dataIn.Width * 3。                             *                              *                              *                              * 一般來說,如果一個像素是一個位元組的話(你的代碼做這樣的假設,其實很不好),                             * bmpData.Stride 應該等於bmpWidth,但實際上往往不相等,要差幾個位元組,                             * 因為bmpData.Stride必須是4的倍數,如果不足,則補上幾個位元組,                             * 讓bmpData.Stride是4的倍數,這些多餘的位元組不會儲存任何顏色資料,                             * ptr += bmpData.Stride - bmpWidth;只是跳過這些多餘的位元組,                             * 讓指標指向下一行                             *                              *                              */                            ptr += bitmapData.Stride - bitmapData.Width * 3;                        }                    }                    bitmap.UnlockBits(bitmapData);                    Bitmap bt = (Bitmap)bitmap.Clone();                    lock (this)                    {                        bitmap_queue.Enqueue(bt);                    }                    if (statistics.isNoSignal)                    {                        if (!panel1.Visible)                        {                            showLable(true);                        }                        Console.WriteLine("No Signal");                    }                    else                    {                        if (panel1.Visible)                        {                            showLable(false);                        }                    }                }            }            catch            {            }        }


 

 

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

c# RTSP播放器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.