視頻采集卡Windows95驅(qū)動程序設(shè)計(jì)
掃描二維碼
隨時隨地手機(jī)看文章
摘要:介紹了Windows95系統(tǒng)中視頻采集卡驅(qū)動程序的原理和結(jié)構(gòu),較詳細(xì)地介紹了虛擬設(shè)備驅(qū)動程序和Video For Window視頻采集驅(qū)動程序設(shè)計(jì)技術(shù)。
關(guān)鍵詞:視頻采集 驅(qū)動程序 Windows95
在計(jì)算機(jī)視頻應(yīng)用中,視頻采集卡承擔(dān)著將模擬視頻信號轉(zhuǎn)換成數(shù)字視頻信號的任務(wù)。Windows95是目前應(yīng)用比較廣泛的操作系統(tǒng),許多視頻應(yīng)用系統(tǒng)是基于該平臺的。不但采集卡設(shè)計(jì)人員需要詳細(xì)了解Windows95系統(tǒng)中視頻采集卡驅(qū)程序設(shè)計(jì)技術(shù),應(yīng)用程序設(shè)計(jì)人員也需要理解驅(qū)動程序的工作原理,以便設(shè)計(jì)出性能更好的應(yīng)用程序。本文以PCI總線視頻采集為例,較詳細(xì)地介紹了Windows95系統(tǒng)中視頻采集卡驅(qū)動程序設(shè)計(jì)技術(shù)。
1 Windows95驅(qū)動程序原理
Windows95作為多線程搶占式多任務(wù)操作系統(tǒng),對硬件設(shè)備進(jìn)行了全面而完善的管理。其設(shè)備驅(qū)動程序的主要目的是使系統(tǒng)中的各個任務(wù)共享硬件設(shè)備,在任務(wù)切換時確保硬件設(shè)備一致性。Windows95設(shè)備驅(qū)動程序是分層設(shè)計(jì)的,層間定義了統(tǒng)一的接口,提高了程序的兼容性,便于系統(tǒng)升級和移值。系統(tǒng)將各類硬件設(shè)備的功能、行為進(jìn)行歸類整理,將實(shí)際設(shè)備抽象成邏輯設(shè)備。邏輯設(shè)備具有某一類型設(shè)備所共有的屬性,具有統(tǒng)一的行為,并以一致的方式進(jìn)行操縱。系統(tǒng)提供必要的函數(shù)和方法供應(yīng)用程序操縱某一類型的邏輯設(shè)備。應(yīng)用程序被嚴(yán)格禁止進(jìn)行直接的硬件設(shè)備操作,所需的操作應(yīng)當(dāng)調(diào)用相應(yīng)的系統(tǒng)API函數(shù)來完成。視頻采集卡的設(shè)備驅(qū)動程序?qū)儆贛ultiMedia類中的VideoCap子類,由虛擬設(shè)備驅(qū)動程序CAPTURE.VXD和可安裝設(shè)備驅(qū)動程序CAPTURE.DRV構(gòu)成。其結(jié)構(gòu)框圖見圖1。
虛擬機(jī)管理器VMM構(gòu)成了Windows95系統(tǒng)的核心。它是一個32位保護(hù)模式操作系統(tǒng),它的主要責(zé)任是創(chuàng)建、運(yùn)行、監(jiān)視以及終止虛擬機(jī)。虛擬機(jī)是一個可執(zhí)行的任務(wù),它由內(nèi)存空間、CPU寄存器組、應(yīng)用程序以及應(yīng)用程序的支持軟件如ROM BIOS、MS-DOS等組成,系統(tǒng)可同時擁有多個虛擬機(jī)。當(dāng)某個硬件設(shè)備的狀態(tài)可能受到任務(wù)切換的干擾時,該調(diào)和就需要相應(yīng)的虛擬設(shè)備驅(qū)動程序的支持。虛擬機(jī)管理器和虛擬設(shè)備驅(qū)動程序一同管理系統(tǒng)的軟硬件資源,響應(yīng)中斷,進(jìn)行I/O操作,確保多個應(yīng)用程序共享資源,互不干擾。
Windows95視頻采集卡設(shè)備驅(qū)動程序包括虛擬設(shè)備驅(qū)動程序和可安裝設(shè)備驅(qū)動程序兩部分,一般可以采用Microsoft Windows95 DDK(Device Driver Kit)進(jìn)行原形、輸入庫以及一些樣例代碼,但是未提供編程所需要的編譯、匯編和連接程序。采用Visual C++ 5.0、Visual C++ 1.5以及MASM 6.0進(jìn)行程序設(shè)計(jì)。設(shè)備驅(qū)動程序設(shè)計(jì)的好壞與采集卡的功能、性能、 兼容性及穩(wěn)定性密切相關(guān)。為保證驅(qū)動程序的質(zhì)量,應(yīng)當(dāng)嚴(yán)格遵照Windows95 DDK的文檔進(jìn)行程序設(shè)計(jì)。
2 虛擬設(shè)備驅(qū)動程序設(shè)計(jì)
在視頻采集卡的驅(qū)動程序中,虛擬設(shè)備驅(qū)動程序CAPTURE.VXD負(fù)責(zé)參與系統(tǒng)即插即用配置過程,管理視頻采集卡的硬件設(shè)備,并向運(yùn)行在權(quán)限級3的上層程序提供調(diào)用接口:一是將分配的資源返回,如內(nèi)存選擇子、I/O地址、中斷號等,使得上層驅(qū)動程序可以使用這資源來操縱采集卡硬件設(shè)備;二是完成一些在權(quán)限級3所不能進(jìn)行的操作,如分配DMA緩沖區(qū)、查看內(nèi)存映射頁表等。虛擬機(jī)管理器和虛擬設(shè)備驅(qū)動程序運(yùn)行在一個單一的32位平板模式址空間中,權(quán)限級為0。系統(tǒng)建立兩個基地址為0、界限為4GB的全局描述符選擇子分別用于代碼段和數(shù)據(jù)段,程序不應(yīng)當(dāng)直接修改段寄存器、內(nèi)存描述符表、中斷描述符表。
2.1 設(shè)備聲明
虛擬設(shè)備驅(qū)動程序必須包含一個聲明,它一般位于程序的前部,聲明中包括虛擬設(shè)備驅(qū)動程序的名稱、版本號、調(diào)用接口等一些重要信息。聲明由宏Declare_Virtual_Device完成,語法如下:
Declare_Virtual_Device<設(shè)備名稱>,<主版本號>,<次版本號>,<設(shè)備控制過程>,<設(shè)備標(biāo)識符>,<初始化次序>,,
設(shè)備名稱定義了虛擬設(shè)備驅(qū)動程序的名稱。設(shè)備控制過程接受來虛擬機(jī)管理器的消息,并根據(jù)不同消息進(jìn)行不同的操作。設(shè)備標(biāo)識符是一個16位整數(shù),它是該程序在系統(tǒng)中的唯一標(biāo)識。初始化次確定虛擬設(shè)備驅(qū)動程序的裝載順序,首先裝入初始化次序值較小的虛擬設(shè)備驅(qū)動程序。V86 API接口用于接受來自虛擬8086模式程序的調(diào)用。PM API接口接受來自16位保護(hù)模式程序的調(diào)用。
2.2 設(shè)備控制過程
虛擬機(jī)管理器在系統(tǒng)的運(yùn)行狀態(tài)發(fā)生改變時向設(shè)備控制過程發(fā)送系統(tǒng)控制消息(System Control Message),以便虛擬設(shè)備驅(qū)動程序能夠跟蹤系統(tǒng)狀態(tài),進(jìn)行必要的處理。發(fā)送消息的時機(jī)包括:系統(tǒng)初始化、系統(tǒng)退出、虛擬機(jī)狀態(tài)改變、虛擬設(shè)備的驅(qū)動程序初始化等。一個設(shè)備控制過程的例子如下:
BeginProc WBD848_Control
Control_Dispatch Sys_Dynamic_Device_Init,WBD848_Dyn_Device_Init
Control_Dispatch Sys_Dynamic_Device_Exit,WBD848_Dyn_Device_Exit
Control_Dispatch PnP_New_DevNode,WBD848_PnP_New_DevNode
Control_Dispatch W32_DEDVICEIOCONTROL,WBD848_W32_DeviceIOControl
Clc
Ret
EndProc WBD848_Control
與視頻采集卡即插即用配置過程相關(guān)的消息是PnP_New_DevNode。系統(tǒng)首先檢測視頻采集卡硬件存在,然后根據(jù)PCI接口板廠商和器件標(biāo)識在注冊表中找到對應(yīng)的虛擬設(shè)備驅(qū)動程序并裝入內(nèi)存,隨后系統(tǒng)向該虛擬設(shè)備驅(qū)動程序發(fā)送PnP_New_DevNode消息。因?yàn)橐曨l采集卡屬于多媒體設(shè)備,設(shè)備驅(qū)動程序的裝入應(yīng)由MMDEVLDR.VXD完成,所以虛擬設(shè)備驅(qū)動程序在處理PnP_New_DevNode消息時,調(diào)用 MMDEVLDR.VXD的服務(wù)MMDEVLDR_Register_Device_Driver注冊了回調(diào)函數(shù)PnP_Config_Handler,系統(tǒng)根據(jù)采集卡PCI配置空間為其分配資源后將調(diào)用此回調(diào)函數(shù)。在PnP_Config_Handler中可以使用 CM_Get_Alloc_Log_Conf服務(wù)獲得系統(tǒng)為采集卡分配的資源。處理系統(tǒng)控制消息PnP_New_DevNode的例程如下:
BeginProc WBD848_PnP_New_DevNode
Mov eax,ebx ;虛擬機(jī)句柄
Mov ebx, offset32 PnP_Config_Handler;即插卻用處理例程
VxDCall MMDEVLDR_Register_Device _Driver
Mov eax,CR_SUCCESS
Stc
Ret
EndProc WBD848_PnP_New_DevNode
在回調(diào)函數(shù)PnP_Config_Handler中獲得的資源包括內(nèi)存、I/O、中斷和DMA四種。PCI總線視頻采集卡主要使用內(nèi)存和中斷資源,它包括一個內(nèi)存窗口作為內(nèi)存映射I/O和一個中斷IRQ號。虛擬設(shè)備驅(qū)動程序應(yīng)用使用_MapPhysToLonear服務(wù)將內(nèi)存窗口物理地址映射到線性地址空間中,并使用_Allocate_GDT_Selector服務(wù)分配內(nèi)存選擇字,以便16位應(yīng)用程序訪問該內(nèi)存區(qū)域。
2.3 應(yīng)用程序接口
虛擬設(shè)備驅(qū)動程序?yàn)樘摂M8086模式、16位及32位保護(hù)模式應(yīng)用程序分別提供應(yīng)用程序編程接口,使運(yùn)行在權(quán)限級3上的應(yīng)用程序可以訪問虛擬設(shè)備驅(qū)動程序。前兩種接口在設(shè)備聲明時定義,應(yīng)用程序通過中斷調(diào)用INT28H AX=1648H獲得虛擬設(shè)備驅(qū)動程序的入口地址。32位接口通過W32_DEVICEIOCONTROL系統(tǒng)信息消息實(shí)現(xiàn),應(yīng)用程序則使用系統(tǒng)API函數(shù)DeviceIoControl對虛擬設(shè)備驅(qū)動程序進(jìn)行調(diào)用。
當(dāng)16位應(yīng)用程序?qū)θ肟诘刂钒l(fā)出遠(yuǎn)調(diào)用后,虛擬機(jī)管理順將應(yīng)用程序的寄存器內(nèi)容保存在Client_Reg_Struc結(jié)構(gòu)中,并將指向該結(jié)構(gòu)的指針賦予EBP寄存器,然后調(diào)用相應(yīng)的虛擬設(shè)備驅(qū)動程序。虛擬設(shè)備驅(qū)動程序必須訪問 Client_Reg_Struc結(jié)構(gòu)中的數(shù)據(jù)以獲得應(yīng)用程序的調(diào)用參數(shù)。一般利用AX寄存器傳遞功能號,利用其它寄存器傳遞參數(shù),執(zhí)行結(jié)果通過 Client_Reg_Struc結(jié)構(gòu)返回。16位保護(hù)模式應(yīng)用程序使用選擇子——偏移量地址模型,而虛擬設(shè)備驅(qū)動程序使用32位平板式地址模型,如果參數(shù)是以指針的形式傳遞給虛擬設(shè)備驅(qū)動程序,需要使用宏Client_Ptr_Flat進(jìn)行轉(zhuǎn)換。
本采集卡中虛擬設(shè)備驅(qū)動程序提供的主要功能是:(1)使應(yīng)用程序獲得系統(tǒng)為采集卡分配的資源,如內(nèi)存映射、I/O地址和中斷IRQ號,以便操縱采集卡;(2)提供有關(guān)內(nèi)存頁表的信息,以便進(jìn)行DMA操作。16位應(yīng)用程序接口的部分代碼如下:
;******** Copy Page Table ********
Client_Ptr_Flat eax,ES,BX ;es:bx指向頁表緩沖區(qū)
Client_Ptr_Flat ebx,DI,SI ;di:si指向DMA緩沖區(qū)
Shr ebx,12 ;起始頁號
Movz ecx,[ebp].Client_CX ;cx為需要拷貝的頁表項(xiàng)個數(shù)
VMMcall _CopyPageTable
Mov [ebp].Client_EAX,eax ;ax返回執(zhí)行結(jié)果
Ret
;********** Get Resource **********
movzx eax, _g_wSelector ;存儲器映射I/O地址選擇子
mov [ebp].Client_EAX,eaz
movzx eax,_g_wIRQ
mov [ebp].Client_EBX,eax
ret
32位應(yīng)用程序接口的功能與16位接口十分相似,只是將存儲器映射I/O地址以32位線性地址的方式返回,以適應(yīng)32位平板模式的尋址要求。另外32位接口不返回中斷IRQ號,因?yàn)?2位應(yīng)用程序中不進(jìn)行有關(guān)中斷的操作。
3 可安裝設(shè)備驅(qū)動程序
可安裝設(shè)備驅(qū)動程序?qū)嵸|(zhì)上是一個16位動態(tài)鏈接庫,可以按照一般的動態(tài)鏈接庫設(shè)計(jì)方法進(jìn)行設(shè)計(jì)。它具有人口函數(shù)DriverProc,用于接收系統(tǒng)發(fā)送的消息。
3.1 Video For Window編程模型
視頻采集卡可安裝設(shè)備驅(qū)動程序采用Video For Window程序模型,它從各種各樣的視頻采集卡抽象出一個統(tǒng)一的邏輯結(jié)構(gòu),以便上層程序調(diào)用。上層程序主要是指由AVICap32.dll等系統(tǒng)動態(tài)鏈接庫構(gòu)成的視頻采集引擎。視頻采集引擎負(fù)責(zé)顯示視頻數(shù)據(jù)、分配數(shù)據(jù)緩沖區(qū)、操縱系統(tǒng)調(diào)色板、存儲AVI文件等工作,它們將應(yīng)用程序的高級調(diào)用翻譯成低級消息發(fā)送給可安裝設(shè)備驅(qū)動程序。可安裝設(shè)備驅(qū)動程序在消息的控制下,操縱采集卡硬件設(shè)備,完成視頻數(shù)據(jù)的采集。Video For Window驅(qū)動程序邏輯結(jié)構(gòu)如圖2所示。
Video For Window驅(qū)動程序模型包括視頻源、幀存儲器、顯示設(shè)備、CPU和四個視頻數(shù)據(jù)通道。幀存儲器只具有邏輯上意義,可能在采集卡上或位于主機(jī)內(nèi)存中或者根本上不存在。它在圖2中只表明處于該閏置的應(yīng)當(dāng)是已經(jīng)解碼完整的視頻數(shù)據(jù)。四個視頻數(shù)據(jù)邏輯通道的功能如下:
External In代表視頻信號由模擬向數(shù)字的轉(zhuǎn)換過程,包括采樣量化、解碼等工作。該通道負(fù)責(zé)視頻信號的選擇(攝像機(jī)、錄像機(jī)、調(diào)諧器等),視頻信號制式選擇(NTSC、PAL、SECAM等),亮度、對比度、色調(diào)的調(diào)節(jié)等工作。
Video In 代表視頻數(shù)據(jù)由幀存儲器向系統(tǒng)緩沖區(qū)的傳輸過程。該通道負(fù)責(zé)視頻圖像數(shù)據(jù)的傳輸工作,如設(shè)定圖像大小、彩色格式,確定圖像幀的同步定時等。
External Out 代表視頻數(shù)據(jù)向顯示設(shè)備的直接傳輸過程。該通道負(fù)責(zé)視頻圖像的實(shí)時顯示工作,如確定顯示窗數(shù)據(jù)格式,進(jìn)行顯示窗口的剪裁等。
Video Out 代表視頻數(shù)據(jù)由系統(tǒng)緩沖區(qū)向幀存儲器的反向傳輸過程。該通道負(fù)責(zé)視頻數(shù)據(jù)的回放,具有視頻解壓縮功能的休集卡可能需要這種反向的傳輸,以便對壓縮數(shù)據(jù)進(jìn)行解碼。
一個最簡單的視頻采集驅(qū)動程序至少應(yīng)當(dāng)實(shí)現(xiàn)External In和Video In兩路數(shù)據(jù)流,也就是實(shí)現(xiàn)視頻信號的采集、解碼和向主機(jī)內(nèi)存的傳輸。通常PCI總線視頻采集卡還可以實(shí)現(xiàn)External Out數(shù)據(jù)流,即實(shí)現(xiàn)視頻數(shù)據(jù)的實(shí)時顯示。
3.2 數(shù)據(jù)傳輸
驅(qū)動程序?qū)⒉杉降臄?shù)據(jù)傳送到上層程序時使用VIDEOHDR結(jié)構(gòu),該結(jié)構(gòu)包含了數(shù)據(jù)緩沖區(qū)、數(shù)據(jù)長度、時間戳等信息,定義如下:
typedef struct {
LPSTR lpData; //address of video buffer
DWORD dwBufferLength; //size,in bytes,of the data buffer
DWORD dwBufferLength; //size,in bytes,of the data buffer
DWORD dwBytesUsed;
DWORD dwTimeCeptured;
DWORD dwUser; //user-specific data
DWORD dwFlags;
DWORD dwReserved[4];//reserved;do not use }VIDEOHDR;
LpData 視頻數(shù)據(jù)緩沖區(qū)指針,由采集引擎填寫;
dwBufferLength 視頻數(shù)據(jù)緩沖區(qū)長度,由采集引擎填寫;
dwBytesUsed 緩沖區(qū)中圖像數(shù)據(jù)的實(shí)際長度,由驅(qū)動程序填寫;
dwTimeCaptured 時間戳,從采集第一幀起以ms為單位記錄,用于視頻數(shù)據(jù)的同步,由驅(qū)動程序填寫;
dwFlage 標(biāo)志,驅(qū)動程序應(yīng)當(dāng)填寫VHDR_DONE以表示采集完成,如果此幀為關(guān)鍵幀還可以同時使用VHDR_KEYFRAME標(biāo)志。
緩沖區(qū)通常由視頻采集引擎分配,并鈄VIDEOHOR結(jié)構(gòu)指針以消息參數(shù)形式發(fā)送給驅(qū)動程序。當(dāng)進(jìn)行單幀采集時,驅(qū)動程序每收到一個DVM_FRAME消息便采集一幀圖像,驅(qū)動程序從DVM_FRAME消息返回時將VIDEOHDR結(jié)構(gòu)返回給采集引擎。
序列圖像的采集比較復(fù)雜,驅(qū)動程序與采集引擎間以緩沖區(qū)隊(duì)列的形式進(jìn)行數(shù)據(jù)交換,確保了連續(xù)的實(shí)時采集。采集引擎使用DVM_ADDBUFFER消息將空數(shù)據(jù)緩沖區(qū)不斷地加到緩沖區(qū)隊(duì)列的隊(duì)尾。同時,驅(qū)動程序?qū)⒖諗?shù)據(jù)緩沖區(qū)從隊(duì)列的隊(duì)首取出,并進(jìn)行視頻采集。驅(qū)動程序?qū)⑻畛湟曨l數(shù)據(jù)的緩沖區(qū)通過回調(diào)函數(shù)返回給采集引擎,由它進(jìn)行顯示、存盤等操作。添加緩沖區(qū)和取出緩沖區(qū)是兩個相對獨(dú)立的異步操作。采集引擎是緩沖區(qū)的生產(chǎn)者,它可以在系統(tǒng)空閑時分配若干個緩沖區(qū)并加入隊(duì)尾。驅(qū)動程序是緩沖區(qū)的消費(fèi)者,在采集卡硬件中斷的驅(qū)動下它不斷取出空緩沖區(qū),并將用過的緩沖區(qū)返還給采集引擎。通過使用緩沖區(qū)隊(duì)列提高了系統(tǒng)的數(shù)據(jù)吞吐能力,確保了采集的實(shí)時性。
3.3 視頻實(shí)時顯示
視頻圖像實(shí)時顯示功能又稱為Overlay,它將視頻圖像以窗口方式在計(jì)算機(jī)屏幕上實(shí)時顯示,顯示的畫面具有良好的視覺效果,顯示窗口與Windows95的圖形具有良好的視覺效果,顯示窗口號 Windows95的圖形界面配合默契。要實(shí)現(xiàn)這些功能,首先采集卡必須具有將數(shù)據(jù)直接傳輸至顯示卡的硬件設(shè)備,因?yàn)閷?shí)時顯示數(shù)據(jù)傳輸量巨大,主機(jī)CPU 是不可能承擔(dān)這樣的任務(wù)的;其次要求軟硬件設(shè)備默契配合,以便恰當(dāng)處理顯示窗口的大小、定位及剪裁。這可以借助DirectDraw中的Overlay功能實(shí)現(xiàn)。
DirectDraw是一種軟件接口標(biāo)準(zhǔn),提供了對顯示設(shè)備的直接訪問。它將顯示畫面分成表面(Surface),每種表面具有不同的屬性,如尺寸大小、彩色格式等。整個屏幕對應(yīng)的表面稱為主表面,程序可以在顯存或內(nèi)存中建立其它表面,并在這些表面中繪制圖形,然后通過某種操作這些表面的內(nèi)容顯示在主表面上,這些操作是高效率的,程序可以從中獲得很高的性能。Overlay表面具有特殊的性質(zhì),它位于顯存,并且可以覆蓋顯示在主表面的任何位置。為了防止Overlay表面遮蓋主表面中的某些重要部分如菜單、對話框等,Overlay 表面還高有色鍵功能,只有主表面中的顏色值與色鍵值相同時,Overlay表面才覆蓋主表面。
當(dāng)驅(qū)動程序的External Out通道收到DVM_STREAM_INIT消息時,開始視頻實(shí)時顯示。首先啟動DirectDraw接口,創(chuàng)建主表面和Overlay表面,并記錄有關(guān)Overlay表面的信息,如尺寸、數(shù)據(jù)格式、內(nèi)存地址等,同時為Overlay表面選擇一個顏色作為色鍵,通常是洋紅色。然后根據(jù)Overlay表面的信息初始化硬件設(shè)備,使DMA設(shè)備將視頻數(shù)據(jù)直接關(guān)入Overlay表面所在的顯存中。當(dāng)顯示窗口移動或改變大小時,視頻采集引擎會發(fā)送DVM_UPDATE消息通知驅(qū)動程序更新顯示,驅(qū)動程序應(yīng)當(dāng)在視頻窗口中填充色鍵的顏色,并移動Overlay表面使其與視頻窗口對齊。因?yàn)榭砂惭b設(shè)備驅(qū)動程序是16位模塊,而DirectDraw位于32位模塊中,在采集卡驅(qū)動程序中不能直接調(diào)用DirectDraw接口,故意需借助Flat Thunk在16位與32位模塊間建立聯(lián)系。
本設(shè)備驅(qū)動程序朝陽區(qū)分利用PCI總線的帶寬和Windows95系統(tǒng)資源,獲得了較高的采集速率(384×288×24bits 25fps),實(shí)現(xiàn)了實(shí)時視頻顯示。驅(qū)動程序性能穩(wěn)定,兼容性良好,在運(yùn)行Windows95的586以上系統(tǒng)中可穩(wěn)定運(yùn)行,并可運(yùn)行于Windows95上。