A-A+
h.265编码库x265实例
x265是一个开源的H.265编码库。API接口方面与x264很相像。本文介绍其在x86 linux及windows 7的编译方法,并给出实例。
一、编译
1、Linux平台
x265编译需要使用到yasm,到下载,最新版本为1.3.1。编译命令如下:
# ./configure;make;make install
x265库下载:,最新版本为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版本,地址:。在安装过程要记得添加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 中午