📄 capturebuf.cpp
字号:
#include "StdAfx.h"
#include "capturebuf.h"
HRESULT InitCaptureCard(CAPTUREPARAM param)
{
HRESULT hr;
if (FAILED(hr= DSStream_Initialize()))
return hr;
if (FAILED(hr= DSStream_ConnectDevice(param.cap_card, FALSE, param.cap_hwnd)))
return hr;
// 窗口显示区域
RECT rc;
if (param.cap_show)
{
rc.left= 0;
rc.right= rc.left + param.cap_width;
rc.top= 0;
rc.bottom= rc.top + param.cap_height;
}
else
{
rc.left= rc.right= rc.top= rc.bottom= 0;
}
DSStream_SetWindowPos(param.cap_card, rc);
// 设置图像格式
DSStream_SetVideoStandard(param.cap_card, VideoStandard_PAL_D);
VIDEOSTREAMINFO vsi;
DSStream_GetVideoInfo(param.cap_card, &vsi, param.cap_pin);
vsi.subtype= VideoSubType_RGB24;
vsi.bmiHeader.biWidth= param.cap_width;
vsi.bmiHeader.biHeight= param.cap_height;
DSStream_SetVideoInfo(param.cap_card, vsi, param.cap_pin);
DSStream_GetVideoInfo(param.cap_card, &vsi, param.cap_pin);
// 设置对比度等参数
DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Saturation, 5000);
DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Brightness, 5000);
DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Contrast, 5000);
DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Hue, 5000);
return S_OK;
}
void ReleaseCard(CAPTUREPARAM param)
{
DSStream_DisconnectDevice(param.cap_card);
DSStream_Uninitialize();
}
CCaptureBuf::CCaptureBuf(void)
: m_phdr(NULL)
, m_size(0)
{
}
CCaptureBuf::~CCaptureBuf(void)
{
Free();
}
// 分配所需的内存空间
bool CCaptureBuf::Alloc(int cap_card)
{
Free();
if (FAILED(DSStream_GetCurrentDib(cap_card, NULL, &m_size)))
return false;
else
{
m_phdr= reinterpret_cast<BITMAPINFOHEADER*>(new unsigned char[m_size]);
m_phdr->biBitCount= 16;
m_phdr->biHeight= 240;
m_phdr->biWidth= 320;
return true;
}
}
// 释放内存
void CCaptureBuf::Free(void)
{
m_size= 0;
delete[] m_phdr;
m_phdr= NULL;
}
// 从采集卡数据流中更新缓冲区数据
bool CCaptureBuf::UpdateBuffer(int cap_card)
{
if (SUCCEEDED(DSStream_GetCurrentDib(cap_card, reinterpret_cast<BYTE *>(m_phdr), &m_size)))
{
long lPitch= 2 * m_phdr->biWidth;
lPitch+= (4 - lPitch % 4) % 4;
// 颠倒扫描线
for (unsigned int y= 0; y < (m_phdr->biHeight / 2); y++)
{
unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned short *pdst= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + (m_phdr->biHeight - y - 1) * lPitch);
for (unsigned int x= 0; x < (m_phdr->biWidth); x++)
{
__asm
{
mov esi, psrc;
mov edi, pdst;
mov ax, [esi];
mov bx, [edi];
mov [edi], ax;
mov [esi], bx;
add esi, 2;
add edi, 2;
mov psrc, esi;
mov pdst, edi;
}
}
}
return true;
}
else
return false;
}
bool CCaptureBuf::UpdateBuffer(LPI_DXSURFACE ps)
{
long lPitch= 2 * m_phdr->biWidth;
lPitch+= (4 - lPitch % 4) % 4;
IMAGEMEMORY img;
ps->LockImage(&img);
if (img.bitcount == 16)
{ // 565 to 555
for (unsigned int y= 0; y < m_phdr->biHeight; y++)
{
unsigned short *pdst= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned short *psrc= reinterpret_cast<unsigned short *>(img.pMemory + img.lPitch * y);
for (unsigned int x= 0; x < m_phdr->biWidth; x++)
{
__asm
{
mov edi, pdst;
mov esi, psrc;
mov ax, [esi];
mov bl, al;
and bl, 0x1F; // 3(0)B5 => bl
shr ax, 1; // 1(0)R5G6B4 => ax
and al, 0x7FE0; // 1(0)R5G5B5(0) => ax
or al, bl; // 1(0)R5G5B5 => ax
mov [edi], ax;
add edi, 2;
add esi, 2;
mov pdst, edi;
mov psrc, esi;
}
}
}
}
else if (img.bitcount == 32)
{ // 888 to 555
for (unsigned int y= 0; y < m_phdr->biHeight; y++)
{
unsigned short *pdst= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned int *psrc= reinterpret_cast<unsigned int *>(img.pMemory + img.lPitch * y);
for (unsigned int x= 0; x < m_phdr->biWidth; x++)
{
__asm
{
mov edi, pdst;
mov esi, psrc;
mov eax, [esi];
mov ebx, eax;
and ebx, 0x000000F8; // b5 => ebx;
mov ecx, eax;
and ecx, 0x0000F800; // g5 => ecx;
and eax, 0x00F80000; // r5 => eax;
shr ebx, 3;
shr ecx, 6;
shr eax, 9;
or eax, ebx;
or eax, ecx;
mov [edi], ax;
add edi, 2;
add esi, 4;
mov pdst, edi;
mov psrc, esi;
}
}
}
}
ps->UnlockImage();
return true;
}
// 图象转换, pBMPHdr为采集卡的数据(16位)
void CCaptureBuf::Bitmap2Surface(LPI_DXSURFACE ps)
{
long lPitch= 2 * m_phdr->biWidth;
lPitch+= (4 - lPitch % 4) % 4;
IMAGEMEMORY img;
ps->LockImage(&img);
if (img.bitcount == 16)
{ // 555 to 565
for (unsigned int y= 0; y < m_phdr->biHeight; y++)
{
unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned short *pdst= reinterpret_cast<unsigned short *>(img.pMemory + img.lPitch * y);
for (unsigned int x= 0; x < m_phdr->biWidth; x++)
{
__asm
{
mov esi, psrc;
mov edi, pdst;
xor eax, eax;
xor ebx, ebx;
mov ax, [esi];
mov bx, ax;
shl ax, 1;
and ax, 0xFFC0; // convert to R5G5G1(0)B5(0)
and bx, 0x001F; // convert to R5(0)G6(0)B5
or ax, bx; // convert to R5G6B6 => ax
mov [edi], ax;
add psrc, 2;
add pdst, 2;
}
}
}
}
else
{ // 555 to 888
for (unsigned int y= 0; y < m_phdr->biHeight; y++)
{
unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned int *pdst= reinterpret_cast<unsigned int *>(img.pMemory + img.lPitch * y);
for (unsigned int x= 0; x < m_phdr->biWidth; x++)
{
__asm
{
mov esi, psrc;
mov edi, pdst;
xor eax, eax;
xor ebx, ebx;
mov ax, [esi];
shl eax, 3;
mov bl, al; // B5B3(0) => bl;
xor al, al;
shl eax, 3;
mov bh, ah; // G5G3(0) => bh;
xor ah, ah;
shl eax, 3;
mov ah, bh;
mov al, bl; // R5R3(0)G5G3(0)B5B3(0) => eax
mov [edi], eax;
add psrc, 2;
add pdst, 4;
}
}
}
}
ps->UnlockImage();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -