x264编译和使用(介绍两种方法)
- 第一种:MSYS2+MinGW64
- 第二种:Github上编译好的x264工程
- vs2017使用编译好的x264
第一种:MSYS2+MinGW64
-
安装msys2和mingw64
官网:https://www.msys2.org/
官方首页就有操作步骤,直接下载最新的exe双击安装,这一步很简单!
切记: 安装完后,打开安装目录下msys2_shell.cmd文件,将注释掉的 rem set MSYS2_PATH_TYPE=inherit 改成 set MSYS2_PATH_TYPE=inherit ,这么改是为了将vs的环境继承给MSYS2,在mingw64 shell中编译x264时就可以直接使用vs的工具了。
-
清华源替换默认源
由于默认的源下载很慢所以为了更愉快的体验最好替换国内的源,此处使用清华源。
在shell输入:
sed -i "s#mirror.msys2.org/#mirrors.tuna.tsinghua.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*
换完源使用命令更新
-
安装需要的包
因为选择使用mingw64编译,关闭上面的shell,在开始目录或msys的安装目录,打开msys2 mingw64,在shell窗口输入:
pacman -S mingw-w64-x86_64-toolchain
安装好之后,就可以关闭shell窗口
-
VS关联打开mingw64
开始菜单vs2017目录下,选择适用于 VS 2017 的 x64 本机工具命令提示打开,在shell窗口中输入:
cd c:\msys64
msys2_shell.cmd -mingw64 #打开msys2的mingw64窗口
检查编译环境工具
which cl link yasm cpp
能看到安装路径,说明关联了vs,是可以直接使用的(没有显示安装路径,则说明没关联上,因为mingw64本身没有lib.exe)
- 编译x264
git clone http://git.videolan.org/git/x264.git
./configure --prefix=../build --host=x86_64-w64-mingw32 --enable-shared --extra-ldflags=-Wl,--output-def=libx264.def
make
make install
上面编译出来的结果没有包含lib文件,需要自己手工生成。
configure时我们生成了libx264.def此时就派上用场。
cp ./libx264.def ../build/lib/
cd ../build/lib
#若要生成64位lib文件则输入如下命令:
lib /machine:X64 /def:libx264.def
这时,我们就编译生成了x264相应的exe、lib、dll文件
第二种:Github上编译好的x264工程
github地址:https://github.com/ShiftMediaProject/x264
这种方式我没有尝试,之后有时间看看。强烈建议大家还是自己亲自动手编译,加深理解
vs2017使用编译好的x264
新建一个vs工程,就可以使用x264了,这里我把代码贴一下把
需要注意的是把编译好的文件要拷贝到你的新工程下的相应位置
#include <iostream>
#include <string>
#include "stdint.h"
#pragma warning(disable : 4996)
#pragma comment(lib, "libx264.lib")
extern "C"
{
#include "../../build/include/x264.h"
#include "../../build/include/x264_config.h"
};
using namespace std;
int main(int argc, char** argv)
{
int ret;
int y_size;
int i, j;
FILE* fp_src = fopen("BasketballPass_416x240_50.yuv", "rb");
FILE* fp_dst = fopen("x.h264", "wb");
//Encode 50 frame
//if set 0, encode all frame
int frame_num = 50;
int csp = X264_CSP_I420;
int width = 416, height = 240;
int iNal = 0;
x264_nal_t* pNals = NULL;
x264_t* pHandle = NULL;
x264_picture_t* pPic_in = (x264_picture_t*)malloc(sizeof(x264_picture_t));
x264_picture_t* pPic_out = (x264_picture_t*)malloc(sizeof(x264_picture_t));
x264_param_t* pParam = (x264_param_t*)malloc(sizeof(x264_param_t));
//Check
if (fp_src == NULL || fp_dst == NULL) {
printf("Error open files.\n");
return -1;
}
x264_param_default(pParam);
pParam->i_width = width;
pParam->i_height = height;
//Param
pParam->i_log_level = X264_LOG_DEBUG;
pParam->i_threads = X264_SYNC_LOOKAHEAD_AUTO;
pParam->i_frame_total = 0;
pParam->i_keyint_max = 10;
pParam->i_bframe = 5;
pParam->b_open_gop = 0;
pParam->i_bframe_pyramid = 0;
pParam->rc.i_qp_constant=0;
pParam->rc.i_qp_max=0;
pParam->rc.i_qp_min=0;
pParam->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
pParam->i_fps_den = 1;
pParam->i_fps_num = 25;
pParam->i_timebase_den = pParam->i_fps_num;
pParam->i_timebase_num = pParam->i_fps_den;
pParam->i_csp = csp;
x264_param_apply_profile(pParam, x264_profile_names[5]);
pHandle = x264_encoder_open(pParam);
x264_picture_init(pPic_out);
x264_picture_alloc(pPic_in, csp, pParam->i_width, pParam->i_height);
//ret = x264_encoder_headers(pHandle, &pNals, &iNal);
y_size = pParam->i_width * pParam->i_height;
//detect frame number
if (frame_num == 0) {
fseek(fp_src, 0, SEEK_END);
switch (csp) {
case X264_CSP_I444:frame_num = ftell(fp_src) / (y_size * 3); break;
case X264_CSP_I420:frame_num = ftell(fp_src) / (y_size * 3 / 2); break;
default:printf("Colorspace Not Support.\n"); return -1;
}
fseek(fp_src, 0, SEEK_SET);
}
//Loop to Encode
for (i = 0; i < frame_num; i++) {
switch (csp) {
case X264_CSP_I444: {
fread(pPic_in->img.plane[0], y_size, 1, fp_src); //Y
fread(pPic_in->img.plane[1], y_size, 1, fp_src); //U
fread(pPic_in->img.plane[2], y_size, 1, fp_src); //V
break; }
case X264_CSP_I420: {
fread(pPic_in->img.plane[0], y_size, 1, fp_src); //Y
fread(pPic_in->img.plane[1], y_size / 4, 1, fp_src); //U
fread(pPic_in->img.plane[2], y_size / 4, 1, fp_src); //V
break; }
default: {
printf("Colorspace Not Support.\n");
return -1; }
}
pPic_in->i_pts = i;
ret = x264_encoder_encode(pHandle, &pNals, &iNal, pPic_in, pPic_out);
if (ret < 0) {
printf("Error.\n");
return -1;
}
printf("Succeed encode frame: %5d\n", i);
for (j = 0; j < iNal; ++j) {
fwrite(pNals[j].p_payload, 1, pNals[j].i_payload, fp_dst);
}
}
i = 0;
//flush encoder
while (1) {
ret = x264_encoder_encode(pHandle, &pNals, &iNal, NULL, pPic_out);
if (ret == 0) {
break;
}
printf("Flush 1 frame.\n");
for (j = 0; j < iNal; ++j) {
fwrite(pNals[j].p_payload, 1, pNals[j].i_payload, fp_dst);
}
i++;
}
x264_picture_clean(pPic_in);
x264_encoder_close(pHandle);
pHandle = NULL;
free(pPic_in);
free(pPic_out);
free(pParam);
fclose(fp_src);
fclose(fp_dst);
return 0;
}
在分析工具中展示编好的视频: