x265是一个开源的H.265编码库。API接口方面与x264很相像。本文介绍其在x86 linux及windows 7的编译方法,并给出实例。

一、编译

1、Linux平台

x265编译需要使用到yasm,到http://www.tortall.net/projects/yasm/releases/下载,最新版本为1.3.1。编译命令如下:

# ./configure;make;make install

x265库下载:https://bitbucket.org/multicoreware/x265/downloads,最新版本为1.7。

解压后,进入源码目录的build目录,选择linux。

# cd x265_1.7/build/linux
# ./make-Makefiles.bash

配置如下:
BIN_INSTALL_DIR                  /home/latelee/bin/x265-1.7                                  
CHECKED_BUILD                    OFF                                                         
CMAKE_BUILD_TYPE                 Release                                                     
CMAKE_INSTALL_PREFIX             /home/latelee/bin/x265-1.7                                  
DETAILED_CU_STATS                OFF                                                         
ENABLE_AGGRESSIVE_CHECKS         OFF                                                         
ENABLE_ASSEMBLY                  ON                                                          
ENABLE_CLI                       ON                                                          
ENABLE_PIC                       OFF                                                         
ENABLE_PPA                       OFF                                                         
ENABLE_SHARED                    OFF  # 不要动态库                                                        
ENABLE_TESTS                     OFF                                                         
ENABLE_VTUNE                     OFF                                                         

ENABLE_SHARED: Build shared library                                                            
Press [enter] to edit option                                                  CMake Version 3.3.1
Press [c] to configure
Press [h] for help           Press [q] to quit without generating
Press [t] to toggle advanced mode (Currently Off)

按c配置,再按g保存并退出。


2、Windows平台

0、安装cmake的windows版本,地址:http://www.cmake.org/download/。在安装过程要记得添加cmake到PATH。
1、进入build目录,根据编译器版本选择不同的工程目录,比如64bit的VS2010,就进入vc10-x86_64目录。双击:build-all.bat。
2、之后出现配置界面时,点击configure,再点击generate,然后关闭窗口。其它不同做。
3、等待cmd窗口编译完成,完成后会自动关闭。
4、在Debug或Release目录找到h265编码器x265.exe,另外还有dll和lib文件。头文件要到源码中找。

注:编译Windows平台,纯粹是为了得到x265,exe文件。

二、实例

下面给出使用的示例。

/**
x265库编码要使用以下库
-lpthread -ldl

ffprobe信息:
Input #0, hevc, from 'test.h265':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: hevc (Main), yuv420p(tv), 176x144, 25 fps, 25 tbr, 1200k
 tbn, 25 tbc
*/

#include <stdio.h>
#include <stdlib.h>

#include "x265.h"

int x265_encode(const char* infile, int width, int height, int type, const char* outfile)
{
	FILE *fp_src = NULL;
	FILE *fp_dst = NULL;
    unsigned int luma_size = 0;
    unsigned int chroma_size = 0;
	//int buff_size = 0;
	char *buff = NULL;
	uint32_t i_nal=0;
    int i_frame=0;
    int ret = 0;

    x265_param param;
    x265_nal *nal = NULL;
	x265_encoder *handle = NULL;
	x265_picture *pic_in = NULL;

    int csp = type; // X265_CSP_I420;

	fp_src = fopen(infile, "rb");
	fp_dst = fopen(outfile, "wb");
	if(fp_src==NULL || fp_dst==NULL)
    {
        perror("Error open yuv files:");
		return -1;
	}

	x265_param_default(¶m);
	param.bRepeatHeaders = 1;//write sps,pps before keyframe
	param.internalCsp = csp;
	param.sourceWidth = width;
	param.sourceHeight = height;
	param.fpsNum = 25; // 帧率
	param.fpsDenom = 1; // 帧率

	handle = x265_encoder_open(¶m);
	if(handle == NULL)
    {
		printf("x265_encoder_open err\n");
		goto out;
	}

	pic_in = x265_picture_alloc();
    if (pic_in == NULL)
    {
        goto out;
    }
	x265_picture_init(¶m, pic_in);

    // Y分量大小
	luma_size = param.sourceWidth * param.sourceHeight;
    // 分量一帧YUV的空间
	switch (csp)
    {
    case X265_CSP_I444:
        buff = (char *)malloc(luma_size*3);
        pic_in->planes[0] = buff;
        pic_in->planes[1] = buff + luma_size;
        pic_in->planes[2] = buff + luma_size*2;
        pic_in->stride[0] = width;
        pic_in->stride[1] = width;
        pic_in->stride[2] = width;
        break;
    case X265_CSP_I420:
        buff = (char *)malloc(luma_size*3/2);
        pic_in->planes[0] = buff;
        pic_in->planes[1] = buff + luma_size;
        pic_in->planes[2] = buff + luma_size*5/4;
        pic_in->stride[0] = width;
        pic_in->stride[1] = width/2;
        pic_in->stride[2] = width/2;
        break;
    default:
        printf("Colorspace Not Support.\n");
        goto out;
	}

    // 计算总帧数
    fseek(fp_src, 0, SEEK_END);
    switch(csp)
    {
    case X265_CSP_I444:
        i_frame = ftell(fp_src) / (luma_size*3);
        chroma_size = luma_size;
        break;
    case X265_CSP_I420:
        i_frame = ftell(fp_src) / (luma_size*3/2);
        chroma_size = luma_size / 4;
        break;
    default:
        printf("Colorspace Not Support.\n");
        return -1;
    }
    fseek(fp_src,0,SEEK_SET);
    printf("framecnt: %d, y: %d u: %d\n", i_frame, luma_size, chroma_size);

	for(int i=0; i < i_frame; i++)
    {
		switch(csp)
        {
		case X265_CSP_I444:
        case X265_CSP_I420:
			 if (fread(pic_in->planes[0], 1, luma_size, fp_src) != luma_size)
                break;
			if (fread(pic_in->planes[1], 1, chroma_size, fp_src) != chroma_size)
                break;
			if (fread(pic_in->planes[2], 1, chroma_size, fp_src) != chroma_size)
                break;
			break;
		default:
			printf("Colorspace Not Support.\n");
			goto out;
		}

		ret = x265_encoder_encode(handle, &nal, &i_nal, pic_in, NULL);	
		printf("encode frame: %5d framesize: %d nal: %d\n", i+1, ret, i_nal);
        if (ret < 0)
        {
            printf("Error encode frame: %d.\n", i+1);
            goto out;
        }

		for(uint32_t j = 0; j < i_nal; j++)
        {
			fwrite(nal[j].payload, 1, nal[j].sizeBytes, fp_dst);
		}
	}
	// Flush Decoder
	while((ret = x265_encoder_encode(handle, &nal, &i_nal, NULL, NULL)))
    {
        static int cnt = 1;
		printf("flush frame: %d\n", cnt++);
		for(uint32_t j=0; j < i_nal; j++)
        {
			fwrite(nal[j].payload, 1, nal[j].sizeBytes, fp_dst);
		}
	}

out:
	x265_encoder_close(handle);
	x265_picture_free(pic_in);
    if (buff)
        free(buff);

	fclose(fp_src);
	fclose(fp_dst);
	
	return 0;
}

使用方法:

x265_encode("../src/suzie_qcif_176x144_yuv420p.yuv", 176, 144, 1, "test.h265");

Makefile见上一文章所述。

李迟 2015.9.14 中午



Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐