diff --git a/build/arm-msvs/obj_int_extract.bat b/build/arm-msvs/obj_int_extract.bat new file mode 100644 index 0000000000000000000000000000000000000000..147342d3d1a7d5ae8fa3a80d90c8f2eff3f4a9aa --- /dev/null +++ b/build/arm-msvs/obj_int_extract.bat @@ -0,0 +1,25 @@ +REM Copyright (c) 2013 The WebM project authors. All Rights Reserved. +REM +REM Use of this source code is governed by a BSD-style license +REM that can be found in the LICENSE file in the root of the source +REM tree. An additional intellectual property rights grant can be found +REM in the file PATENTS. All contributing project authors may +REM be found in the AUTHORS file in the root of the source tree. +echo on + +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp9/common/vp9_asm_com_offsets.c" +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp9/decoder/vp9_asm_dec_offsets.c" +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp9/encoder/vp9_asm_enc_offsets.c" +obj_int_extract.exe rvds "vp9_asm_com_offsets.obj" > "vp9_asm_com_offsets.asm" +obj_int_extract.exe rvds "vp9_asm_dec_offsets.obj" > "vp9_asm_dec_offsets.asm" +obj_int_extract.exe rvds "vp9_asm_enc_offsets.obj" > "vp9_asm_enc_offsets.asm" + +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/common/vp8_asm_com_offsets.c" +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/decoder/vp8_asm_dec_offsets.c" +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/encoder/vp8_asm_enc_offsets.c" +obj_int_extract.exe rvds "vp8_asm_com_offsets.obj" > "vp8_asm_com_offsets.asm" +obj_int_extract.exe rvds "vp8_asm_dec_offsets.obj" > "vp8_asm_dec_offsets.asm" +obj_int_extract.exe rvds "vp8_asm_enc_offsets.obj" > "vp8_asm_enc_offsets.asm" + +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vpx_scale/vpx_scale_asm_offsets.c" +obj_int_extract.exe rvds "vpx_scale_asm_offsets.obj" > "vpx_scale_asm_offsets.asm" diff --git a/build/make/Makefile b/build/make/Makefile index de71c613317944036db0ec41e935b82ce15631bf..7a2523960d3f653a0727aad5f4d5841758104b69 100644 --- a/build/make/Makefile +++ b/build/make/Makefile @@ -388,11 +388,14 @@ ifneq ($(call enabled,DIST-SRCS),) DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh DIST-SRCS-$(CONFIG_MSVS) += build/x86-msvs/yasm.rules DIST-SRCS-$(CONFIG_MSVS) += build/x86-msvs/obj_int_extract.bat + DIST-SRCS-$(CONFIG_MSVS) += build/arm-msvs/obj_int_extract.bat DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh # Include obj_int_extract if we use offsets from *_asm_*_offsets DIST-SRCS-$(ARCH_ARM)$(ARCH_X86)$(ARCH_X86_64) += build/make/obj_int_extract.c DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas.pl DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas_apple.pl + DIST-SRCS-$(ARCH_ARM) += build/make/ads2armasm_ms.pl + DIST-SRCS-$(ARCH_ARM) += build/make/thumb.pm DIST-SRCS-yes += $(target:-$(TOOLCHAIN)=).mk endif INSTALL-SRCS := $(call cond_enabled,CONFIG_INSTALL_SRCS,INSTALL-SRCS) diff --git a/build/make/ads2armasm_ms.pl b/build/make/ads2armasm_ms.pl new file mode 100755 index 0000000000000000000000000000000000000000..1def53901d42fb0e214c571b692af2d37f4a40c1 --- /dev/null +++ b/build/make/ads2armasm_ms.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl +## +## Copyright (c) 2013 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + +use FindBin; +use lib $FindBin::Bin; +use thumb; + +print "; This file was created from a .asm file\n"; +print "; using the ads2armasm_ms.pl script.\n"; + +while (<STDIN>) +{ + undef $comment; + undef $line; + + s/REQUIRE8//; + s/PRESERVE8//; + s/^\s*ARM\s*$//; + s/AREA\s+\|\|(.*)\|\|/AREA |$1|/; + s/qsubaddx/qsax/i; + s/qaddsubx/qasx/i; + + thumb::FixThumbInstructions($_, 1); + + s/ldrneb/ldrbne/i; + s/ldrneh/ldrhne/i; + + print; +} + diff --git a/build/make/ads2gas.pl b/build/make/ads2gas.pl index 95be467ab1ea62395cfbaa123db9d1f6db94b518..9c41901295f51ee70febb0b6556d912c2d1fd72f 100755 --- a/build/make/ads2gas.pl +++ b/build/make/ads2gas.pl @@ -17,9 +17,24 @@ # # Usage: cat inputfile | perl ads2gas.pl > outputfile # + +use FindBin; +use lib $FindBin::Bin; +use thumb; + +my $thumb = 0; + +foreach my $arg (@ARGV) { + $thumb = 1 if ($arg eq "-thumb"); +} + print "@ This file was created from a .asm file\n"; print "@ using the ads2gas.pl script.\n"; print "\t.equ DO1STROUNDING, 0\n"; +if ($thumb) { + print "\t.syntax unified\n"; + print "\t.thumb\n"; +} # Stack of procedure names. @proc_stack = (); @@ -151,8 +166,13 @@ while (<STDIN>) # ALIGN directive s/\bALIGN\b/.balign/g; - # ARM code - s/\sARM/.arm/g; + if ($thumb) { + # ARM code - we force everything to thumb with the declaration in the header + s/\sARM//g; + } else { + # ARM code + s/\sARM/.arm/g; + } # push/pop s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g; @@ -162,6 +182,10 @@ while (<STDIN>) s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g; s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g; + if ($thumb) { + thumb::FixThumbInstructions($_, 0); + } + # eabi_attributes numerical equivalents can be found in the # "ARM IHI 0045C" document. diff --git a/build/make/configure.sh b/build/make/configure.sh index c50ef58ad923f9251331e7bea396eeafd1287fee..ee4493d2b5f3b870ba0c7ee66c6fce350a95de38 100755 --- a/build/make/configure.sh +++ b/build/make/configure.sh @@ -88,6 +88,7 @@ Build options: ${toggle_debug} enable/disable debug mode ${toggle_gprof} enable/disable gprof profiling instrumentation ${toggle_gcov} enable/disable gcov coverage instrumentation + ${toggle_thumb} enable/disable building arm assembly in thumb mode Install options: ${toggle_install_docs} control whether docs are installed @@ -416,6 +417,8 @@ SRC_PATH_BARE=$source_path BUILD_PFX=${BUILD_PFX} TOOLCHAIN=${toolchain} ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl} +GEN_VCPROJ=${gen_vcproj_cmd} +MSVS_ARCH_DIR=${msvs_arch_dir} CC=${CC} CXX=${CXX} @@ -433,6 +436,7 @@ ASFLAGS = ${ASFLAGS} extralibs = ${extralibs} AS_SFX = ${AS_SFX:-.asm} EXE_SFX = ${EXE_SFX} +VCPROJ_SFX = ${VCPROJ_SFX} RTCD_OPTIONS = ${RTCD_OPTIONS} EOF @@ -794,7 +798,13 @@ process_common_toolchain() { check_add_asflags --defsym ARCHITECTURE=${arch_int} tune_cflags="-mtune=" if [ ${tgt_isa} == "armv7" ]; then - [ -z "${float_abi}" ] && float_abi=softfp + if [ -z "${float_abi}" ]; then + check_cpp <<EOF && float_abi=hard || float_abi=softfp +#ifndef __ARM_PCS_VFP +#error "not hardfp" +#endif +EOF + fi check_add_cflags -march=armv7-a -mfloat-abi=${float_abi} check_add_asflags -march=armv7-a -mfloat-abi=${float_abi} @@ -814,6 +824,18 @@ process_common_toolchain() { enabled debug && add_asflags -g asm_conversion_cmd="${source_path}/build/make/ads2gas.pl" + if enabled thumb; then + asm_conversion_cmd="$asm_conversion_cmd -thumb" + check_add_cflags -mthumb + check_add_asflags -mthumb -mimplicit-it=always + fi + ;; + vs*) + asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl" + AS_SFX=.s + msvs_arch_dir=arm-msvs + disable multithread + disable unit_tests ;; rvct) CC=armcc @@ -1057,6 +1079,7 @@ EOF # invoked directly. Checking at configure time is unnecessary. # Skip the check by setting AS arbitrarily AS=msvs + msvs_arch_dir=x86-msvs ;; esac @@ -1180,7 +1203,7 @@ EOF check_cc <<EOF && INLINE="inline" static inline function() {} EOF - check_cc <<EOF && INLINE="__attribute__((always_inline))" + check_cc <<EOF && INLINE="__inline__ __attribute__((always_inline))" static __attribute__((always_inline)) function() {} EOF diff --git a/build/make/gen_msvs_sln.sh b/build/make/gen_msvs_sln.sh index 240678b6455388dc09f4c9e92cf85c51b8fd1385..5a8c793682343e69ba1a56ded1479f4d5232600b 100755 --- a/build/make/gen_msvs_sln.sh +++ b/build/make/gen_msvs_sln.sh @@ -25,7 +25,7 @@ files. Options: --help Print this message --out=outfile Redirect output to a file - --ver=version Version (7,8,9) of visual studio to generate for + --ver=version Version (7,8,9,10,11) of visual studio to generate for --target=isa-os-cc Target specifier EOF exit 1 @@ -55,14 +55,19 @@ indent_pop() { parse_project() { local file=$1 - local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` - local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` + if [ "$sfx" = "vcproj" ]; then + local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` + local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` + else + local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` + local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` + fi # save the project GUID to a varaible, normalizing to the basename of the # vcproj file without the extension local var var=${file##*/} - var=${var%%.vcproj} + var=${var%%.${sfx}} eval "${var}_file=\"$1\"" eval "${var}_name=$name" eval "${var}_guid=$guid" @@ -83,14 +88,14 @@ process_project() { # vcproj file without the extension local var var=${file##*/} - var=${var%%.vcproj} + var=${var%%.${sfx}} eval "${var}_guid=$guid" echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\"" indent_push eval "local deps=\"\${${var}_deps}\"" - if [ -n "$deps" ]; then + if [ -n "$deps" ] && [ "$sfx" = "vcproj" ]; then echo "${indent}ProjectSection(ProjectDependencies) = postProject" indent_push @@ -221,7 +226,7 @@ for opt in "$@"; do ;; --ver=*) vs_ver="$optval" case $optval in - [789]) + [789]|10|11) ;; *) die Unrecognized Visual Studio Version in $opt ;; @@ -257,6 +262,20 @@ case "${vs_ver:-8}" in 9) sln_vers="10.00" sln_vers_str="Visual Studio 2008" ;; + 10) sln_vers="11.00" + sln_vers_str="Visual Studio 2010" + ;; + 11) sln_vers="12.00" + sln_vers_str="Visual Studio 2012" + ;; +esac +case "${vs_ver:-8}" in + [789]) + sfx=vcproj + ;; + 10|11) + sfx=vcxproj + ;; esac for f in "${file_list[@]}"; do diff --git a/build/make/gen_msvs_vcxproj.sh b/build/make/gen_msvs_vcxproj.sh new file mode 100755 index 0000000000000000000000000000000000000000..4875915250cb3441efd324747c939ea9027f1fff --- /dev/null +++ b/build/make/gen_msvs_vcxproj.sh @@ -0,0 +1,530 @@ +#!/bin/bash +## +## Copyright (c) 2013 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + + +self=$0 +self_basename=${self##*/} +self_dirname=$(dirname "$0") +EOL=$'\n' + +show_help() { + cat <<EOF +Usage: ${self_basename} --name=projname [options] file1 [file2 ...] + +This script generates a Visual Studio project file from a list of source +code files. + +Options: + --help Print this message + --exe Generate a project for building an Application + --lib Generate a project for creating a static library + --dll Generate a project for creating a dll + --static-crt Use the static C runtime (/MT) + --target=isa-os-cc Target specifier (required) + --out=filename Write output to a file [stdout] + --name=project_name Name of the project (required) + --proj-guid=GUID GUID to use for the project + --module-def=filename File containing export definitions (for DLLs) + --ver=version Version (10,11) of visual studio to generate for + --src-path-bare=dir Path to root of source tree + -Ipath/to/include Additional include directories + -DFLAG[=value] Preprocessor macros to define + -Lpath/to/lib Additional library search paths + -llibname Library to link against +EOF + exit 1 +} + +die() { + echo "${self_basename}: $@" >&2 + exit 1 +} + +die_unknown(){ + echo "Unknown option \"$1\"." >&2 + echo "See ${self_basename} --help for available options." >&2 + exit 1 +} + +generate_uuid() { + local hex="0123456789ABCDEF" + local i + local uuid="" + local j + #93995380-89BD-4b04-88EB-625FBE52EBFB + for ((i=0; i<32; i++)); do + (( j = $RANDOM % 16 )) + uuid="${uuid}${hex:$j:1}" + done + echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}" +} + +indent1=" " +indent="" +indent_push() { + indent="${indent}${indent1}" +} +indent_pop() { + indent="${indent%${indent1}}" +} + +tag_attributes() { + for opt in "$@"; do + optval="${opt#*=}" + [ -n "${optval}" ] || + die "Missing attribute value in '$opt' while generating $tag tag" + echo "${indent}${opt%%=*}=\"${optval}\"" + done +} + +open_tag() { + local tag=$1 + shift + if [ $# -ne 0 ]; then + echo "${indent}<${tag}" + indent_push + tag_attributes "$@" + echo "${indent}>" + else + echo "${indent}<${tag}>" + indent_push + fi +} + +close_tag() { + local tag=$1 + indent_pop + echo "${indent}</${tag}>" +} + +tag() { + local tag=$1 + shift + if [ $# -ne 0 ]; then + echo "${indent}<${tag}" + indent_push + tag_attributes "$@" + indent_pop + echo "${indent}/>" + else + echo "${indent}<${tag}/>" + fi +} + +tag_content() { + local tag=$1 + local content=$2 + shift + shift + if [ $# -ne 0 ]; then + echo "${indent}<${tag}" + indent_push + tag_attributes "$@" + echo "${indent}>${content}</${tag}>" + indent_pop + else + echo "${indent}<${tag}>${content}</${tag}>" + fi +} + +generate_filter() { + local name=$1 + local pats=$2 + local file_list_sz + local i + local f + local saveIFS="$IFS" + local pack + echo "generating filter '$name' from ${#file_list[@]} files" >&2 + IFS=* + + file_list_sz=${#file_list[@]} + for i in ${!file_list[@]}; do + f=${file_list[i]} + for pat in ${pats//;/$IFS}; do + if [ "${f##*.}" == "$pat" ]; then + unset file_list[i] + + objf=$(echo ${f%.*}.obj | sed -e 's/^[\./]\+//g' -e 's,/,_,g') + + if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then + open_tag CustomBuild \ + Include=".\\$f" + for plat in "${platforms[@]}"; do + for cfg in Debug Release; do + tag_content Message "Assembling %(Filename)%(Extension)" \ + Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" + tag_content Command "$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \ + Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" + tag_content Outputs "\$(IntDir)$objf" \ + Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" + done + done + close_tag CustomBuild + elif [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then + open_tag ClCompile \ + Include=".\\$f" + # Separate file names with Condition? + tag_content ObjectFileName "\$(IntDir)$objf" + close_tag ClCompile + elif [ "$pat" == "h" ] ; then + tag ClInclude \ + Include=".\\$f" + elif [ "$pat" == "vcxproj" ] ; then + open_tag ProjectReference \ + Include="$f" + depguid=`grep ProjectGuid "$f" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` + tag_content Project "$depguid" + tag_content ReferenceOutputAssembly false + close_tag ProjectReference + else + tag None \ + Include=".\\$f" + fi + + break + fi + done + done + + IFS="$saveIFS" +} + +# Process command line +unset target +for opt in "$@"; do + optval="${opt#*=}" + case "$opt" in + --help|-h) show_help + ;; + --target=*) target="${optval}" + ;; + --out=*) outfile="$optval" + ;; + --name=*) name="${optval}" + ;; + --proj-guid=*) guid="${optval}" + ;; + --module-def=*) module_def="${optval}" + ;; + --exe) proj_kind="exe" + ;; + --dll) proj_kind="dll" + ;; + --lib) proj_kind="lib" + ;; + --src-path-bare=*) src_path_bare="$optval" + ;; + --static-crt) use_static_runtime=true + ;; + --ver=*) + vs_ver="$optval" + case "$optval" in + 10|11) + ;; + *) die Unrecognized Visual Studio Version in $opt + ;; + esac + ;; + -I*) + opt="${opt%/}" + incs="${incs}${incs:+;}${opt##-I}" + yasmincs="${yasmincs} ${opt}" + ;; + -D*) defines="${defines}${defines:+;}${opt##-D}" + ;; + -L*) # fudge . to $(OutDir) + if [ "${opt##-L}" == "." ]; then + libdirs="${libdirs}${libdirs:+;}\$(OutDir)" + else + # Also try directories for this platform/configuration + libdirs="${libdirs}${libdirs:+;}${opt##-L}" + libdirs="${libdirs}${libdirs:+;}${opt##-L}/\$(PlatformName)/\$(Configuration)" + libdirs="${libdirs}${libdirs:+;}${opt##-L}/\$(PlatformName)" + fi + ;; + -l*) libs="${libs}${libs:+ }${opt##-l}.lib" + ;; + -*) die_unknown $opt + ;; + *) + file_list[${#file_list[@]}]="$opt" + case "$opt" in + *.asm|*.s) uses_asm=true + ;; + esac + ;; + esac +done +outfile=${outfile:-/dev/stdout} +guid=${guid:-`generate_uuid`} +asm_use_custom_step=false +uses_asm=${uses_asm:-false} +case "${vs_ver:-11}" in + 10|11) + asm_use_custom_step=$uses_asm + ;; +esac + +[ -n "$name" ] || die "Project name (--name) must be specified!" +[ -n "$target" ] || die "Target (--target) must be specified!" + +if ${use_static_runtime:-false}; then + release_runtime=MultiThreaded + debug_runtime=MultiThreadedDebug + lib_sfx=mt +else + release_runtime=MultiThreadedDLL + debug_runtime=MultiThreadedDebugDLL + lib_sfx=md +fi + +# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename +# it to ${lib_sfx}d.lib. This precludes linking to release libs from a +# debug exe, so this may need to be refactored later. +for lib in ${libs}; do + if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then + lib=${lib%.lib}d.lib + fi + debug_libs="${debug_libs}${debug_libs:+ }${lib}" +done +debug_libs=${debug_libs// /;} +libs=${libs// /;} + + +# List of all platforms supported for this target +case "$target" in + x86_64*) + platforms[0]="x64" + asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + ;; + x86*) + platforms[0]="Win32" + asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + ;; + arm*) + asm_Debug_cmdline="armasm -nologo "%(FullPath)"" + asm_Release_cmdline="armasm -nologo "%(FullPath)"" + if [ "$name" = "obj_int_extract" ]; then + # We don't want to build this tool for the target architecture, + # but for an architecture we can run locally during the build. + platforms[0]="Win32" + else + platforms[0]="ARM" + fi + ;; + *) die "Unsupported target $target!" + ;; +esac + +generate_vcxproj() { + echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + open_tag Project \ + DefaultTargets="Build" \ + ToolsVersion="4.0" \ + xmlns="http://schemas.microsoft.com/developer/msbuild/2003" \ + + open_tag ItemGroup \ + Label="ProjectConfigurations" + for plat in "${platforms[@]}"; do + for config in Debug Release; do + open_tag ProjectConfiguration \ + Include="$config|$plat" + tag_content Configuration $config + tag_content Platform $plat + close_tag ProjectConfiguration + done + done + close_tag ItemGroup + + open_tag PropertyGroup \ + Label="Globals" + tag_content ProjectGuid "{${guid}}" + tag_content RootNamespace ${name} + tag_content Keyword ManagedCProj + close_tag PropertyGroup + + tag Import \ + Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" + + for plat in "${platforms[@]}"; do + for config in Release Debug; do + open_tag PropertyGroup \ + Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" \ + Label="Configuration" + if [ "$proj_kind" = "exe" ]; then + tag_content ConfigurationType Application + elif [ "$proj_kind" = "dll" ]; then + tag_content ConfigurationType DynamicLibrary + else + tag_content ConfigurationType StaticLibrary + fi + if [ "$vs_ver" = "11" ]; then + if [ "$plat" = "ARM" ]; then + # Setting the wp80 toolchain automatically sets the + # WINAPI_FAMILY define, which is required for building + # code for arm with the windows headers. Alternatively, + # one could add AppContainerApplication=true in the Globals + # section and add PrecompiledHeader=NotUsing and + # CompileAsWinRT=false in ClCompile and SubSystem=Console + # in Link. + tag_content PlatformToolset v110_wp80 + else + tag_content PlatformToolset v110 + fi + fi + tag_content CharacterSet Unicode + if [ "$config" = "Release" ]; then + tag_content WholeProgramOptimization true + fi + close_tag PropertyGroup + done + done + + tag Import \ + Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" + + open_tag ImportGroup \ + Label="PropertySheets" + tag Import \ + Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" \ + Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" \ + Label="LocalAppDataPlatform" + close_tag ImportGroup + + tag PropertyGroup \ + Label="UserMacros" + + for plat in "${platforms[@]}"; do + plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'` + for config in Debug Release; do + open_tag PropertyGroup \ + Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" + tag_content OutDir "\$(SolutionDir)$plat_no_ws\\\$(Configuration)\\" + tag_content IntDir "$plat_no_ws\\\$(Configuration)\\${name}\\" + close_tag PropertyGroup + done + done + + for plat in "${platforms[@]}"; do + for config in Debug Release; do + open_tag ItemDefinitionGroup \ + Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" + if [ "$name" = "vpx" ]; then + open_tag PreBuildEvent + tag_content Command "call obj_int_extract.bat $src_path_bare" + close_tag PreBuildEvent + fi + open_tag ClCompile + if [ "$config" = "Debug" ]; then + opt=Disabled + runtime=$debug_runtime + curlibs=$debug_libs + confsuffix=d + case "$name" in + obj_int_extract) + debug=DEBUG + ;; + *) + debug=_DEBUG + ;; + esac + else + opt=MaxSpeed + runtime=$release_runtime + curlibs=$libs + confsuffix="" + tag_content FavorSizeOrSpeed Speed + debug=NDEBUG + fi + case "$name" in + obj_int_extract) + extradefines=";_CONSOLE" + ;; + *) + extradefines=";$defines" + ;; + esac + tag_content Optimization $opt + tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)" + tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)" + tag_content RuntimeLibrary $runtime + tag_content WarningLevel Level3 + # DebugInformationFormat + close_tag ClCompile + case "$proj_kind" in + exe) + open_tag Link + if [ "$name" = "obj_int_extract" ]; then + tag_content OutputFile "${name}.exe" + else + tag_content AdditionalDependencies "$curlibs" + tag_content AdditionalLibraryDirectories "$libdirs;%(AdditionalLibraryDirectories)" + fi + tag_content GenerateDebugInformation true + close_tag Link + ;; + dll) + open_tag Link + tag_content GenerateDebugInformation true + tag_content ModuleDefinitionFile $module_def + close_tag Link + ;; + lib) + open_tag Lib + tag_content OutputFile "\$(OutDir)${name}${lib_sfx}${confsuffix}.lib" + close_tag Lib + ;; + esac + close_tag ItemDefinitionGroup + done + + done + + open_tag ItemGroup + generate_filter "Source Files" "c;cc;def;odl;idl;hpj;bat;asm;asmx;s" + close_tag ItemGroup + open_tag ItemGroup + generate_filter "Header Files" "h;hm;inl;inc;xsd" + close_tag ItemGroup + open_tag ItemGroup + generate_filter "Build Files" "mk" + close_tag ItemGroup + open_tag ItemGroup + generate_filter "References" "vcxproj" + close_tag ItemGroup + + tag Import \ + Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" + + open_tag ImportGroup \ + Label="ExtensionTargets" + close_tag ImportGroup + + close_tag Project + + # This must be done from within the {} subshell + echo "Ignored files list (${#file_list[@]} items) is:" >&2 + for f in "${file_list[@]}"; do + echo " $f" >&2 + done +} + +# This regexp doesn't catch most of the strings in the vcxproj format, +# since they're like <tag>path</tag> instead of <tag attr="path" /> +# as previously. It still seems to work ok despite this. +generate_vcxproj | + sed -e '/"/s;\([^ "]\)/;\1\\;g' | + sed -e '/xmlns/s;\\;/;g' > ${outfile} + +exit diff --git a/build/make/thumb.pm b/build/make/thumb.pm new file mode 100644 index 0000000000000000000000000000000000000000..f34728743c6f0ae6276e31e03873ca8b94df780e --- /dev/null +++ b/build/make/thumb.pm @@ -0,0 +1,70 @@ +#!/usr/bin/perl +## +## Copyright (c) 2013 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + +package thumb; + +sub FixThumbInstructions($$) +{ + my $short_branches = $_[1]; + my $branch_shift_offset = $short_branches ? 1 : 0; + + # Write additions with shifts, such as "add r10, r11, lsl #8", + # in three operand form, "add r10, r10, r11, lsl #8". + s/(add\s+)(r\d+),\s*(r\d+),\s*(lsl #\d+)/$1$2, $2, $3, $4/g; + + # Convert additions with a non-constant shift into a sequence + # with left shift, addition and a right shift (to restore the + # register to the original value). Currently the right shift + # isn't necessary in the code base since the values in these + # registers aren't used, but doing the shift for consitency. + # This converts instructions such as "add r12, r12, r5, lsl r4" + # into the sequence "lsl r5, r4", "add r12, r12, r5", "lsr r5, r4". + s/^(\s*)(add)(\s+)(r\d+),\s*(r\d+),\s*(r\d+),\s*lsl (r\d+)/$1lsl$3$6, $7\n$1$2$3$4, $5, $6\n$1lsr$3$6, $7/g; + + # Convert loads with right shifts in the indexing into a + # sequence of an add, load and sub. This converts + # "ldrb r4, [r9, lr, asr #1]" into "add r9, r9, lr, asr #1", + # "ldrb r9, [r9]", "sub r9, r9, lr, asr #1". + s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+),\s*(asr #\d+)\]/$1add $3$5, $5, $6, $7\n$1$2$3$4, [$5]\n$1sub $3$5, $5, $6, $7/g; + + # Convert register indexing with writeback into a separate add + # instruction. This converts "ldrb r12, [r1, r2]!" into + # "ldrb r12, [r1, r2]", "add r1, r1, r2". + s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+)\]!/$1$2$3$4, [$5, $6]\n$1add $3$5, $6/g; + + # Convert negative register indexing into separate sub/add instructions. + # This converts "ldrne r4, [src, -pstep, lsl #1]" into + # "subne src, src, pstep, lsl #1", "ldrne r4, [src]", + # "addne src, src, pstep, lsl #1". In a couple of cases where + # this is used, it's used for two subsequent load instructions, + # where a hand-written version of it could merge two subsequent + # add and sub instructions. + s/^(\s*)((ldr|str)(ne)?)(\s+)(r\d+),\s*\[(\w+), -([^\]]+)\]/$1sub$4$5$7, $7, $8\n$1$2$5$6, [$7]\n$1add$4$5$7, $7, $8/g; + + # Convert register post indexing to a separate add instruction. + # This converts "ldrneb r9, [r0], r2" into "ldrneb r9, [r0]", + # "add r0, r2". + s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g; + + # Convert a conditional addition to the pc register into a series of + # instructions. This converts "addlt pc, pc, r3, lsl #2" into + # "itttt lt", "movlt.n r12, pc", "addlt.w r12, #12", + # "addlt.w r12, r12, r3, lsl #2", "movlt.n pc, r12". + # This assumes that r12 is free at this point. + s/^(\s*)addlt(\s+)pc,\s*pc,\s*(\w+),\s*lsl\s*#(\d+)/$1itttt$2lt\n$1movlt.n$2r12, pc\n$1addlt.w$2r12, #12\n$1addlt.w$2r12, r12, $3, lsl #($4-$branch_shift_offset)\n$1movlt.n$2pc, r12/g; + + # Convert "mov pc, lr" into "bx lr", since the former only works + # for switching from arm to thumb (and only in armv7), but not + # from thumb to arm. + s/mov(\s*)pc\s*,\s*lr/bx$1lr/g; +} + +1; diff --git a/configure b/configure index 05e5384b51fdbd39046e9d9175032f2b6712c78c..28676fbc6c3a6e99134969b7ddd6e2052a6f08e5 100755 --- a/configure +++ b/configure @@ -98,6 +98,7 @@ all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8 all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8 all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8 all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8 +all_platforms="${all_platforms} armv7-win32-vs11" all_platforms="${all_platforms} mips32-linux-gcc" all_platforms="${all_platforms} ppc32-darwin8-gcc" all_platforms="${all_platforms} ppc32-darwin9-gcc" @@ -122,6 +123,8 @@ all_platforms="${all_platforms} x86-win32-gcc" all_platforms="${all_platforms} x86-win32-vs7" all_platforms="${all_platforms} x86-win32-vs8" all_platforms="${all_platforms} x86-win32-vs9" +all_platforms="${all_platforms} x86-win32-vs10" +all_platforms="${all_platforms} x86-win32-vs11" all_platforms="${all_platforms} x86_64-darwin9-gcc" all_platforms="${all_platforms} x86_64-darwin10-gcc" all_platforms="${all_platforms} x86_64-darwin11-gcc" @@ -132,6 +135,8 @@ all_platforms="${all_platforms} x86_64-solaris-gcc" all_platforms="${all_platforms} x86_64-win64-gcc" all_platforms="${all_platforms} x86_64-win64-vs8" all_platforms="${all_platforms} x86_64-win64-vs9" +all_platforms="${all_platforms} x86_64-win64-vs10" +all_platforms="${all_platforms} x86_64-win64-vs11" all_platforms="${all_platforms} universal-darwin8-gcc" all_platforms="${all_platforms} universal-darwin9-gcc" all_platforms="${all_platforms} universal-darwin10-gcc" @@ -309,6 +314,7 @@ CMDLINE_SELECT=" optimizations ccache runtime_cpu_detect + thumb libs examples @@ -642,6 +648,16 @@ process_toolchain() { vs*) enable msvs enable solution vs_version=${tgt_cc##vs} + case $vs_version in + [789]) + VCPROJ_SFX=vcproj + gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh + ;; + 10|11) + VCPROJ_SFX=vcxproj + gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh + ;; + esac all_targets="${all_targets} solution" INLINE="__forceinline" ;; diff --git a/examples.mk b/examples.mk index 8426ee7690bc92bebb70296c7dc51df1e100222e..5b5ca237931cd68bdadabede9e1bbde0b3aace8c 100644 --- a/examples.mk +++ b/examples.mk @@ -231,19 +231,19 @@ endif # even though there is no real dependency there (the dependency is on # the makefiles). We may want to revisit this. define vcproj_template -$(1): $($(1:.vcproj=).SRCS) +$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX) @echo " [vcproj] $$@" - $$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh\ + $$(GEN_VCPROJ)\ --exe\ --target=$$(TOOLCHAIN)\ - --name=$$(@:.vcproj=)\ + --name=$$(@:.$(VCPROJ_SFX)=)\ --ver=$$(CONFIG_VS_VERSION)\ - --proj-guid=$$($$(@:.vcproj=).GUID)\ + --proj-guid=$$($$(@:.$(VCPROJ_SFX)=).GUID)\ $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \ --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \ - $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) -lwinmm $$^ + $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) $$^ endef -PROJECTS-$(CONFIG_MSVS) += $(ALL_EXAMPLES:.c=.vcproj) +PROJECTS-$(CONFIG_MSVS) += $(ALL_EXAMPLES:.c=.$(VCPROJ_SFX)) INSTALL-BINS-$(CONFIG_MSVS) += $(foreach p,$(VS_PLATFORMS),\ $(addprefix bin/$(p)/,$(ALL_EXAMPLES:.c=.exe))) $(foreach proj,$(call enabled,PROJECTS),\ diff --git a/libs.mk b/libs.mk index adcde33f75d1bdaf1613a03b9ab57ae8bf218a31..8428f899d2d17fee2165d75cb2f4548f0a82728e 100644 --- a/libs.mk +++ b/libs.mk @@ -12,7 +12,7 @@ # ARM assembly files are written in RVCT-style. We use some make magic to # filter those files to allow GCC compilation ifeq ($(ARCH_ARM),yes) - ASM:=$(if $(filter yes,$(CONFIG_GCC)),.asm.s,.asm) + ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.s,.asm) else ASM:=.asm endif @@ -207,10 +207,10 @@ libvpx_srcs.txt: ifeq ($(CONFIG_EXTERNAL_BUILD),yes) ifeq ($(CONFIG_MSVS),yes) -obj_int_extract.vcproj: $(SRC_PATH_BARE)/build/make/obj_int_extract.c - @cp $(SRC_PATH_BARE)/build/x86-msvs/obj_int_extract.bat . +obj_int_extract.$(VCPROJ_SFX): $(SRC_PATH_BARE)/build/make/obj_int_extract.c + @cp $(SRC_PATH_BARE)/build/$(MSVS_ARCH_DIR)/obj_int_extract.bat . @echo " [CREATE] $@" - $(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ + $(qexec)$(GEN_VCPROJ) \ --exe \ --target=$(TOOLCHAIN) \ --name=obj_int_extract \ @@ -221,7 +221,7 @@ obj_int_extract.vcproj: $(SRC_PATH_BARE)/build/make/obj_int_extract.c -I. \ -I"$(SRC_PATH_BARE)" \ -PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.vcproj +PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.$(VCPROJ_SFX) vpx.def: $(call enabled,CODEC_EXPORTS) @echo " [CREATE] $@" @@ -230,9 +230,9 @@ vpx.def: $(call enabled,CODEC_EXPORTS) --out=$@ $^ CLEAN-OBJS += vpx.def -vpx.vcproj: $(CODEC_SRCS) vpx.def +vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def obj_int_extract.$(VCPROJ_SFX) @echo " [CREATE] $@" - $(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ + $(qexec)$(GEN_VCPROJ) \ $(if $(CONFIG_SHARED),--dll,--lib) \ --target=$(TOOLCHAIN) \ $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ @@ -243,10 +243,10 @@ vpx.vcproj: $(CODEC_SRCS) vpx.def --out=$@ $(CFLAGS) $^ \ --src-path-bare="$(SRC_PATH_BARE)" \ -PROJECTS-$(BUILD_LIBVPX) += vpx.vcproj +PROJECTS-$(BUILD_LIBVPX) += vpx.$(VCPROJ_SFX) -vpx.vcproj: vpx_config.asm -vpx.vcproj: $(RTCD) +vpx.$(VCPROJ_SFX): vpx_config.asm +vpx.$(VCPROJ_SFX): $(RTCD) endif else @@ -403,9 +403,9 @@ testdata:: $(LIBVPX_TEST_DATA) ifeq ($(CONFIG_EXTERNAL_BUILD),yes) ifeq ($(CONFIG_MSVS),yes) -gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc +gtest.$(VCPROJ_SFX): $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc @echo " [CREATE] $@" - $(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ + $(qexec)$(GEN_VCPROJ) \ --lib \ --target=$(TOOLCHAIN) \ $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ @@ -414,14 +414,14 @@ gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc --ver=$(CONFIG_VS_VERSION) \ --src-path-bare="$(SRC_PATH_BARE)" \ -D_VARIADIC_MAX=10 \ - --out=gtest.vcproj $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc \ + --out=gtest.$(VCPROJ_SFX) $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc \ -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" -I"$(SRC_PATH_BARE)/third_party/googletest/src" -PROJECTS-$(CONFIG_MSVS) += gtest.vcproj +PROJECTS-$(CONFIG_MSVS) += gtest.$(VCPROJ_SFX) -test_libvpx.vcproj: $(LIBVPX_TEST_SRCS) +test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX) @echo " [CREATE] $@" - $(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ + $(qexec)$(GEN_VCPROJ) \ --exe \ --target=$(TOOLCHAIN) \ --name=test_libvpx \ @@ -431,9 +431,9 @@ test_libvpx.vcproj: $(LIBVPX_TEST_SRCS) $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ - -L. -l$(CODEC_LIB) -lwinmm -l$(GTEST_LIB) $^ + -L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^ -PROJECTS-$(CONFIG_MSVS) += test_libvpx.vcproj +PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX) test:: testdata @set -e; for t in $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BINS:.cc=.exe))); do $$t; done diff --git a/nestegg/halloc/src/macros.h b/nestegg/halloc/src/macros.h index c36b516eed38c5728761b6c82d2829bcccc3324f..1f84bc2779363aacb31c010c4ea10f82f3060f2a 100644 --- a/nestegg/halloc/src/macros.h +++ b/nestegg/halloc/src/macros.h @@ -20,7 +20,7 @@ /* restore pointer to the structure by a pointer to its field */ -#define structof(p,t,f) ((t*)(- offsetof(t,f) + (char*)(p))) +#define structof(p,t,f) ((t*)(- (ptrdiff_t) offsetof(t,f) + (char*)(p))) /* * redefine for the target compiler diff --git a/solution.mk b/solution.mk index 948305f0594384f0202e40e7c977799c58d0a6a1..2c8d29a2a1e87ecfad0229f254af42d2e502c5e7 100644 --- a/solution.mk +++ b/solution.mk @@ -9,14 +9,14 @@ ## # libvpx reverse dependencies (targets that depend on libvpx) -VPX_NONDEPS=$(addsuffix .vcproj,vpx gtest obj_int_extract) +VPX_NONDEPS=$(addsuffix .$(VCPROJ_SFX),vpx gtest obj_int_extract) VPX_RDEPS=$(foreach vcp,\ - $(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.vcproj=):vpx) + $(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.$(VCPROJ_SFX)=):vpx) -vpx.sln: $(wildcard *.vcproj) +vpx.sln: $(wildcard *.$(VCPROJ_SFX)) @echo " [CREATE] $@" $(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \ - $(if $(filter vpx.vcproj,$^),$(VPX_RDEPS)) \ + $(if $(filter vpx.$(VCPROJ_SFX),$^),$(VPX_RDEPS)) \ --dep=vpx:obj_int_extract \ --dep=test_libvpx:gtest \ --ver=$(CONFIG_VS_VERSION)\ diff --git a/vp8/common/arm/armv6/filter_v6.asm b/vp8/common/arm/armv6/filter_v6.asm index 1ba91ddd657a1da84f84426f82b3d9a37fcfb7cb..eb4b75bd8025d7391535bdd7997cd4ec28558296 100644 --- a/vp8/common/arm/armv6/filter_v6.asm +++ b/vp8/common/arm/armv6/filter_v6.asm @@ -394,7 +394,7 @@ mov r4, #0x40 ; rounding factor (for smlad{x}) |height_loop_2nd_4| - ldrd r8, [r0, #-4] ; load the data + ldrd r8, r9, [r0, #-4] ; load the data orr r7, r7, r3, lsr #1 ; loop counter |width_loop_2nd_4| diff --git a/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm b/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm index e7a3ed173f3d158b6eefe75c0c5f281675ca4ef6..9d22c52521c747ab7ab9fb7a8abfda4854998bce 100644 --- a/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm +++ b/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm @@ -9,9 +9,6 @@ ; -bilinear_taps_coeff - DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112 - ;----------------- EXPORT |vp8_sub_pixel_variance16x16_neon_func| @@ -29,6 +26,9 @@ bilinear_taps_coeff ; stack(r6) unsigned int *sse ;note: most of the code is copied from bilinear_predict16x16_neon and vp8_variance16x16_neon. +bilinear_taps_coeff + DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112 + |vp8_sub_pixel_variance16x16_neon_func| PROC push {r4-r6, lr} diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 5baeb3c5ba2a1443ac0740d464a749926d04c02c..b550f6be1cfd5a143958a46fb3e129ead227518c 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -1299,8 +1299,9 @@ int vp8cx_encode_inter_macroblock } { - /* Experimental code. Special case for gf and arf zeromv modes. - * Increase zbin size to supress noise + /* Experimental code. + * Special case for gf and arf zeromv modes, for 1 temporal layer. + * Increase zbin size to supress noise. */ x->zbin_mode_boost = 0; if (x->zbin_mode_boost_enabled) @@ -1309,7 +1310,8 @@ int vp8cx_encode_inter_macroblock { if (xd->mode_info_context->mbmi.mode == ZEROMV) { - if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) + if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME && + cpi->oxcf.number_of_layers == 1) x->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST; else x->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST; diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index aec7bffa4a9124394d1173b3911eddc3a16b8641..51b154f45c15417aeca535d501feaff0b23a9c94 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -289,6 +289,125 @@ static void restore_layer_context(VP8_COMP *cpi, const int layer) sizeof(cpi->mb.count_mb_ref_frame_usage)); } +static int rescale(int val, int num, int denom) +{ + int64_t llnum = num; + int64_t llden = denom; + int64_t llval = val; + + return (int)(llval * llnum / llden); +} + +static void init_temporal_layer_context(VP8_COMP *cpi, + VP8_CONFIG *oxcf, + const int layer, + double prev_layer_frame_rate) +{ + LAYER_CONTEXT *lc = &cpi->layer_context[layer]; + + lc->frame_rate = cpi->output_frame_rate / cpi->oxcf.rate_decimator[layer]; + lc->target_bandwidth = cpi->oxcf.target_bitrate[layer] * 1000; + + lc->starting_buffer_level_in_ms = oxcf->starting_buffer_level; + lc->optimal_buffer_level_in_ms = oxcf->optimal_buffer_level; + lc->maximum_buffer_size_in_ms = oxcf->maximum_buffer_size; + + lc->starting_buffer_level = + rescale((int)(oxcf->starting_buffer_level), + lc->target_bandwidth, 1000); + + if (oxcf->optimal_buffer_level == 0) + lc->optimal_buffer_level = lc->target_bandwidth / 8; + else + lc->optimal_buffer_level = + rescale((int)(oxcf->optimal_buffer_level), + lc->target_bandwidth, 1000); + + if (oxcf->maximum_buffer_size == 0) + lc->maximum_buffer_size = lc->target_bandwidth / 8; + else + lc->maximum_buffer_size = + rescale((int)(oxcf->maximum_buffer_size), + lc->target_bandwidth, 1000); + + /* Work out the average size of a frame within this layer */ + if (layer > 0) + lc->avg_frame_size_for_layer = + (int)((cpi->oxcf.target_bitrate[layer] - + cpi->oxcf.target_bitrate[layer-1]) * 1000 / + (lc->frame_rate - prev_layer_frame_rate)); + + lc->active_worst_quality = cpi->oxcf.worst_allowed_q; + lc->active_best_quality = cpi->oxcf.best_allowed_q; + lc->avg_frame_qindex = cpi->oxcf.worst_allowed_q; + + lc->buffer_level = lc->starting_buffer_level; + lc->bits_off_target = lc->starting_buffer_level; + + lc->total_actual_bits = 0; + lc->ni_av_qi = 0; + lc->ni_tot_qi = 0; + lc->ni_frames = 0; + lc->rate_correction_factor = 1.0; + lc->key_frame_rate_correction_factor = 1.0; + lc->gf_rate_correction_factor = 1.0; + lc->inter_frame_target = 0; +} + +// Upon a run-time change in temporal layers, reset the layer context parameters +// for any "new" layers. For "existing" layers, let them inherit the parameters +// from the previous layer state (at the same layer #). In future we may want +// to better map the previous layer state(s) to the "new" ones. +static void reset_temporal_layer_change(VP8_COMP *cpi, + VP8_CONFIG *oxcf, + const int prev_num_layers) +{ + unsigned int i; + double prev_layer_frame_rate = 0; + const int curr_num_layers = cpi->oxcf.number_of_layers; + // If the previous state was 1 layer, get current layer context from cpi. + // We need this to set the layer context for the new layers below. + if (prev_num_layers == 1) + { + cpi->current_layer = 0; + save_layer_context(cpi); + } + for (i = 0; i < curr_num_layers; i++) + { + LAYER_CONTEXT *lc = &cpi->layer_context[i]; + if (i >= prev_num_layers) + { + init_temporal_layer_context(cpi, oxcf, i, prev_layer_frame_rate); + } + // The initial buffer levels are set based on their starting levels. + // We could set the buffer levels based on the previous state (normalized + // properly by the layer bandwidths) but we would need to keep track of + // the previous set of layer bandwidths (i.e., target_bitrate[i]) + // before the layer change. For now, reset to the starting levels. + lc->buffer_level = cpi->oxcf.starting_buffer_level_in_ms * + cpi->oxcf.target_bitrate[i]; + lc->bits_off_target = lc->buffer_level; + // TDOD(marpan): Should we set the rate_correction_factor and + // active_worst/best_quality to values derived from the previous layer + // state (to smooth-out quality dips/rate fluctuation at transition)? + + // We need to treat the 1 layer case separately: oxcf.target_bitrate[i] + // is not set for 1 layer, and the restore_layer_context/save_context() + // are not called in the encoding loop, so we need to call it here to + // pass the layer context state to |cpi|. + if (curr_num_layers == 1) + { + lc->target_bandwidth = cpi->oxcf.target_bandwidth; + lc->buffer_level = cpi->oxcf.starting_buffer_level_in_ms * + lc->target_bandwidth / 1000; + lc->bits_off_target = lc->buffer_level; + restore_layer_context(cpi, 0); + } + prev_layer_frame_rate = cpi->output_frame_rate / + cpi->oxcf.rate_decimator[i]; + } +} + static void setup_features(VP8_COMP *cpi) { // If segmentation enabled set the update flags @@ -1200,17 +1319,6 @@ void vp8_new_frame_rate(VP8_COMP *cpi, double framerate) } -static int -rescale(int val, int num, int denom) -{ - int64_t llnum = num; - int64_t llden = denom; - int64_t llval = val; - - return (int)(llval * llnum / llden); -} - - static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { VP8_COMMON *cm = &cpi->common; @@ -1265,59 +1373,9 @@ static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) for (i=0; i<cpi->oxcf.number_of_layers; i++) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - - /* Layer configuration */ - lc->frame_rate = - cpi->output_frame_rate / cpi->oxcf.rate_decimator[i]; - lc->target_bandwidth = cpi->oxcf.target_bitrate[i] * 1000; - - lc->starting_buffer_level_in_ms = oxcf->starting_buffer_level; - lc->optimal_buffer_level_in_ms = oxcf->optimal_buffer_level; - lc->maximum_buffer_size_in_ms = oxcf->maximum_buffer_size; - - lc->starting_buffer_level = - rescale((int)(oxcf->starting_buffer_level), - lc->target_bandwidth, 1000); - - if (oxcf->optimal_buffer_level == 0) - lc->optimal_buffer_level = lc->target_bandwidth / 8; - else - lc->optimal_buffer_level = - rescale((int)(oxcf->optimal_buffer_level), - lc->target_bandwidth, 1000); - - if (oxcf->maximum_buffer_size == 0) - lc->maximum_buffer_size = lc->target_bandwidth / 8; - else - lc->maximum_buffer_size = - rescale((int)oxcf->maximum_buffer_size, - lc->target_bandwidth, 1000); - - /* Work out the average size of a frame within this layer */ - if (i > 0) - lc->avg_frame_size_for_layer = - (int)((cpi->oxcf.target_bitrate[i] - - cpi->oxcf.target_bitrate[i-1]) * 1000 / - (lc->frame_rate - prev_layer_frame_rate)); - - lc->active_worst_quality = cpi->oxcf.worst_allowed_q; - lc->active_best_quality = cpi->oxcf.best_allowed_q; - lc->avg_frame_qindex = cpi->oxcf.worst_allowed_q; - - lc->buffer_level = lc->starting_buffer_level; - lc->bits_off_target = lc->starting_buffer_level; - - lc->total_actual_bits = 0; - lc->ni_av_qi = 0; - lc->ni_tot_qi = 0; - lc->ni_frames = 0; - lc->rate_correction_factor = 1.0; - lc->key_frame_rate_correction_factor = 1.0; - lc->gf_rate_correction_factor = 1.0; - lc->inter_frame_target = 0; - - prev_layer_frame_rate = lc->frame_rate; + init_temporal_layer_context(cpi, oxcf, i, prev_layer_frame_rate); + prev_layer_frame_rate = cpi->output_frame_rate / + cpi->oxcf.rate_decimator[i]; } } @@ -1384,7 +1442,7 @@ static void update_layer_contexts (VP8_COMP *cpi) void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { VP8_COMMON *cm = &cpi->common; - int last_w, last_h; + int last_w, last_h, prev_number_of_layers; if (!cpi) return; @@ -1409,6 +1467,7 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) last_w = cpi->oxcf.Width; last_h = cpi->oxcf.Height; + prev_number_of_layers = cpi->oxcf.number_of_layers; cpi->oxcf = *oxcf; @@ -1601,6 +1660,16 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) cpi->target_bandwidth = cpi->oxcf.target_bandwidth; + // Check if the number of temporal layers has changed, and if so reset the + // pattern counter and set/initialize the temporal layer context for the + // new layer configuration. + if (cpi->oxcf.number_of_layers != prev_number_of_layers) + { + // If the number of temporal layers are changed we must start at the + // base of the pattern cycle, so reset temporal_pattern_counter. + cpi->temporal_pattern_counter = 0; + reset_temporal_layer_change(cpi, oxcf, prev_number_of_layers); + } cm->Width = cpi->oxcf.Width; cm->Height = cpi->oxcf.Height; @@ -1738,6 +1807,7 @@ struct VP8_COMP* vp8_create_compressor(VP8_CONFIG *oxcf) memcpy(cpi->base_skip_false_prob, vp8cx_base_skip_false_prob, sizeof(vp8cx_base_skip_false_prob)); cpi->common.current_video_frame = 0; + cpi->temporal_pattern_counter = 0; cpi->kf_overspend_bits = 0; cpi->kf_bitrate_adjustment = 0; cpi->frames_till_gf_update_due = 0; @@ -3485,6 +3555,8 @@ static void encode_frame_to_data_rate cm->current_video_frame++; cpi->frames_since_key++; + // We advance the temporal pattern for dropped frames. + cpi->temporal_pattern_counter++; #if CONFIG_INTERNAL_STATS cpi->count ++; @@ -3526,6 +3598,8 @@ static void encode_frame_to_data_rate #endif cm->current_video_frame++; cpi->frames_since_key++; + // We advance the temporal pattern for dropped frames. + cpi->temporal_pattern_counter++; return; } @@ -4693,6 +4767,7 @@ static void encode_frame_to_data_rate { cm->current_video_frame++; cpi->frames_since_key++; + cpi->temporal_pattern_counter++; } /* reset to normal state now that we are done. */ @@ -5012,7 +5087,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l /* Restore layer specific context & set frame rate */ layer = cpi->oxcf.layer_id[ - cm->current_video_frame % cpi->oxcf.periodicity]; + cpi->temporal_pattern_counter % cpi->oxcf.periodicity]; restore_layer_context (cpi, layer); vp8_new_frame_rate (cpi, cpi->layer_context[layer].frame_rate); } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index c79531c5dbeb622c1eb8f1f67327c3db0c6f55ae..5120fcce9924c258310a4c885c6d6bde76659a04 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -509,6 +509,10 @@ typedef struct VP8_COMP int cyclic_refresh_q; signed char *cyclic_refresh_map; + // Frame counter for the temporal pattern. Counter is rest when the temporal + // layers are changed dynamically (run-time change). + unsigned int temporal_pattern_counter; + #if CONFIG_MULTITHREAD /* multithread data */ int * mt_current_mb_col; diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 90a175436dbf517a36d42243de85303deb02f54b..45cf3859e30c04239f9b0c4c1b3574360b7b1890 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -659,7 +659,7 @@ static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t *ctx, /* iter acts as a flip flop, so an image is only returned on the first * call to get_frame. */ - if (!(*iter)) + if (!(*iter) && ctx->yv12_frame_buffers.pbi[0]) { YV12_BUFFER_CONFIG sd; int64_t time_stamp = 0, time_end_stamp = 0; @@ -943,10 +943,10 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, { int *corrupted = va_arg(args, int *); + VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; - if (corrupted) + if (corrupted && pbi) { - VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; *corrupted = pbi->common.frame_to_show->corrupted; return VPX_CODEC_OK; diff --git a/vp9/encoder/x86/vp9_dct_sse2.c b/vp9/encoder/x86/vp9_dct_sse2.c index 49cb837e01c5ed79d95b7c39362afb1c360b0c23..aaacebee2cff64c1c0995d6f4e56b818daca136c 100644 --- a/vp9/encoder/x86/vp9_dct_sse2.c +++ b/vp9/encoder/x86/vp9_dct_sse2.c @@ -362,14 +362,14 @@ void vp9_short_fdct8x8_sse2(int16_t *input, int16_t *output, int pitch) { in6 = _mm_srai_epi16(in6, 1); in7 = _mm_srai_epi16(in7, 1); // store results - _mm_storeu_si128 ((__m128i *)(output + 0 * 8), in0); - _mm_storeu_si128 ((__m128i *)(output + 1 * 8), in1); - _mm_storeu_si128 ((__m128i *)(output + 2 * 8), in2); - _mm_storeu_si128 ((__m128i *)(output + 3 * 8), in3); - _mm_storeu_si128 ((__m128i *)(output + 4 * 8), in4); - _mm_storeu_si128 ((__m128i *)(output + 5 * 8), in5); - _mm_storeu_si128 ((__m128i *)(output + 6 * 8), in6); - _mm_storeu_si128 ((__m128i *)(output + 7 * 8), in7); + _mm_storeu_si128((__m128i *)(output + 0 * 8), in0); + _mm_storeu_si128((__m128i *)(output + 1 * 8), in1); + _mm_storeu_si128((__m128i *)(output + 2 * 8), in2); + _mm_storeu_si128((__m128i *)(output + 3 * 8), in3); + _mm_storeu_si128((__m128i *)(output + 4 * 8), in4); + _mm_storeu_si128((__m128i *)(output + 5 * 8), in5); + _mm_storeu_si128((__m128i *)(output + 6 * 8), in6); + _mm_storeu_si128((__m128i *)(output + 7 * 8), in7); } } @@ -915,14 +915,14 @@ void vp9_short_fdct16x16_sse2(int16_t *input, int16_t *output, int pitch) { // 05 15 25 35 45 55 65 75 // 06 16 26 36 46 56 66 76 // 07 17 27 37 47 57 67 77 - _mm_storeu_si128 ((__m128i *)(out + 0 * 16), tr2_0); - _mm_storeu_si128 ((__m128i *)(out + 1 * 16), tr2_1); - _mm_storeu_si128 ((__m128i *)(out + 2 * 16), tr2_2); - _mm_storeu_si128 ((__m128i *)(out + 3 * 16), tr2_3); - _mm_storeu_si128 ((__m128i *)(out + 4 * 16), tr2_4); - _mm_storeu_si128 ((__m128i *)(out + 5 * 16), tr2_5); - _mm_storeu_si128 ((__m128i *)(out + 6 * 16), tr2_6); - _mm_storeu_si128 ((__m128i *)(out + 7 * 16), tr2_7); + _mm_storeu_si128((__m128i *)(out + 0 * 16), tr2_0); + _mm_storeu_si128((__m128i *)(out + 1 * 16), tr2_1); + _mm_storeu_si128((__m128i *)(out + 2 * 16), tr2_2); + _mm_storeu_si128((__m128i *)(out + 3 * 16), tr2_3); + _mm_storeu_si128((__m128i *)(out + 4 * 16), tr2_4); + _mm_storeu_si128((__m128i *)(out + 5 * 16), tr2_5); + _mm_storeu_si128((__m128i *)(out + 6 * 16), tr2_6); + _mm_storeu_si128((__m128i *)(out + 7 * 16), tr2_7); } { // 00 01 02 03 04 05 06 07 @@ -982,14 +982,14 @@ void vp9_short_fdct16x16_sse2(int16_t *input, int16_t *output, int pitch) { // 06 16 26 36 46 56 66 76 // 07 17 27 37 47 57 67 77 // Store results - _mm_storeu_si128 ((__m128i *)(out + 8 + 0 * 16), tr2_0); - _mm_storeu_si128 ((__m128i *)(out + 8 + 1 * 16), tr2_1); - _mm_storeu_si128 ((__m128i *)(out + 8 + 2 * 16), tr2_2); - _mm_storeu_si128 ((__m128i *)(out + 8 + 3 * 16), tr2_3); - _mm_storeu_si128 ((__m128i *)(out + 8 + 4 * 16), tr2_4); - _mm_storeu_si128 ((__m128i *)(out + 8 + 5 * 16), tr2_5); - _mm_storeu_si128 ((__m128i *)(out + 8 + 6 * 16), tr2_6); - _mm_storeu_si128 ((__m128i *)(out + 8 + 7 * 16), tr2_7); + _mm_storeu_si128((__m128i *)(out + 8 + 0 * 16), tr2_0); + _mm_storeu_si128((__m128i *)(out + 8 + 1 * 16), tr2_1); + _mm_storeu_si128((__m128i *)(out + 8 + 2 * 16), tr2_2); + _mm_storeu_si128((__m128i *)(out + 8 + 3 * 16), tr2_3); + _mm_storeu_si128((__m128i *)(out + 8 + 4 * 16), tr2_4); + _mm_storeu_si128((__m128i *)(out + 8 + 5 * 16), tr2_5); + _mm_storeu_si128((__m128i *)(out + 8 + 6 * 16), tr2_6); + _mm_storeu_si128((__m128i *)(out + 8 + 7 * 16), tr2_7); } out += 8*16; } diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c index 32cd62037f811bcfb2c535b13d63c4a31ffaf3e2..c240a9e614400e6999b1a4b6daf5c90abb2fa5c8 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -406,7 +406,7 @@ static void parse_superframe_index(const uint8_t *data, if (data_sz >= index_sz && data[data_sz - index_sz] == marker) { // found a valid superframe index - int i, j; + uint32_t i, j; const uint8_t *x = data + data_sz - index_sz + 1; for (i = 0; i < frames; i++) { diff --git a/vpx_ports/x86.h b/vpx_ports/x86.h index f1cf6265e766a05fb3a094dd84d81a799df9e650..a51cd2e01bb3f14dfc968ad9898a27b9d408dc78 100644 --- a/vpx_ports/x86.h +++ b/vpx_ports/x86.h @@ -33,7 +33,7 @@ typedef enum { VPX_CPU_LAST } vpx_cpu_t; -#if defined(__GNUC__) && __GNUC__ +#if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__) #if ARCH_X86_64 #define cpuid(func,ax,bx,cx,dx)\ __asm__ __volatile__ (\ @@ -49,7 +49,7 @@ typedef enum { : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \ : "a" (func)); #endif -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/ #if ARCH_X86_64 #define cpuid(func,ax,bx,cx,dx)\ asm volatile (\ @@ -69,7 +69,7 @@ typedef enum { : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \ : "a" (func)); #endif -#else +#else /* end __SUNPRO__ */ #if ARCH_X86_64 void __cpuid(int CPUInfo[4], int info_type); #pragma intrinsic(__cpuid) @@ -86,7 +86,7 @@ void __cpuid(int CPUInfo[4], int info_type); __asm mov c, ecx\ __asm mov d, edx #endif -#endif +#endif /* end others */ #define HAS_MMX 0x01 #define HAS_SSE 0x02 diff --git a/vpxdec.c b/vpxdec.c index 9ae868f294b0c53f5ae068314c1aca038886f79b..deb45d35949e26287679dab87bed021505cd6c2d 100644 --- a/vpxdec.c +++ b/vpxdec.c @@ -715,6 +715,7 @@ int main(int argc, const char **argv_) { int do_scale = 0; int stream_w = 0, stream_h = 0; vpx_image_t *scaled_img = NULL; + int frame_avail, got_data; /* Parse command line */ exec_name = argv_[0]; @@ -982,30 +983,50 @@ int main(int argc, const char **argv_) { arg_skip--; } + frame_avail = 1; + got_data = 0; + /* Decode file */ - while (!read_frame(&input, &buf, &buf_sz, &buf_alloc_sz)) { + while (frame_avail || got_data) { vpx_codec_iter_t iter = NULL; vpx_image_t *img; struct vpx_usec_timer timer; int corrupted; - vpx_usec_timer_start(&timer); + frame_avail = 0; + if (!stop_after || frame_in < stop_after) { + if(!read_frame(&input, &buf, &buf_sz, &buf_alloc_sz)) { + frame_avail = 1; + frame_in++; - if (vpx_codec_decode(&decoder, buf, (unsigned int)buf_sz, NULL, 0)) { - const char *detail = vpx_codec_error_detail(&decoder); - fprintf(stderr, "Failed to decode frame: %s\n", vpx_codec_error(&decoder)); + vpx_usec_timer_start(&timer); - if (detail) - fprintf(stderr, " Additional information: %s\n", detail); + if (vpx_codec_decode(&decoder, buf, (unsigned int)buf_sz, NULL, 0)) { + const char *detail = vpx_codec_error_detail(&decoder); + fprintf(stderr, "Failed to decode frame: %s\n", + vpx_codec_error(&decoder)); - goto fail; + if (detail) + fprintf(stderr, " Additional information: %s\n", detail); + goto fail; + } + + vpx_usec_timer_mark(&timer); + dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); + } + } + + vpx_usec_timer_start(&timer); + + got_data = 0; + if ((img = vpx_codec_get_frame(&decoder, &iter))) { + ++frame_out; + got_data = 1; } vpx_usec_timer_mark(&timer); dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); - ++frame_in; - if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) { fprintf(stderr, "Failed VP8_GET_FRAME_CORRUPTED: %s\n", vpx_codec_error(&decoder)); @@ -1013,14 +1034,6 @@ int main(int argc, const char **argv_) { } frames_corrupted += corrupted; - vpx_usec_timer_start(&timer); - - if ((img = vpx_codec_get_frame(&decoder, &iter))) - ++frame_out; - - vpx_usec_timer_mark(&timer); - dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); - if (progress) show_progress(frame_in, frame_out, dx_time);