# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python from cerbero.tools.libtool import LibtoolLibrary class Recipe(recipe.Recipe): name = 'ffmpeg' version = '4.1.1' licenses = [License.LGPLv2_1Plus] stype = SourceType.TARBALL url = 'https://ffmpeg.org/releases/%(name)s-%(version)s.tar.bz2' tarball_checksum = '0cb40e3b8acaccd0ecb38aa863f66f0c6e02406246556c2992f67bf650fab058' btype = BuildType.MAKEFILE configure_tpl = './configure --prefix=%(prefix)s --libdir=%(libdir)s \ --ar="$AR" --as="$CC" --cc="$CC" --ld="$CC" --nm="$NM" --ranlib="$RANLIB" \ --strip="$STRIP" --enable-static --enable-pic --enable-shared \ --disable-avdevice --disable-postproc --disable-swscale \ --disable-programs --disable-ffplay --disable-ffprobe --disable-ffmpeg \ --disable-encoder=flac --disable-protocols --disable-devices \ --disable-network --disable-hwaccels --disable-dxva2 --disable-vdpau \ --disable-filters --enable-filter=yadif --disable-doc --disable-d3d11va \ --disable-audiotoolbox --disable-videotoolbox --disable-vaapi --disable-crystalhd \ --disable-mediacodec --disable-nvenc --disable-mmal --disable-omx \ --disable-omx-rpi --disable-cuda --disable-cuvid --disable-libmfx \ --disable-libnpp --disable-iconv --disable-jni --disable-v4l2_m2m \ --enable-optimizations --disable-nonfree --disable-version3 %(options)s' deps = ['bzip2', 'zlib'] files_libs = ['libavcodec', 'libavformat', 'libavutil', 'libswresample', 'libavfilter'] files_devel = [] def prepare(self): # Populate self.files_devel files_devel_tpl = ['lib/{}.la', 'lib/pkgconfig/{}.pc', 'include/{}'] # ffmpeg can only build either shared or static on Windows, not both if self.config.target_platform != Platform.WINDOWS: files_devel_tpl += ['lib/{}.a'] for lib in self.files_libs: self.files_devel += [tpl.format(lib) for tpl in files_devel_tpl] # Default AS is $CC, except iOS (set below) if Architecture.is_arm(self.config.target_arch): if self.config.target_platform == Platform.IOS: if 'GAS' in os.environ: self.set_env('AS', os.environ['GAS']) else: self.set_env('AS', os.environ['CC']) libavextraconf = '' # Arch-specific flags if self.config.target_platform == Platform.ANDROID: if self.config.target_arch == Architecture.X86: # libav internally aligns stacks, while Android doesn't libavextraconf += " --extra-cflags='-mstackrealign'" elif self.config.target_arch in [Architecture.ARM, Architecture.ARMv7]: # Fails to link into an android App # https://github.com/android-ndk/ndk/issues/337 libavextraconf += " --disable-neon" if self.config.target_arch in [Architecture.X86]: # Fails to link into an android app with relocation warnings # in the custom assembly # https://stackoverflow.com/questions/34691970/ffmpeg-for-android-neon-build-has-text-relocations/34697703#34697703 # https://issuetracker.google.com/issues/37067983 # https://trac.ffmpeg.org/ticket/4928 libavextraconf += " --disable-asm" elif self.config.target_platform == Platform.IOS: # Some optimisations that were previously silently disabled # cause warnings now. Ignore them libavextraconf += " --extra-cflags='-Wno-ignored-optimization-argument' " if self.config.target_arch == Architecture.X86: # Fails to link in gst-libav due to text relocations in # custom assembly: # ld: illegal text-relocation to 'anon' in libavfilter.a(vf_yadif.o) # from '_ff_yadif_filter_line_ssse3' in libavfilter.a(vf_yadif.o) # for architecture i386 libavextraconf += ' --disable-asm ' if self.config.cross_compiling(): libavextraconf += ' --enable-cross-compile' target_os = self.config.target_platform if target_os == 'windows': target_os = 'mingw32' elif target_os == 'ios': target_os = 'darwin' target_arch = self.config.host.split('-', 1)[0] libavextraconf += ' --target-os=' + target_os libavextraconf += ' --arch=' + target_arch libavextraconf += ' --cross-prefix={}- '.format(self.config.host) self.configure_options += libavextraconf # On Windows, make fails if V=1 is passed with: # `couldn't commit memory for cygwin heap, Win32 error 0` if self.config.platform == Platform.WINDOWS: self.make = 'make ' def configure(self): super(recipe.Recipe, self).configure() libav_path = self.build_dir if self.config.target_platform == Platform.WINDOWS: # XXX: --windres option doesn't exist, despite --help listing it replacements = {'WINDRES=windres': 'WINDRES=' + os.environ['WINDRES'], 'DLLTOOL=dlltool': 'DLLTOOL=' + os.environ['DLLTOOL']} shell.replace(os.path.join(libav_path, 'ffbuild', 'config.mak'), replacements) elif self.config.target_platform in [Platform.DARWIN, Platform.IOS]: if self.config.target_arch == Architecture.X86: replacements = {'HAVE_EBX_AVAILABLE=yes': 'HAVE_EBX_AVAILABLE=no', 'HAVE_EBX_AVAILABLE 1': 'HAVE_EBX_AVAILABLE 0',} shell.replace(os.path.join(libav_path, 'ffbuild', 'config.mak'), replacements) shell.replace(os.path.join(libav_path, 'config.h'), replacements) # log2 and log2f are not provided by bionic, but they are not checked # properly elif self.config.target_platform == Platform.ANDROID: replacements = {'HAVE_LOG2 1': 'HAVE_LOG2 0', 'HAVE_LOG2F 1': 'HAVE_LOG2F 0',} shell.replace(os.path.join(libav_path, 'config.h'), replacements) v = DistroVersion.get_android_api_version(self.config.target_distro_version) if self.config.target_arch in [Architecture.ARM, Architecture.ARMv7, Architecture.X86] and v < 21: replacements = {'-D_FILE_OFFSET_BITS=64': '',} shell.replace(os.path.join(libav_path, 'ffbuild', 'config.mak'), replacements) def post_install(self): LibtoolLibrary('avutil', None, None, None, self.config.libdir, self.config.target_platform).save() LibtoolLibrary('swresample', None, None, None, self.config.libdir, self.config.target_platform, deps=['avutil']).save() LibtoolLibrary('avcodec', None, None, None, self.config.libdir, self.config.target_platform, deps=['swresample', 'avutil', 'z']).save() LibtoolLibrary('avformat', None, None, None, self.config.libdir, self.config.target_platform, deps=['avcodec', 'swresample', 'avutil', 'bz2', 'z']).save() LibtoolLibrary('avfilter', None, None, None, self.config.libdir, self.config.target_platform, deps=['avformat', 'avcodec', 'swresample', 'avutil']).save() super().post_install()