编译:
下载:https://github.com/videolan/x265.git
安装Cmake:
ubuntu: sudo apt-get install cmake
$ cd x265/build/linux
$ ./make-Makefiles.bash
$ make && make install
X265lib:
pro文件添加x265库引用;

encoder.h头文件
\*这是编码头文件,以子线程的方式启动,不阻塞主进程.*\
#ifndef ENCODER_H
#define ENCODER_H
#include <QObject>
#include <QThread>
class encoder : public QThread
{
Q_OBJECT
public:
explicit encoder(QThread *parent = nullptr);
QList<QByteArray> returnyuv(); //截屏返回yuv 4:2:0
void run();
signals:
public slots:
private:
int width;
int height;
};
#endif // ENCODER_H
encode.cpp
#include "encoder.h"
#include <QGuiApplication>
#include <x265.h>
#include <QPixmap>
#include <QScreen>
#include <QDebug>
#include <QUdpSocket>
#include <QFile>
#include <QImage>
#include <QDataStream>
#include <QDateTime>
#include <QFile>
#include <string>
encoder::encoder(QThread *parent) : QThread(parent)
{
width=1280; //截屏后修改图片宽度
height=720; //截屏后修改图片高度
}
QList<QByteArray> encoder::returnyuv(){ //截屏转换YUV 4:2:0
//此处截屏返回YUV代码参考 https://www.jianshu.com/p/0825464edcf4
return yuv_byte;
}
void encoder::run(){
int status;
x265_param *param=x265_param_alloc(); //创建x265参数结构体,并分配了内存.
//预设编码https://x265.readthedocs.io/en/default/presets.html#presets
status=x265_param_default_preset(param,"ultrafast","zerolatency");
if(status!=0){
qDebug()<<"快速,发送!";
x265_param_free(param);
return;
}
param->sourceWidth=width; //视频宽_同yuv的宽度
param->sourceHeight=height; //视频高_同yuv的高度
param->frameNumThreads=1; //并发编码帧数,0为自动检测(默认值),在2到6直接会导致运动搜索(比如6个B帧)
param->numaPools="none" ; //""|"*"所有的numa节点都用于线程池
//"none" 没有创建线程池只能进行帧并行编码。
//numa理解为服务器各CPU自己的内存区域。因此在多CPu编码并行时,因为各个帧要依赖于上一帧,所以可能导致在多个cpu内存来回取数据(个人理解)
param->fpsNum=10; //帧率的分子
param->fpsDenom=1; //帧率的分母
param->interlaceMode=0; //源图片的隔行类型:0:渐进图片(默认)
// 1:顶场优先
// 2:底场优先
param->keyframeMax=10; //I帧的间隔
param->interRefine=1; //启用当前编码中的中间块的优化
// 启用当前编码中的中间块的优化。
// 级别0-从保存编码强制模式和深度。
// 级别1-当当前块大小比min-cu-size大1时,评估当前深度(n)和深度(n + 1)的所有帧间模式。强制使用较大块的模式。
// 级别2-除级别1的功能外,还限制了当保存编码将特定模式确定为最佳模式时评估的模式。
// 保存编码中的2nx2n-禁用对rect和amp的重新评估。
// 跳过保存编码-仅重新评估跳过,合并和2nx2n模式。
// 级别3-在重用保存编码中的深度时执行帧间模式分析。
// 默认值0。
param->internalCsp=X265_CSP_I420; //设置格式为YUV 4:2:0
//rc结构体
param->rc.rateControlMode=X265_RC_CRF; //(默认 CRF)码率控制模式
// X265_RC_ABR, //指定平均码率, x264的一位主要开发者说你应该永远不要使用它,由于编码器无法提前知道要编码视频的情况,它将不得不猜测如何达到比特率。
// X265_RC_CQP, //恒定QP
param->rc.qp=51; //0表示无损 范围0-51,值越大表示越大的量化步长;
// X265_RC_CRF //恒定质量因子,对于运动或细节丰富的场景会增大量化失真,对静止或平坦区域则减少量化失真;
param->rc.rfConstantMax=51; //crf最大码率,0-51 值越大视频质量越低,压缩率越高
param->rc.rfConstantMin=0; //crf最小码率
param->rc.rfConstant=0; //常量码率
param->bRepeatHeaders=true; //是否命令行输出 vps sps pps 头标志
param->bAnnexB=true; //是否生成NUAL起始标志 0000001;
QByteArray data;
x265_encoder *encoder;
encoder=x265_encoder_open(param);
x265_encoder_reconfig(encoder,param);
//x265_encoder_open(param); //创建一个编码器指针
x265_nal *pp_nal; //x265_nal结构体,包含编码后的数据
uint32_t pi_nal; //帧数
x265_picture *picture; //x265图片结构体
int frame=0;
QFile medie_file("./tmp.hevc");
while (true){
//追加方式打开文件
medie_file.open(QIODevice::ReadWrite|QFile::Append);
data.clear();
//开始时间
QDateTime start_jieping=QDateTime::currentDateTime();
//截屏转yuv4:2:0
QList<QByteArray> yuv=returnyuv();
//给x265_picture结构体分配内存空间
picture = x265_picture_alloc();
//根据参数初始化x265_picture
x265_picture_init(param,picture);
//给x265_picture设置y的char *地址
picture->planes[0]=yuv[0].data(); //y
//给x265_picture设置u的char *地址
picture->planes[1]=yuv[1].data();//u
//给x265_picture设置v的char *地址
picture->planes[2]=yuv[2].data(); //v
//给x265_picture设置Y的宽度
picture->stride[0]=param->sourceWidth;
//给x265_picture设置U的宽度,也就是只有Y宽度的一半
picture->stride[1]=param->sourceWidth/2;
//给x265_picture设置V的宽度,也就是只有Y宽度的一半
picture->stride[2]=param->sourceWidth/2;
frame++;
//执行编码
x265_encoder_encode(encoder,&pp_nal,&pi_nal,picture,NULL);
int data_byte_size=0; //存储编码后的数据总长度.
//变量每一帧的长度和就是这张图片编码后的总大小.
for(int i=0;i<pi_nal;i++){
data_byte_size+=pp_nal[i].sizeBytes;
}
//创建数据缓冲
char data_char[data_byte_size];
//复制编码后的所有数据到缓冲区.
memcpy(&data_char, pp_nal[0].payload,data_byte_size);
//char*转<QByteArray>个人习惯.
data=QByteArray(data_char,data_byte_size);
//编码结束时间.
QDateTime end_jieping=QDateTime::currentDateTime();
medie_file.write(data);
medie_file.flush();
medie_file.close();
}
x265_param_free(param);
x265_picture_free(picture);
x265_encoder_close(encoder);
}
网友评论