Qt截屏 X265lib编码 rtsp请求 rtp流发送 (x265视频编码)实现

编译:

下载: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库引用;


2020-01-12 11-32-56屏幕截图.png

encoder.h头文件

\*这是编码头文件,以子线程的方式启动,不阻塞主进程.*\
#ifndef ENCODER_H
#define ENCODER_H
#include 
#include 
class encoder : public QThread
{
    Q_OBJECT
public:
    explicit encoder(QThread *parent = nullptr);
    QList returnyuv(); //截屏返回yuv 4:2:0
    void run();
signals:
public slots:
private:
    int width;
    int height;
};

#endif // ENCODER_H

encode.cpp

#include "encoder.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
encoder::encoder(QThread *parent) : QThread(parent)
{
    width=1280; //截屏后修改图片宽度
    height=720; //截屏后修改图片高度
}
QList 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 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个人习惯.
     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);
}

你可能感兴趣的:(Qt截屏 X265lib编码 rtsp请求 rtp流发送 (x265视频编码)实现)