FFMPEG on cygwin failed to compile libx264 error: unknown type name ‘HMODULE’
FFMPEG on cygwin failed to compile libx264 error: unknown type name ‘HMODULE’
我正在尝试在cygwin环境下用ffmpeg编译libx264
我遵循了 Koohiimaster's blog, FFMPEG compilation guide, SO post 1, SO post 2 几个来源的一些指示,但我总是停留在同一个步骤,即 libx264 编译(制作)过程。
如 FFMPEG 编译指南中所述,应遵循这些步骤以使 libx264 正常工作
cd ~/ffmpeg_sources
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" bindir="$HOME/bin" --enable-static --disable-opencl
PATH="$HOME/bin:$PATH" make
make install
但是当我输入此命令时 PATH="$HOME/bin:$PATH" make
编译器总是停止并出现以下错误:
In file included from input/avs.c:49:0:
./extras/avisynth_c.h:825:3: error: unknown type name ‘HMODULE’
HMODULE handle;
^
我想知道这是否是libx264源码的bug,但我尝试了几个较早的源码版本后,都出现了同样的错误。有什么想法可以解决这个问题吗?
信息
类型 HMODULE
在 WinDef.h
中声明。所以你没有包含这个 header。我认为通常 WinDef.h
包含在 windows.h
中。
备选方案 1:无 AVS
如果您不需要 avs 支持,您可以禁用它并查看它是否有效:
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" bindir="$HOME/bin" --enable-static --disable-opencl --disable-avs
实际上,这是一个不错的选择,只需检查一下,看看它是否能为您提供有关您的问题的更多信息。
备选方案 2:检查 windows.h
另一件事是检查配置中使用了哪个 windows.h
文件。
在 libx264 源代码中 input/input.h
包括 windows.h
。
input.h
本身随后被 avs.c
包含。 avs.c
之后还包括 extras/avisynth_c.h
。因此,总而言之,当编译器出现 HMODULE handle
行时,windows.h
应该已经被包含(其中 WinDef.h
应该被包含)。
所以你的 windows.h
文件不知何故 "wrong" 或者在预处理过程中确实出了问题。
在我的系统(Cygwin 2.9.0(0.318/5/3)/Windows 7 64-bit SP1)上,HMODULE 定义在 wtypes.h
中,不包含在 windows.h 或任何其他包含的文件。
编辑 windows.h(在 /usr/lib/w32api/windows.h)以添加 #include <wtypes.h>
对我有用(我在 #define _INC_WINDOWS
之后的行中添加了它)。
我还在配置命令中添加了 --extra-cflags="-I/usr/include/w32api/"
以及 --extra-ldflags="-L:/usr/local/lib/"
,尽管我不确定添加 ldflags 是否与此相关或 libfdk-aac
编辑:我从快照页面查看了自述文件。
$ wget -O - \
https://download.videolan.org/x264/snapshots/x264-snapshot-20191218-README.txt \
2>/dev/null
The snapshotting service is discontinued.
Please use https://code.videolan.org/videolan/x264/ to get the tarballs.
因此,我使用了新的存储库进行下载。
如果您使用了之前的说明,您可能想要清除之前的 x264
内容,如下所示
cd $HOME/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
make clean
make distclean
然后,如果你 运行 make install
为 x264
,你还需要执行以下操作
cd $HOME/programs/ffmpeg
find . -type f -name "*x264*" -print0 | \
xargs -I'{}' -0 \
bash -c 'orig="{}"; echo; echo "Attempting to remove:"; '\
'echo "${orig}"; echo " ... "; echo " ... as file ..."; '\
'[ -e "${orig}" ] && rm "${orig}" && '\
'echo " ... success" || '\
'echo " ... FAILURE";'; \
find . -type d -name "*x264*" -print0 | \
xargs -I'{}' -0 \
bash -c 'orig="{}"; echo; echo "Attempting to remove:"; '\
'echo "${orig}"; echo " ... "; echo " ... as directory ..."; '\
'[ -d "${orig}" ] && rm -rf "${orig}" && '\
'echo " ... success" || '\
'echo " ... FAILURE";';
第二个命令有一个更短但信息量更少的版本。它将尝试删除已删除目录中的文件,这可能需要更长的时间。我不确定检查它是否始终有效的最佳方法。
find . -name "*x265*" -print0 | \
xargs -I'{}' -0 \
bash -c 'orig="{}"; echo > tmpf; [ -e "${orig}" ] && rm "${orig}" 2>tmpf; '\
'grep -v "rm.*cannot.*remove.*directory" tmpf; rm tmpf; '\
'[ -d "${orig}" ] && rm -rf "${orig}";'
现在,我们继续用最新的方法来处理x264
。
cd $HOME/programs/ffmpeg/ffmpeg_sources
git clone https://code.videolan.org/videolan/x264.git
cd x264
从这里开始,我必须按照与快照页面中的 tarball 相同的步骤进行操作,即我只是重复以
开头的说明
PATH="$HOME/programs/ffmpeg/bin:$PATH" \
./configure --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
--bindir="$HOME/programs/ffmpeg/bin" \
--enable-static`
包括 wtypes.h
修复。
我已经用 标记了这个位置++从哪里开始更新的下载++
我的系统略有不同。得益于@Missy 和@Jan 以及其他参考资料的提示,我能够让事情正常进行 - koohiimaster especially (since I want a Cygwin build), as well as this SuperUser answer for "How to compile the best version of FFmpeg for Windows"(Windows 构建 - 离我想要的更远)。
但是,有几件事完全不同,我将它们分享给可能处于我的情况的任何人。
系统详细信息
$ date && date +'%s'
Sat, May 2, 2020 2:41:12 PM
1588452072
$ uname -a
CYGWIN_NT-10.0 MY-MACHINE 3.1.4(0.340/5/3) 2020-02-19 08:49 x86_64 Cygwin
$ bash --version | head -n 1
GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin)
$ gcc --version | head -n 1
gcc (GCC) 9.3.0
$ g++ --version | head -n 1
g++ (GCC) 9.3.0
$ make --version | head -n 2
GNU Make 4.3
Built for x86_64-pc-cygwin
$ systeminfo | sed -n 's#^OS\ *##p'
Name: Microsoft Windows 10 Home
Version: 10.0.18363 N/A Build 18363
Manufacturer: Microsoft Corporation
Configuration: Standalone Workstation
Build Type: Multiprocessor Free
我的目录结构有点不同,但我希望足够接近,以便大家继续。
我的步骤和(错误)输出
mkdir -p ~/programs/ffmpeg
cd ~/programs/ffmpeg
mkdir bin && mkdir ffmpeg_sources && mkdir ffmpeg_build
cd ffmpeg_build
请注意,说明要求您使用以下命令下载和解压缩,
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
然而,这不是真实的 URL;他们要你从 https://download.videolan.org/x264/snapshots/
下载最新的 x264
版本。我也得到了 README
,因为它让我远离麻烦。
wget https://download.videolan.org/x264/snapshots/x264-snapshot-20191217-2245.tar.bz2 ## necessary
wget https://download.videolan.org/x264/snapshots/x264-snapshot-20191218-README.txt ## optional, but helpful
如果您在几个月左右看到这个答案,希望您在文件名末尾有一个不同的日期。为了在这个答案中保存一些 space,我使用 xjf
标志而不是 xjvf
- 我不想冗长。 untar
ing 之后,我将按照说明继续。
$ tar xjf x264-snapshot-20191217-2245.tar.bz2
$ cd x264-snapshot-20191217-2245
现在,我们已准备好构建。您应该在类似于以下的目录中(尽管您的日期可能不同)。
$HOME/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
++从哪里开始下载新版本++
cd $HOME/programs/ffmpeg/ffmpeg_sources
git clone https://code.videolan.org/videolan/x264.git
cd x264
(如果你下载的是较新的,你的目录应该是$HOME/programs/ffmpeg/ffmpeg_sources/x264
)
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" \
./configure --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
--bindir="$HOME/programs/ffmpeg/bin" \
--enable-static
##
抑制输出:关于配置的一些不错的信息。没有错误的东西。
You can run 'make' or 'make fprofiled' now.
下一个命令:
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)
##
抑制输出:一些好的输出 - 甚至没有任何警告。
In file included from input/avs.c:49:
./extras/avisynth_c.h:825:3: error: unknown type name ‘HMODULE’
825 | HMODULE handle;
##
抑制输出:修复此问题后我们将看不到一堆警告。
make: *** [Makefile:272: input/avs.o] Error 1
解决方案(以及如何实现)
感谢@Missy,我知道要寻找什么和做什么。
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果不匹配,cd
进入你需要的目录。
$ whereis w32api
w32api: /usr/lib/w32api /usr/include/w32api
grep -iIRHn "^typedef.*HMODULE[;]" /usr/include/w32api
/usr/include/w32api/wtypes.h:78:typedef void *HMODULE;
## For grep
## -i : ignore case
## -I : ignore binary files
## -R : recursive search
## -H : output the filename
## -n : output the line number
请注意,你们中的某些人可能拥有 mingw
版本或某些其他版本,例如
/usr/i686-pc-cygwin/sys-root/usr/include/w32api/
但如果我们想要构建 Cygwin,那将无济于事。您可能需要像@Missy 那样做一些事情
[add] --extra-cflags="-I/usr/include/w32api/"
to the configure command, along with --extra-ldflags="-L:/usr/local/lib/"
不过,我不必那样做。
我们可以转到 ./input/input.h
和 ./extras/avisynth_c.h
(其中,对我来说 .
是 ~/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
)添加行以包含 wtypes.h
,但是,当我这样做时,它没有用。 header 文件有问题,我们需要先修复。我将通过传递 grep
命令进行一些探索,在找到行:-C 10
。我还将使用 cat -n
放入行号。该命令如下(请注意,由于行号,我在 grep
的正则表达式的开头不再有 ^
锚点)。
cat -n /usr/include/w32api/wtypes.h | grep -C 10 "typedef.*HMODULE[;]"
这使我能够找到问题并用更少的行向您展示。我们会在 (-B <n_lines>
) 之前放一些,在 (-A <n_lines>
) 之后放一些。
$ ### before
$ cat -n /usr/include/w32api/wtypes.h | grep -B 6 -A 2 "typedef.*HMODULE[;]"
72 byte data[1];
73 } RemHBRUSH;
74 #if 0
75 typedef UINT_PTR WPARAM;
76 typedef LONG_PTR LPARAM;
77 typedef LONG_PTR LRESULT;
78 typedef void *HMODULE;
79 typedef void *HINSTANCE;
80 typedef void *HTASK;
那 #if 0
将成为一个问题 - 它等同于说 if false
,所以它永远不会被评估或执行。 (如果您想一直看到 #endif
,请将 -A 49
与您的 grep
一起使用。
在我看来,最简单的解决方案是从 if
语句中取出 typedef void *HMODULE:
。我会注意文件评论的警告,
$ head -n 5 /usr/include/w32api/wtypes.h ### BEFORE
/*** Autogenerated by WIDL 1.6 from include/wtypes.idl - Do not edit ***/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
并且不编辑。我认为最好不要管 Win32 API。我会将 header 文件复制到我们的项目中。由于链接器查找 header 文件的方式,它将首先查找我们的 ffmpeg_sources/wtypes.h
。 (我尝试重命名它以避免可能的 namespace conlicts,但这没有用)。
好吧,当它在我们的项目文件夹中时,我无法让链接器找到新的 header(我将其命名为 wtypesx264.h
)。进行编辑后,我将使用新名称将其移回 /usr/include/w32api/
。
再说一次,我不想把 Win32 API 搞得一团糟,所以我不会编辑 windows.h
。这是副本,然后是编辑(我已在 vim
中完成,但您可以在任何您想要的编辑器中进行)。为了向您展示需要进行哪些更改,我展示了 BEFORE
版本 - 之前的 head
和 grep
- 以及即将推出的 AFTER
版本)。
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果你的不匹配,cd
进入适当的目录。
$ cp /usr/include/w32api/wtypes.h ./wtypes.h
$ vim wtypes.h
$ head -n 7 wtypes.h ### AFTER
/*** Edited from the version Autogenerated by WIDL 1.6 from include/wtypes.idl
* - Edited 2020-05-02 by bballdave025
***/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
$ cat -n wtypes.h | head -n 83 | tail -n 10 ### AFTER
74 byte data[1];
75 } RemHBRUSH;
76 typedef void *HMODULE;/*[A]Moved here from inside `#if 0` DWB 20200502*/
77 #if 0
78 typedef UINT_PTR WPARAM;
79 typedef LONG_PTR LPARAM;
80 typedef LONG_PTR LRESULT;
81 /*[A]Removed `typedef void *HMODULE;` from inside `#if 0` DWB 20200502*/
82 typedef void *HINSTANCE;
83 typedef void *HTASK;
现在,我们将 header 文件包含在需要的位置。再一次,我将展示之前和之后,以显示需要进行的编辑。
第一次编辑:./input/input.h
$ cat -n ./input/input.h | head -n 37 | tail -11 ### BEFORE
27
28 #ifndef X264_INPUT_H
29 #define X264_INPUT_H
30
31 #include "x264cli.h"
32
33 #ifdef _WIN32
34 #include <windows.h>
35 #endif
36
37 /* options that are used by only some demuxers */
$ vim ./input/input.h
$ cat -n ./input/input.h | head -n 39 | tail -13 ### AFTER
27
28 #ifndef X264_INPUT_H
29 #define X264_INPUT_H
30
31 #include "x264cli.h"
32
33 #ifdef _WIN32
34 #include <windows.h>
35 /*Next line added by bballdave025 2020-05-02*/
36 #include "wtypes.h"
37 #endif
38
39 /* options that are used by only some demuxers */
第二次(也是最后一次)编辑:./extras/avisynth_c.h
$ cat -n extras/avisynth_c.h | head -n 47 | tail -12 ### BEFORE
36
37 #ifndef __AVISYNTH_C__
38 #define __AVISYNTH_C__
39
40 #ifdef __cplusplus
41 # define EXTERN_C extern "C"
42 #else
43 # define EXTERN_C
44 #endif
45
46 #define AVSC_USE_STDCALL 1
47
$ vim extras/avisynth_c.h
$ cat -n extras/avisynth_c.h | head -n 53 | tail -18 ### AFTER
36
37 #ifndef __AVISYNTH_C__
38 #define __AVISYNTH_C__
39
40 #ifdef __cplusplus
41 # define EXTERN_C extern "C"
42 #else
43 # define EXTERN_C
44 #endif
45
46 /*Start of the part added by bballdave025 2020-05-02*/
47 #ifdef _WIN32
48 #include "wtypes.h"
49 #endif
50 /* End of the part added by bballdave025 2020-05-02*/
51
52 #define AVSC_USE_STDCALL 1
53
再试一次
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果你的不匹配,cd
进入适当的目录。
$ make clean # I won't show any of the output - there's a lot
$ make distclean # I won't show any of the output - there's a lot
让我们检查一下我们的更改是否通过了 distclean
$ ls wt*.h
wtypes.h
$ grep -RHn "[#]include \"wtypes.h\"" .
./extras/avisynth_c.h:48:#include "wtypes.h"
./input/input.h:36:#include "wtypes.h"
运行 ./configure
脚本;这很快,所以我不用担心使用多个处理器。
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" \
./configure --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
--bindir="$HOME/programs/ffmpeg/bin" \
--enable-static ### I won't show output
这是我们的测试,看看它是否有效 - 让我们 运行 make
,使用我们所有的处理器。
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)
输出有一些警告,但没有错误。我不想回去确保一切都达到完美-C
标准,所以我要继续安装部分。
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果你的不匹配,cd
进入适当的目录。
$ make install ### I won't show output
$ make distclean ### I won't show output.
现在,我们将使用 ~/.bashrc
将可执行文件添加到我们的 PATH
,但我们会先备份,并确保我们知道备份名称以备不时之需快速修复。
备份
$ date && date +'%s'
Sun, May 3, 2020 3:07:48 PM
1588540068
$ cp ~/.bashrc ~/.bashrc.$(date +'%s').bak
$ echo "$PATH" > ~/.PATH.$(date +'%s').bak
$ find ~ -mindepth 1 -maxdepth 1 -type f -name ".bashrc*.bak" | sort | tail -1
/home/13852/.bashrc.1588540100.bak
$ find ~ -mindepth 1 -maxdepth 1 -type f -name ".PATH*.bak" | sort | tail -1
/home/13852/.PATH.1588540128.bak
实际变化
$ echo -e "\n## Make x264 available\nexport PATH=\"/home/bballdave025/programs/ffmpeg/bin:"'$PATH'"\"\n\n" >> ~/.bashrc
$ source ~/.bashrc
测试预期输出
二三礼high-jump视频。 (我不认为我可以上传它,在这里,所以试试你自己的视频)。
$ # TEST 1
$ x264 --help | head -n 14
x264 core:157
Syntax: x264 [options] -o outfile infile
Infile can be raw (in which case resolution is required),
or YUV4MPEG (*.y4m),
or Avisynth if compiled with support (no).
or libav* formats if compiled with lavf support (no) or ffms support (no).
Outfile type is selected by filename:
.264 -> Raw bytestream
.mkv -> Matroska
.flv -> Flash Video
.mp4 -> MP4 if compiled with GPAC or L-SMASH support (no)
Output bit depth: 8/10
$ ## That works, but it seems strange that there's no Avisynth after all
$ ## that trouble
$ # TEST 2
$ bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop
$ x264 --input-res 480x360 --preset placebo --tune psnr -o highjump2.mkv FOSBUR-Dick_1968_Olympics_Mexico_City.mkv
raw [info]: 480x360p 0:0 @ 25/1 fps (cfr)
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AX2
x264 [info]: profile Progressive High, level 3.1, 4:2:0, 8-bit
x264 [info]: frame I:1 Avg QP:28.40 size:147888
x264 [info]: frame P:1 Avg QP:29.52 size:137810
x264 [info]: mb I I16..4: 0.0% 0.0% 100.0%
x264 [info]: mb P I16..4: 95.7% 0.0% 4.3% P16..4: 0.0% 0.0% 0.0% 0.0% .0% skip: 0.0%
x264 [info]: 8x8 transform intra:0.0%
x264 [info]: coded y,uvDC,uvAC intra: 98.8% 100.0% 100.0%
x264 [info]: i16 v,h,dc,p: 0% 0% 90% 10%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 6% 3% 37% 9% 10% 7% 10% 8% 10%
x264 [info]: i8c dc,h,v,p: 91% 0% 0% 8%
x264 [info]: Weighted P-Frames: Y:100.0% UV:100.0%
x264 [info]: kb/s:28569.80
encoded 2 frames, 3.83 fps, 28639.30 kb/s
bballdave025@MY-COMPUTER /cygdrive/c/Users/bballdave025/Desktop
$
我们得到了输出视频。它看起来不像视频,但我预计质量会下降很多。
因为我想将它用于 FFMPEG 的 Cygwin 构建,所以我认为我在正确的轨道上。
我正在尝试在cygwin环境下用ffmpeg编译libx264
我遵循了 Koohiimaster's blog, FFMPEG compilation guide, SO post 1, SO post 2 几个来源的一些指示,但我总是停留在同一个步骤,即 libx264 编译(制作)过程。
如 FFMPEG 编译指南中所述,应遵循这些步骤以使 libx264 正常工作
cd ~/ffmpeg_sources
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" bindir="$HOME/bin" --enable-static --disable-opencl
PATH="$HOME/bin:$PATH" make
make install
但是当我输入此命令时 PATH="$HOME/bin:$PATH" make
编译器总是停止并出现以下错误:
In file included from input/avs.c:49:0:
./extras/avisynth_c.h:825:3: error: unknown type name ‘HMODULE’
HMODULE handle;
^
我想知道这是否是libx264源码的bug,但我尝试了几个较早的源码版本后,都出现了同样的错误。有什么想法可以解决这个问题吗?
信息
类型 HMODULE
在 WinDef.h
中声明。所以你没有包含这个 header。我认为通常 WinDef.h
包含在 windows.h
中。
备选方案 1:无 AVS
如果您不需要 avs 支持,您可以禁用它并查看它是否有效:
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" bindir="$HOME/bin" --enable-static --disable-opencl --disable-avs
实际上,这是一个不错的选择,只需检查一下,看看它是否能为您提供有关您的问题的更多信息。
备选方案 2:检查 windows.h
另一件事是检查配置中使用了哪个 windows.h
文件。
在 libx264 源代码中 input/input.h
包括 windows.h
。
input.h
本身随后被 avs.c
包含。 avs.c
之后还包括 extras/avisynth_c.h
。因此,总而言之,当编译器出现 HMODULE handle
行时,windows.h
应该已经被包含(其中 WinDef.h
应该被包含)。
所以你的 windows.h
文件不知何故 "wrong" 或者在预处理过程中确实出了问题。
在我的系统(Cygwin 2.9.0(0.318/5/3)/Windows 7 64-bit SP1)上,HMODULE 定义在 wtypes.h
中,不包含在 windows.h 或任何其他包含的文件。
编辑 windows.h(在 /usr/lib/w32api/windows.h)以添加 #include <wtypes.h>
对我有用(我在 #define _INC_WINDOWS
之后的行中添加了它)。
我还在配置命令中添加了 --extra-cflags="-I/usr/include/w32api/"
以及 --extra-ldflags="-L:/usr/local/lib/"
,尽管我不确定添加 ldflags 是否与此相关或 libfdk-aac
编辑:我从快照页面查看了自述文件。
$ wget -O - \
https://download.videolan.org/x264/snapshots/x264-snapshot-20191218-README.txt \
2>/dev/null
The snapshotting service is discontinued.
Please use https://code.videolan.org/videolan/x264/ to get the tarballs.
因此,我使用了新的存储库进行下载。
如果您使用了之前的说明,您可能想要清除之前的 x264
内容,如下所示
cd $HOME/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
make clean
make distclean
然后,如果你 运行 make install
为 x264
,你还需要执行以下操作
cd $HOME/programs/ffmpeg
find . -type f -name "*x264*" -print0 | \
xargs -I'{}' -0 \
bash -c 'orig="{}"; echo; echo "Attempting to remove:"; '\
'echo "${orig}"; echo " ... "; echo " ... as file ..."; '\
'[ -e "${orig}" ] && rm "${orig}" && '\
'echo " ... success" || '\
'echo " ... FAILURE";'; \
find . -type d -name "*x264*" -print0 | \
xargs -I'{}' -0 \
bash -c 'orig="{}"; echo; echo "Attempting to remove:"; '\
'echo "${orig}"; echo " ... "; echo " ... as directory ..."; '\
'[ -d "${orig}" ] && rm -rf "${orig}" && '\
'echo " ... success" || '\
'echo " ... FAILURE";';
第二个命令有一个更短但信息量更少的版本。它将尝试删除已删除目录中的文件,这可能需要更长的时间。我不确定检查它是否始终有效的最佳方法。
find . -name "*x265*" -print0 | \
xargs -I'{}' -0 \
bash -c 'orig="{}"; echo > tmpf; [ -e "${orig}" ] && rm "${orig}" 2>tmpf; '\
'grep -v "rm.*cannot.*remove.*directory" tmpf; rm tmpf; '\
'[ -d "${orig}" ] && rm -rf "${orig}";'
现在,我们继续用最新的方法来处理x264
。
cd $HOME/programs/ffmpeg/ffmpeg_sources
git clone https://code.videolan.org/videolan/x264.git
cd x264
从这里开始,我必须按照与快照页面中的 tarball 相同的步骤进行操作,即我只是重复以
开头的说明PATH="$HOME/programs/ffmpeg/bin:$PATH" \
./configure --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
--bindir="$HOME/programs/ffmpeg/bin" \
--enable-static`
包括 wtypes.h
修复。
我已经用 标记了这个位置++从哪里开始更新的下载++
我的系统略有不同。得益于@Missy 和@Jan 以及其他参考资料的提示,我能够让事情正常进行 - koohiimaster especially (since I want a Cygwin build), as well as this SuperUser answer for "How to compile the best version of FFmpeg for Windows"(Windows 构建 - 离我想要的更远)。
但是,有几件事完全不同,我将它们分享给可能处于我的情况的任何人。
系统详细信息
$ date && date +'%s'
Sat, May 2, 2020 2:41:12 PM
1588452072
$ uname -a
CYGWIN_NT-10.0 MY-MACHINE 3.1.4(0.340/5/3) 2020-02-19 08:49 x86_64 Cygwin
$ bash --version | head -n 1
GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin)
$ gcc --version | head -n 1
gcc (GCC) 9.3.0
$ g++ --version | head -n 1
g++ (GCC) 9.3.0
$ make --version | head -n 2
GNU Make 4.3
Built for x86_64-pc-cygwin
$ systeminfo | sed -n 's#^OS\ *##p'
Name: Microsoft Windows 10 Home
Version: 10.0.18363 N/A Build 18363
Manufacturer: Microsoft Corporation
Configuration: Standalone Workstation
Build Type: Multiprocessor Free
我的目录结构有点不同,但我希望足够接近,以便大家继续。
我的步骤和(错误)输出
mkdir -p ~/programs/ffmpeg
cd ~/programs/ffmpeg
mkdir bin && mkdir ffmpeg_sources && mkdir ffmpeg_build
cd ffmpeg_build
请注意,说明要求您使用以下命令下载和解压缩,
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
然而,这不是真实的 URL;他们要你从 https://download.videolan.org/x264/snapshots/
下载最新的 x264
版本。我也得到了 README
,因为它让我远离麻烦。
wget https://download.videolan.org/x264/snapshots/x264-snapshot-20191217-2245.tar.bz2 ## necessary
wget https://download.videolan.org/x264/snapshots/x264-snapshot-20191218-README.txt ## optional, but helpful
如果您在几个月左右看到这个答案,希望您在文件名末尾有一个不同的日期。为了在这个答案中保存一些 space,我使用 xjf
标志而不是 xjvf
- 我不想冗长。 untar
ing 之后,我将按照说明继续。
$ tar xjf x264-snapshot-20191217-2245.tar.bz2
$ cd x264-snapshot-20191217-2245
现在,我们已准备好构建。您应该在类似于以下的目录中(尽管您的日期可能不同)。
$HOME/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
++从哪里开始下载新版本++
cd $HOME/programs/ffmpeg/ffmpeg_sources
git clone https://code.videolan.org/videolan/x264.git
cd x264
(如果你下载的是较新的,你的目录应该是$HOME/programs/ffmpeg/ffmpeg_sources/x264
)
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" \
./configure --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
--bindir="$HOME/programs/ffmpeg/bin" \
--enable-static
##
抑制输出:关于配置的一些不错的信息。没有错误的东西。
You can run 'make' or 'make fprofiled' now.
下一个命令:
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)
##
抑制输出:一些好的输出 - 甚至没有任何警告。
In file included from input/avs.c:49:
./extras/avisynth_c.h:825:3: error: unknown type name ‘HMODULE’
825 | HMODULE handle;
##
抑制输出:修复此问题后我们将看不到一堆警告。
make: *** [Makefile:272: input/avs.o] Error 1
解决方案(以及如何实现)
感谢@Missy,我知道要寻找什么和做什么。
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果不匹配,cd
进入你需要的目录。
$ whereis w32api
w32api: /usr/lib/w32api /usr/include/w32api
grep -iIRHn "^typedef.*HMODULE[;]" /usr/include/w32api
/usr/include/w32api/wtypes.h:78:typedef void *HMODULE;
## For grep
## -i : ignore case
## -I : ignore binary files
## -R : recursive search
## -H : output the filename
## -n : output the line number
请注意,你们中的某些人可能拥有 mingw
版本或某些其他版本,例如
/usr/i686-pc-cygwin/sys-root/usr/include/w32api/
但如果我们想要构建 Cygwin,那将无济于事。您可能需要像@Missy 那样做一些事情
[add]
--extra-cflags="-I/usr/include/w32api/"
to the configure command, along with--extra-ldflags="-L:/usr/local/lib/"
不过,我不必那样做。
我们可以转到 ./input/input.h
和 ./extras/avisynth_c.h
(其中,对我来说 .
是 ~/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
)添加行以包含 wtypes.h
,但是,当我这样做时,它没有用。 header 文件有问题,我们需要先修复。我将通过传递 grep
命令进行一些探索,在找到行:-C 10
。我还将使用 cat -n
放入行号。该命令如下(请注意,由于行号,我在 grep
的正则表达式的开头不再有 ^
锚点)。
cat -n /usr/include/w32api/wtypes.h | grep -C 10 "typedef.*HMODULE[;]"
这使我能够找到问题并用更少的行向您展示。我们会在 (-B <n_lines>
) 之前放一些,在 (-A <n_lines>
) 之后放一些。
$ ### before
$ cat -n /usr/include/w32api/wtypes.h | grep -B 6 -A 2 "typedef.*HMODULE[;]"
72 byte data[1];
73 } RemHBRUSH;
74 #if 0
75 typedef UINT_PTR WPARAM;
76 typedef LONG_PTR LPARAM;
77 typedef LONG_PTR LRESULT;
78 typedef void *HMODULE;
79 typedef void *HINSTANCE;
80 typedef void *HTASK;
那 #if 0
将成为一个问题 - 它等同于说 if false
,所以它永远不会被评估或执行。 (如果您想一直看到 #endif
,请将 -A 49
与您的 grep
一起使用。
在我看来,最简单的解决方案是从 if
语句中取出 typedef void *HMODULE:
。我会注意文件评论的警告,
$ head -n 5 /usr/include/w32api/wtypes.h ### BEFORE
/*** Autogenerated by WIDL 1.6 from include/wtypes.idl - Do not edit ***/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
并且不编辑。我认为最好不要管 Win32 API。我会将 header 文件复制到我们的项目中。由于链接器查找 header 文件的方式,它将首先查找我们的 ffmpeg_sources/wtypes.h
。 (我尝试重命名它以避免可能的 namespace conlicts,但这没有用)。
好吧,当它在我们的项目文件夹中时,我无法让链接器找到新的 header(我将其命名为 wtypesx264.h
)。进行编辑后,我将使用新名称将其移回 /usr/include/w32api/
。
再说一次,我不想把 Win32 API 搞得一团糟,所以我不会编辑 windows.h
。这是副本,然后是编辑(我已在 vim
中完成,但您可以在任何您想要的编辑器中进行)。为了向您展示需要进行哪些更改,我展示了 BEFORE
版本 - 之前的 head
和 grep
- 以及即将推出的 AFTER
版本)。
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果你的不匹配,cd
进入适当的目录。
$ cp /usr/include/w32api/wtypes.h ./wtypes.h
$ vim wtypes.h
$ head -n 7 wtypes.h ### AFTER
/*** Edited from the version Autogenerated by WIDL 1.6 from include/wtypes.idl
* - Edited 2020-05-02 by bballdave025
***/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
$ cat -n wtypes.h | head -n 83 | tail -n 10 ### AFTER
74 byte data[1];
75 } RemHBRUSH;
76 typedef void *HMODULE;/*[A]Moved here from inside `#if 0` DWB 20200502*/
77 #if 0
78 typedef UINT_PTR WPARAM;
79 typedef LONG_PTR LPARAM;
80 typedef LONG_PTR LRESULT;
81 /*[A]Removed `typedef void *HMODULE;` from inside `#if 0` DWB 20200502*/
82 typedef void *HINSTANCE;
83 typedef void *HTASK;
现在,我们将 header 文件包含在需要的位置。再一次,我将展示之前和之后,以显示需要进行的编辑。
第一次编辑:./input/input.h
$ cat -n ./input/input.h | head -n 37 | tail -11 ### BEFORE
27
28 #ifndef X264_INPUT_H
29 #define X264_INPUT_H
30
31 #include "x264cli.h"
32
33 #ifdef _WIN32
34 #include <windows.h>
35 #endif
36
37 /* options that are used by only some demuxers */
$ vim ./input/input.h
$ cat -n ./input/input.h | head -n 39 | tail -13 ### AFTER
27
28 #ifndef X264_INPUT_H
29 #define X264_INPUT_H
30
31 #include "x264cli.h"
32
33 #ifdef _WIN32
34 #include <windows.h>
35 /*Next line added by bballdave025 2020-05-02*/
36 #include "wtypes.h"
37 #endif
38
39 /* options that are used by only some demuxers */
第二次(也是最后一次)编辑:./extras/avisynth_c.h
$ cat -n extras/avisynth_c.h | head -n 47 | tail -12 ### BEFORE
36
37 #ifndef __AVISYNTH_C__
38 #define __AVISYNTH_C__
39
40 #ifdef __cplusplus
41 # define EXTERN_C extern "C"
42 #else
43 # define EXTERN_C
44 #endif
45
46 #define AVSC_USE_STDCALL 1
47
$ vim extras/avisynth_c.h
$ cat -n extras/avisynth_c.h | head -n 53 | tail -18 ### AFTER
36
37 #ifndef __AVISYNTH_C__
38 #define __AVISYNTH_C__
39
40 #ifdef __cplusplus
41 # define EXTERN_C extern "C"
42 #else
43 # define EXTERN_C
44 #endif
45
46 /*Start of the part added by bballdave025 2020-05-02*/
47 #ifdef _WIN32
48 #include "wtypes.h"
49 #endif
50 /* End of the part added by bballdave025 2020-05-02*/
51
52 #define AVSC_USE_STDCALL 1
53
再试一次
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果你的不匹配,cd
进入适当的目录。
$ make clean # I won't show any of the output - there's a lot
$ make distclean # I won't show any of the output - there's a lot
让我们检查一下我们的更改是否通过了 distclean
$ ls wt*.h
wtypes.h
$ grep -RHn "[#]include \"wtypes.h\"" .
./extras/avisynth_c.h:48:#include "wtypes.h"
./input/input.h:36:#include "wtypes.h"
运行 ./configure
脚本;这很快,所以我不用担心使用多个处理器。
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" \
./configure --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
--bindir="$HOME/programs/ffmpeg/bin" \
--enable-static ### I won't show output
这是我们的测试,看看它是否有效 - 让我们 运行 make
,使用我们所有的处理器。
$ PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)
输出有一些警告,但没有错误。我不想回去确保一切都达到完美-C
标准,所以我要继续安装部分。
根据您使用的是旧快照还是新快照 git
,您当前的工作目录 (pwd
) 会有所不同。
$ pwd ### (older snapshot)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245
$ pwd ### (newer git stuff)
/home/bballdave025/programs/ffmpeg/ffmpeg_sources/x264
如果你的不匹配,cd
进入适当的目录。
$ make install ### I won't show output
$ make distclean ### I won't show output.
现在,我们将使用 ~/.bashrc
将可执行文件添加到我们的 PATH
,但我们会先备份,并确保我们知道备份名称以备不时之需快速修复。
备份
$ date && date +'%s'
Sun, May 3, 2020 3:07:48 PM
1588540068
$ cp ~/.bashrc ~/.bashrc.$(date +'%s').bak
$ echo "$PATH" > ~/.PATH.$(date +'%s').bak
$ find ~ -mindepth 1 -maxdepth 1 -type f -name ".bashrc*.bak" | sort | tail -1
/home/13852/.bashrc.1588540100.bak
$ find ~ -mindepth 1 -maxdepth 1 -type f -name ".PATH*.bak" | sort | tail -1
/home/13852/.PATH.1588540128.bak
实际变化
$ echo -e "\n## Make x264 available\nexport PATH=\"/home/bballdave025/programs/ffmpeg/bin:"'$PATH'"\"\n\n" >> ~/.bashrc
$ source ~/.bashrc
测试预期输出
二三礼high-jump视频。 (我不认为我可以上传它,在这里,所以试试你自己的视频)。
$ # TEST 1
$ x264 --help | head -n 14
x264 core:157
Syntax: x264 [options] -o outfile infile
Infile can be raw (in which case resolution is required),
or YUV4MPEG (*.y4m),
or Avisynth if compiled with support (no).
or libav* formats if compiled with lavf support (no) or ffms support (no).
Outfile type is selected by filename:
.264 -> Raw bytestream
.mkv -> Matroska
.flv -> Flash Video
.mp4 -> MP4 if compiled with GPAC or L-SMASH support (no)
Output bit depth: 8/10
$ ## That works, but it seems strange that there's no Avisynth after all
$ ## that trouble
$ # TEST 2
$ bballdave025@MY-MACHINE /cygdrive/c/Users/bballdave025/Desktop
$ x264 --input-res 480x360 --preset placebo --tune psnr -o highjump2.mkv FOSBUR-Dick_1968_Olympics_Mexico_City.mkv
raw [info]: 480x360p 0:0 @ 25/1 fps (cfr)
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AX2
x264 [info]: profile Progressive High, level 3.1, 4:2:0, 8-bit
x264 [info]: frame I:1 Avg QP:28.40 size:147888
x264 [info]: frame P:1 Avg QP:29.52 size:137810
x264 [info]: mb I I16..4: 0.0% 0.0% 100.0%
x264 [info]: mb P I16..4: 95.7% 0.0% 4.3% P16..4: 0.0% 0.0% 0.0% 0.0% .0% skip: 0.0%
x264 [info]: 8x8 transform intra:0.0%
x264 [info]: coded y,uvDC,uvAC intra: 98.8% 100.0% 100.0%
x264 [info]: i16 v,h,dc,p: 0% 0% 90% 10%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 6% 3% 37% 9% 10% 7% 10% 8% 10%
x264 [info]: i8c dc,h,v,p: 91% 0% 0% 8%
x264 [info]: Weighted P-Frames: Y:100.0% UV:100.0%
x264 [info]: kb/s:28569.80
encoded 2 frames, 3.83 fps, 28639.30 kb/s
bballdave025@MY-COMPUTER /cygdrive/c/Users/bballdave025/Desktop
$
我们得到了输出视频。它看起来不像视频,但我预计质量会下降很多。
因为我想将它用于 FFMPEG 的 Cygwin 构建,所以我认为我在正确的轨道上。