gecko/media/libvpx/update.py
Jan Gerber 7daba17fb2 Bug 918550 - Update libvpx to 1.3.0 r=glandium,cpearce
This updates our in-tree copy of libvpx to the
v1.3.0 git tag (2e88f2f2ec777259bda1714e72f1ecd2519bceb5)
libvpx 1.3.0 adds support for VP9. VP9 support is built
but not yet exposed with this commit.

Our update.sh script is replaced with update.py that can
update the build system to a given git commit.
 - checkout out upstream git
 - create platform dependend config files
 - add/remove changed libvpx files
 - update moz.build
 - warn about new build categories in libvpx
2013-12-06 03:19:00 -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 = {
'ENCODER': [
'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_ENCODER': [
'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_ENCODER': [
'VP8_CX_SRCS-$(ARCH_X86_64)',
'VP9_CX_SRCS-$(ARCH_X86_64)',
],
'ARM_ASM_ENCODER': [
'VP8_CX_SRCS-$(ARCH_ARM)',
'VP8_CX_SRCS-$(HAVE_EDSP)',
'VP8_CX_SRCS-$(HAVE_MEDIA)',
'VP8_CX_SRCS-$(HAVE_NEON)',
],
'COMMON': [
'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',
],
'ERROR_CONCEALMENT': [
'VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT)',
],
'AVX2': [
'VP9_COMMON_SRCS-$(HAVE_AVX2)',
],
'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)',
],
'X86-64_ASM': [
],
'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_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_ENCODER': [
'vp9/encoder/x86/vp9_quantize_ssse3.asm',
],
'X86-64_ASM': [
'third_party/x86inc/x86inc.asm',
'vp8/common/x86/loopfilter_block_sse2.asm',
],
'X86_ASM': [
]
}
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.c',
'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']
if 'darwin9' in target:
configure += ['--enable-pic']
if 'linux' in target:
configure += ['--enable-pic']
# mozilla linux toolchain currently does not support avx2,
# remove once gcc is updated
configure += ['--disable-avx2']
# 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)
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")
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()