2021年7月13日 星期二

Build x264 by Using Visual Studio

    x264 is a wirely-use H264 encoder for its profound performance, thus to study how it works is an interesting issue. However, its sourcecode build is bash-shell  + gcc in default. It leads to trace the code is not as simple as in an full integrated IDE. For this case, this post wants to instruct how to build x264 by Visual Studio + Microsoft Visual C. 

I use Visual Studio 2015, and the X264_POINTVER= "0.164.x" (2021/6/13 release). 

零. Build and run x264 in the MinGW system (skippable)

     MinGW could be download from here.

     Download and decompress the x264 tar ball, and we configure x264 as:

$ ./configure  --disable-asm --disable-thread --bit-depth=8 --disable-opencl
    ※For study of x264 purpose, we disable asm, thread opengl, and leave bit-depth works for 8 bit only. It brings x264 workflow simpler.

    After make, we test x264 by below command and use VLC player to verify the output.    
$ x264 --input-res 704x480 --bitrate 200 --output out.h264 plush-704x480.yuv
yuv [info]: 704x480p 0:0 @ 25/1 fps (cfr)
:

※ You could download the test yuv420 file from here.

壹. Build x264 by Visual Studio

  甲. Copy  those files into the same folder.
common folder: 
cabac.c -> common_cabac.c
macroblock.c -> common_macroblock.c
set.c -> common_set.c

encoder folder:
cabac.c -> encoder_cabac.c
macroblock.c -> encoder_macroblock.c
set.c -> encoder_set.c

input folder :
raw.c -> input_raw.c

output folder:
raw.c -> output_raw.c

  乙. Create an empty VS solution & project.
  The project file I assume you place at x264 source folder root,  named x264. we add those source file into the project :
common\base.c
common\bitstream.c
common\common.c
common\common_cabac.c
common\common_macroblock.c
common\common_set.c
common\cpu.c
common\dct.c
common\deblock.c
common\frame.c
common\mc.c
common\mvpred.c
common\osdep.c
common\pixel.c
common\predict.c
common\quant.c
common\rectangle.c
common\tables.c
common\vlc.c

encoder\analyse.c
encoder\api.c
encoder\cavlc.c
encoder\encoder.c
encoder\encoder_cabac.c
encoder\encoder_macroblock.c
encoder\encoder_set.c
encoder\lookahead.c
encoder\me.c
encoder\ratecontrol.c
encoder\slicetype-cl.c

filters\filters.c
filters\video\cache.c
filters\video\crop.c
filters\video\depth.c
filters\video\fix_vfr_pts.c
filters\video\internal.c
filters\video\resize.c
filters\video\select_every.c
filters\video\source.c
filters\video\video.c

input\avs.c
input\input.c
input\input_raw.c
input\timecode.c
input\y4m.c

output\flv.c
output\flv_bytestream.c
output\matroska.c
output\matroska_ebml.c
output\output_raw.c

extras\getopt.c

autocomplete.c
x264.c

If you do not build x264 in MinGW, you need to create a file, config.h in the x264 root, which file content is as below :
#define ARCH_X86 1
#define SYS_WINDOWS 1
#define STACK_ALIGNMENT 64
#define HAVE_LOG2F 1
#define HAVE_AVS 1
#define USE_AVXSYNTH 0
#define HAVE_VECTOREXT 1
#define fseek fseeko64
#define ftell ftello64
#define HAVE_BITDEPTH8 1
#define HAVE_GPL 1
#define HAVE_INTERLACED 1
#define HAVE_MALLOC_H 0
#define HAVE_ALTIVEC 0
#define HAVE_ALTIVEC_H 0
#define HAVE_MMX 0
#define HAVE_ARMV6 0
#define HAVE_ARMV6T2 0
#define HAVE_NEON 0
#define HAVE_AARCH64 0
#define HAVE_BEOSTHREAD 0
#define HAVE_POSIXTHREAD 0
#define HAVE_WIN32THREAD 0
#define HAVE_THREAD 0
#define HAVE_SWSCALE 0
#define HAVE_LAVF 0
#define HAVE_FFMS 0
#define HAVE_GPAC 0
#define HAVE_CPU_COUNT 0
#define HAVE_OPENCL 0
#define HAVE_THP 0
#define HAVE_LSMASH 0
#define HAVE_X86_INLINE_ASM 0
#define HAVE_AS_FUNC 0
#define HAVE_INTEL_DISPATCHER 0
#define HAVE_MSA 0
#define HAVE_MMAP 0
#define HAVE_WINRT 0
#define HAVE_VSX 0
#define HAVE_ARM_INLINE_ASM 0
#define HAVE_STRTOK_R 0
#define HAVE_CLOCK_GETTIME 0
#define HAVE_BITDEPTH10 0

  丙. Change the setting of  the VS project :
Main menu ->project -> x264 properies -> C/C++ -> General -> Add include directorie :
.
common
encoder
input
output
filters
filters/video
extras

Main menu ->project -> x264 properies -> C/C++ -> Preprocessor-> Preprocessor Definitions:
HAVE_STRING_H=1
HIGH_BIT_DEPTH=0
BIT_DEPTH=8
fseeko64=_fseeki64
ftello64=_ftelli64

Main menu ->project -> x264 properies -> C/C++ -> Advanced-> Disable Specific Warnings :
4996

  丁. Modify those code to pass the compilation:
common\osdep.h, aboult line 340, avoid MS VC defines REALIGN_STACK:
#define ALIGNED_ARRAY_32 ALIGNED_ARRAY_16
#define ALIGNED_ARRAY_64 ALIGNED_ARRAY_16
#endif

#if (STACK_ALIGNMENT > 16 || (ARCH_X86 && STACK_ALIGNMENT > 4) ) && defined(__GNUC__)
#define REALIGN_STACK __attribute__((force_align_arg_pointer))
#else
#define REALIGN_STACK
#endif

encoder\api.c, about line 97, comment out the "if else" :
        api->x264 = x264_8_encoder_open( param, api );
    }
#if(0)
    else if( HAVE_BITDEPTH10 && param->i_bitdepth == 10 )
    {
        api->nal_encode = x264_10_nal_encode;
        api->encoder_reconfig = x264_10_encoder_reconfig;
        api->encoder_parameters = x264_10_encoder_parameters;
        api->encoder_headers = x264_10_encoder_headers;
        api->encoder_encode = x264_10_encoder_encode;
        api->encoder_close = x264_10_encoder_close;
        api->encoder_delayed_frames = x264_10_encoder_delayed_frames;
        api->encoder_maximum_delayed_frames = x264_10_encoder_maximum_delayed_frames;
        api->encoder_intra_refresh = x264_10_encoder_intra_refresh;
        api->encoder_invalidate_reference = x264_10_encoder_invalidate_reference;

        api->x264 = x264_10_encoder_open( param, api );

    }
#endif
    else
        x264_log_internal( X264_LOG_ERROR, "not compiled with %d bit depth support\n", param->i_bitdepth );

To here, the VS is able to build x264.

參. Run x264 on Visual Studio :
Add the command line arguments, it is in 
Main menu ->project -> x264 properies ->Debugging->Command Arguments :
--input-res 704x480   --output out.h264 plush-704x480.yuv --bitrate 200

The arguments are indentical with what we run in MinGW command line.


Now press the VS "play" button, everything should be fine. If you are in the debug mode, do not be surprised at the encoding is very slow:




沒有留言:

張貼留言