文章出處

  有些OMCS用戶在他的系統使用了特殊的視頻采集卡作為視頻源(如AV-878采集卡),雖然這些采集卡可以虛擬為一個攝像頭,但有些視頻采集卡需要依賴于自帶了sdk才能正常地完成視頻采集工作。在這種情況下,OMCS是不直接支持這些采集卡的。我們的思路是使OMCS具有自定義擴展的能力:我們讓OMCS提供了擴展接口,讓使用者可以向OMCS框架中注入其自己的視頻采集程序。使用者要達到這種自定義的擴展相當簡單,只需實現兩個接口即可。

1.IVideoCapturer接口

  OMCS.Engine.Video.IVideoCapturer定義了視頻采集器的基本功能,其用于采集RGB24格式的圖像,其定義如下:

    public interface IVideoCapturer :IDisposable
    {
        /// <summary>
        /// 要采集的視頻大小(分辨率)
        /// </summary>
        Size VideoSize { get; }

        /// <summary>
        /// 采集的幀頻
        /// </summary>
        int FrameRate { get; }

        /// <summary>
        /// 是否正在采集?
        /// </summary>
        bool IsCapturing { get; }

        /// <summary>
        /// 開始采集
        /// </summary>
        void Start();

        /// <summary>
        /// 停止采集
        /// </summary>
        void Stop();     

        /// <summary>
        /// 當采集完一幀時,觸發此事件。事件參數為圖像數據。
        /// </summary>
        event CbGeneric<byte[]> VideoCaptured;

        /// <summary>
        /// 當采集發生錯誤時,觸發此事件。
        /// </summary>
        event CbGeneric<Exception> VideoError;

        /// <summary>
        /// 當采集的分辨率發生變化時,觸發此事件。
        /// </summary>
        event CbGeneric<Size> VideoSizeChanged;
    }

(1)在定義實現該接口的類時,可以通過類的構造函數傳入三個參數:設備的Index、采集的分辨率、采集的視頻幀率。

(2)OMCS會在合適的時候調用Start方法啟動注入的采集器,采集器啟動后,當每采集到一幀視頻時,就觸發VideoCaptured事件。OMCS內部預定了該事件,以獲取采集到的圖像數據。

(3)如果在采集的過程中,采集器發生了任何異常,請通過觸發VideoError事件來通知OMCS框架。

(4)如果在采集的過程中,更改了采集器采集的分辨率,請通過觸發VideoSizeChanged事件來通知OMCS。

  請特別注意VideoCaptured事件參數的含義:它并不是一個Bitmap的完整數據,而是不包含位圖header的核心數據(OMCS通過設定的采集的分辨率來推斷位圖header的信息)。從Bitmap轉為不包含頭的核心數據的代碼如下所示:

    public byte[] GetBitmapCoreData(Bitmap bm)
    {
        int buffSize =bm.Width * bm.Height * 24 / 8;
        byte[] destBuff = new byte[buffSize];
        Rectangle bmRect = new Rectangle(new Point(0, 0), new Size(bm.Width, bm.Height));
        BitmapData data = bm.LockBits(bmRect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
        Marshal.Copy(data.Scan0, destBuff, 0, destBuff.Length);
        bm.UnlockBits(data);
        return destBuff;
    }

  當然,如果視頻采集器采集到的本來就是位圖核心數據(通常情況下都是如此),就不需要這層轉換了。

2.IVideoCapturerFactory接口

  在實現完IVideoCapturer接口后,我們還需要實現簡單的OMCS.Passive.IVideoCapturerFactory接口。   

    public interface IVideoCapturerFactory
    {
        /// <summary>
        /// 創建一個新的視頻采集器實例。
        /// 如果返回null,則表示使用框架內置的視頻采集器。
        /// </summary>
        /// <param name="deviceIndex">攝像頭索引</param>
        /// <param name="videoSize">要采集的視頻大小(分辨率)</param>
        /// <param name="frameRate">采集的幀頻</param>     
        IVideoCapturer CreateVideoCapturer(int deviceIndex, Size videoSize, int frameRate);

        /// <summary>
        /// 獲取視頻采集器支持的采集分辨率。
        /// 如果返回null,則表示指示框架自己去獲取這些信息。
        /// </summary>
        /// <param name="deviceIndex">攝像頭索引</param>      
        List<CameraCapability> GetCameraCapability(int deviceIndex);
    }

可以按如下邏輯來實現IVideoCapturerFactory的兩個方法:

(1)實現CreateVideoCapturer方法:判斷deviceIndex所對應的視頻設備是否是特殊的類型,如果是,則new一個我們剛實現的視頻采集類的實例返回;如果不是,則返回null,表示使用框架內置的視頻采集程序。

(2)實現GetCameraCapability方法:判斷deviceIndex所對應的視頻設備是否是特殊的類型,如果是,則把該設備支持的所有分辨率放入列表中返回;如果不是,則返回null,以指示框架自己獲取目標設備的分辨率信息。

3.注入到OMCS

  在調用IMultimediaManager的Initialize方法之前,先new一個上面實現的Factory類,然后將其賦值給IMultimediaManager的VideoCapturerFactory屬性。這樣,就完成對OMCS視頻設備的擴展。

 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()