Thursday 13 March 2014

Building x264 on Windows with Visual Studio

For anyone who has ever done any video encoding (or just watching for that matter) will probably have heard of x264. And if you havnt then you should have at least have heard of h264 (and if you still havnt then this post is probably not for you) which is the standard name for the video codec that the x264 encoder implements. So in the world of h264 video encoding x264 is probably one of, if not the best. And it is completely free and open source. So anyone who wants to get their hands on it can do so easily.

One downside of the x264 project (much like most open source projects) is that the default build tool is a gnu make style build chain. These don't run natively on Windows and generally requires an emulated shell such as MSYS or Cygwin. And even from within these shells they only support gcc (MinGW on Windows) based compilers.

But for those wanting to compile x264 natively on Windows using the native Windows build chain (i.e. Visual Studio) then that can actually be done rather simply. For those with Visual Studio 2013 then compiling many similar open source projects becomes a lot easier due to the addition of partial C99 support. C99 is something Microsoft have been neglecting for many years but with the 2013 updates it is a lot closer. x264 however still requires some manipulation in order to get it compile under MSVC's mostly C89 world.
Luckily changing x264 for be MSVC compatiblilty is rather straightforward. Most of the issues are a result of C89 requiring all variable declarations to be altogether and the start of each logical block of code. Straight of the bat most of the errors that Visual Studio will spit out about the x264 code will be a result of this issue (although the error codes don't do you any favours in realising this). So most errors will be due to code such as the following:

int padv = PADV >> v_shift;
// buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
if( b_end && !b_start )
    height += 4 >> (v_shift + SLICE_MBAFF);
pixel *pix;
int starty = 16*mb_y - 4*!b_start;

This will generate an error on the variable 'pix' because it is declared mid way through a block of code. Luckily the specifications say 'block' of code, which does not mean function or something similar. Instead it essential means anything between a set of '{' or '}'s (There iss actually a bit more to it than that but for our purposes - as you'll see later - it is good enough). In the above example we can see that the declaration of 'pix' occurs after an if statement. So if all we need to separate blocks are some '{}'s then modifying the code to the following will actually work:

int padv = PADV >> v_shift;
// buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
if( b_end && !b_start )
{
    height += 4 >> (v_shift + SLICE_MBAFF);
}
pixel *pix;
int starty = 16*mb_y - 4*!b_start;

All we did here was add the '{' and the '}' to the if statement. This makes that statement a block and so the line following it becomes a new block which makes everything work. This is surprisingly simple fix and will work for all of the cases found in libx264. In fact a complete working libx264 can be achieved by just performing the above operation at 10 different location in code. Or if you couldn't be bothered doing it yourself you can just apply the following patch that I have already made up for you.

Download patch file:
https://github.com/ShiftMediaProject/x264/commit/d9004ba604283fb70a3b67d444f67576c00a0e2e.diff

Now for those who don't just want the lib for x264 but actually want to compile the command line x264.exe then you'll have to perform the same operation a few more times. However there are 2 additional things youll need to do.
First is related to an issue with the use of unions. Specifically the following piece of code:

return (union {double f; uint64_t i;}){value}.i;

The above is too much for MSVC to handle. But with a bit of massaging it can be made to work. Massaging such as this:

union { double f; uint64_t i; } ulld = { value };
return ulld.i

The second issue is due to initialization lists being used on an array of structs. MSVC defaults to thinking that each element in the initializer list is actually an input for each component for the actual struct. So in the following piece of code MSVC treats the initializer list as actually an initializer list for the first 'AVS_Value' in the array.

AVS_Value arg_arr[] = { res, avs_new_value_bool( info->interlaced ), avs_new_value_string( matrix ) };

This will cause some nonsensical errors such as how a type of AVS_Value can not be converted to type short (short here being the type of the first member of AVS_Value). There is pretty much no combination of additional '('s and '{' that will fix this problem. So we have to fallback to the slightly less convenient way of just specifying each array element individually.

AVS_Value arg_arr[3];
arg_arr[0] = res;
arg_arr[1] = avs_new_value_bool( info->interlaced );
arg_arr[2] = avs_new_value_string( matrix );

This is not as nice to look at but it works. Putting all these pieces together and x264cli will compile under Visual Studio without any further problems. Again for those who dont want to do all this themselves then the appropriate patch can be acquired from below.

Download patch file:
https://github.com/ShiftMediaProject/x264/commit/4c51a4fc51737d932eddb4060bcd03d861dfec7d.diff

Of course if you don't want to worry about any of the above then you can check out my git repository that has all the necessary changes already applied and even comes with a pre-built Visual Studio project file. My repo is up to date with the current upstream master and with x264 development slowing down due to the upcoming x265 then its unlikely my repo will fall behind the upstream master so can be treated as up to date.

git repository:
https://github.com/ShiftMediaProject/x264

So with all of those above fixes it should be reasonable trivial to get x264 building natively in Windows. As to whether this is worth it is a debate for another time. For those who aren't familiar with MSYS/Cygwin but are familiar with Visual Studio then this should be a big win. What will be interesting is to test the performance of the compiled binaries between the different compilers. Perhaps ill have more on that soon.....

62 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. It is really helpful. Thanks a lot.

    I don't quite understand the part of changing vsyasm.props.

    Below is the changed line of my vsyasm.props. Is it correct?
    "$(YasmPath)"vsyasm.exe -Xvc -f $(Platform) [AllOptions] [AdditionalOptions] "%(FullPath)"

    I compiled with VC++ 2013 update 2. There were only two parts in avs.c need to be modified according to your AVS_Value comments. The update 2 might be improved in some areas.

    I successfully built x264.sln with some kinds of warnings.
    1. cl : Command line warning D9030: '/Gm' is incompatible with multiprocessing; ignoring /MP switch
    2. You must include stdint.h or inttypes.h before x264.h
    3. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(1193,5): warning MSB8012: TargetPath(C:\Code\x264\SMC\..\..\..\msvc32\x264clid.exe) does not match the Linker's OutputFile property value (C:\msvc32\bin\x264clid.exe). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile).

    It is great. I will try it with my application.

    ReplyDelete
    Replies
    1. Yep, that is exactly the correct vsyasm.props (which you probably worked out by the fact that it compiles fine). The reason the change is needed is with multi-processor compilation VS will just pass every asm file to yasm in 1 call which yasm does not support.

      And yes the newer versions of msvc are getting better at supporting the standards. Hopefully many of the fixes listed above wont be needed in future version at all!

      And as for those warnings they can all be completely ignored as they are entirely harmless.

      Also... thanks ;)

      Delete
  3. Hi,

    I followed your instructions but got the following error:

    error MSB8020: The build tools for Intel C++ Compiler XE 14.0 (Platform Toolset = 'Intel C++ Compiler XE 14.0') cannot be found. To build using the Intel C++ Compiler XE 14.0 build tools, please install Intel C++ Compiler XE 14.0 build tools. Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Upgrade Solution...". C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Cpp.Platform.targets

    Thanks for your assistance. Having a VS debug build could help me debug the crashes and other problems I'm currently experiencing. It's also possible that the build won't crash at all, as I intend to use windows threads as someone recommended on the Doom10 forums.

    Thanks!

    ReplyDelete
    Replies
    1. Thats a simple problem to fix. Recently the default project from the repo was updated to use the Intel compiler to test compatibility. Thats has since been reverted. So a repository update should fix the problem.
      Alternatively you can update your copy of the project by going into the project properties then setting Configuration Properties->General->Platform Toolset to "Visual Studio 2013".
      Hope thats of some help.

      Delete
    2. I can't believe I didn't see that. D'oh! Well ok, it was late and my dinner was disagreeing with me :-)

      Delete
    3. Sorry to bother you again, but now I'm getting this:

      cmd.exe /C "C:\Users\gygax\AppData\Local\Temp\tmpc5418d08dfd24f8e91c658d0bc572f72.cmd"
      "D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\"vsyasm.exe -Xvc -f Win32 -i "D:\Libraries\x264\SMC\\..\common\x86" -d "PREFIX" -d "STACK_ALIGNMENT=4" -d "HIGH_BIT_DEPTH=0" -d "BIT_DEPTH=8" -d "WIN32=1" -d "ARCH_X86_64=0" -o "D:\Libraries\x264\SMC\\obj\DebugDLL\Win32\x264\\" -rnasm -pnasm "D:\Libraries\x264\common\x86\bitstream-a.asm"
      1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations\vsyasm.targets(45,5): error MSB3721: The command ""D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\"vsyasm.exe -Xvc -f Win32 -i "D:\Libraries\x264\SMC\\..\common\x86" -d "PREFIX" -d "STACK_ALIGNMENT=4" -d "HIGH_BIT_DEPTH=0" -d "BIT_DEPTH=8" -d "WIN32=1" -d "ARCH_X86_64=0" -o "D:\Libraries\x264\SMC\\obj\DebugDLL\Win32\x264\\" -rnasm -pnasm "D:\Libraries\x264\common\x86\bitstream-a.asm"" exited with code 1.

      The problem comes from the "-f Win32" switch - I copy-pasted the above line and got "vsyasm: FATAL: unrecognized object format `win32´. Removing the switch makes the command succeed.

      Delete
    4. This unfortunately is a bug in the latest 1.3.0 release of vsyasm. The older 1.2.0 still works fine and is the version I have been using (and so wasn't actually aware of the 1.3 error). Quite brilliantly the vsyasm 1.3.0 release doesn't actually work (score 1 for testing before release).
      Luckily I was able to find an easy fix. The main problem is that the Win32 and x64 switches are no longer accepted and only win32/win64 (lower case w) will work.
      This can be fixed by opening up the vsyasm.props file again and replacing the 1 occurrence of $(Platform) with win$(PlatformArchitecture). That should fix the problem on both 32 and 64 bit platforms.
      I have updated the included readme.txt from the repo accordingly.

      Delete
    5. Thanks Matthew, for the ultra-fast fix. It builds now.

      I think there is a problem with the output path of x264cli (I can't seem to start the debugger), plus the Debug DLL version reports that it cannot link libx264d.lib.

      But those are peanuts, I now have the means to build a library that is debuggable, and that's all I need for now. Thanks again!

      Delete
    6. No problem.

      Just FYI but the DLL builds are not actually supported by the cli (hence why they don't build). The cli uses functions that are not exported by the dll and so cant be used with one. Thats why the cli project doesn't actually have DLL configurations and the solution DLL configurations only apply to libx264 (the fact the solution provides DLL configs is probably a slight source of confusion).

      As for the cli debugging thats just VS being derp and looking in the wrong place. This is a user config setting and cannot be set in the repo. But you can just change the Debugging->Command in the project properties from $(TargetPath) to $(TargetDir)\bin\$(TargetFileName) and debugging should work fine.

      Delete
    7. I was able to link with your version of libx264 and can now debug. Unfortunately, I'm getting errors that the debugger can't catch (I've had "invalid instruction" and a complete system freeze).

      I can encode something like a minute's worth of video (quality is great), at which point something always goes wrong.

      This is getting urgent; I need some kind of solution by tomorrow. I'll start by resetting the number of threads to 1 (currently at 8), but I'd be grateful for any kind of help. If you'd prefer to converse outside these comments, my email is "gygax" to be found at "practicomp" located in "ch". Thanks!

      Delete
    8. Do you get invalid instruction when debugging only or do you get it when running a release build outside of Visual Studio as well?

      If you get an instruction error with release builds you may want to check what processor you are testing on. By default the project compiles with SSE2 requirements so if your processor does not support those then you will need to turn them off.

      X264 also uses newer instruction sets (AVX etc.) that may be being incorrectly called. Placing a debug point in x264_cpu_detect in cpu.c will allow you to see what features x264 is detecting and make sure that they align with your processor.

      Delete
    9. Thanks Matthew. It seems that my most recent problems were caused by an overheating CPU - I really should have seen this sooner. There *are* problems with alignment, but those are much less urgent.

      Delete
  4. Hi Matthew, I recently found your GitHub repos for x264 and FFmpeg and I was interested in building these myself. I'm currently hitting a crash that I don't understand and I am hoping you've seen this before. I am targeting the x64 release version for these projects and all other dependencies. I have FFmpeg compiling and linking successfully using this configuration:

    project_generate.exe --enable-gpl --enable-version3 --enable-nonfree --enable-libx264 --toolchain=msvc

    Then I ran FFmpeg with this command line:

    C:\ValidPath\ffmpeg\msvc64\bin\ffmpeg.exe -i "input.mkv" -c:v libx264 -preset medium -crf 22 -c:a aac -cutoff 15000 -b:a 192k -ac 2 -strict -2 "output.mp4"

    When I run this, I get a crash at:
    ffmpeg!x264_frame_init_lowres_core_avx+0x10:
    00007ff7`21c1bb30 c57829442420 vmovaps xmmword ptr [rsp+20h],xmm8 ss:0000003e`c0bdf448=00000000000000770000003ec4822780


    My CPU is supposed to support AVX and if I modify cpu.c to say it doesn't, I get a crash in the SSE3 version of this function. Do you know what is happening here?

    Thanks.

    ReplyDelete
    Replies
    1. I pushed a new commit to the x264 repo which should fix the problem. Grab that and then let me know if you have any more issues.

      Delete
    2. Thanks Matthew, your recent commits did the trick. I rebuilt x264 and FFmpeg and now the same command works just fine!

      Delete
  5. Hm... See you again. and I really sorry to border you. I downloaded your git. But there is no project generate. and when I start with 'x264.sln' on visual studio 2013, Window. and then, I saw a message like this. "Unable to start program 'libx264d.lib" and couln't find that file. how can i solve that? and... I want to know how can i compile ffmpeg + x264 what Kevin did?

    ReplyDelete
    Replies
    1. No need for project generate on any other projects found in my git repo (github.com/ShiftMediaProject/) as there are no configuration options to change. All the projects in my repo have a Visual Studio project file in the SMP folder which can be used to build any of the libraries for use with FFmpeg.

      x264 and x265 are the only ones that included extra projects to build the CLI program. If your only building x264 to link with FFmpeg then you only need to build the libx264 project and then use that to link with ffmpeg.

      The error your getting is because your trying to 'run' the libx264 lib. This is not an executable so you cant really run it ;)

      You can link it with ffmpeg and run ffmpeg or if you want to run the x264 CLI program then select the x264cli project, right click and make sure it is "set as startup project".

      Im guessing your new to Visual Studio coding so if your having similar issues you might want to read up a bit on that first. Anyway hope that helps.

      Delete
    2. To build ffmpeg using only just x264 (the default ffmpeg projects are configured for all of the libs found in my repo). Then just build libx264 (build it, not run it). Then run ffmpeg generator with an additional --enable-x264. Rebuild ffmpeg and it will auto pick up the built x264.

      Delete
    3. Oh! That's it...Thanks a lot. I didn't think that way... Really sorry and Thank you very much.

      Delete
  6. man i got these errors:
    "Error 20 error LNK1181: cannot open input file '..\SMP\\obj\Debug\Win32\libx264\bitstream-a.obj' ..\SMP\LINK libx264
    "
    i have bitstream.obj file instead of bitstream-a.obj file..

    ReplyDelete
  7. bitstream-a.obj is generated from the asm source files. If your missing this file then you most likely havnt installed yasm properly. Make sure you read the readme.txt and follow the instructions.

    ReplyDelete
  8. Hi Matthew,

    I cloned the repo to my laptop and to my home pc. On my Laptop (Win8.1 64bit, VS2013, YASM1.3.0) the .dll builds fine, but on my pc (Win7 64bit, VS2013 Update 4, YASM1-3-0) i get two errors:

    The first one is:
    1> Assembling x86util.asm
    1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations\vsyasm.targets(45,5): error MSB3721: The command ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\"vsyasm.exe -Xvc -f Win32 -i "G:\ATView_streaming\vobs\attower\src\libs\x264\SMP\\..\common\x86" -d "PREFIX" -d "STACK_ALIGNMENT=4" -d "HIGH_BIT_DEPTH=0" -d "BIT_DEPTH=8" -d "WIN32=1" -d "ARCH_X86_64=0" -o "G:\ATView_streaming\vobs\attower\src\libs\x264\SMP\\obj\ReleaseDLL\Win32\libx264\\" -rnasm -pnasm "..\common\x86\bitstream-a.asm" "..\common\x86\cabac-a.asm" "..\common\x86\const-a.asm" "..\common\x86\cpu-a.asm" "..\common\x86\dct-32.asm" "..\common\x86\dct-a.asm" "..\common\x86\deblock-a.asm" "..\common\x86\mc-a.asm" "..\common\x86\mc-a2.asm" "..\common\x86\pixel-32.asm" "..\common\x86\pixel-a.asm" "..\common\x86\predict-a.asm" "..\common\x86\quant-a.asm" "..\common\x86\sad-a.asm"" exited with code 1.

    You mentioned this one could be fixed by changing the vsyasm.props. I did that, but it didn't have any effect.

    The second one is
    Error 9 error MSB3073: The command "if exist ..\config.h (
    del ..\config.h
    )
    if exist ..\x264_config.h (
    del ..\x264_config.h
    )
    if not exist ../common/oclobj.h (
    type ..\common\opencl\x264-cl.h ..\common\opencl\bidir.cl ..\common\opencl\downscale.cl ..\common\opencl\weightp.cl ..\common\opencl\intra.cl ..\common\opencl\subpel.cl ..\common\opencl\motionsearch.cl | perl ..\tools\cltostr.pl x264_opencl_source > ..\common\oclobj.h
    )
    :VCEnd" exited with code 255. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets 122 x264cli

    I can live without the CLI, but it still bothers me why it won't build on my home pc.

    Can you help me?
    Thanks in advance!

    ReplyDelete
  9. Well the second one shouldnt happen as that header already exists and its failing (my guess) due to missing perl while trying to create it.

    I added a new update upstream that should fix that issue.

    But the first I have no idea. Without knowing what the error actually is I cant really help. Try pasting the failed command into a VS command prompt and read the error message from that as hopefully it should give more detail.

    ReplyDelete
    Replies
    1. Thank you for the fast fix for the second error.
      The other one was a "picnic". I added the wrong directory to the build customizations so VS couldn't find the correct yasm version. Thanks again!

      Delete
    2. Hi Markus.
      I have your first problem in compile.
      can you say me how you can correct your problem.
      tanx a lot.

      MIM

      Delete
  10. Hi Matthew,

    I get the following error when I try to build x264:

    LINK : fatal error LNK1181: cannot open input file 'common/x86/const-a.o'
    make: *** [libx264.lib] Error 157

    I have followed the instructions in reademe.txt of yasm (version 1.2.0) and have made the changes to vsyasm.props but the build fails. I am using MSYS to build x264 but I am not sure what I'm missing.

    ReplyDelete
    Replies
    1. The instructions in the readme are only for compiling with the included Visual Studio project. If you are using msys then you would be using the default configure/make which is completely different.

      The repo is designed to mainly support building through Visual Studio. I do however test that it works when building with MinGW as well so if you really want to go that route (although if its for windows then using VS would be the better solution) then it should work.

      However you should be using MSYS2 and I can confirm that using the msys2 mingw packages it works fine (look up the msys2 help to find out how to use pacman to download packages). The original msys is quite old and buggy so I suggest you move to msys2 and see how things go.

      Delete
  11. Some older version of Visual Studio 2013 run into this problem:

    https://connect.microsoft.com/VisualStudio/feedback/details/808472/c99-support-of-mixed-declarations-and-statements-fails-with-certain-types-and-constructs

    ReplyDelete
    Replies
    1. I dont have a pre-Update 2 version of 2013 to test this but never got any errors back when I was. If your getting errors compiling the current version of the code in the repo using an older 2013 version then list the errors/locations and ill go ahead and fix them.

      Delete
  12. This comment has been removed by the author.

    ReplyDelete
  13. This comment has been removed by the author.

    ReplyDelete
  14. Hi, I'm having a problem when using your git x264/visual studio. Everything compiles fine, but when I run the x264cli program with --opencl, it fails to compile opencl kernels. The error log is very long but basically, it's types not found, starting with:

    :12:7: error: unknown type name 'sum2_t'
    local sum2_t *tmpp,
    ^
    :15:25: warning: type specifier missing, defaults to 'int'

    These définitions are in x264_cl.h and i've tried to feed that to clCompileProgram but with no luck.
    Would you have an idea?

    Thank you

    ReplyDelete
    Replies
    1. When you try and run x264cli what device does it try and use for opencl acceleration?
      x264 requires newer opencl versions not supported by all drivers

      Delete
    2. Hi Matthew,
      It opens the right device, I believe:
      x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX UnalignedStack
      x264 [info]: OpenCL acceleration enabled with NVIDIA Corporation GeForce GTX 970
      x264 [info]: Compiling OpenCL kernels...
      x264 [warning]: OpenCL: kernel build errors written to x264_kernel_build_log.txt

      When I use the official compiled binary from the x264 website, it works fine with two differences: the "Unaligned stack" appears only in the VS compiled binary and, obviously, the opencl kernels compile fine with the official exe.

      thanks

      Delete
    3. The unaligned stack is expected as this is a result of differences between how VS aligns stack data compared to gcc.

      Interesting you have an opencl error as it works fine on my test NVIDIA 780ti with the latest drivers. Which if you are using the newest drivers will be the same as yours.

      What build configuration did you use to build the program? It may be an issue with a debug build or something.

      Delete
    4. Hi,

      Yes, I have the latest drivers, currently 355.98 (just checked to make sure there was nothing newer).
      I've tried only release builds, x86 and AMD64, both have the problem.

      Again, to me, it looks like an include problem (in the error log, it's all about unknown types). Is there a way to include x264_cl.h when compiling these kernels? (i've tried but it didn't work or I didn't do it properly). I think it may be something with my configuration. But i've tried sources files from your git and then I've tried with the latest x264 sources, no luck so far...

      thank you for your time.

      Delete
    5. All the used opencl kernels are prebuilt into SMP/common/oclobj.h. This file is what is used to load in the opencl code as a string and compile it at runtime. This string is x264_opencl_source and is used to create the opencl program on line 265 of opencl.c.

      If you are getting errors output by the opencl ICD while compiling the kernels at runtime then something has happened to your oclobj.h as that is the only way that x264 loads opencl code.

      Delete
    6. Hi,
      oclobj.h seems correct. It seems identical on your git, my hard drive, and in memory when it's being fed to clBuildProgram. It decodes to a 1744-lines block of code, starting with a comment and
      int bidir_satd_8x8_ii_coop4( read_only image2d_t fenc_lowres, (...)

      clBuildProgram fails with error -11, appearently failing because of unkown types which are normally in x264_cl.h
      That file is actually present in x264-master\common\opencl

      I checked the solution, I didn't see any obvious mistake but I may have missed something...

      thanks

      Delete
    7. OK I think ive tracked down a potential issue. Im not sure why it worked on mine when i tested it but not on yours but I have created a new oclobj.h that i just pushed to the repo. Try it with this new update and see how it works now.

      Delete
    8. Hi Matthew,
      Congratulations, it works!
      Thank you very much for your help and for the very useful and very professional VS projects you created. Great work.

      Delete
  15. I am trying to compile in Visual Studio 2015 from the latest commit ('project: Set minimum Windows version.') and am running into some issues.

    libx264.vcxproj cannot be loaded as part of the solution, with the helpful error 'one or more errors occured'.

    Then I see these errors when trying to compile x264cli project:

    Severity Code Description Project File Line
    Warning MSB8012 TargetPath(C:\Users\mbelleau\Documents\Visual Studio 2012\trunk_15\x264-master\SMP\..\..\..\msvc\x264clid.exe) does not match the Linker's OutputFile property value (C:\Users\mbelleau\Documents\Visual Studio 2012\msvc\bin\x86\x264clid.exe). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile). x264cli C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppBuild.targets 1189
    Warning D9030 '/Gm' is incompatible with multiprocessing; ignoring /MP switch x264cli C:\Users\mbelleau\Documents\Visual Studio 2012\trunk_15\x264-master\SMP\cl 1

    This for a debug/Win32 build.

    ReplyDelete
    Replies
    1. Interesting, I also use VS 2015 and have not run in to any such issues. Did loading the project work before the most recent commit?

      The output from x264cli compile that you listed are both warnings and not errors. Both these warning are standard and expected and can be entirely ignored.

      Delete
    2. I tried a version from a few commits before that and it also failed. I tried to compile from command line to see if the error made more sense. Here's what I got:

      C:\Users\mbelleau\Documents\x264\SMP>"C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild" x264.sln
      Microsoft (R) Build Engine version 14.0.23107.0
      Copyright (C) Microsoft Corporation. All rights reserved.

      Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
      Build started 10/11/2015 3:35:21 PM.
      Project "C:\Users\mbelleau\Documents\x264\SMP\x264.sln" on node 1 (default targets).
      ValidateSolutionConfiguration:
      Building solution configuration "Debug|Win32".
      Project "C:\Users\mbelleau\Documents\x264\SMP\x264.sln" (1) is building "C:\Users\mbelleau\Documents\x264\SMP\libx264.v
      cxproj" (2) on node 1 (default targets).
      C:\Users\mbelleau\Documents\x264\SMP\libx264.vcxproj(126,5): error MSB4019: The imported project "C:\Program Files (x86
      )\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\vsyasm.props" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
      Done Building Project "C:\Users\mbelleau\Documents\x264\SMP\libx264.vcxproj" (default targets) -- FAILED.

      Done Building Project "C:\Users\mbelleau\Documents\x264\SMP\x264.sln" (default targets) -- FAILED.


      Build FAILED.

      "C:\Users\mbelleau\Documents\x264\SMP\x264.sln" (default target) (1) ->
      "C:\Users\mbelleau\Documents\x264\SMP\libx264.vcxproj" (default target) (2) ->
      C:\Users\mbelleau\Documents\x264\SMP\libx264.vcxproj(126,5): error MSB4019: The imported project "C:\Program Files (x
      86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\vsyasm.props" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

      0 Warning(s)
      1 Error(s)

      Time Elapsed 00:00:00.04

      Delete
    3. I copied vsyasm.exe to C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin, made the changes listed in SMP/readme.txt and it all seems to compile now!

      Delete
  16. Hello,

    I downloaded the code from the github project you link to.
    I also get errors when I try to load libx264 . (37 of them, all of the type "The element 'PropertyGroup' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003' has invalid child element 'IntDir' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003'. List of possible elements expected: 'Property, VisualStudioVersion, MinimumVisualStudioVersion, AdditionalFileItemNames, AllowUnsafeBlocks, AppConfigForCompiler, ApplicationIcon, ApplicationRevision, .... M:\Buildx264\x264-master\SMP\libx264.vcxproj 161")
    With VS2010 I manage to load the solution but get a lot of compiling errors, which seem to come from VS2010 not supporting this C99 if I followed correctly.

    Would you have any idea where the errors occurring with VS2015 might come from?
    Sorry if it's a noob question but I've spent a full day on it but haven't made any progress...
    Thanks!

    ReplyDelete
    Replies
    1. The project will not work in VS 2010 and these days I recommend atleast 2013 for best results.

      As for the errors make sure you have followed the readme with regards to installing yasm. However based on the errors it seems to be potentially unrelated as its complaining about not being able to resolve the intermediate directory value. This most likely has happened as VS has messed itself up.

      To fix this close down all copies of VS and reset your git repo to original (this will remove any temp files VS will have made - also any changes you have made so back those up if you want to keep them). Do this by running 'git clean -xdf' from command prompt (or by just downloading a clean copy of the repo). Then open the solution directly in VS 2015.

      Delete
    2. It was because of yasm... I had updated the .props file but in the wrong directory (even though you indicate the right one in the readme file...).
      Thanks for the help and for the great project!

      Delete
  17. This comment has been removed by the author.

    ReplyDelete
  18. I recently downloaded your source code for x264 and I am trying to build it. I have followed all the steps but I am running into 2 erros error. One of them you have already fixed in one of the comments above but it still appears for me and the second one is regarding to the linking of libx264d.lib. I will be grateful if you can help me out.

    1. Severity Code Description Project File Line Suppression State
    Error MSB3073 The command "if exist ..\config.h (
    del ..\config.h
    )
    if exist ..\x264_config.h (
    del ..\x264_config.h
    )
    if exist ..\common\oclobj.h (
    del ..\common\oclobj.h
    )
    if not exist .\common\oclobj.h (
    echo "Error: Missing oclobj.h, can not regenerate!"
    exit /b 1
    )
    if exist C:\Users\ZAN1\Documents\Visual Studio 2015\Projects\x264-master\SMP\..\..\..\msvc\\include\x264.h (
    del C:\Users\ZAN1\Documents\Visual Studio 2015\Projects\x264-master\SMP\..\..\..\msvc\\include\x264.h
    )
    if exist C:\Users\ZAN1\Documents\Visual Studio 2015\Projects\x264-master\SMP\..\..\..\msvc\\include\x264_config.h (
    del C:\Users\ZAN1\Documents\Visual Studio 2015\Projects\x264-master\SMP\..\..\..\msvc\\include\x264_config.h
    )
    :VCEnd" exited with code 1. libx264 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets 123
    2. Severity Code Description Project File Line Suppression State
    Error LNK1181 cannot open input file 'libx264d.lib' x264cli C:\Users\ZAN1\Documents\Visual Studio 2015\Projects\x264-master\SMP\LINK 1

    I am using Visual Studio 2015 on a Windows 7 64 bit PC !!

    ReplyDelete
    Replies
    1. Not sure about the first error. You can try and get more detailed error information by changing the log verbosity "Tools->Options->Projects and Solutions->Build and Run->MSBuild output verbosity". But really it should only fail if SMP/common/oclobj.h does not exist in your local copy.

      As for the second error, that can happen if you are building a DLL configuration. The cli doesnt work with dlls as it uses private functions that are not exported by libx264. This can be fixed by first building a static lib by using either the Debug or Release configurations.

      Delete
    2. Thank you very much for your response. I was able to build x264 source using msys2 following some of your instructions your instructions. The matter is solved.

      Delete
    3. Thank you Matthew for your efforts!

      For what its worth, I discovered the cause of the pre-build script failing. It will fail if you have spaces in the project path. e.g. "Documents\Visual Studio 2015\Projects" contains spaces.

      Another script was failing during build because my YASMPATH environment variable didn't have a backslash after the directory name. Correct: "some_path\vsyasm-1.3.0-win64\". Incorrect: "some_path\vsyasm-1.3.0-win64"

      I hope this helps someone.

      Delete
  19. Could anyone tell me how to build the solution to support 10-bit high422?

    I tried to modify/add x264_config.h with
    #define X264_BIT_DEPTH 10
    #define X264_CHROMA_FORMAT X264_CSP_I422
    #define HIGH_BIT_DEPTH 1

    and added
    #define CHROMA_FORMAT CHROMA_422
    to common/common.h
    But I got a load of link errors of undefined and redefined functions as partly listed at the end of the comments.

    I also tried some other combinations of the above, but have runtime errors which indicate that the above settings are required.

    Any resolutions and comments are greatly appreciated.

    Dongning

    ------ part of linker errors
    1>------ Build started: Project: x264cli, Configuration: Release x64 ------
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_4x4_mmx2 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_8x8_mmx2 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_8x8c_mmx2 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_8x8c_ssse3 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_16x16_mmx2 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_16x16_sse2 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(sad-a.obj) : error LNK2005: x264_intra_sad_x3_16x16_ssse3 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(pixel-a.obj) : error LNK2005: x264_intra_sa8d_x3_8x8_sse2 already defined in libx264.lib(pixel.obj)
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_8x8_sse2 referenced in function x264_intra_sad_x3_8x8c_sse2
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_8x4_sse2 referenced in function x264_pixel_init
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_8x16_sse2_aligned referenced in function x264_pixel_init
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_8x8_sse2_aligned referenced in function x264_pixel_init
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_16x16_ssse3 referenced in function x264_intra_sad_x3_16x16_ssse3
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_16x8_ssse3 referenced in function x264_pixel_init
    1>libx264.lib(pixel.obj) : error LNK2019: unresolved external symbol x264_pixel_sad_8x16_ssse3 referenced in function x264_intra_sad_x3_8x16c_ssse3

    ReplyDelete
    Replies
    1. When compiling a version for high bit depth you need to remove the sad-a.asm file and replace it with sad16-a.asm.
      The standard sad file contains only the 8bit functions so you need to add the higher bitdepth variant when compiling for high bit depth support

      Delete
  20. This comment has been removed by the author.

    ReplyDelete
  21. Dear Matthew,

    Thank you for your reply.

    I finally made 10-bit high422 work. In addition to my above changes, I made the following changes to make it build and encode correctly:

    SMP/config.h:
    commented out "#define HAVE_MMX 1"

    SMP/libx264.vcxproj:
    Changed YASM setting to use: HIGH_BIT_DEPTH=1;BIT_DEPTH=10

    common/common.h:
    Added "#define HIGH_BIT_DEPTH 1"

    Dongning

    ReplyDelete
  22. Hi
    I downloaded your project from git..
    When i'm enabling opencl in x264, i'm getting errors.
    like 'OpenCL fatal error aborting encode'.
    can you help me

    ReplyDelete
    Replies
    1. Ill need more info than that. Start by opening a ticket on the github page and then posting the complete log as that is needed as a minimum for any type of debugging.

      Delete
  23. Hi. I downloaded GIT project. Compilation was successful, but when i tried to port my screen capture Linux app, i'ev got wrong video file.
    It plays, but screen is almost black, except some moving squares o the top.

    here is encoder code (it works in linux)

    x264SourceFrm.i_pts = x264Pts;
    x264SourceFrm.i_type = X264_TYPE_AUTO;

    x264SourceFrm.img.plane[0] = (uint8_t *)frame->yColors->Bytes;
    x264SourceFrm.img.plane[1] = (uint8_t *)frame->uColors->Bytes;
    x264SourceFrm.img.plane[2] = (uint8_t *)frame->vColors->Bytes;
    x264SourceFrm.img.plane[3] = 0;

    int frame_size = x264_encoder_encode(x264Encoder, &x264Nals, numNals, &x264SourceFrm, &x264DestFrm);

    for (int i = 0; i < *numNals; i++)
    {
    myFile.write((char *)x264Nals[i].p_payload, x264Nals[i].i_payload);
    }
    ++x264Pts;

    ReplyDelete
    Replies
    1. I cant comment on your code but i just checked the latest x264 on my end and it works fine. I would first make sure that your screen capture is actually working properly on windows. If that doesnt work id check your code is correct directly with the x264 help channel.

      FYI. The git page also contains precompiled libs in the release section so you can use those instead of compiling it yourself.

      Delete
    2. I tested screen capture over Media Transforms Foundation h264 encoder. It works fine. I even created a test checker pattern.

      static uint8_t Ys[1920 * 1080];
      static uint8_t Us[960 * 540];
      static uint8_t Vs[960 * 540];


      int crx;
      int cry;
      uint8_t v;
      for (int y = 0; y < 1080; y++)
      {
      cry = y >> 1;
      for (int x = 0; x < 1920; x++)
      {
      /* v = x % 200 > 63 ? 255 : 14;
      v = y % 200 > 63 ? ~v : v; */
      v = x % 128 > 63 ? 240 : 0;
      v = y % 128 > 63 ? ~v : v;
      Ys[x + y * 1920] = v;
      crx = x >> 1;
      Us[crx + cry * 960] = 0;
      Vs[crx + cry * 960] = 64;
      }
      }


      x264SourceFrm.img.plane[0] = Ys;
      x264SourceFrm.img.plane[1] = Us;
      x264SourceFrm.img.plane[2] = Vs;
      x264SourceFrm.img.plane[3] = 0;

      int frame_size = x264_encoder_encode(x264Encoder, &x264Nals, numNals, &x264SourceFrm, &x264DestFrm);

      Results vary from black screen with some parts of checker on the top to full checker frame. It depends on size of squares and their colors. Seems very strange to me.
      Here is codec initialization code:

      myFile.open("capture.mp4");
      int r = 0;
      int nheader = 0;
      int header_size = 0;

      x264_picture_init(&x264SourceFrm);
      r = x264_picture_alloc(&x264DestFrm, X264_CSP_I420, videoWidth, videoHeight);

      x264SourceFrm.img.i_plane = 3;
      x264SourceFrm.img.i_csp = X264_CSP_I420;
      x264_param_default_preset(&x264Params, "ultrafast", "zerolatency");
      x264Params.i_threads = 1;
      x264Params.i_log_level = X264_LOG_DEBUG;
      x264Params.i_width = videoWidth;
      x264Params.i_height = videoHeight;
      x264Params.i_fps_num = 25;
      x264Params.i_fps_den = 1;
      x264Params.i_keyint_max = 30;

      x264Params.b_intra_refresh = 1;
      x264Params.rc.i_rc_method = X264_RC_CRF;
      x264Params.rc.f_rf_constant = 25;
      x264Params.rc.f_rf_constant_max = 35; */

      // create the encoder using our params
      x264Encoder = x264_encoder_open(&x264Params);
      // write headers
      r = x264_encoder_headers(x264Encoder, &x264Nals, &nheader);
      header_size = x264Nals[0].i_payload + x264Nals[1].i_payload + x264Nals[2].i_payload;
      myFile.write((char *)x264Nals[0].p_payload, header_size);
      x264Pts = 0;

      Delete