164 lines
3.0 KiB
C++
164 lines
3.0 KiB
C++
#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; //²»ÆôÓÃ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;
|
|
}
|
|
|
|
//ÉèÖÃ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;
|
|
}
|