windows multimedia techniques - video capture 井民全製作

23
Windows Multimedia Windows Multimedia Techniques Techniques - Video Capture - Video Capture 井井井井井

Upload: june-berry

Post on 05-Jan-2016

229 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Windows Multimedia Techniques - Video Capture 井民全製作

Windows Multimedia TechniquesWindows Multimedia Techniques

- Video Capture- Video Capture

井民全製作

Page 2: Windows Multimedia Techniques - Video Capture 井民全製作

為何要使用 為何要使用 Video For WindowsVideo For Windows

• 簡單就是美 : – 你不需要知道 COM 的原理 , 就能寫影像處理

程式 ( 相對於 DirectX)

• 開發容易 : – 你不用下載 數百 M 的 DirectX SDK

Page 3: Windows Multimedia Techniques - Video Capture 井民全製作

Video for Windows Video for Windows 的缺點的缺點• doesn't handle audio/video synchronization • doesn't support variable-length frames

• 基於以上缺點– 目前 Microsoft 使用 DirectShow 與 WDM Stream Class

來解決這個問題

• Driver 開發– 請使用 WDM Stream Class 取代 VFW architecture 

Page 4: Windows Multimedia Techniques - Video Capture 井民全製作

IntroductionIntroduction

• using the AVICap window class to enable video capture– Simple– message-based interface

• Access the hardware• Control the stream to disk

Page 5: Windows Multimedia Techniques - Video Capture 井民全製作

IntroductionIntroduction

• Streaming video capture & single-frame capture in real-time

• Using Media Control Interface (MCI)– You can control the start and stop positions of

a video source

Page 6: Windows Multimedia Techniques - Video Capture 井民全製作

The tasks of the AVICap window classThe tasks of the AVICap window class

• Capture audio & video stream AVI file• Connect and Disconnect the devices

dynamically.• View a live incoming video signal • Set the capture rate• Display dialog boxes that control the video

source and format• Capture and save a single image as a device-

independent bitmap (DIB)

Page 7: Windows Multimedia Techniques - Video Capture 井民全製作

Previewing Video DemoPreviewing Video Demo

• 必要 include 檔 : vfw.h

• Library : vfw32.lib

#include <vfw.h>#pragma comment( lib, "Vfw32.lib" )

#include <vfw.h>#pragma comment( lib, "Vfw32.lib" )

Page 8: Windows Multimedia Techniques - Video Capture 井民全製作

Creating a Capture WindowCreating a Capture Window

HWND hwndParent=this->m_hWnd;HWND hWndC = capCreateCaptureWindow ( "Capture Window",

WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, 0);if(hWndC==NULL) ShowError();

HWND hwndParent=this->m_hWnd;HWND hWndC = capCreateCaptureWindow ( "Capture Window",

WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, 0);if(hWndC==NULL) ShowError();

你要顯示畫面的視窗 Handle

capDriverConnect (hWndC, 0); capDriverConnect (hWndC, 0);

Connecting to a Capture Driver

Page 9: Windows Multimedia Techniques - Video Capture 井民全製作

Obtaining the Status of a Capture WindowObtaining the Status of a Capture Window

CAPSTATUS CapStatus;BOOL bOK;bOK=capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

::SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth, \

CapStatus.uiImageHeight,\ SWP_NOZORDER | SWP_NOMOVE);

CAPSTATUS CapStatus;BOOL bOK;bOK=capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

::SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth, \

CapStatus.uiImageHeight,\ SWP_NOZORDER | SWP_NOMOVE);

調整 Capture Window 大小

得到 Frame 的大小

Page 10: Windows Multimedia Techniques - Video Capture 井民全製作

Previewing VideoPreviewing Video

capPreviewRate(hWndC, 66); // rate, in millisecondscapPreview(hWndC, TRUE); // starts preview

capPreviewRate(hWndC, 66); // rate, in millisecondscapPreview(hWndC, TRUE); // starts preview

Page 11: Windows Multimedia Techniques - Video Capture 井民全製作

完整程式完整程式#include <vfw.h>#pragma comment( lib, "Vfw32.lib" ) // 使用 Video For Window 32 libraryvoid CSimpleVideoDlg::OnBnClickedOk() {

// 建立 Capture 視窗HWND hwndParent=this->m_hWnd;HWND hWndC = capCreateCaptureWindow ( "Capture Window", WS_CHILD | WS_VISIBLE , 0, 0, 160, 120,

hwndParent, 0); // 與 Device Driver 連線

capDriverConnect (hWndC, 0); // 讀取一張 frame 的大小

CAPSTATUS CapStatus;BOOL bOK=capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS)); ::SetWindowPos(hWndC, NULL, 0, 0,

CapStatus.uiImageWidth, CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);

// 設定 Preview Rate 並且 顯示出來capPreviewRate(hWndC, 66); // rate, in millisecondscapPreview(hWndC, TRUE); // starts preview

} Simple Video

Page 12: Windows Multimedia Techniques - Video Capture 井民全製作

更多的選項更多的選項 :: 列舉出目前系統所擁有的 列舉出目前系統所擁有的 Capture DriverCapture Driver

char szDeviceName[80];char szDeviceVersion[80];CString DeviceList;for (int wIndex = 0; wIndex < 10; wIndex++) {

if (capGetDriverDescription (wIndex, szDeviceName, \sizeof (szDeviceName), szDeviceVersion, \sizeof (szDeviceVersion)))

{// Append name to list of installed capture drivers// and then let the user select a driver to use.DeviceList.Append(szDeviceName);

}} MessageBox(DeviceList," 系統中 Capture Driver 描述 ");

char szDeviceName[80];char szDeviceVersion[80];CString DeviceList;for (int wIndex = 0; wIndex < 10; wIndex++) {

if (capGetDriverDescription (wIndex, szDeviceName, \sizeof (szDeviceName), szDeviceVersion, \sizeof (szDeviceVersion)))

{// Append name to list of installed capture drivers// and then let the user select a driver to use.DeviceList.Append(szDeviceName);

}} MessageBox(DeviceList," 系統中 Capture Driver 描述 ");

• 使用 capGetDriverDescription 函式

可以 0 ~ 9

傳回的 Capture Driver 描述

傳回的 版本資訊

印出來

Page 13: Windows Multimedia Techniques - Video Capture 井民全製作

更多的選項更多的選項 :: 選擇 選擇 Video SourceVideo Source

CAPDRIVERCAPS CapDriverCaps; ::SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS, \ sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDriverCaps);

if (CapDriverCaps.fHasDlgVideoSource) capDlgVideoSource(hWndC);

CAPDRIVERCAPS CapDriverCaps; ::SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS, \ sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDriverCaps);

if (CapDriverCaps.fHasDlgVideoSource) capDlgVideoSource(hWndC);

傳回的硬體裝置的基本能力描述

顯示 Video Source 對話框由使用者選擇

看看是否支援 Video Source Dialog

Page 14: Windows Multimedia Techniques - Video Capture 井民全製作

更多的選項更多的選項 :: 如何得知抓到的如何得知抓到的影像格式影像格式呢呢 ? ?

現在是 RGB 24

// Video format dialog box. if (CapDriverCaps. fHasDlgVideoFormat){ capDlgVideoFormat (hWndC);

// Are there new image dimensions? capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

}

// Video format dialog box. if (CapDriverCaps. fHasDlgVideoFormat){ capDlgVideoFormat (hWndC);

// Are there new image dimensions? capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

}

顯示 Video Format 對話框 , 供使用者設定

Page 15: Windows Multimedia Techniques - Video Capture 井民全製作

更多的選項更多的選項 :: 調整輸出影像的調整輸出影像的對比亮度對比亮度等屬性等屬性• 注意 : 不會影響 video data

// Video display dialog box. if (CapDriverCaps.fHasDlgVideoDisplay)

capDlgVideoDisplay(hWndC);

// Video display dialog box. if (CapDriverCaps.fHasDlgVideoDisplay)

capDlgVideoDisplay(hWndC);

Page 16: Windows Multimedia Techniques - Video Capture 井民全製作

更多的選項更多的選項 :: 傳回目前正在使用的 傳回目前正在使用的 video formatvideo format

DWORD dwSize;dwSize = capGetVideoFormatSize(hWndC);

lpbi = (LPBITMAPINFO) GlobalAllocPtr(GHND, dwSize);capGetVideoFormat(hWndC, lpbi, dwSize);

DWORD dwSize;dwSize = capGetVideoFormatSize(hWndC);

lpbi = (LPBITMAPINFO) GlobalAllocPtr(GHND, dwSize);capGetVideoFormat(hWndC, lpbi, dwSize);

Step 1: 先計算 Video Format 所需的 大小

Step 2: 取出 Video Format

LPBITMAPINFO lpbi;

Video Format 用 BITMAPINFO 結構表示

Page 17: Windows Multimedia Techniques - Video Capture 井民全製作

影像資料的擷取影像資料的擷取• 我們利用 capSetCallbackOnFrame 函式

– 當一張 frame 填滿後 , 會呼叫你的 fucntion

BOOL bOk= capSetCallbackOnFrame(hWndC, \ capVideoStreamCallback);

BOOL bOk= capSetCallbackOnFrame(hWndC, \ capVideoStreamCallback);

LRESULT CALLBACK capVideoStreamCallback (HWND hWnd , \ LPVIDEOHDR lpVHdr) { …}

填滿後 , 自動呼叫

Page 18: Windows Multimedia Techniques - Video Capture 井民全製作

全部合在一起全部合在一起#include "Vfw.h"#include <windowsx.h> // for GlobalAllocPtr#pragma comment( lib, "Vfw32.lib" ) // 使用 Video For Window 32 library

LRESULT CALLBACK capVideoStreamCallback(HWND hWnd,LPVIDEOHDR lpVHdr);HWND hMyWnd;LPBITMAPINFO lpbi; // for video format

void CWin32VideoCaptureDlg::OnBnClickedOk(){

hMyWnd=this->m_hWnd; // Step 1. 建立 Capture Window 並且把這個 Window 貼在 Dialog 上

HWND hWndC = capCreateCaptureWindow ( (LPSTR) "My Capture Window", // window name if pop-up WS_CHILD | WS_VISIBLE, // window style 0, 0, 160, 120, // window position and dimensions

this->m_hWnd, // 不能給 NULL, 否則會失敗 0 /* child ID */); // Step 2. 與硬體驅動程式連線 LRESULT fOK = ::SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0, 0L);

接下頁 VFW Demo

Page 19: Windows Multimedia Techniques - Video Capture 井民全製作

// Step 3. 列舉出目前系統所擁有的 Capture Driverchar szDeviceName[80];char szDeviceVersion[80];CString DeviceList;for (int wIndex = 0; wIndex < 10; wIndex++) {

if (capGetDriverDescription (wIndex, szDeviceName, \sizeof (szDeviceName), szDeviceVersion, \sizeof (szDeviceVersion))) {// Append name to list of installed capture drivers// and then let the user select a driver to use.DeviceList.Append(szDeviceName);

}} // end of listMessageBox(DeviceList," 系統中 Capture Driver 描述 ");

// Step 4. 取得目前 Capture 的功能 // ( 我們藉此判斷使用者是否可以設定 Video Source 與 Video Format) CAPDRIVERCAPS CapDriverCaps; ::SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS, \

sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDriverCaps);

// Step 5: 讓使用者使用者選定的 Video Sourceif (CapDriverCaps.fHasDlgVideoSource)

capDlgVideoSource(hWndC); 接下頁

選擇 video source 部分

系統中是否有 Capture

Driver

Page 20: Windows Multimedia Techniques - Video Capture 井民全製作

// Step 6: 讓使用者調整的 Video Format CAPSTATUS CapStatus;

if (CapDriverCaps.fHasDlgVideoFormat){capDlgVideoFormat(hWndC); // Are there new image dimensions?capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));// If so, notify the parent of a size change.

} // Step 7: 讓使用者調整影像的輸出屬性 ( 亮度 , 對比 , 彩度 )

if (CapDriverCaps.fHasDlgVideoDisplay)capDlgVideoDisplay(hWndC);

// Step 8: 得到最後的硬體狀態BOOL bOK=capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

// Step 9: 調整 Capture 視窗的大小 ,::SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth, \ CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);

// Step 10. Obtaining and Setting the Video FormatDWORD dwSize;dwSize = capGetVideoFormatSize(hWndC);lpbi = (LPBITMAPINFO) GlobalAllocPtr(GHND, dwSize);capGetVideoFormat(hWndC, lpbi, dwSize);

接下頁

由 lpbi 可以得知一張 frame 的寬與高

Page 21: Windows Multimedia Techniques - Video Capture 井民全製作

// Step 11. Previewing VideocapPreviewRate(hWndC, 66); // rate, in millisecondscapPreview(hWndC, TRUE); // starts preview

// Step 12. 當一張 frame 填滿後 , 呼叫登記的 function 處理BOOL bOk= capSetCallbackOnFrame(hWndC, capVideoStreamCallback);

} // end of OnBnClickedOk

int gdwFrameNum=0;char *gachBuffer=new char[100];LRESULT CALLBACK capVideoStreamCallback(HWND hWnd,LPVIDEOHDR lpVHdr){ if (!hWnd) return FALSE; // 若你的 video format 為 RGB24, 注意 : DIB 左下角 = (0,0) wsprintf(gachBuffer, "Preview frame# %ld 一個 pixel=%d bits; 寬 =%d; 高 =%d; (RGB)=(%d,%d,%d) 使用的長度 =%d" ,\

gdwFrameNum++, lpbi->bmiHeader.biBitCount,\ lpbi->bmiHeader.biWidth, lpbi->bmiHeader.biHeight,\

(int)*(lpVHdr->lpData),\ (int)*(lpVHdr->lpData+1),\ (int)*(lpVHdr->lpData+2),\ lpVHdr->dwBytesUsed );

SetWindowText(hMyWnd, (LPSTR)gachBuffer); return (LRESULT) TRUE ; }

Call Back Function

Page 22: Windows Multimedia Techniques - Video Capture 井民全製作

目前發展近況目前發展近況• Microsoft 使用新架構取代 VFW

– WDM Stream class and Microsoft DirectShow

Page 23: Windows Multimedia Techniques - Video Capture 井民全製作

• End