天天看点

x264编译和使用(windows + vs2017)第一种:MSYS2+MinGW64第二种:Github上编译好的x264工程vs2017使用编译好的x264

x264编译和使用(介绍两种方法)

  • 第一种:MSYS2+MinGW64
  • 第二种:Github上编译好的x264工程
  • vs2017使用编译好的x264

第一种:MSYS2+MinGW64

  1. 安装msys2和mingw64

    官网:https://www.msys2.org/

    官方首页就有操作步骤,直接下载最新的exe双击安装,这一步很简单!

x264编译和使用(windows + vs2017)第一种:MSYS2+MinGW64第二种:Github上编译好的x264工程vs2017使用编译好的x264
x264编译和使用(windows + vs2017)第一种:MSYS2+MinGW64第二种:Github上编译好的x264工程vs2017使用编译好的x264

切记: 安装完后,打开安装目录下msys2_shell.cmd文件,将注释掉的 rem set MSYS2_PATH_TYPE=inherit 改成 set MSYS2_PATH_TYPE=inherit ,这么改是为了将vs的环境继承给MSYS2,在mingw64 shell中编译x264时就可以直接使用vs的工具了。

  1. 清华源替换默认源

    由于默认的源下载很慢所以为了更愉快的体验最好替换国内的源,此处使用清华源。

    在shell输入:

sed -i "s#mirror.msys2.org/#mirrors.tuna.tsinghua.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*
           

换完源使用命令更新

  1. 安装需要的包

    因为选择使用mingw64编译,关闭上面的shell,在开始目录或msys的安装目录,打开msys2 mingw64,在shell窗口输入:

pacman -S mingw-w64-x86_64-toolchain
           
x264编译和使用(windows + vs2017)第一种:MSYS2+MinGW64第二种:Github上编译好的x264工程vs2017使用编译好的x264

安装好之后,就可以关闭shell窗口

  1. VS关联打开mingw64

    开始菜单vs2017目录下,选择适用于 VS 2017 的 x64 本机工具命令提示打开,在shell窗口中输入:

cd c:\msys64
msys2_shell.cmd -mingw64   #打开msys2的mingw64窗口
           

检查编译环境工具

which cl link yasm cpp
           
x264编译和使用(windows + vs2017)第一种:MSYS2+MinGW64第二种:Github上编译好的x264工程vs2017使用编译好的x264

能看到安装路径,说明关联了vs,是可以直接使用的(没有显示安装路径,则说明没关联上,因为mingw64本身没有lib.exe)

  1. 编译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;
}
           

在分析工具中展示编好的视频:

x264编译和使用(windows + vs2017)第一种:MSYS2+MinGW64第二种:Github上编译好的x264工程vs2017使用编译好的x264