gecko/media/libvpx/update.py
Ralph Giles cfce978887 Bug 960840 - Don't disable avx2 when updating libvpx. r=cpearce DONTBUILD
Jan reminded me we reset this in update.py, so we need to remove
the lines here as well as enabling avx2 in the linux builds as
we did in bug 946639.
2014-01-16 17:49:32 -08:00

532 lines
16 KiB
Python
Executable File

#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import argparse
import os
import re
import shutil
import sys
import subprocess
from pprint import pprint
from StringIO import StringIO
PLATFORMS= [
'x86-win32-vs8',
'x86_64-win64-vs8',
'x86-linux-gcc',
'x86_64-linux-gcc',
'generic-gnu',
'x86-darwin9-gcc',
'x86_64-darwin9-gcc',
'armv7-android-gcc',
]
mk_files = [
'vp8/vp8_common.mk',
'vp8/vp8cx_arm.mk',
'vp8/vp8cx.mk',
'vp8/vp8dx.mk',
'vp9/vp9_common.mk',
'vp9/vp9cx.mk',
'vp9/vp9dx.mk',
'vpx_mem/vpx_mem.mk',
'vpx_ports/vpx_ports.mk',
'vpx_scale/vpx_scale.mk',
'vpx/vpx_codec.mk',
]
extensions = ['.asm', '.c', '.h']
MODULES = {
'UNIFIED_SOURCES': [
'API_DOC_SRCS-$(CONFIG_VP8_DECODER)',
'API_DOC_SRCS-yes',
'API_EXPORTS',
'API_SRCS-$(CONFIG_VP8_DECODER)',
'API_SRCS-yes',
'MEM_SRCS-yes',
'PORTS_SRCS-yes',
'SCALE_SRCS-$(CONFIG_SPATIAL_RESAMPLING)',
'SCALE_SRCS-no',
'SCALE_SRCS-yes',
'VP8_COMMON_SRCS-yes',
'VP8_DX_EXPORTS',
'VP8_DX_SRCS-$(CONFIG_MULTITHREAD)',
'VP8_DX_SRCS-no',
'VP8_DX_SRCS_REMOVE-no',
'VP8_DX_SRCS_REMOVE-yes',
'VP8_DX_SRCS-yes',
'VP9_COMMON_SRCS-yes',
'VP9_DX_EXPORTS',
'VP9_DX_SRCS-no',
'VP9_DX_SRCS_REMOVE-no',
'VP9_DX_SRCS_REMOVE-yes',
'VP9_DX_SRCS-yes',
'API_DOC_SRCS-$(CONFIG_VP8_ENCODER)',
'API_SRCS-$(BUILD_LIBVPX)',
'API_SRCS-$(CONFIG_VP8_ENCODER)',
'API_SRCS-$(CONFIG_VP9_ENCODER)',
'VP8_CX_EXPORTS',
'VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING)',
'VP8_CX_SRCS-$(CONFIG_MULTITHREAD)',
'VP8_CX_SRCS-$(CONFIG_TEMPORAL_DENOISING)',
'VP8_CX_SRCS-no',
'VP8_CX_SRCS_REMOVE-no',
'VP8_CX_SRCS_REMOVE-yes',
'VP8_CX_SRCS-yes',
'VP9_CX_EXPORTS',
'VP9_CX_SRCS-no',
'VP9_CX_SRCS_REMOVE-no',
'VP9_CX_SRCS_REMOVE-yes',
'VP9_CX_SRCS-yes',
],
'X86_ASM': [
'PORTS_SRCS-$(BUILD_LIBVPX)',
'VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
'VP8_COMMON_SRCS-$(HAVE_MMX)',
'VP8_COMMON_SRCS-$(HAVE_SSE2)',
'VP8_COMMON_SRCS-$(HAVE_SSE3)',
'VP8_COMMON_SRCS-$(HAVE_SSE4_1)',
'VP8_COMMON_SRCS-$(HAVE_SSSE3)',
'VP9_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
'VP9_COMMON_SRCS-$(HAVE_MMX)',
'VP9_COMMON_SRCS-$(HAVE_SSE2)',
'VP9_COMMON_SRCS-$(HAVE_SSSE3)',
'VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
'VP8_CX_SRCS-$(HAVE_MMX)',
'VP8_CX_SRCS-$(HAVE_SSE2)',
'VP8_CX_SRCS-$(HAVE_SSE4_1)',
'VP8_CX_SRCS-$(HAVE_SSSE3)',
'VP8_CX_SRCS_REMOVE-$(HAVE_SSE2)',
'VP9_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
'VP9_CX_SRCS-$(HAVE_MMX)',
'VP9_CX_SRCS-$(HAVE_SSE2)',
'VP9_CX_SRCS-$(HAVE_SSE3)',
'VP9_CX_SRCS-$(HAVE_SSE4_1)',
'VP9_CX_SRCS-$(HAVE_SSSE3)',
],
'X86-64_ASM': [
'VP8_CX_SRCS-$(ARCH_X86_64)',
'VP9_CX_SRCS-$(ARCH_X86_64)',
],
'ARM_ASM': [
'PORTS_SRCS-$(ARCH_ARM)',
'SCALE_SRCS-$(HAVE_NEON)',
'VP8_COMMON_SRCS-$(ARCH_ARM)',
'VP8_COMMON_SRCS-$(HAVE_MEDIA)',
'VP8_COMMON_SRCS-$(HAVE_NEON)',
'VP9_COMMON_SRCS-$(HAVE_NEON)',
'VP8_CX_SRCS-$(ARCH_ARM)',
'VP8_CX_SRCS-$(HAVE_EDSP)',
'VP8_CX_SRCS-$(HAVE_MEDIA)',
'VP8_CX_SRCS-$(HAVE_NEON)',
],
'ERROR_CONCEALMENT': [
'VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT)',
],
'AVX2': [
'VP9_COMMON_SRCS-$(HAVE_AVX2)',
],
'VP8_POSTPROC': [
'VP8_COMMON_SRCS-$(CONFIG_POSTPROC)',
],
'VP9_POSTPROC': [
'VP9_COMMON_SRCS-$(CONFIG_VP9_POSTPROC)',
]
}
DISABLED_MODULES = [
'MEM_SRCS-$(CONFIG_MEM_MANAGER)',
'MEM_SRCS-$(CONFIG_MEM_TRACKER)',
'VP8_COMMON_SRCS-$(CONFIG_POSTPROC_VISUALIZER)',
'VP9_COMMON_SRCS-$(CONFIG_POSTPROC_VISUALIZER)',
'VP8_CX_SRCS-$(CONFIG_INTERNAL_STATS)',
'VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS)',
# mips files are also ignored via ignored_folders
'SCALE_SRCS-$(HAVE_DSPR2)',
'VP8_COMMON_SRCS-$(HAVE_DSPR2)',
'VP9_COMMON_SRCS-$(HAVE_DSPR2)',
'VP8_CX_SRCS_REMOVE-$(HAVE_EDSP)',
]
libvpx_files = [
'build/make/obj_int_extract.c',
'build/make/ads2gas.pl',
'build/make/thumb.pm',
'LICENSE',
'PATENTS',
]
ignore_files = [
'vp8/common/context.c',
'vp8/common/textblit.c',
'vp8/encoder/ssim.c',
'vp8/encoder/x86/ssim_opt.asm',
'vp9/common/vp9_textblit.c',
'vp9/common/vp9_textblit.h',
'vp9/encoder/vp9_ssim.c',
'vp9/encoder/x86/vp9_ssim_opt.asm',
'vpx_mem/vpx_mem_tracker.c',
'vpx_scale/generic/bicubic_scaler.c',
'vpx_scale/win32/scaleopt.c',
'vpx_scale/win32/scalesystemdependent.c',
]
ignore_folders = [
'examples/',
'googletest/',
'libmkv/',
'libyuv/',
'mips/',
'nestegg/',
'objdir/',
'ppc/',
'test/',
'vpx_mem/memory_manager/',
]
files = {
'EXPORTS': [
'vpx_mem/include/vpx_mem_intrnl.h',
'vpx_mem/vpx_mem.h',
'vpx_ports/arm.h',
'vpx_ports/mem.h',
'vpx_ports/vpx_timer.h',
'vpx_ports/x86.h',
'vpx_scale/vpx_scale.h',
'vpx_scale/yv12config.h',
'vpx/vp8cx.h',
'vpx/vp8dx.h',
'vpx/vp8.h',
'vpx/vpx_codec.h',
'vpx/vpx_decoder.h',
'vpx/vpx_encoder.h',
'vpx/vpx_image.h',
'vpx/vpx_integer.h',
],
'X86-64_ASM': [
'third_party/x86inc/x86inc.asm',
'vp8/common/x86/loopfilter_block_sse2.asm',
'vp9/encoder/x86/vp9_quantize_ssse3.asm',
],
'SOURCES': [
'vp8/common/rtcd.c',
'vp8/common/sad_c.c',
'vp8/vp8_dx_iface.c',
'vp9/common/vp9_entropymv.c',
'vp9/common/vp9_rtcd.c',
'vp9/encoder/vp9_bitstream.c',
'vpx/src/svc_encodeframe.c',
'vpx_mem/vpx_mem.c',
]
}
manual = [
# special case in moz.build
'vp8/encoder/boolhuff.c',
# 64bit only
'vp8/common/x86/loopfilter_block_sse2.asm',
'vp9/encoder/x86/vp9_quantize_ssse3.asm',
# offsets are special cased in Makefile.in
'vp8/encoder/vp8_asm_enc_offsets.c',
'vpx_scale/vpx_scale_asm_offsets.c',
# ignore while vp9 postproc is not enabled
'vp9/common/x86/vp9_postproc_mmx.asm',
'vp9/common/x86/vp9_postproc_sse2.asm',
# ssim_opt is not enabled
'vp8/encoder/x86/ssim_opt.asm',
'vp9/encoder/x86/vp9_ssim_opt.asm',
# asm includes
'vpx_ports/x86_abi_support.asm',
]
platform_files = [
'vp8_rtcd.h',
'vp9_rtcd.h',
'vpx_config.asm',
'vpx_config.h',
'vpx_scale_rtcd.h',
]
def prepare_upstream(prefix, commit=None):
if os.path.exists(prefix):
print "Please remove '%s' folder before running %s" % (prefix, sys.argv[0])
sys.exit(1)
upstream_url = 'https://gerrit.chromium.org/gerrit/webm/libvpx'
subprocess.call(['git', 'clone', upstream_url, prefix])
if commit:
os.chdir(prefix)
subprocess.call(['git', 'checkout', commit])
else:
os.chdir(prefix)
p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
commit = stdout.strip()
for target in PLATFORMS:
target_objdir = os.path.join(prefix, 'objdir', target)
os.makedirs(target_objdir)
os.chdir(target_objdir)
configure = ['../../configure', '--target=%s' % target,
'--disable-examples', '--disable-install-docs',
'--enable-multi-res-encoding',
]
if 'darwin9' in target:
configure += ['--enable-pic']
if 'linux' in target:
configure += ['--enable-pic']
# x86inc.asm is not compatible with pic 32bit builds
if target == 'x86-linux-gcc':
configure += ['--disable-use-x86inc']
if target == 'armv7-android-gcc':
configure += ['--sdk-path=%s' % ndk_path]
subprocess.call(configure)
make_targets = [f for f in platform_files if not os.path.exists(f)]
if make_targets:
subprocess.call(['make'] + make_targets)
for f in make_targets:
if not os.path.exists(f):
print "%s missing from %s, check toolchain" % (f, target)
sys.exit(1)
os.chdir(base)
return commit
def cleanup_upstream():
shutil.rmtree(os.path.join(base, 'upstream'))
def get_module(key):
for module in MODULES:
if key in MODULES[module]:
return module
def get_libvpx_files(prefix):
for root, folders, files in os.walk(prefix):
for f in files:
f = os.path.join(root, f)[len(prefix):]
if os.path.splitext(f)[-1] in extensions \
and os.sep in f \
and f not in ignore_files \
and not any(folder in f for folder in ignore_folders):
libvpx_files.append(f)
return libvpx_files
def get_sources(prefix):
source = {}
unknown = {}
disabled = {}
for mk in mk_files:
with open(os.path.join(prefix, mk)) as f:
base = os.path.dirname(mk)
for l in f:
if '+=' in l:
l = l.split('+=')
key = l[0].strip()
value = l[1].strip().replace('$(ASM)', '.asm')
value = os.path.join(base, value)
if not key.startswith('#') and os.path.splitext(value)[-1] in extensions:
if key not in source:
source[key] = []
source[key].append(value)
for key in source:
for f in source[key]:
if key.endswith('EXPORTS') and f.endswith('.h'):
files['EXPORTS'].append(f)
if os.path.splitext(f)[-1] in ('.c', '.asm') and not f in manual:
module = get_module(key)
if module:
if not module in files:
files[module] = []
t = files[module]
elif key in DISABLED_MODULES:
if not key in disabled:
disabled[key] = []
t = disabled[key]
else:
if not key in unknown:
unknown[key] = []
t = unknown[key]
t.append(f)
files['UNIFIED_SOURCES'] = [f for f in files['UNIFIED_SOURCES'] if f not in files['SOURCES']]
for key in files:
files[key] = list(sorted(set(files[key])))
return source, files, disabled, unknown
def update_sources_mozbuild(files, sources_mozbuild):
f = StringIO()
pprint(files, stream=f)
sources_mozbuild_new = "files = {\n %s\n}\n" % f.getvalue().strip()[1:-1]
if sources_mozbuild != sources_mozbuild_new:
print 'updating sources.mozbuild'
with open('sources.mozbuild', 'w') as f:
f.write(sources_mozbuild_new)
def get_current_files():
current_files = []
for root, folders, files in os.walk('.'):
for f in files:
f = os.path.join(root, f)[len('.%s'%os.sep):]
if 'upstream%s'%os.sep in f or not os.sep in f:
continue
if os.path.splitext(f)[-1] in extensions:
current_files.append(f)
return current_files
def is_new(a, b):
return not os.path.exists(a) \
or not os.path.exists(b) \
or open(a).read() != open(b).read()
def get_sources_mozbuild():
with open('sources.mozbuild') as f:
sources_mozbuild = f.read()
exec(sources_mozbuild)
return sources_mozbuild, files
def update_and_remove_files(prefix, libvpx_files, files):
current_files = get_current_files()
def copy(src, dst):
print ' ', dst
shutil.copy(src, dst)
# Update files
first = True
for f in libvpx_files:
fdir = os.path.dirname(f)
if fdir and not os.path.exists(fdir):
os.makedirs(fdir)
s = os.path.join(prefix, f)
if is_new(f, s):
if first:
print "Copy files:"
first = False
copy(s, f)
# Copy configuration files for each platform
for target in PLATFORMS:
first = True
for f in platform_files:
t = os.path.splitext(f)
t = '%s_%s%s' % (t[0], target, t[1])
f = os.path.join(prefix, 'objdir', target, f)
if is_new(f, t):
if first:
print "Copy files for %s:" % target
first = False
copy(f, t)
# Copy vpx_version.h from one of the build targets
s = os.path.join(prefix, 'objdir/x86-linux-gcc/vpx_version.h')
f = 'vpx_version.h'
if is_new(s, f):
copy(s, f)
# Remove unknown files from tree
removed_files = [f for f in current_files if f not in libvpx_files]
if removed_files:
print "Remove files:"
for f in removed_files:
os.unlink(f)
print ' ', f
def apply_patches():
# Patch to permit vpx users to specify their own <stdint.h> types.
os.system("patch -p3 < stdint.patch")
os.system("patch -p3 < unified.patch")
def update_readme(commit):
with open('README_MOZILLA') as f:
readme = f.read()
if 'The git commit ID used was' in readme:
new_readme = re.sub('The git commit ID used was [a-f0-9]+',
'The git commit ID used was %s' % commit, readme)
else:
new_readme = "%s\n\nThe git commit ID used was %s\n" % (readme, commit)
if readme != new_readme:
with open('README_MOZILLA', 'w') as f:
f.write(new_readme)
def print_info(source, files, disabled, unknown, moz_build_files):
for key in moz_build_files:
if key not in files:
print key, 'MISSING'
else:
gone = set(moz_build_files[key]) - set(files[key])
new = set(files[key]) - set(moz_build_files[key])
if gone:
print key, 'GONE:'
print ' '+ '\n '.join(gone)
if new:
print key, 'NEW:'
print ' '+ '\n '.join(new)
if unknown:
print "Please update this script, the following modules are unknown"
pprint(unknown)
if DEBUG:
print "===== SOURCE"
pprint(source)
print "===== FILES"
pprint(files)
print "===== DISABLED"
pprint(disabled)
print "===== UNKNOWN"
pprint(unknown)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='''This script only works on Mac OS X since the OS X Toolchain is not available on other platforms.
In addition you need XCode and the Android NDK installed.
If commit hash is not provided, current git master is used.''')
parser.add_argument('--debug', dest='debug', action="store_true")
parser.add_argument('--ndk', dest='ndk', type=str)
parser.add_argument('--commit', dest='commit', type=str, default=None)
args = parser.parse_args()
if sys.platform != 'darwin' or not args.ndk:
parser.print_help()
sys.exit(1)
ndk_path = args.ndk
commit = args.commit
DEBUG = args.debug
base = os.path.abspath(os.curdir)
prefix = os.path.join(base, 'upstream/')
commit = prepare_upstream(prefix, commit)
libvpx_files = get_libvpx_files(prefix)
source, files, disabled, unknown = get_sources(prefix)
sources_mozbuild, moz_build_files = get_sources_mozbuild()
print_info(source, files, disabled, unknown, moz_build_files)
update_sources_mozbuild(files, sources_mozbuild)
update_and_remove_files(prefix, libvpx_files, files)
apply_patches()
update_readme(commit)
cleanup_upstream()