itprofes
Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.

Tự tạo webcam ảo

Go down

Tự tạo webcam ảo Empty Tự tạo webcam ảo

Bài gửi  admin 26/3/2010, 8:27 am

Đối với những người hay chat, có lẽ không ít thì
nhiều cũng nghe qua phần mềm Fakewebcam
, đây là phần mềm khá độc đáo, cho phép đưa dữ liệu từ một file video
hay file hình bất kỳ vào chương trình để chia sẻ với bạn bè. Cách đây
khá lâu, một người bạn có nhờ tôi làm hộ một chương trình tương tự như
Fakewebcam, dữ liệu lấy từ webcam thật, sau quá trình xử lý ảnh (bằng
một chương trình_application) sẽ được đưa cho Yahoo. Vấn đề ở đây là làm
thế nào có thể đưa dữ liệu hình ảnh sau xử lý cho Yahoo. Sau khi tìm
kiếm trên mạng, tham khảo thêm thông tin từ DirectX, và nhất là tìm kiếm
trong bộ source code mẫu của WDF, tôi nghĩ có một giải pháp là làm giả
thiết bị webcam (Virtual webcam) ở mức độ hệ thống.

Trong hình trên, dấu mũi tên là đường đi dữ liệu: dữ
liệu từ webcam thật đến chương trình xử lý ảnh, hình ảnh xử lý xong sẽ
được đưa cho webcam ảo, Yahoo (hay các chương trình ứng dụng khác) truy
cập vào webcam ảo để lấy dữ liệu. Ở đây chúng ta có vấn đề nảy sinh tiếp
theo là dữ liệu từ driver webcam thật có thể đọc được từ chương trình
ứng dụng (sử dụng DirectShow, hay VFW), nhưng làm thế nào để đưa dữ liệu
từ ứng dụng xuống cho driver.
Chia sẻ
dữ liệu giữa các tiến trình
Giải
pháp là sử dụng: kỹ thuật chia sẻ vùng nhớ giữa các process với nhau. Ở
đây là chia sẻ giữa driver và ứng dụng.
1.
Phía ứng dụng:
khởi tạo vùng nhớ và đưa dữ liệu vào.
+CreateFileMapping:
hàm này sẽ khởi tạo vùng nhớ.
+MapViewOfFile:
hàm này sẽ đưa cho ta địa chỉ trỏ tới vùng nhớ đã được khởi tạo bởi
CreateFileMapping ở trên.
Đoạn mã thực
hiện việc tạo vùng nhớ và địa chỉ trỏ tới vùng nhớ:
#define szName
L"MyFakeWebcamMappingObject"
void
COpenFakeWebcamDlg::CreateMappFile()
{
MapFile =
CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging
file
NULL, // default security

PAGE_READWRITE, // read/write access
0,
// max. object size
BUF_SIZE, //
buffer size
szName);
if(MapFile == NULL)
{
MessageBox(L"Create MapFile Failed !",L"Error");

this->CloseWindow();
}
MapBuffer = (unsigned
char*)MapViewOfFile(
MapFile, // handle to map object

FILE_MAP_ALL_ACCESS, // read/write permission
0,

0,
BUF_SIZE);
if(MapBuffer == NULL)
{
MessageBox(L"Create
MapBuffer Failed !",L"Error");
this->CloseWindow();

}
}
2. Phía driver:
mở vùng nhớ (nếu đã được tạo bởi ứng dụng), đọc dữ liệu và đưa ra giao
diện xuất dữ liệu.
+ZwOpenSection:
hàm này mở 1 section đã có sẵn thông qua tên gọi của nó. Section này là
vùng dữ liệu chúng ta cần chia sẻ. Lưu ý là dùng xong thì chúng ta phải
đóng section này lại bằng hàm ZwClose
để giải phóng tài nguyên.
+ZwMapViewOfSection:
sau khi mở section xong, hàm này sẽ ánh xạ vùng dữ liệu của section vào
vùng nhớ ảo để có thể truy xuất. Sau khi truy xuất xong thì dùng hàm ZwUnmapViewOfSection
để giải phóng tài nguyên.
RtlInitUnicodeString(

&fileNameUnicodeString,

L"\\BaseNamedObjects\\MyFakeWebcamMappingObject");
InitializeObjectAttributes(
&objectAttributes,
&fileNameUnicodeString,

OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
(HANDLE)NULL,

(PSECURITY_DEscriptOR)NULL );
rc = ZwOpenSection(

&hFileHandle,
SECTION_MAP_READ,

&objectAttributes);
if (NT_SUCCESS(rc))
{
rc =
ZwMapViewOfSection(
hFileHandle, //section handle

ZwCurrentProcess(), // current process
&uBaseAddress,
//virtual based address
0L, //Zerobits
size,

0, // optional
(PSIZE_T)&ViewSize, // How much to
map
ViewShare, // Inherit disposition
0,
//ALlocation Type
PAGE_READWRITE //protection
);

if (NT_SUCCESS(rc))
{
m_Device->
m_HardwareSimulation -> bFileOk = TRUE;
RtlCopyMemory(
m_Device-> m_HardwareSimulation -> FileBuffer,

uBaseAddress,ViewSize );
//release memory

ZwUnmapViewOfSection(
ZwCurrentProcess(), // current
process
uBaseAddress);
}
} Nền
tảng phát triển
Driver: sử dụng
driver của chương trình mẫu có sẵn trong WDF: AVStream Simulated
Hardware Sample Driver (\src\AVStream\avshws), phát triển thêm các phần
chia sẻ dữ liệu với chương trình ứng dụng.

Ứng dụng: sử dụng DirectX
để đọc dữ liệu từ các file video.
Thao
tác dữ liệu
Sau khi đã tạo vùng
chia sẽ dữ liệu chung, công việc còn lại bao gồm:
+Ứng dụng đọc dữ liệu và ghi vào vùng nhớ chia sẻ đã
được khởi tạo
for(long
y=0 ; y < height && y< HEIGHT ; y++)
{

bufAddress = (long)(y*width*4);
for(long x=0; x< width
&& x< WIDTH ; x++)
{
MapBuffer[index] =
bufData[bufAddress];
MapBuffer[index+1] =
bufData[bufAddress+1];
MapBuffer[index+2] =
bufData[bufAddress+2];
index+=3;
bufAddress += 4;
}
} +Phía driver chép dữ liệu vào vùng đệm
int w = m_ImageSynth ->
m_Width;
int h = m_ImageSynth -> m_Height;
int size = w*h*3;
RtlCopyMemory
(
m_ImageSynth -> m_SynthesisBuffer,
FileBuffer,size);
//
Fill scatter gather buffers
if (!NT_SUCCESS
(FillScatterGatherBuffers ())) {
InterlockedIncrement (PLONG
(&m_NumFramesSkipped));
} Biên dịch, cài đặt và sử
dụng chương trình
Về cách biên dịch
và cài đặt driver, có thể tham khảo tại ở bài viết "Lập
trình driver trên Windows - Cài đặt bộ công cụ lập trình"
.
Sau khi cài đặt Webcam ảo thành công, vào Device
Manager->Sound,Video and game controllers để kiểm tra xem thiết bị
Webcam ảo có xuất hiện hay không.
Hướng dẫn sử
dụng:

Hạn chế
của chương trình
Có thể nhận thấy là
chương trình này chiếm khá nhiều tài nguyên và bộ nhớ hệ thống, hiệu
suất chưa cao, ngoài ra chỉ mới hỗ trợ cho Windows XP.
Kết luận
Vậy
là chúng ta đã có thể tự tạo cho mình một webcam ảo. Quan trọng hơn là
chúng ta đã tiếp cận tới hệ thống driver của Microsoft, làm một ứng dụng
cụ thể, có khả năng áp dụng thực tế mà lại không quá khó. Hi vọng ví dụ
nhỏ này sẽ giúp các bạn có thêm hứng thú với lập trình hệ thống. Chúc
các bạn thành công.
admin
admin
Thiếu Úy III
Thiếu Úy III

Tổng số bài gửi : 627
Diem : 6539
Thank : 4
Join date : 24/03/2010
Đến từ : Bỉm Sơn - Thanh hóa

https://itprofes.forumvi.com

Về Đầu Trang Go down

Về Đầu Trang


 
Permissions in this forum:
Bạn không có quyền trả lời bài viết