x265编码H265

目录

一、前言

二、x265介绍

三、x265主要编码接口介绍

1、int x265_param_default_preset(x265_param *, const char *preset, const char *tune)

2、int x265_param_apply_profile(x265_param *, const char *profile);

3、x265_encoder* x265_encoder_open(x265_param *)

4、void x265_encoder_close(x265_encoder *)

5、int x265_encoder_headers(x265_encoder *, x265_nal **pp_nal, uint32_t *pi_nal)

6、x265_picture *x265_picture_alloc(void);

7、void x265_picture_free(x265_picture *);

8、void x265_picture_init(x265_param *param, x265_picture *pic);

 9、int x265_encoder_encode(x265_encoder *encoder, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out);

四、x265编码yuv的代码示例

1、编码器参数初始化

2、打开编码器

3、关闭编码器

4、编码输入图像缓存申请

5、编码输入图像缓存释放

6、编码一帧YUV

7、编码器关闭

8、编码参数资源释放

9、输入图像资源释放

五、x265编码软件框图


《libx265编码摄像头数据为H265代码实现》链接:

https://edu.csdn.net/learn/38258/606134?spm=1003.2001.3001.4157

一、前言

        随着高清视频的发展,4k、8K分辨率的视频越来越多,但是4k、8k等超大分辨数据也是非常大,所以就需要一个压缩效率更高的视频压缩编码器,于是2013年推出了新一代压缩编码标准H265(HEVC)。x265软件编码器就是一个开源的H265编码器。

二、x265介绍

       和x264类似,x265不仅提供了一个命令行工具进行编码,还提供了一组丰富的接口(API)可以被调用来编码h265视频。x265开源软件下载路径为:https://github.com/videolan/x265.git

三、x265主要编码接口介绍

1、int x265_param_default_preset(x265_param *, const char *preset, const char *tune)

       该函数是对x265编码器配置默认参数,并根据第二第三个参数进行场景化"一键"配置。该函数调用x265_param_default的接口进行默认参数配置的;如下图是x265_param_default函数里面部分参数配置代码。

x265编码H265_第1张图片

x265_param_default_preset函数会根据第二个参数preset配置编码器参数来配置画质和速度的一个取舍。preset的取值如下,medium是默认的一个参数配置;medium之前的是编码速度快、画质会降低的的场景,如ultrafast的编码速度最快,画质可能最差的;medium之后的是编码速度慢、画质会提升的的场景,如veryslow的编码速度是非常慢,画质也会明显的提示。

const x265_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };

x265_param_default_preset函数第三个参数tune是根据不同场景下配置不同的参数,tune的参数如下;zerolatency通常在x265实时场景中使用,表示低延迟的场景配置。

const x265_tune_names[] = { "psnr", "ssim", "grain", "zerolatency", "fastdecode", "animation", 0 };

2、int x265_param_apply_profile(x265_param *, const char *profile);

       该函数用于配置H265编码档次,入参profile支持的档次如下;在H265视频码流结构分析

一文中介绍了H265编码器的档次。 

static const char * const x265_profile_names[] = {
    /* HEVC v1 */
    "main", "main10", "mainstillpicture", /* alias */ "msp",

    /* HEVC v2 (Range Extensions) */
    "main-intra", "main10-intra",
    "main444-8",  "main444-intra", "main444-stillpicture",

    "main422-10", "main422-10-intra",
    "main444-10", "main444-10-intra",

    "main12",     "main12-intra",
    "main422-12", "main422-12-intra",
    "main444-12", "main444-12-intra",

    "main444-16-intra", "main444-16-stillpicture", /* Not Supported! */
    0
};

3、x265_encoder* x265_encoder_open(x265_param *)

     该函数用于打开一个编码器。根据x265_param 参数创建一个h265的编码器并返回编码器的句柄。

4、void x265_encoder_close(x265_encoder *)

      该函数用于关闭编码器。输入参数x265_encoder 是x265_encoder_open函数返回的句柄。

5、int x265_encoder_headers(x265_encoder *, x265_nal **pp_nal, uint32_t *pi_nal)

     在开始编码yuv之前可以通过该函数用于获取该编码器中输出码流的nal单元部信息数据,包含SPS、PPS等信息。

6、x265_picture *x265_picture_alloc(void);

     该函数用于申请一个x265_picture 类型的变量。x265_picture的定义如下,包含了当前图像的pts、数据地址planes[3]、数据地址跨距stride[3]、图像像素位深bitDepth等。

typedef struct x265_picture
{
    /* presentation time stamp: user-specified, returned on output */
    int64_t pts;

    /* display time stamp: ignored on input, copied from reordered pts. Returned
     * on output */
    int64_t dts;

    /* force quantizer for != X265_QP_AUTO */
    /* The value provided on input is returned with the same picture (POC) on
     * output */
    void*   userData;

    /* Must be specified on input pictures, the number of planes is determined
     * by the colorSpace value */
    void*   planes[3];

    /* Stride is the number of bytes between row starts */
    int     stride[3];
    
    int     bitDepth;

    /* Must be specified on input pictures: X265_TYPE_AUTO or other.
     * x265_picture_init() sets this to auto, returned on output */
    int     sliceType;

    /* Ignored on input, set to picture count, returned on output */
    int     poc;

    /* Must be specified on input pictures: X265_CSP_I420 or other. It must
     * match the internal color space of the encoder. x265_picture_init() will
     * initialize this value to the internal color space */
    int     colorSpace;

    /* Force the slice base QP for this picture within the encoder. Set to 0
     * to allow the encoder to determine base QP */
    int     forceqp;

    x265_analysis_data analysisData;

    float            *quantOffsets;

    /* Frame level statistics */
    x265_frame_stats frameData;

    /* User defined SEI */
    x265_sei         userSEI;

    /* Ratecontrol statistics for collecting the ratecontrol information.
     * It is not used for collecting the last pass ratecontrol data in 
     * multi pass ratecontrol mode. */
    void*  rcData;

    uint64_t framesize;

    int    height;

    // pts is reordered in the order of encoding.
    int64_t reorderedPts;

    //Dolby Vision RPU metadata
    x265_dolby_vision_rpu rpu;
 
    int fieldNum;
} x265_picture;

7、void x265_picture_free(x265_picture *);

该函数用于释放x265_picture_alloc申请的变量地址。

8、void x265_picture_init(x265_param *param, x265_picture *pic);

该函数根据编码器参数x265_param 来初始化x265_picture。该函数的定义如下,主要是对x265_picture里面的变量赋值,如位深、图像颜色空间等。

x265编码H265_第2张图片

 9、int x265_encoder_encode(x265_encoder *encoder, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out);

该函数主要是对输入的图像YUV进行编码输出一个编码帧数据,也可以返回编码重建解码的YUV。encoder:编码器句柄。
pp_nal:存放SPS、PPS、ISlices、Psliec等nal单元信息的地址
pi_nal:nal单元头的个数,比如nal只有VPS、SPS、PPS则该值为3,如果还包含了ISlice该值为4.
pic_in:输入yuv帧数据,当该值为空的时候会刷新编码器缓冲区强制输出最后一帧编码数据。通常在编码结束关闭编码器前调用x265_encoder_encode函数并将pic_in设置NULL,来强制输出最后一帧确保编码器缓存为空。
pic_out :通常是编码过程中该帧编码后重建的yuv。

四、x265编码yuv的代码示例

1、编码器参数初始化

      h265_enc_init函数申请编码参数资源并根据编码分辨率帧率设置编码参数,该套参数通常用于低延时场景,追求编码速度快。

static x265_param *h265_enc_init(int width,int height,int fps)
{
    x265_param* pX265Param = x265_param_alloc();
	x265_param_default_preset(pX265Param, "ultrafast", "zerolatency");
    
    pX265Param->sourceWidth  = width;         //* width
	pX265Param->sourceHeight = height;       //* height
	pX265Param->keyframeMax  = 2 * fps;
    
    pX265Param->rc.bitrate = 1024 * 512;  //设置编码码率512kbps
    pX265Param->fpsDenom  = 1;              //编码帧率
	pX265Param->fpsNum    = fps*2;           
    pX265Param->bRepeatHeaders  = 1;       //sps/pps等重复出现在I帧头部
    pX265Param->bAnnexB         = 1;
    pX265Param->internalCsp = X265_CSP_I420;
    x265_param_apply_profile(pX265Param, x265_profile_names[0]); //main

    return pX265Param;
}

2、打开编码器

     根据编码器配置参数调用x265编码器打开编码器返回句柄,

static x265_encoder* h265_enc_open(x265_param *pX265Param)
{
   return x265_encoder_open(pX265Param);
}

3、关闭编码器

     传入编码器句柄来关闭已经打开的编码器。

void h265_enc_close(x265_encoder *encHandle)
{
    x265_encoder_close(encHandle);
}

4、编码输入图像缓存申请

根据输入图像分辨率和图像格式申请输入图像的缓存。

static x265_picture* h265_enc_pic_alloc(x265_param *pH265Param)
{
    x265_picture* pPic = x265_picture_alloc();

    x265_picture_init(pH265Param,pPic); 
    uint8_t * buff = new uint8_t [pH265Param->sourceWidth * pH265Param->sourceHeight * 3 / 2];
    pPic->planes[0] = buff;
    pPic->planes[1] = buff + pH265Param->sourceWidth * pH265Param->sourceHeight;
    pPic->planes[2] = buff + pH265Param->sourceWidth * pH265Param->sourceHeight + pH265Param->sourceWidth * pH265Param->sourceHeight  / 4;
    pPic->stride[0] = pH265Param->sourceWidth;
    pPic->stride[1] = pH265Param->sourceWidth  / 2;
    pPic->stride[2] = pH265Param->sourceWidth  / 2;
    return pPic;
}

5、编码输入图像缓存释放

static void h265_enc_pic_free(x265_picture *pPic)
{
    delete [] pPic->planes[0];
    x265_picture_free(pPic);
}

6、编码一帧YUV

输入YUV图像,编码后返回编码帧nal包的地址和包的个数。

static int h265_encoder(x265_encoder *pX265Handle, x265_picture* pPicIn,x265_nal**pNals,uint64_t *pEncPts)
{
    x265_picture pic_out = {0};
    uint32_t i_nal = 0,numEncoded = 0;
    if(pPicIn) //编码一帧yuv
    {
        numEncoded = x265_encoder_encode(pX265Handle, pNals, &i_nal, pPicIn, &pic_out);
        if(numEncoded < 0)
        {
            std::cout << " x265_encoder_encode error"<< std::endl;
            return -1;
        }
    }
    else //刷新编码缓存-通常是关闭编码器前的操作
    {
        numEncoded = x265_encoder_encode(pX265Handle, pNals, &i_nal, NULL, &pic_out);
        if(numEncoded < 0)
        {
            std::cout << " x265_encoder_encode error"<< std::endl;
            return -1;
        }   
    }

    if (pPicIn && (pic_out.pts != pPicIn->pts))
    {
        std::cout << "pic in pts:"<< pPicIn->pts<< " enc out pts:"<

7、编码器关闭

void h265_enc_close(x265_encoder *encHandle)
{
    x265_encoder_close(encHandle);
}

8、编码参数资源释放

static void h265_enc_deinit(x265_param *pX265Param)
{
   x265_param_free(pX265Param);
}

9、输入图像资源释放

static void h265_enc_pic_free(x265_picture *pPic)
{
    delete [] pPic->planes[0];
    x265_picture_free(pPic);
}

五、x265编码软件框图

x265编码H265_第3张图片

你可能感兴趣的:(rtsp,音视频开发,音视频,视频编解码,实时音视频)