头:
#ifndef __MANAGE_X264__
#define __MANAGE_X264__
#include "x264.h"
#include <opencv.hpp>
using namespace cv;
class ManageX264
{
public:
ManageX264();
~ManageX264();
public:
bool Init(long nWidth, long nHeight);
void Uninit();
public:
void EncoderImg(const Mat& frame, unsigned char** pData, long& nLen);
private:
long m_nScreenWidth = 0;
long m_nScreenHeight = 0;
private:
x264_picture_t m_picIn;
x264_t* m_handle;
};
#endif
源:
#include "ManageX264.h"
#include <memory>
ManageX264::ManageX264()
{
}
ManageX264::~ManageX264()
{
}
bool ManageX264::Init(long nWidth, long nHeight)
{
x264_param_t param;
if (x264_param_default_preset(¶m, "ultrafast", NULL) < 0) {
return false;
}
/* Configure non-default params */
param.i_bitdepth = 8;
param.i_csp = X264_CSP_I420;
param.i_width = nWidth;
param.i_height = nHeight;
param.b_vfr_input = 0;
param.b_repeat_headers = 1;
param.b_annexb = 1;
if (x264_param_apply_profile(¶m, "high") < 0) {
return false;
}
if (x264_picture_alloc(&m_picIn, param.i_csp, param.i_width, param.i_height) < 0) {
return false;
}
m_handle = x264_encoder_open(¶m);
if (!m_handle) {
return false;
}
m_nScreenWidth = nWidth;
m_nScreenHeight = nHeight;
return true;
}
void ManageX264::EncoderImg(const Mat& frame, unsigned char** pData, long& nLen)
{
int luma_size = m_nScreenWidth * m_nScreenHeight;
int chroma_size = luma_size / 4;
memcpy(m_picIn.img.plane[0], frame.data, luma_size);
memcpy(m_picIn.img.plane[1], frame.data + luma_size, chroma_size);
memcpy(m_picIn.img.plane[2], frame.data + luma_size + chroma_size, chroma_size);
x264_nal_t* nal = nullptr;
int i_nal;
m_picIn.i_pts++;
x264_picture_t pic_out;
int i_frame_size = x264_encoder_encode(m_handle, &nal, &i_nal, &m_picIn, &pic_out);
if (i_frame_size < 0) {
return;
}
if (i_frame_size) {
/*FILE* pFile = fopen("d:\\1.264", "ab+");
if (pFile) {
fwrite(nal->p_payload, i_frame_size, 1, pFile);
fclose(pFile);
}*/
try {
*pData = new unsigned char[i_frame_size];
}
catch (...) {}
if (*pData) {
memcpy(*pData, nal->p_payload, i_frame_size);
nLen = i_frame_size;
}
}
}
void ManageX264::Uninit()
{
x264_encoder_close(m_handle);
x264_picture_clean(&m_picIn);
}
调用:
long nImageLen = 0;
unsigned char* pImageData = SingleTon<ManageBmp>::GetInstance()->GetData(nImageLen);
if (pImageData) {//带bmp头的bmp图像。BGR
cv::Mat stMatOfMem(1, nImageLen, CV_8UC1, pImageData);
cv::Mat stDecodedImage = cv::imdecode(stMatOfMem, cv::IMREAD_COLOR);
if (!stDecodedImage.empty()) {
cv::Mat stYUV;
cv::cvtColor(stDecodedImage, stYUV, cv::COLOR_BGR2YUV_I420);
//_WriteFile("1.yuv", "wb+", stYUV.data, 1920 * 1080 * 3 / 2);
ST_DATA* pstData = NULL;
while (!pstData) {
try {
pstData = new ST_DATA;
}
catch (...) {}
}
SingleTon<ManageX264>::GetInstance()->EncoderImg(stYUV, (unsigned char**)&(pstData->buf), pstData->dwTotalLen);
if (pstData->dwTotalLen > 0) {
pThis->m_mutex.lock();
pThis->m_vData.push_back(pstData);
pThis->m_mutex.unlock();
}
else {
if(pstData){
if(pstData->buf){
delete[] pstData->buf;
}
delete pstData;
}
pstData = NULL;
}
}
}
H264录像截图: