Screen image transmission uses H.264 compression #65
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include "X264Encoder.h"
|
||||
|
||||
|
||||
class ThreadPool {
|
||||
@@ -103,11 +104,12 @@ public:
|
||||
int m_FrameID; // ֡<><D6A1><EFBFBD><EFBFBD>
|
||||
int m_GOP; // <20>ؼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||
bool m_SendKeyFrame; // <20><><EFBFBD>ؼ<CDB9>֡
|
||||
CX264Encoder *m_encoder; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
ScreenCapture() : m_ThreadPool(nullptr), m_FirstBuffer(nullptr), m_RectBuffer(nullptr),
|
||||
m_BitmapInfor_Full(nullptr), m_bAlgorithm(ALGORITHM_DIFF),
|
||||
ScreenCapture(BYTE algo = ALGORITHM_DIFF) : m_ThreadPool(nullptr), m_FirstBuffer(nullptr), m_RectBuffer(nullptr),
|
||||
m_BitmapInfor_Full(nullptr), m_bAlgorithm(algo),
|
||||
m_ulFullWidth(0), m_ulFullHeight(0), m_bZoomed(false), m_wZoom(1), m_hZoom(1),
|
||||
m_FrameID(0), m_GOP(DEFAULT_GOP), m_SendKeyFrame(false){
|
||||
m_FrameID(0), m_GOP(DEFAULT_GOP), m_SendKeyFrame(false), m_encoder(nullptr){
|
||||
|
||||
m_BlockNum = 8;
|
||||
m_ThreadPool = new ThreadPool(m_BlockNum);
|
||||
@@ -127,6 +129,14 @@ public:
|
||||
Mprintf("=> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><C5B1><EFBFBD>: %.2f, %.2f\t<EFBFBD>ֱ<EFBFBD><EFBFBD>ʣ<EFBFBD>%d x %d\n", m_wZoom, m_hZoom, m_ulFullWidth, m_ulFullHeight);
|
||||
m_wZoom = 1.0 / m_wZoom, m_hZoom = 1.0 / m_hZoom;
|
||||
|
||||
if (ALGORITHM_H264 == m_bAlgorithm)
|
||||
{
|
||||
m_encoder = new CX264Encoder();
|
||||
if (!m_encoder->open(m_ulFullWidth, m_ulFullHeight, 20, m_ulFullWidth * m_ulFullHeight / 1266)) {
|
||||
Mprintf("Open x264encoder failed!!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
m_BlockBuffers = new LPBYTE[m_BlockNum];
|
||||
m_BlockSizes = new ULONG[m_BlockNum];
|
||||
for (int blockY = 0; blockY < m_BlockNum; ++blockY) {
|
||||
@@ -147,6 +157,7 @@ public:
|
||||
SAFE_DELETE_ARRAY(m_BlockSizes);
|
||||
|
||||
SAFE_DELETE(m_ThreadPool);
|
||||
SAFE_DELETE(m_encoder);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -240,6 +251,12 @@ public:
|
||||
return m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
}
|
||||
|
||||
void ToGray(LPBYTE dst, LPBYTE src, int biSizeImage) {
|
||||
for (ULONG i = 0; i < biSizeImage; i += 4, dst += 4, src += 4) {
|
||||
dst[0] = dst[1] = dst[2] = (306 * src[2] + 601 * src[0] + 117 * src[1]) >> 10;
|
||||
}
|
||||
}
|
||||
|
||||
// <20>㷨+<2B><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LPBYTE GetNextScreenData(ULONG* ulNextSendLength) {
|
||||
BYTE algo = m_bAlgorithm;
|
||||
@@ -266,7 +283,9 @@ public:
|
||||
// <20>ֶ<EFBFBD>ɨ<EFBFBD><C9A8>ȫ<EFBFBD><C8AB>Ļ <20><><EFBFBD>µ<EFBFBD>λͼ<CEBB><CDBC><EFBFBD>뵽m_hDiffMemDC<44><43>
|
||||
LPBYTE nextData = ScanNextScreen();
|
||||
if (nullptr == nextData) {
|
||||
return nullptr;
|
||||
// ɨ<><C9A8><EFBFBD><EFBFBD>һ֡ʧ<D6A1><CAA7>Ҳ<EFBFBD><D2B2>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><CDB9><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>
|
||||
*ulNextSendLength = 1 + offset;
|
||||
return m_RectBuffer;
|
||||
}
|
||||
|
||||
#if SCREENYSPY_IMPROVE
|
||||
@@ -281,22 +300,57 @@ public:
|
||||
|
||||
if (keyFrame)
|
||||
{
|
||||
*ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
if (algo != ALGORITHM_GRAY)
|
||||
switch (algo)
|
||||
{
|
||||
case ALGORITHM_DIFF: {
|
||||
*ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
memcpy(data + offset, nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LPBYTE dst = data + offset, src = nextData;
|
||||
for (ULONG i = 0; i < m_BitmapInfor_Full->bmiHeader.biSizeImage; i += 4, dst += 4, src += 4) {
|
||||
dst[0] = dst[1] = dst[2] = (306 * src[2] + 601 * src[0] + 117 * src[1]) >> 10;
|
||||
case ALGORITHM_GRAY: {
|
||||
*ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
ToGray(data + offset, nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
break;
|
||||
}
|
||||
case ALGORITHM_H264: {
|
||||
uint8_t* encoded_data = nullptr;
|
||||
uint32_t encoded_size = 0;
|
||||
int err = m_encoder->encode(nextData, 32, 4*m_BitmapInfor_Full->bmiHeader.biWidth,
|
||||
m_ulFullWidth, m_ulFullHeight, &encoded_data, &encoded_size);
|
||||
if (err) {
|
||||
return nullptr;
|
||||
}
|
||||
*ulNextSendLength = 1 + offset + encoded_size;
|
||||
memcpy(data + offset, encoded_data, encoded_size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memcpy(GetFirstBuffer(), nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
else {
|
||||
*ulNextSendLength = 1 + offset + MultiCompareBitmap(nextData, GetFirstBuffer(), data + offset, GetBMPSize(), algo);
|
||||
switch (algo)
|
||||
{
|
||||
case ALGORITHM_DIFF: case ALGORITHM_GRAY: {
|
||||
*ulNextSendLength = 1 + offset + MultiCompareBitmap(nextData, GetFirstBuffer(), data + offset, GetBMPSize(), algo);
|
||||
break;
|
||||
}
|
||||
case ALGORITHM_H264: {
|
||||
uint8_t* encoded_data = nullptr;
|
||||
uint32_t encoded_size = 0;
|
||||
int err = m_encoder->encode(nextData, 32, 4 * m_BitmapInfor_Full->bmiHeader.biWidth,
|
||||
m_ulFullWidth, m_ulFullHeight, &encoded_data, &encoded_size);
|
||||
if (err) {
|
||||
return nullptr;
|
||||
}
|
||||
*ulNextSendLength = 1 + offset + encoded_size;
|
||||
memcpy(data + offset, encoded_data, encoded_size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_RectBuffer;
|
||||
|
||||
Reference in New Issue
Block a user