VS2010编译x264(20091006)

2011年12月29日 分类:学习笔记C++x264

H264可以说是现在视频发展的趋势,越来越多的视频舍弃了rmvb投入了H264的怀抱。
我自己压的视频都是用H264编码的,因此想学习H264的编码,当然这里面也有专业的原因。
要想学习H264,第一部就是编译x264。

如果你仅仅需要使用x264的话你可以到这下载:http://x264.nl/
x264的源码下载地址:http://www.videolan.org/developers/x264.html
历史版本下载地址:ftp://ftp.videolan.org/pub/videolan/x264/snapshots/
由于最新版的源码已经没有了vs工程,这篇文章编译的源码是最后一版带有vs工程的x264-snapshot-20091006-2245版本。
这里我们还需要yasm(汇编器):http://yasm.tortall.net/Download.html
解压放到build\win32里,把vsyasm.exe改为yasm.exe

准备完成,双击x264.sln,vs2010会提示转换工程,下一步,完成。
首先编译libx264,右击设为启动项。 x264 开始编译,按F7,失败,提示:

>1>G:\x264-snapshot-20091006-2245\common/common.h(170): error C2143: 语法错误 : 缺少“;”(在“类型”的前面)  
1>G:\x264-snapshot-20091006-2245\common/common.h(171): error C2065: “i”: 未声明的标识符  
1>G:\x264-snapshot-20091006-2245\common/common.h(171): error C2065: “i”: 未声明的标识符

后面还有很多类似的错误,都是因为MS的VS编译器对C99标准支持不好,不支持函数当中混合定义、声明变量。
解决办法:在函数开头统一定义变量。
比如上面第一个错误,原文是:

static ALWAYS_INLINE int x264_exp2fix8( float x )
{
    if( x >= 512.f/6.f ) return 0;
    if( x >6) >> 8;
}

把i的定义放到函数体开头:

static ALWAYS_INLINE int x264_exp2fix8( float x )
{
    int i;
    if( x >= 512.f/6.f ) return 0;
    if( x >6) >> 8;
}

错误消失,后面类似的错误都要用这种方法解决。(而且大部分都是这种错误,真麻烦啊!)
再次编译,warning就不用管了。再次出现错误,提示为: >1>....\encoder\analyse.c(2950): error C2059: 语法错误:“[”

双击提示找到错误位置。

static const uint8_t check_mv_lists[X264_MBTYPE_MAX] = {[P_L0]=1, [B_L0_L0]=1, [B_L1_L1]=2};

改为:

static const uint8_t check_mv_lists[X264_MBTYPE_MAX] ={0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,0,0,0};

编译,提示: >2>....\muxers.c(299): error C2146: 语法错误: 缺少“)”(在标识符“PRIx32”的前面)

fprintf( stderr, "Bad header magic (%"PRIx32"  %s)\n", *((uint32_t*)header), header );

改为:

fprintf( stderr, "Bad header magic (%ld %s)\n", *((uint32_t*)header), header );

继续编译,提示:

>2>libx264.lib(encoder.obj) : error LNK2019: 无法解析的外部符号 _x264_lookahead_init,该符号在函数 _x264_encoder_open_76 中被引用  
2>libx264.lib(encoder.obj) : error LNK2019: 无法解析的外部符号 _x264_lookahead_is_empty,该符号在函数 _x264_encoder_encode 中被引用  
2>libx264.lib(encoder.obj) : error LNK2019: 无法解析的外部符号 _x264_lookahead_get_frames,该符号在函数 _x264_encoder_encode 中被引用  
2>libx264.lib(encoder.obj) : error LNK2019: 无法解析的外部符号 _x264_lookahead_put_frame,该符号在函数 _x264_encoder_encode 中被引用  
2>libx264.lib(encoder.obj) : error LNK2019: 无法解析的外部符号 _x264_lookahead_delete,该符号在函数 _x264_encoder_close 中被引用  
2>libx264.lib(analyse.obj) : error LNK2019: 无法解析的外部符号 _log2f,该符号在函数 _x264_analyse_init_costs 中被引用

这是由于libx264工程没有添加lookahead.c文件,从而缺少几个函数的定义造成的,添加lookahead.c进工程。 x264 再次编译,修改lookahead.c中的几个错误,成功1个,失败1个,提示: >2>libx264.lib(analyse.obj) : error LNK2019: 无法解析的外部符号 _log2f,该符号在函数 _x264_analyse_init_costs 中被引用

这个只要定义一下log2f(x)就可以了。
在osdep.h中添加log2f(x)定义。

#ifdef _MSC_VER
#define inline __inline
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define snprintf _snprintf
#define fseek _fseeki64
#define ftell _ftelli64
#define isfinite _finite
#define strtok_r strtok_s
#define _CRT_SECURE_NO_DEPRECATE
#define X264_VERSION "" // no configure script for msvc
#define log2f(x) (logf(x)*1.4426950408889634f)
#endif

编译,成功2个。
在bin文件夹下成功生成libx264.lib和x264.exe两个文件,大功告成。
推荐博文:http://jmvc.blog.sohu.com/145356341.html(里面有一些函数的注解很不错)

下面的是我修改好的源文件:

http://115.com/file/c2bujtuh#
x264-snapshot-20091006-2245.rar

作者:wuyuan 本文来自Wuyuan's Blog 转载请注明,谢谢! 文章地址: https://wuyuans.com/2011/12/vs2010-complies-x264-20091006