cygwin上的FFMPEG无法编译libx264错误:未知类型名称'HMODULE'

时间:2017-07-19 04:39:18

标签: ffmpeg cygwin libx264

我正在尝试在cygwin环境下的ffmpeg中编译libx264。

我已经从Koohiimaster's blogFFMPEG compilation guideSO post 1SO post 2的几个来源中遵循了一些指示,但我始终坚持与libx264编译相同的步骤(make过程。

如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,但是在我尝试了几个早期的源代码之后,它产生了同样的错误。有什么想法解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

信息

类型Length is 6 HMODULE中声明。所以你错过了包含这个标题。我认为WinDef.h通常包含WinDef.h

备选方案1:没有AVS

如果您不需要avs支持,您可能只是禁用它,然后查看它是否有效:

windows.h

实际上,这是一个很好的选择,只需检查一下,看看它是否能为您提供有关您问题的更多信息。

备选方案2:检查windows.h

另一件事是检查配置中使用了哪个PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" bindir="$HOME/bin" --enable-static --disable-opencl --disable-avs 文件。

在libx264中,来源windows.h包括input/input.h

windows.h本身随后包含在input.h中。此后avs.c还包括avs.c。总而言之,当编译器出现extras/avisynth_c.h行时,HMODULE handle应该已经包含在内(应该包含windows.h)。

所以你的WinDef.h文件不知何故"错误"或者在预处理过程中出现了什么问题。

答案 1 :(得分:1)

在我的系统上(Cygwin 2.9.0(0.318 / 5/3)/ Windows 7 64位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

答案 2 :(得分:1)

编辑:我从快照页面查看了自述文件。

$ 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(因为我想要构建Cygwin),以及this SuperUser answer的“如何编译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,因为它使我免于麻烦。

Showing the latest versions of X 264 from the website

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

希望,如果您在几个月左右的时间内看到此答案,则文件名末尾会有一个不同的日期。为了在此答案中节省一些空间,我使用xjf标志而不是xjvf-我不想冗长。 untar处理完后,我将按照说明继续操作。

$ 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和

的操作

[添加] --extra-cflags="-I/usr/include/w32api/"--extra-ldflags="-L:/usr/local/lib/"

但是我不必这样做。

我们可以转到./input/input.h./extras/avisynth_c.h(其中.对我来说是~/programs/ffmpeg/ffmpeg_sources/x264-snapshot-20191217-2245)来添加包含wtypes.h的行,但是当我做到了,那没有用。该头文件存在问题,我们需要首先修复该问题。我将通过传递grep命令来进行一些探索,该命令将在找到的行之前和之后给出十行( 10 )的 C 文本: }}。我还将在行号中加上-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)。

在我看来,最简单的解决方案是将greptypedef void *HMODULE:语句中删除。我会留意文件注释的警告,

if

,而不进行编辑。我认为最好不要理会Win32 API。我将头文件复制到我们的项目中。由于链接器查找头文件的方式,它将首先查找我们的$ 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 。 (我尝试重命名它以避免可能的名称空间冲突,但这没有用)。

好吧,当它位于我们的项目文件夹中时,我无法使链接器找到新的标头(我将其命名为ffmpeg_sources/wtypes.h)。进行修改后,我将其重新命名为wtypesx264.h

再一次,我不想惹Win32 API,所以我不会编辑/usr/include/w32api/。这是副本,然后是编辑(我在windows.h中完成了该操作,但是您可以在所需的任何编辑器中执行此操作)。为了向您展示需要进行哪些更改,我展示了vim版本-之前的BEFOREhead-版本和即将发布的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;

./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. 将可执行文件添加到PATH中,但是首先要备份内容,并确保我们知道备份名称,以防需要创建文件名。快速修复。

备份

~/.bashrc

实际变化

$ 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
$ # 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

我们得到了一个输出视频。它看起来几乎不像视频,但我希望质量会下降。

由于我想将其用于FFMPEG的Cygwin构建,因此我认为自己的方向正确。