Merge "vp9/10: fix forced keyframes w/alt-refs enabled"
diff --git a/CHANGELOG b/CHANGELOG
index 7746cc6..7db420e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+Next Release
+ - Incompatible changes:
+ The VP9 encoder's default keyframe interval changed to 128 from 9999.
+
2015-11-09 v1.5.0 "Javan Whistling Duck"
This release improves upon the VP9 encoder and speeds up the encoding and
decoding processes.
diff --git a/test/datarate_test.cc b/test/datarate_test.cc
index 9d5074e..e94df20 100644
--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -905,6 +905,9 @@
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
cfg_.rc_dropframe_thresh = 10;
+ // TODO(marpan): another test should be added for default/small kf_max_dist
+ // once https://bugs.chromium.org/p/webm/issues/detail?id=1150 is fixed.
+ cfg_.kf_max_dist = 9999;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
diff --git a/test/lpf_8_test.cc b/test/lpf_8_test.cc
index b16f14c..778a36c 100644
--- a/test/lpf_8_test.cc
+++ b/test/lpf_8_test.cc
@@ -430,7 +430,7 @@
using std::tr1::make_tuple;
-#if HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH
+#if HAVE_MMX && CONFIG_USE_X86INC && !CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
MMX, Loop8Test6Param,
::testing::Values(
diff --git a/third_party/x86inc/README.libvpx b/third_party/x86inc/README.libvpx
index e91e305..8d3cd96 100644
--- a/third_party/x86inc/README.libvpx
+++ b/third_party/x86inc/README.libvpx
@@ -1,5 +1,5 @@
-URL: http://git.videolan.org/?p=x264.git
-Version: a95584945dd9ce3acc66c6cd8f6796bc4404d40d
+URL: https://git.videolan.org/git/x264.git
+Version: d23d18655249944c1ca894b451e2c82c7a584c62
License: ISC
License File: LICENSE
@@ -13,12 +13,8 @@
Manage name mangling (prefixing with '_') manually because 'PREFIX' does not
exist in libvpx.
Expand PIC default to macho64 and respect CONFIG_PIC from libvpx
-Catch all elf formats for 'hidden' status and SECTION notes.
-Avoid 'amdnop' when building with nasm.
Set 'private_extern' visibility for macho targets.
Copy PIC 'GLOBAL' macros from x86_abi_support.asm
Use .text instead of .rodata on macho to avoid broken tables in PIC mode.
Use .text with no alignment for aout
Only use 'hidden' visibility with Chromium
-Move '%use smartalign' for nasm out of 'INIT_CPUFLAGS' and before
- 'ALIGNMODE'.
diff --git a/third_party/x86inc/x86inc.asm b/third_party/x86inc/x86inc.asm
index e7d3fa5..fc65bd3 100644
--- a/third_party/x86inc/x86inc.asm
+++ b/third_party/x86inc/x86inc.asm
@@ -1,7 +1,7 @@
;*****************************************************************************
;* x86inc.asm: x264asm abstraction layer
;*****************************************************************************
-;* Copyright (C) 2005-2015 x264 project
+;* Copyright (C) 2005-2016 x264 project
;*
;* Authors: Loren Merritt <lorenm@u.washington.edu>
;* Anton Mitrofanov <BugMaster@narod.ru>
@@ -66,16 +66,35 @@
%endif
%endif
-%ifidn __OUTPUT_FORMAT__,elf32
- %define mangle(x) x
+%define FORMAT_ELF 0
+%ifidn __OUTPUT_FORMAT__,elf
+ %define FORMAT_ELF 1
+%elifidn __OUTPUT_FORMAT__,elf32
+ %define FORMAT_ELF 1
%elifidn __OUTPUT_FORMAT__,elf64
- %define mangle(x) x
-%elifidn __OUTPUT_FORMAT__,x64
- %define mangle(x) x
-%elifidn __OUTPUT_FORMAT__,win64
- %define mangle(x) x
+ %define FORMAT_ELF 1
+%endif
+
+%define FORMAT_MACHO 0
+%ifidn __OUTPUT_FORMAT__,macho32
+ %define FORMAT_MACHO 1
+%elifidn __OUTPUT_FORMAT__,macho64
+ %define FORMAT_MACHO 1
+%endif
+
+; Set PREFIX for libvpx builds.
+%if FORMAT_ELF
+ %undef PREFIX
+%elif WIN64
+ %undef PREFIX
%else
+ %define PREFIX
+%endif
+
+%ifdef PREFIX
%define mangle(x) _ %+ x
+%else
+ %define mangle(x) x
%endif
; In some instances macho32 tables get misaligned when using .rodata.
@@ -94,14 +113,6 @@
%endif
%endmacro
-%macro SECTION_TEXT 0-1 16
- %ifidn __OUTPUT_FORMAT__,aout
- SECTION .text
- %else
- SECTION .text align=%1
- %endif
-%endmacro
-
; PIC macros are copied from vpx_ports/x86_abi_support.asm. The "define PIC"
; from original code is added in for 64bit.
%ifidn __OUTPUT_FORMAT__,elf32
@@ -190,6 +201,10 @@
%endif
; Done with PIC macros
+%ifdef __NASM_VER__
+ %use smartalign
+%endif
+
; Macros to eliminate most code duplication between x86_32 and x86_64:
; Currently this works only for leaf functions which load all their arguments
; into registers at the start, and make no other use of the stack. Luckily that
@@ -237,6 +252,7 @@
%define r%1w %2w
%define r%1b %2b
%define r%1h %2h
+ %define %2q %2
%if %0 == 2
%define r%1m %2d
%define r%1mp %2
@@ -261,9 +277,9 @@
%define e%1h %3
%define r%1b %2
%define e%1b %2
-%if ARCH_X86_64 == 0
- %define r%1 e%1
-%endif
+ %if ARCH_X86_64 == 0
+ %define r%1 e%1
+ %endif
%endmacro
DECLARE_REG_SIZE ax, al, ah
@@ -373,7 +389,7 @@
%macro ASSERT 1
%if (%1) == 0
- %error assert failed
+ %error assertion ``%1'' failed
%endif
%endmacro
@@ -464,8 +480,10 @@
%if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT
%if %1 > 0
%assign regs_used (regs_used + 1)
- %elif ARCH_X86_64 && regs_used == num_args && num_args <= 4 + UNIX64 * 2
- %warning "Stack pointer will overwrite register argument"
+ %endif
+ %if ARCH_X86_64 && regs_used < 5 + UNIX64 * 3
+ ; Ensure that we don't clobber any registers containing arguments
+ %assign regs_used 5 + UNIX64 * 3
%endif
%endif
%endif
@@ -579,9 +597,9 @@
%macro RET 0
WIN64_RESTORE_XMM_INTERNAL rsp
POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7
-%if mmsize == 32
- vzeroupper
-%endif
+ %if mmsize == 32
+ vzeroupper
+ %endif
AUTO_REP_RET
%endmacro
@@ -618,17 +636,17 @@
%define has_epilogue regs_used > 9 || mmsize == 32 || stack_size > 0
%macro RET 0
-%if stack_size_padded > 0
-%if required_stack_alignment > STACK_ALIGNMENT
- mov rsp, rstkm
-%else
- add rsp, stack_size_padded
-%endif
-%endif
+ %if stack_size_padded > 0
+ %if required_stack_alignment > STACK_ALIGNMENT
+ mov rsp, rstkm
+ %else
+ add rsp, stack_size_padded
+ %endif
+ %endif
POP_IF_USED 14, 13, 12, 11, 10, 9
-%if mmsize == 32
- vzeroupper
-%endif
+ %if mmsize == 32
+ vzeroupper
+ %endif
AUTO_REP_RET
%endmacro
@@ -674,29 +692,29 @@
%define has_epilogue regs_used > 3 || mmsize == 32 || stack_size > 0
%macro RET 0
-%if stack_size_padded > 0
-%if required_stack_alignment > STACK_ALIGNMENT
- mov rsp, rstkm
-%else
- add rsp, stack_size_padded
-%endif
-%endif
+ %if stack_size_padded > 0
+ %if required_stack_alignment > STACK_ALIGNMENT
+ mov rsp, rstkm
+ %else
+ add rsp, stack_size_padded
+ %endif
+ %endif
POP_IF_USED 6, 5, 4, 3
-%if mmsize == 32
- vzeroupper
-%endif
+ %if mmsize == 32
+ vzeroupper
+ %endif
AUTO_REP_RET
%endmacro
%endif ;======================================================================
%if WIN64 == 0
-%macro WIN64_SPILL_XMM 1
-%endmacro
-%macro WIN64_RESTORE_XMM 1
-%endmacro
-%macro WIN64_PUSH_XMM 0
-%endmacro
+ %macro WIN64_SPILL_XMM 1
+ %endmacro
+ %macro WIN64_RESTORE_XMM 1
+ %endmacro
+ %macro WIN64_PUSH_XMM 0
+ %endmacro
%endif
; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either
@@ -709,24 +727,26 @@
%else
rep ret
%endif
+ annotate_function_size
%endmacro
%define last_branch_adr $$
%macro AUTO_REP_RET 0
- %ifndef cpuflags
- times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ != last_branch_adr.
- %elif notcpuflag(ssse3)
- times ((last_branch_adr-$)>>31)+1 rep
+ %if notcpuflag(ssse3)
+ times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ == last_branch_adr.
%endif
ret
+ annotate_function_size
%endmacro
%macro BRANCH_INSTR 0-*
%rep %0
%macro %1 1-2 %1
%2 %1
- %%branch_instr:
- %xdefine last_branch_adr %%branch_instr
+ %if notcpuflag(ssse3)
+ %%branch_instr equ $
+ %xdefine last_branch_adr %%branch_instr
+ %endif
%endmacro
%rotate 1
%endrep
@@ -741,6 +761,7 @@
%elif %2
jmp %1
%endif
+ annotate_function_size
%endmacro
;=============================================================================
@@ -762,6 +783,7 @@
cglobal_internal 0, %1 %+ SUFFIX, %2
%endmacro
%macro cglobal_internal 2-3+
+ annotate_function_size
%if %1
%xdefine %%FUNCTION_PREFIX private_prefix
; libvpx explicitly sets visibility in shared object builds. Avoid
@@ -782,17 +804,10 @@
CAT_XDEFINE cglobaled_, %2, 1
%endif
%xdefine current_function %2
- %ifidn __OUTPUT_FORMAT__,elf32
+ %xdefine current_function_section __SECT__
+ %if FORMAT_ELF
global %2:function %%VISIBILITY
- %elifidn __OUTPUT_FORMAT__,elf64
- global %2:function %%VISIBILITY
- %elifidn __OUTPUT_FORMAT__,macho32
- %ifdef __NASM_VER__
- global %2
- %else
- global %2:private_extern
- %endif
- %elifidn __OUTPUT_FORMAT__,macho64
+ %elif FORMAT_MACHO
%ifdef __NASM_VER__
global %2
%else
@@ -822,16 +837,16 @@
; like cextern, but without the prefix
%macro cextern_naked 1
- %xdefine %1 mangle(%1)
+ %ifdef PREFIX
+ %xdefine %1 mangle(%1)
+ %endif
CAT_XDEFINE cglobaled_, %1, 1
extern %1
%endmacro
%macro const 1-2+
%xdefine %1 mangle(private_prefix %+ _ %+ %1)
- %ifidn __OUTPUT_FORMAT__,elf32
- global %1:data hidden
- %elifidn __OUTPUT_FORMAT__,elf64
+ %if FORMAT_ELF
global %1:data hidden
%else
global %1
@@ -839,14 +854,29 @@
%1: %2
%endmacro
-; This is needed for ELF, otherwise the GNU linker assumes the stack is
-; executable by default.
-%ifidn __OUTPUT_FORMAT__,elf32
-SECTION .note.GNU-stack noalloc noexec nowrite progbits
-%elifidn __OUTPUT_FORMAT__,elf64
-SECTION .note.GNU-stack noalloc noexec nowrite progbits
+; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default.
+%if FORMAT_ELF
+ [SECTION .note.GNU-stack noalloc noexec nowrite progbits]
%endif
+; Tell debuggers how large the function was.
+; This may be invoked multiple times per function; we rely on later instances overriding earlier ones.
+; This is invoked by RET and similar macros, and also cglobal does it for the previous function,
+; but if the last function in a source file doesn't use any of the standard macros for its epilogue,
+; then its size might be unspecified.
+%macro annotate_function_size 0
+ %ifdef __YASM_VER__
+ %ifdef current_function
+ %if FORMAT_ELF
+ current_function_section
+ %%ecf equ $
+ size current_function %%ecf - current_function
+ __SECT__
+ %endif
+ %endif
+ %endif
+%endmacro
+
; cpuflags
%assign cpuflags_mmx (1<<0)
@@ -875,12 +905,9 @@
%assign cpuflags_bmi1 (1<<22)|cpuflags_lzcnt
%assign cpuflags_bmi2 (1<<23)|cpuflags_bmi1
-%define cpuflag(x) ((cpuflags & (cpuflags_ %+ x)) == (cpuflags_ %+ x))
-%define notcpuflag(x) ((cpuflags & (cpuflags_ %+ x)) != (cpuflags_ %+ x))
-
-%ifdef __NASM_VER__
- %use smartalign
-%endif
+; Returns a boolean value expressing whether or not the specified cpuflag is enabled.
+%define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1)
+%define notcpuflag(x) (cpuflag(x) ^ 1)
; Takes an arbitrary number of cpuflags from the above list.
; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu.
@@ -917,12 +944,18 @@
%endif
%endif
- %ifdef __NASM_VER__
- ALIGNMODE k7
- %elif ARCH_X86_64 || cpuflag(sse2)
- CPU amdnop
+ %if ARCH_X86_64 || cpuflag(sse2)
+ %ifdef __NASM_VER__
+ ALIGNMODE k8
+ %else
+ CPU amdnop
+ %endif
%else
- CPU basicnop
+ %ifdef __NASM_VER__
+ ALIGNMODE nop
+ %else
+ CPU basicnop
+ %endif
%endif
%endmacro
@@ -951,14 +984,14 @@
%define movnta movntq
%assign %%i 0
%rep 8
- CAT_XDEFINE m, %%i, mm %+ %%i
- CAT_XDEFINE nnmm, %%i, %%i
- %assign %%i %%i+1
+ CAT_XDEFINE m, %%i, mm %+ %%i
+ CAT_XDEFINE nnmm, %%i, %%i
+ %assign %%i %%i+1
%endrep
%rep 8
- CAT_UNDEF m, %%i
- CAT_UNDEF nnmm, %%i
- %assign %%i %%i+1
+ CAT_UNDEF m, %%i
+ CAT_UNDEF nnmm, %%i
+ %assign %%i %%i+1
%endrep
INIT_CPUFLAGS %1
%endmacro
@@ -969,7 +1002,7 @@
%define mmsize 16
%define num_mmregs 8
%if ARCH_X86_64
- %define num_mmregs 16
+ %define num_mmregs 16
%endif
%define mova movdqa
%define movu movdqu
@@ -977,9 +1010,9 @@
%define movnta movntdq
%assign %%i 0
%rep num_mmregs
- CAT_XDEFINE m, %%i, xmm %+ %%i
- CAT_XDEFINE nnxmm, %%i, %%i
- %assign %%i %%i+1
+ CAT_XDEFINE m, %%i, xmm %+ %%i
+ CAT_XDEFINE nnxmm, %%i, %%i
+ %assign %%i %%i+1
%endrep
INIT_CPUFLAGS %1
%endmacro
@@ -990,7 +1023,7 @@
%define mmsize 32
%define num_mmregs 8
%if ARCH_X86_64
- %define num_mmregs 16
+ %define num_mmregs 16
%endif
%define mova movdqa
%define movu movdqu
@@ -998,9 +1031,9 @@
%define movnta movntdq
%assign %%i 0
%rep num_mmregs
- CAT_XDEFINE m, %%i, ymm %+ %%i
- CAT_XDEFINE nnymm, %%i, %%i
- %assign %%i %%i+1
+ CAT_XDEFINE m, %%i, ymm %+ %%i
+ CAT_XDEFINE nnymm, %%i, %%i
+ %assign %%i %%i+1
%endrep
INIT_CPUFLAGS %1
%endmacro
@@ -1024,7 +1057,7 @@
%assign i 0
%rep 16
DECLARE_MMCAST i
-%assign i i+1
+ %assign i i+1
%endrep
; I often want to use macros that permute their arguments. e.g. there's no
@@ -1042,23 +1075,23 @@
; doesn't cost any cycles.
%macro PERMUTE 2-* ; takes a list of pairs to swap
-%rep %0/2
- %xdefine %%tmp%2 m%2
- %rotate 2
-%endrep
-%rep %0/2
- %xdefine m%1 %%tmp%2
- CAT_XDEFINE nn, m%1, %1
- %rotate 2
-%endrep
+ %rep %0/2
+ %xdefine %%tmp%2 m%2
+ %rotate 2
+ %endrep
+ %rep %0/2
+ %xdefine m%1 %%tmp%2
+ CAT_XDEFINE nn, m%1, %1
+ %rotate 2
+ %endrep
%endmacro
%macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs)
-%ifnum %1 ; SWAP 0, 1, ...
- SWAP_INTERNAL_NUM %1, %2
-%else ; SWAP m0, m1, ...
- SWAP_INTERNAL_NAME %1, %2
-%endif
+ %ifnum %1 ; SWAP 0, 1, ...
+ SWAP_INTERNAL_NUM %1, %2
+ %else ; SWAP m0, m1, ...
+ SWAP_INTERNAL_NAME %1, %2
+ %endif
%endmacro
%macro SWAP_INTERNAL_NUM 2-*
@@ -1068,7 +1101,7 @@
%xdefine m%2 %%tmp
CAT_XDEFINE nn, m%1, %1
CAT_XDEFINE nn, m%2, %2
- %rotate 1
+ %rotate 1
%endrep
%endmacro
@@ -1076,7 +1109,7 @@
%xdefine %%args nn %+ %1
%rep %0-1
%xdefine %%args %%args, nn %+ %2
- %rotate 1
+ %rotate 1
%endrep
SWAP_INTERNAL_NUM %%args
%endmacro
@@ -1093,7 +1126,7 @@
%assign %%i 0
%rep num_mmregs
CAT_XDEFINE %%f, %%i, m %+ %%i
- %assign %%i %%i+1
+ %assign %%i %%i+1
%endrep
%endmacro
@@ -1103,20 +1136,20 @@
%rep num_mmregs
CAT_XDEFINE m, %%i, %1_m %+ %%i
CAT_XDEFINE nn, m %+ %%i, %%i
- %assign %%i %%i+1
+ %assign %%i %%i+1
%endrep
%endif
%endmacro
; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't
%macro call 1
- call_internal %1, %1 %+ SUFFIX
+ call_internal %1 %+ SUFFIX, %1
%endmacro
%macro call_internal 2
- %xdefine %%i %1
- %ifndef cglobaled_%1
- %ifdef cglobaled_%2
- %xdefine %%i %2
+ %xdefine %%i %2
+ %ifndef cglobaled_%2
+ %ifdef cglobaled_%1
+ %xdefine %%i %1
%endif
%endif
call %%i
@@ -1159,7 +1192,7 @@
%endif
CAT_XDEFINE sizeofxmm, i, 16
CAT_XDEFINE sizeofymm, i, 32
-%assign i i+1
+ %assign i i+1
%endrep
%undef i
@@ -1536,7 +1569,7 @@
%else
CAT_XDEFINE q, j, i
%endif
-%assign i i+1
+ %assign i i+1
%endrep
%undef i
%undef j
@@ -1559,55 +1592,54 @@
FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation
FMA_INSTR pmadcswd, pmaddwd, paddd
-; convert FMA4 to FMA3 if possible
-%macro FMA4_INSTR 4
- %macro %1 4-8 %1, %2, %3, %4
- %if cpuflag(fma4)
- v%5 %1, %2, %3, %4
- %elifidn %1, %2
- v%6 %1, %4, %3 ; %1 = %1 * %3 + %4
- %elifidn %1, %3
- v%7 %1, %2, %4 ; %1 = %2 * %1 + %4
- %elifidn %1, %4
- v%8 %1, %2, %3 ; %1 = %2 * %3 + %1
- %else
- %error fma3 emulation of ``%5 %1, %2, %3, %4'' is not supported
- %endif
- %endmacro
+; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax.
+; FMA3 is only possible if dst is the same as one of the src registers.
+; Either src2 or src3 can be a memory operand.
+%macro FMA4_INSTR 2-*
+ %push fma4_instr
+ %xdefine %$prefix %1
+ %rep %0 - 1
+ %macro %$prefix%2 4-6 %$prefix, %2
+ %if notcpuflag(fma3) && notcpuflag(fma4)
+ %error use of ``%5%6'' fma instruction in cpuname function: current_function
+ %elif cpuflag(fma4)
+ v%5%6 %1, %2, %3, %4
+ %elifidn %1, %2
+ ; If %3 or %4 is a memory operand it needs to be encoded as the last operand.
+ %ifid %3
+ v%{5}213%6 %2, %3, %4
+ %else
+ v%{5}132%6 %2, %4, %3
+ %endif
+ %elifidn %1, %3
+ v%{5}213%6 %3, %2, %4
+ %elifidn %1, %4
+ v%{5}231%6 %4, %2, %3
+ %else
+ %error fma3 emulation of ``%5%6 %1, %2, %3, %4'' is not supported
+ %endif
+ %endmacro
+ %rotate 1
+ %endrep
+ %pop
%endmacro
-FMA4_INSTR fmaddpd, fmadd132pd, fmadd213pd, fmadd231pd
-FMA4_INSTR fmaddps, fmadd132ps, fmadd213ps, fmadd231ps
-FMA4_INSTR fmaddsd, fmadd132sd, fmadd213sd, fmadd231sd
-FMA4_INSTR fmaddss, fmadd132ss, fmadd213ss, fmadd231ss
+FMA4_INSTR fmadd, pd, ps, sd, ss
+FMA4_INSTR fmaddsub, pd, ps
+FMA4_INSTR fmsub, pd, ps, sd, ss
+FMA4_INSTR fmsubadd, pd, ps
+FMA4_INSTR fnmadd, pd, ps, sd, ss
+FMA4_INSTR fnmsub, pd, ps, sd, ss
-FMA4_INSTR fmaddsubpd, fmaddsub132pd, fmaddsub213pd, fmaddsub231pd
-FMA4_INSTR fmaddsubps, fmaddsub132ps, fmaddsub213ps, fmaddsub231ps
-FMA4_INSTR fmsubaddpd, fmsubadd132pd, fmsubadd213pd, fmsubadd231pd
-FMA4_INSTR fmsubaddps, fmsubadd132ps, fmsubadd213ps, fmsubadd231ps
-
-FMA4_INSTR fmsubpd, fmsub132pd, fmsub213pd, fmsub231pd
-FMA4_INSTR fmsubps, fmsub132ps, fmsub213ps, fmsub231ps
-FMA4_INSTR fmsubsd, fmsub132sd, fmsub213sd, fmsub231sd
-FMA4_INSTR fmsubss, fmsub132ss, fmsub213ss, fmsub231ss
-
-FMA4_INSTR fnmaddpd, fnmadd132pd, fnmadd213pd, fnmadd231pd
-FMA4_INSTR fnmaddps, fnmadd132ps, fnmadd213ps, fnmadd231ps
-FMA4_INSTR fnmaddsd, fnmadd132sd, fnmadd213sd, fnmadd231sd
-FMA4_INSTR fnmaddss, fnmadd132ss, fnmadd213ss, fnmadd231ss
-
-FMA4_INSTR fnmsubpd, fnmsub132pd, fnmsub213pd, fnmsub231pd
-FMA4_INSTR fnmsubps, fnmsub132ps, fnmsub213ps, fnmsub231ps
-FMA4_INSTR fnmsubsd, fnmsub132sd, fnmsub213sd, fnmsub231sd
-FMA4_INSTR fnmsubss, fnmsub132ss, fnmsub213ss, fnmsub231ss
-
-; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug
-%if ARCH_X86_64 == 0
-%macro vpbroadcastq 2
-%if sizeof%1 == 16
- movddup %1, %2
-%else
- vbroadcastsd %1, %2
-%endif
-%endmacro
+; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0)
+%ifdef __YASM_VER__
+ %if __YASM_VERSION_ID__ < 0x01030000 && ARCH_X86_64 == 0
+ %macro vpbroadcastq 2
+ %if sizeof%1 == 16
+ movddup %1, %2
+ %else
+ vbroadcastsd %1, %2
+ %endif
+ %endmacro
+ %endif
%endif
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 9ce137d..7fc5733 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -859,7 +859,7 @@
VPX_CODEC_CORRUPT_FRAME, "Invalid block size.");
}
- vpx_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
+ vp9_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
if (mi->skip) {
dec_reset_skip_context(xd);
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 8604420..3bd42ec 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -149,17 +149,12 @@
}
static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
- int mi_row, int mi_col, vpx_reader *r) {
+ int mi_row, int mi_col, vpx_reader *r,
+ int x_mis, int y_mis) {
struct segmentation *const seg = &cm->seg;
MODE_INFO *const mi = xd->mi[0];
int predicted_segment_id, segment_id;
const int mi_offset = mi_row * cm->mi_cols + mi_col;
- const int bw = xd->plane[0].n4_w >> 1;
- const int bh = xd->plane[0].n4_h >> 1;
-
- // TODO(slavarnway): move x_mis, y_mis into xd ?????
- const int x_mis = VPXMIN(cm->mi_cols - mi_col, bw);
- const int y_mis = VPXMIN(cm->mi_rows - mi_row, bh);
if (!seg->enabled)
return 0; // Default for disabled segmentation
@@ -202,19 +197,14 @@
static void read_intra_frame_mode_info(VP9_COMMON *const cm,
MACROBLOCKD *const xd,
- int mi_row, int mi_col, vpx_reader *r) {
+ int mi_row, int mi_col, vpx_reader *r,
+ int x_mis, int y_mis) {
MODE_INFO *const mi = xd->mi[0];
const MODE_INFO *above_mi = xd->above_mi;
const MODE_INFO *left_mi = xd->left_mi;
const BLOCK_SIZE bsize = mi->sb_type;
int i;
const int mi_offset = mi_row * cm->mi_cols + mi_col;
- const int bw = xd->plane[0].n4_w >> 1;
- const int bh = xd->plane[0].n4_h >> 1;
-
- // TODO(slavarnway): move x_mis, y_mis into xd ?????
- const int x_mis = VPXMIN(cm->mi_cols - mi_col, bw);
- const int y_mis = VPXMIN(cm->mi_rows - mi_row, bh);
mi->segment_id = read_intra_segment_id(cm, mi_offset, x_mis, y_mis, r);
mi->skip = read_skip(cm, xd, mi->segment_id, r);
@@ -839,12 +829,14 @@
static void read_inter_frame_mode_info(VP9Decoder *const pbi,
MACROBLOCKD *const xd,
- int mi_row, int mi_col, vpx_reader *r) {
+ int mi_row, int mi_col, vpx_reader *r,
+ int x_mis, int y_mis) {
VP9_COMMON *const cm = &pbi->common;
MODE_INFO *const mi = xd->mi[0];
int inter_block;
- mi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
+ mi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r, x_mis,
+ y_mis);
mi->skip = read_skip(cm, xd, mi->segment_id, r);
inter_block = read_is_inter_block(cm, xd, mi->segment_id, r);
mi->tx_size = read_tx_size(cm, xd, !mi->skip || !inter_block, r);
@@ -860,7 +852,7 @@
memcpy(dst, src, sizeof(*dst) * 2);
}
-void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
+void vp9_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
int mi_row, int mi_col, vpx_reader *r,
int x_mis, int y_mis) {
VP9_COMMON *const cm = &pbi->common;
@@ -869,9 +861,9 @@
int w, h;
if (frame_is_intra_only(cm)) {
- read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r);
+ read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis);
} else {
- read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r);
+ read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
for (h = 0; h < y_mis; ++h) {
for (w = 0; w < x_mis; ++w) {
diff --git a/vp9/decoder/vp9_decodemv.h b/vp9/decoder/vp9_decodemv.h
index 75f568c..45569ec 100644
--- a/vp9/decoder/vp9_decodemv.h
+++ b/vp9/decoder/vp9_decodemv.h
@@ -19,7 +19,7 @@
extern "C" {
#endif
-void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
+void vp9_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
int mi_row, int mi_col, vpx_reader *r,
int x_mis, int y_mis);
diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c
index 0a02bde..c2ba276 100644
--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -198,6 +198,9 @@
refresh_this_block = 1;
}
+ if (cpi->oxcf.rc_mode == VPX_VBR && mi->ref_frame[0] == GOLDEN_FRAME)
+ refresh_this_block = 0;
+
// If this block is labeled for refresh, check if we should reset the
// segment_id.
if (cyclic_refresh_segment_id_boosted(mi->segment_id)) {
@@ -305,6 +308,8 @@
rc->baseline_gf_interval = VPXMIN(4 * (100 / cr->percent_refresh), 40);
else
rc->baseline_gf_interval = 40;
+ if (cpi->oxcf.rc_mode == VPX_VBR)
+ rc->baseline_gf_interval = 20;
}
// Update some encoding stats (from the just encoded frame). If this frame's
@@ -504,6 +509,18 @@
cr->motion_thresh = 4;
cr->rate_boost_fac = 12;
}
+ if (cpi->oxcf.rc_mode == VPX_VBR) {
+ // To be adjusted for VBR mode, e.g., based on gf period and boost.
+ // For now use smaller qp-delta (than CBR), no second boosted seg, and
+ // turn-off (no refresh) on golden refresh (since it's already boosted).
+ cr->percent_refresh = 10;
+ cr->rate_ratio_qdelta = 1.5;
+ cr->rate_boost_fac = 10;
+ if (cpi->refresh_golden_frame == 1) {
+ cr->percent_refresh = 0;
+ cr->rate_ratio_qdelta = 1.0;
+ }
+ }
}
// Setup cyclic background refresh: set delta q and segmentation map.
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 06d245e..f8f681a 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3363,11 +3363,13 @@
(cpi->oxcf.pass == 0));
// Avoid scaling last_source unless its needed.
- // Last source is currently only used for screen-content mode,
- // if partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
+ // Last source is needed if vp9_avg_source_sad() is used, or if
+ // partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
// estimation is enabled.
if (cpi->unscaled_last_source != NULL &&
(cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+ (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR &&
+ cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5) ||
cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION ||
cpi->noise_estimate.enabled))
cpi->Last_Source = vp9_scale_if_required(cm,
@@ -3377,10 +3379,12 @@
vp9_update_noise_estimate(cpi);
if (cpi->oxcf.pass == 0 &&
- cpi->oxcf.rc_mode == VPX_CBR &&
+ cpi->oxcf.mode == REALTIME &&
+ cpi->oxcf.speed >= 5 &&
cpi->resize_state == 0 &&
cm->frame_type != KEY_FRAME &&
- cpi->oxcf.content == VP9E_CONTENT_SCREEN)
+ (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+ cpi->oxcf.rc_mode == VPX_VBR))
vp9_avg_source_sad(cpi);
// TODO(wonkap/marpan): For 1 pass SVC, since only ZERMOV is allowed for
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 5df2909..d64b5c5 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1469,7 +1469,12 @@
cm->frame_type = INTER_FRAME;
}
if (rc->frames_till_gf_update_due == 0) {
- rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
+ if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0) {
+ vp9_cyclic_refresh_set_golden_update(cpi);
+ } else {
+ rc->baseline_gf_interval =
+ (rc->min_gf_interval + rc->max_gf_interval) / 2;
+ }
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
// NOTE: frames_till_gf_update_due must be <= frames_to_key.
if (rc->frames_till_gf_update_due > rc->frames_to_key) {
@@ -1487,6 +1492,8 @@
else
target = calc_pframe_target_size_one_pass_vbr(cpi);
vp9_rc_set_frame_target(cpi, target);
+ if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0)
+ vp9_cyclic_refresh_update_parameters(cpi);
}
static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
@@ -2010,13 +2017,17 @@
VP9_COMMON * const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
rc->high_source_sad = 0;
- if (cpi->Last_Source != NULL) {
+ if (cpi->Last_Source != NULL &&
+ cpi->Last_Source->y_width == cm->width &&
+ cpi->Last_Source->y_height == cm->height) {
const uint8_t *src_y = cpi->Source->y_buffer;
const int src_ystride = cpi->Source->y_stride;
const uint8_t *last_src_y = cpi->Last_Source->y_buffer;
const int last_src_ystride = cpi->Last_Source->y_stride;
int sbi_row, sbi_col;
const BLOCK_SIZE bsize = BLOCK_64X64;
+ uint32_t min_thresh = 4000;
+ float thresh = 8.0f;
// Loop over sub-sample of frame, and compute average sad over 64x64 blocks.
uint64_t avg_sad = 0;
int num_samples = 0;
@@ -2047,12 +2058,32 @@
// between current and the previous frame value(s). Use a minimum threshold
// for cases where there is small change from content that is completely
// static.
- if (avg_sad > VPXMAX(4000, (rc->avg_source_sad << 3)) &&
+ if (cpi->oxcf.rc_mode == VPX_VBR) {
+ min_thresh = 20000;
+ thresh = 2.0f;
+ }
+ if (avg_sad >
+ VPXMAX(min_thresh, (unsigned int)(rc->avg_source_sad * thresh)) &&
rc->frames_since_key > 1)
rc->high_source_sad = 1;
else
rc->high_source_sad = 0;
- rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1;
+ if (avg_sad > 0)
+ rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1;
+ // For VBR, under scene change/high content change, force golden refresh.
+ if (cpi->oxcf.rc_mode == VPX_VBR &&
+ rc->high_source_sad &&
+ cpi->refresh_golden_frame == 0 &&
+ cpi->ext_refresh_frame_flags_pending == 0) {
+ int target;
+ cpi->refresh_golden_frame = 1;
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval >> 1;
+ if (rc->frames_till_gf_update_due > rc->frames_to_key)
+ rc->frames_till_gf_update_due = rc->frames_to_key;
+ rc->gfu_boost = DEFAULT_GF_BOOST;
+ target = calc_pframe_target_size_one_pass_vbr(cpi);
+ vp9_rc_set_frame_target(cpi, target);
+ }
}
}
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 11df1e4..624d5c9 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -1566,7 +1566,7 @@
// keyframing settings (kf)
VPX_KF_AUTO, // g_kfmode
0, // kf_min_dist
- 9999, // kf_max_dist
+ 128, // kf_max_dist
VPX_SS_DEFAULT_LAYERS, // ss_number_layers
{0},
diff --git a/vpx_dsp/vpx_dsp.mk b/vpx_dsp/vpx_dsp.mk
index e394688..581ec3a 100644
--- a/vpx_dsp/vpx_dsp.mk
+++ b/vpx_dsp/vpx_dsp.mk
@@ -39,6 +39,7 @@
DSP_SRCS-yes += intrapred.c
ifeq ($(CONFIG_USE_X86INC),yes)
+DSP_SRCS-$(HAVE_MMX) += x86/loopfilter_mmx.asm
DSP_SRCS-$(HAVE_SSE) += x86/intrapred_sse2.asm
DSP_SRCS-$(HAVE_SSE2) += x86/intrapred_sse2.asm
DSP_SRCS-$(HAVE_SSSE3) += x86/intrapred_ssse3.asm
@@ -128,7 +129,6 @@
DSP_SRCS-$(ARCH_X86)$(ARCH_X86_64) += x86/loopfilter_sse2.c
DSP_SRCS-$(HAVE_AVX2) += x86/loopfilter_avx2.c
-DSP_SRCS-$(HAVE_MMX) += x86/loopfilter_mmx.asm
DSP_SRCS-$(HAVE_NEON) += arm/loopfilter_neon.c
ifeq ($(HAVE_NEON_ASM),yes)
diff --git a/vpx_dsp/vpx_dsp_rtcd_defs.pl b/vpx_dsp/vpx_dsp_rtcd_defs.pl
index d7835f4..34dd0bc 100644
--- a/vpx_dsp/vpx_dsp_rtcd_defs.pl
+++ b/vpx_dsp/vpx_dsp_rtcd_defs.pl
@@ -543,7 +543,7 @@
$vpx_lpf_vertical_8_dual_neon_asm=vpx_lpf_vertical_8_dual_neon;
add_proto qw/void vpx_lpf_vertical_4/, "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh";
-specialize qw/vpx_lpf_vertical_4 mmx neon dspr2 msa/;
+specialize qw/vpx_lpf_vertical_4 neon dspr2 msa/, "$mmx_x86inc";
add_proto qw/void vpx_lpf_vertical_4_dual/, "uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1";
specialize qw/vpx_lpf_vertical_4_dual sse2 neon dspr2 msa/;
@@ -564,7 +564,7 @@
$vpx_lpf_horizontal_8_dual_neon_asm=vpx_lpf_horizontal_8_dual_neon;
add_proto qw/void vpx_lpf_horizontal_4/, "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh";
-specialize qw/vpx_lpf_horizontal_4 mmx neon dspr2 msa/;
+specialize qw/vpx_lpf_horizontal_4 neon dspr2 msa/, "$mmx_x86inc";
add_proto qw/void vpx_lpf_horizontal_4_dual/, "uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1";
specialize qw/vpx_lpf_horizontal_4_dual sse2 neon dspr2 msa/;
diff --git a/vpx_dsp/x86/loopfilter_mmx.asm b/vpx_dsp/x86/loopfilter_mmx.asm
index 15105e3..3c4c8a5 100644
--- a/vpx_dsp/x86/loopfilter_mmx.asm
+++ b/vpx_dsp/x86/loopfilter_mmx.asm
@@ -1,5 +1,5 @@
;
-; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+; Copyright (c) 2016 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
@@ -8,589 +8,425 @@
; be found in the AUTHORS file in the root of the source tree.
;
-
-%include "vpx_ports/x86_abi_support.asm"
-
-
-;void vpx_lpf_horizontal_4_mmx
-;(
-; unsigned char *src_ptr,
-; int src_pixel_step,
-; const char *blimit,
-; const char *limit,
-; const char *thresh
-;)
-global sym(vpx_lpf_horizontal_4_mmx) PRIVATE
-sym(vpx_lpf_horizontal_4_mmx):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- GET_GOT rbx
- push rsi
- push rdi
- ; end prolog
-
- ALIGN_STACK 16, rax
- sub rsp, 32 ; reserve 32 bytes
- %define t0 [rsp + 0] ;__declspec(align(16)) char t0[8];
- %define t1 [rsp + 16] ;__declspec(align(16)) char t1[8];
-
- mov rsi, arg(0) ;src_ptr
- movsxd rax, dword ptr arg(1) ;src_pixel_step ; destination pitch?
-
- mov rdx, arg(3) ;limit
- movq mm7, [rdx]
- mov rdi, rsi ; rdi points to row +1 for indirect addressing
- add rdi, rax
-
- ; calculate breakout conditions
- movq mm2, [rdi+2*rax] ; q3
- movq mm1, [rsi+2*rax] ; q2
- movq mm6, mm1 ; q2
- psubusb mm1, mm2 ; q2-=q3
- psubusb mm2, mm6 ; q3-=q2
- por mm1, mm2 ; abs(q3-q2)
- psubusb mm1, mm7 ;
-
-
- movq mm4, [rsi+rax] ; q1
- movq mm3, mm4 ; q1
- psubusb mm4, mm6 ; q1-=q2
- psubusb mm6, mm3 ; q2-=q1
- por mm4, mm6 ; abs(q2-q1)
-
- psubusb mm4, mm7
- por mm1, mm4
-
- movq mm4, [rsi] ; q0
- movq mm0, mm4 ; q0
- psubusb mm4, mm3 ; q0-=q1
- psubusb mm3, mm0 ; q1-=q0
- por mm4, mm3 ; abs(q0-q1)
- movq t0, mm4 ; save to t0
- psubusb mm4, mm7
- por mm1, mm4
-
-
- neg rax ; negate pitch to deal with above border
-
- movq mm2, [rsi+4*rax] ; p3
- movq mm4, [rdi+4*rax] ; p2
- movq mm5, mm4 ; p2
- psubusb mm4, mm2 ; p2-=p3
- psubusb mm2, mm5 ; p3-=p2
- por mm4, mm2 ; abs(p3 - p2)
- psubusb mm4, mm7
- por mm1, mm4
-
-
- movq mm4, [rsi+2*rax] ; p1
- movq mm3, mm4 ; p1
- psubusb mm4, mm5 ; p1-=p2
- psubusb mm5, mm3 ; p2-=p1
- por mm4, mm5 ; abs(p2 - p1)
- psubusb mm4, mm7
- por mm1, mm4
-
- movq mm2, mm3 ; p1
-
- movq mm4, [rsi+rax] ; p0
- movq mm5, mm4 ; p0
- psubusb mm4, mm3 ; p0-=p1
- psubusb mm3, mm5 ; p1-=p0
- por mm4, mm3 ; abs(p1 - p0)
- movq t1, mm4 ; save to t1
- psubusb mm4, mm7
- por mm1, mm4
-
- movq mm3, [rdi] ; q1
- movq mm4, mm3 ; q1
- psubusb mm3, mm2 ; q1-=p1
- psubusb mm2, mm4 ; p1-=q1
- por mm2, mm3 ; abs(p1-q1)
- pand mm2, [GLOBAL(tfe)] ; set lsb of each byte to zero
- psrlw mm2, 1 ; abs(p1-q1)/2
-
- movq mm6, mm5 ; p0
- movq mm3, [rsi] ; q0
- psubusb mm5, mm3 ; p0-=q0
- psubusb mm3, mm6 ; q0-=p0
- por mm5, mm3 ; abs(p0 - q0)
- paddusb mm5, mm5 ; abs(p0-q0)*2
- paddusb mm5, mm2 ; abs (p0 - q0) *2 + abs(p1-q1)/2
-
- mov rdx, arg(2) ;blimit ; get blimit
- movq mm7, [rdx] ; blimit
-
- psubusb mm5, mm7 ; abs (p0 - q0) *2 + abs(p1-q1)/2 > blimit
- por mm1, mm5
- pxor mm5, mm5
- pcmpeqb mm1, mm5 ; mask mm1
-
- ; calculate high edge variance
- mov rdx, arg(4) ;thresh ; get thresh
- movq mm7, [rdx] ;
- movq mm4, t0 ; get abs (q1 - q0)
- psubusb mm4, mm7
- movq mm3, t1 ; get abs (p1 - p0)
- psubusb mm3, mm7
- paddb mm4, mm3 ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
-
- pcmpeqb mm4, mm5
-
- pcmpeqb mm5, mm5
- pxor mm4, mm5
-
-
- ; start work on filters
- movq mm2, [rsi+2*rax] ; p1
- movq mm7, [rdi] ; q1
- pxor mm2, [GLOBAL(t80)] ; p1 offset to convert to signed values
- pxor mm7, [GLOBAL(t80)] ; q1 offset to convert to signed values
- psubsb mm2, mm7 ; p1 - q1
- pand mm2, mm4 ; high var mask (hvm)(p1 - q1)
- pxor mm6, [GLOBAL(t80)] ; offset to convert to signed values
- pxor mm0, [GLOBAL(t80)] ; offset to convert to signed values
- movq mm3, mm0 ; q0
- psubsb mm0, mm6 ; q0 - p0
- paddsb mm2, mm0 ; 1 * (q0 - p0) + hvm(p1 - q1)
- paddsb mm2, mm0 ; 2 * (q0 - p0) + hvm(p1 - q1)
- paddsb mm2, mm0 ; 3 * (q0 - p0) + hvm(p1 - q1)
- pand mm1, mm2 ; mask filter values we don't care about
- movq mm2, mm1
- paddsb mm1, [GLOBAL(t4)] ; 3* (q0 - p0) + hvm(p1 - q1) + 4
- paddsb mm2, [GLOBAL(t3)] ; 3* (q0 - p0) + hvm(p1 - q1) + 3
-
- pxor mm0, mm0 ;
- pxor mm5, mm5
- punpcklbw mm0, mm2 ;
- punpckhbw mm5, mm2 ;
- psraw mm0, 11 ;
- psraw mm5, 11
- packsswb mm0, mm5
- movq mm2, mm0 ; (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
-
- pxor mm0, mm0 ; 0
- movq mm5, mm1 ; abcdefgh
- punpcklbw mm0, mm1 ; e0f0g0h0
- psraw mm0, 11 ; sign extended shift right by 3
- pxor mm1, mm1 ; 0
- punpckhbw mm1, mm5 ; a0b0c0d0
- psraw mm1, 11 ; sign extended shift right by 3
- movq mm5, mm0 ; save results
-
- packsswb mm0, mm1 ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
- paddsw mm5, [GLOBAL(ones)]
- paddsw mm1, [GLOBAL(ones)]
- psraw mm5, 1 ; partial shifted one more time for 2nd tap
- psraw mm1, 1 ; partial shifted one more time for 2nd tap
- packsswb mm5, mm1 ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
- pandn mm4, mm5 ; high edge variance additive
-
- paddsb mm6, mm2 ; p0+= p0 add
- pxor mm6, [GLOBAL(t80)] ; unoffset
- movq [rsi+rax], mm6 ; write back
-
- movq mm6, [rsi+2*rax] ; p1
- pxor mm6, [GLOBAL(t80)] ; reoffset
- paddsb mm6, mm4 ; p1+= p1 add
- pxor mm6, [GLOBAL(t80)] ; unoffset
- movq [rsi+2*rax], mm6 ; write back
-
- psubsb mm3, mm0 ; q0-= q0 add
- pxor mm3, [GLOBAL(t80)] ; unoffset
- movq [rsi], mm3 ; write back
-
- psubsb mm7, mm4 ; q1-= q1 add
- pxor mm7, [GLOBAL(t80)] ; unoffset
- movq [rdi], mm7 ; write back
-
- add rsp, 32
- pop rsp
- ; begin epilog
- pop rdi
- pop rsi
- RESTORE_GOT
- UNSHADOW_ARGS
- pop rbp
- ret
-
-
-;void vpx_lpf_vertical_4_mmx
-;(
-; unsigned char *src_ptr,
-; int src_pixel_step,
-; const char *blimit,
-; const char *limit,
-; const char *thresh
-;)
-global sym(vpx_lpf_vertical_4_mmx) PRIVATE
-sym(vpx_lpf_vertical_4_mmx):
- push rbp
- mov rbp, rsp
- SHADOW_ARGS_TO_STACK 5
- GET_GOT rbx
- push rsi
- push rdi
- ; end prolog
-
- ALIGN_STACK 16, rax
- sub rsp, 64 ; reserve 64 bytes
- %define t0 [rsp + 0] ;__declspec(align(16)) char t0[8];
- %define t1 [rsp + 16] ;__declspec(align(16)) char t1[8];
- %define srct [rsp + 32] ;__declspec(align(16)) char srct[32];
-
- mov rsi, arg(0) ;src_ptr
- movsxd rax, dword ptr arg(1) ;src_pixel_step ; destination pitch?
-
- lea rsi, [rsi + rax*4 - 4]
-
- mov rdi, rsi ; rdi points to row +1 for indirect addressing
- add rdi, rax
-
-
- ;transpose
- movq mm6, [rsi+2*rax] ; 67 66 65 64 63 62 61 60
- movq mm7, mm6 ; 77 76 75 74 73 72 71 70
-
- punpckhbw mm7, [rdi+2*rax] ; 77 67 76 66 75 65 74 64
- punpcklbw mm6, [rdi+2*rax] ; 73 63 72 62 71 61 70 60
-
- movq mm4, [rsi] ; 47 46 45 44 43 42 41 40
- movq mm5, mm4 ; 47 46 45 44 43 42 41 40
-
- punpckhbw mm5, [rsi+rax] ; 57 47 56 46 55 45 54 44
- punpcklbw mm4, [rsi+rax] ; 53 43 52 42 51 41 50 40
-
- movq mm3, mm5 ; 57 47 56 46 55 45 54 44
- punpckhwd mm5, mm7 ; 77 67 57 47 76 66 56 46
-
- punpcklwd mm3, mm7 ; 75 65 55 45 74 64 54 44
- movq mm2, mm4 ; 53 43 52 42 51 41 50 40
-
- punpckhwd mm4, mm6 ; 73 63 53 43 72 62 52 42
- punpcklwd mm2, mm6 ; 71 61 51 41 70 60 50 40
-
- neg rax
- movq mm6, [rsi+rax*2] ; 27 26 25 24 23 22 21 20
-
- movq mm1, mm6 ; 27 26 25 24 23 22 21 20
- punpckhbw mm6, [rsi+rax] ; 37 27 36 36 35 25 34 24
-
- punpcklbw mm1, [rsi+rax] ; 33 23 32 22 31 21 30 20
- movq mm7, [rsi+rax*4]; ; 07 06 05 04 03 02 01 00
-
- punpckhbw mm7, [rdi+rax*4] ; 17 07 16 06 15 05 14 04
- movq mm0, mm7 ; 17 07 16 06 15 05 14 04
-
- punpckhwd mm7, mm6 ; 37 27 17 07 36 26 16 06
- punpcklwd mm0, mm6 ; 35 25 15 05 34 24 14 04
-
- movq mm6, mm7 ; 37 27 17 07 36 26 16 06
- punpckhdq mm7, mm5 ; 77 67 57 47 37 27 17 07 = q3
-
- punpckldq mm6, mm5 ; 76 66 56 46 36 26 16 06 = q2
-
- movq mm5, mm6 ; 76 66 56 46 36 26 16 06
- psubusb mm5, mm7 ; q2-q3
-
- psubusb mm7, mm6 ; q3-q2
- por mm7, mm5; ; mm7=abs (q3-q2)
-
- movq mm5, mm0 ; 35 25 15 05 34 24 14 04
- punpckhdq mm5, mm3 ; 75 65 55 45 35 25 15 05 = q1
-
- punpckldq mm0, mm3 ; 74 64 54 44 34 24 15 04 = q0
- movq mm3, mm5 ; 75 65 55 45 35 25 15 05 = q1
-
- psubusb mm3, mm6 ; q1-q2
- psubusb mm6, mm5 ; q2-q1
-
- por mm6, mm3 ; mm6=abs(q2-q1)
- lea rdx, srct
-
- movq [rdx+24], mm5 ; save q1
- movq [rdx+16], mm0 ; save q0
-
- movq mm3, [rsi+rax*4] ; 07 06 05 04 03 02 01 00
- punpcklbw mm3, [rdi+rax*4] ; 13 03 12 02 11 01 10 00
-
- movq mm0, mm3 ; 13 03 12 02 11 01 10 00
- punpcklwd mm0, mm1 ; 31 21 11 01 30 20 10 00
-
- punpckhwd mm3, mm1 ; 33 23 13 03 32 22 12 02
- movq mm1, mm0 ; 31 21 11 01 30 20 10 00
-
- punpckldq mm0, mm2 ; 70 60 50 40 30 20 10 00 =p3
- punpckhdq mm1, mm2 ; 71 61 51 41 31 21 11 01 =p2
-
- movq mm2, mm1 ; 71 61 51 41 31 21 11 01 =p2
- psubusb mm2, mm0 ; p2-p3
-
- psubusb mm0, mm1 ; p3-p2
- por mm0, mm2 ; mm0=abs(p3-p2)
-
- movq mm2, mm3 ; 33 23 13 03 32 22 12 02
- punpckldq mm2, mm4 ; 72 62 52 42 32 22 12 02 = p1
-
- punpckhdq mm3, mm4 ; 73 63 53 43 33 23 13 03 = p0
- movq [rdx+8], mm3 ; save p0
-
- movq [rdx], mm2 ; save p1
- movq mm5, mm2 ; mm5 = p1
-
- psubusb mm2, mm1 ; p1-p2
- psubusb mm1, mm5 ; p2-p1
-
- por mm1, mm2 ; mm1=abs(p2-p1)
- mov rdx, arg(3) ;limit
-
- movq mm4, [rdx] ; mm4 = limit
- psubusb mm7, mm4
-
- psubusb mm0, mm4
- psubusb mm1, mm4
-
- psubusb mm6, mm4
- por mm7, mm6
-
- por mm0, mm1
- por mm0, mm7 ; abs(q3-q2) > limit || abs(p3-p2) > limit ||abs(p2-p1) > limit || abs(q2-q1) > limit
-
- movq mm1, mm5 ; p1
-
- movq mm7, mm3 ; mm3=mm7=p0
- psubusb mm7, mm5 ; p0 - p1
-
- psubusb mm5, mm3 ; p1 - p0
- por mm5, mm7 ; abs(p1-p0)
-
- movq t0, mm5 ; save abs(p1-p0)
- lea rdx, srct
-
- psubusb mm5, mm4
- por mm0, mm5 ; mm0=mask
-
- movq mm5, [rdx+16] ; mm5=q0
- movq mm7, [rdx+24] ; mm7=q1
-
- movq mm6, mm5 ; mm6=q0
- movq mm2, mm7 ; q1
- psubusb mm5, mm7 ; q0-q1
-
- psubusb mm7, mm6 ; q1-q0
- por mm7, mm5 ; abs(q1-q0)
-
- movq t1, mm7 ; save abs(q1-q0)
- psubusb mm7, mm4
-
- por mm0, mm7 ; mask
-
- movq mm5, mm2 ; q1
- psubusb mm5, mm1 ; q1-=p1
- psubusb mm1, mm2 ; p1-=q1
- por mm5, mm1 ; abs(p1-q1)
- pand mm5, [GLOBAL(tfe)] ; set lsb of each byte to zero
- psrlw mm5, 1 ; abs(p1-q1)/2
-
- mov rdx, arg(2) ;blimit ;
-
- movq mm4, [rdx] ;blimit
- movq mm1, mm3 ; mm1=mm3=p0
-
- movq mm7, mm6 ; mm7=mm6=q0
- psubusb mm1, mm7 ; p0-q0
-
- psubusb mm7, mm3 ; q0-p0
- por mm1, mm7 ; abs(q0-p0)
- paddusb mm1, mm1 ; abs(q0-p0)*2
- paddusb mm1, mm5 ; abs (p0 - q0) *2 + abs(p1-q1)/2
-
- psubusb mm1, mm4 ; abs (p0 - q0) *2 + abs(p1-q1)/2 > blimit
- por mm1, mm0; ; mask
-
- pxor mm0, mm0
- pcmpeqb mm1, mm0
-
- ; calculate high edge variance
- mov rdx, arg(4) ;thresh ; get thresh
- movq mm7, [rdx]
- ;
- movq mm4, t0 ; get abs (q1 - q0)
- psubusb mm4, mm7
-
- movq mm3, t1 ; get abs (p1 - p0)
- psubusb mm3, mm7
-
- por mm4, mm3 ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
- pcmpeqb mm4, mm0
-
- pcmpeqb mm0, mm0
- pxor mm4, mm0
-
-
-
- ; start work on filters
- lea rdx, srct
-
- movq mm2, [rdx] ; p1
- movq mm7, [rdx+24] ; q1
-
- movq mm6, [rdx+8] ; p0
- movq mm0, [rdx+16] ; q0
-
- pxor mm2, [GLOBAL(t80)] ; p1 offset to convert to signed values
- pxor mm7, [GLOBAL(t80)] ; q1 offset to convert to signed values
-
- psubsb mm2, mm7 ; p1 - q1
- pand mm2, mm4 ; high var mask (hvm)(p1 - q1)
-
- pxor mm6, [GLOBAL(t80)] ; offset to convert to signed values
- pxor mm0, [GLOBAL(t80)] ; offset to convert to signed values
-
- movq mm3, mm0 ; q0
- psubsb mm0, mm6 ; q0 - p0
-
- paddsb mm2, mm0 ; 1 * (q0 - p0) + hvm(p1 - q1)
- paddsb mm2, mm0 ; 2 * (q0 - p0) + hvm(p1 - q1)
-
- paddsb mm2, mm0 ; 3 * (q0 - p0) + hvm(p1 - q1)
- pand mm1, mm2 ; mask filter values we don't care about
-
- movq mm2, mm1
- paddsb mm1, [GLOBAL(t4)] ; 3* (q0 - p0) + hvm(p1 - q1) + 4
-
- paddsb mm2, [GLOBAL(t3)] ; 3* (q0 - p0) + hvm(p1 - q1) + 3
- pxor mm0, mm0 ;
-
- pxor mm5, mm5
- punpcklbw mm0, mm2 ;
-
- punpckhbw mm5, mm2 ;
- psraw mm0, 11 ;
-
- psraw mm5, 11
- packsswb mm0, mm5
-
- movq mm2, mm0 ; (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
-
- pxor mm0, mm0 ; 0
- movq mm5, mm1 ; abcdefgh
-
- punpcklbw mm0, mm1 ; e0f0g0h0
- psraw mm0, 11 ; sign extended shift right by 3
-
- pxor mm1, mm1 ; 0
- punpckhbw mm1, mm5 ; a0b0c0d0
-
- psraw mm1, 11 ; sign extended shift right by 3
- movq mm5, mm0 ; save results
-
- packsswb mm0, mm1 ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
- paddsw mm5, [GLOBAL(ones)]
-
- paddsw mm1, [GLOBAL(ones)]
- psraw mm5, 1 ; partial shifted one more time for 2nd tap
-
- psraw mm1, 1 ; partial shifted one more time for 2nd tap
- packsswb mm5, mm1 ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
-
- pandn mm4, mm5 ; high edge variance additive
-
- paddsb mm6, mm2 ; p0+= p0 add
- pxor mm6, [GLOBAL(t80)] ; unoffset
-
- ; mm6=p0 ;
- movq mm1, [rdx] ; p1
- pxor mm1, [GLOBAL(t80)] ; reoffset
-
- paddsb mm1, mm4 ; p1+= p1 add
- pxor mm1, [GLOBAL(t80)] ; unoffset
- ; mm6 = p0 mm1 = p1
-
- psubsb mm3, mm0 ; q0-= q0 add
- pxor mm3, [GLOBAL(t80)] ; unoffset
-
- ; mm3 = q0
- psubsb mm7, mm4 ; q1-= q1 add
- pxor mm7, [GLOBAL(t80)] ; unoffset
- ; mm7 = q1
-
- ; transpose and write back
- ; mm1 = 72 62 52 42 32 22 12 02
- ; mm6 = 73 63 53 43 33 23 13 03
- ; mm3 = 74 64 54 44 34 24 14 04
- ; mm7 = 75 65 55 45 35 25 15 05
-
- movq mm2, mm1 ; 72 62 52 42 32 22 12 02
- punpcklbw mm2, mm6 ; 33 32 23 22 13 12 03 02
-
- movq mm4, mm3 ; 74 64 54 44 34 24 14 04
- punpckhbw mm1, mm6 ; 73 72 63 62 53 52 43 42
-
- punpcklbw mm4, mm7 ; 35 34 25 24 15 14 05 04
- punpckhbw mm3, mm7 ; 75 74 65 64 55 54 45 44
-
- movq mm6, mm2 ; 33 32 23 22 13 12 03 02
- punpcklwd mm2, mm4 ; 15 14 13 12 05 04 03 02
-
- punpckhwd mm6, mm4 ; 35 34 33 32 25 24 23 22
- movq mm5, mm1 ; 73 72 63 62 53 52 43 42
-
- punpcklwd mm1, mm3 ; 55 54 53 52 45 44 43 42
- punpckhwd mm5, mm3 ; 75 74 73 72 65 64 63 62
-
-
- ; mm2 = 15 14 13 12 05 04 03 02
- ; mm6 = 35 34 33 32 25 24 23 22
- ; mm5 = 55 54 53 52 45 44 43 42
- ; mm1 = 75 74 73 72 65 64 63 62
-
-
-
- movd [rsi+rax*4+2], mm2
- psrlq mm2, 32
-
- movd [rdi+rax*4+2], mm2
- movd [rsi+rax*2+2], mm6
-
- psrlq mm6, 32
- movd [rsi+rax+2],mm6
-
- movd [rsi+2], mm1
- psrlq mm1, 32
-
- movd [rdi+2], mm1
- neg rax
-
- movd [rdi+rax+2],mm5
- psrlq mm5, 32
-
- movd [rdi+rax*2+2], mm5
-
- add rsp, 64
- pop rsp
- ; begin epilog
- pop rdi
- pop rsi
- RESTORE_GOT
- UNSHADOW_ARGS
- pop rbp
- ret
+%include "third_party/x86inc/x86inc.asm"
SECTION_RODATA
align 16
tfe:
times 8 db 0xfe
-align 16
t80:
times 8 db 0x80
-align 16
t3:
times 8 db 0x03
-align 16
t4:
times 8 db 0x04
-align 16
ones:
times 4 dw 0x0001
+
+SECTION .text
+
+%define stkreg rsp
+
+%define t0 0
+%define t1 t0 + 16
+%define p1 t1 + 16
+%define p0 p1 + 16
+%define q0 p0 + 16
+%define q1 q0 + 16
+%define lstacksize q1 + 16
+
+%define goffsetq _limitq
+
+;void vpx_lpf_horizontal_4_mmx(unsigned char *src_ptr, int src_pixel_step,
+; const char *blimit, const char *limit,
+; const char *thresh);
+INIT_MMX mmx
+cglobal lpf_horizontal_4, 5, 6, 8, 0 - lstacksize, \
+ s, p, _blimit, _limit, _thresh, s1
+ movq m7, [_limitq]
+ GET_GOT goffsetq
+ lea s1q, [sq + pq] ; s1q points to row +1
+
+ ; calculate breakout conditions
+ movq m2, [s1q + 2 * pq] ; q3
+ movq m1, [ sq + 2 * pq] ; q2
+ movq m6, m1 ; q2
+ psubusb m1, m2 ; q2-=q3
+ psubusb m2, m6 ; q3-=q2
+ por m1, m2 ; abs(q3-q2)
+ psubusb m1, m7
+ movq m4, [sq + pq] ; q1
+ movq m3, m4 ; q1
+ psubusb m4, m6 ; q1-=q2
+ psubusb m6, m3 ; q2-=q1
+ por m4, m6 ; abs(q2-q1)
+ psubusb m4, m7
+ por m1, m4
+ movq m4, [sq] ; q0
+ movq m0, m4 ; q0
+ psubusb m4, m3 ; q0-=q1
+ psubusb m3, m0 ; q1-=q0
+ por m4, m3 ; abs(q0-q1)
+ movq [stkreg + t0], m4 ; save to t0
+ psubusb m4, m7
+ por m1, m4
+ neg pq ; negate pitch to deal with
+ ; above border
+ movq m2, [ sq + 4 * pq] ; p3
+ movq m4, [s1q + 4 * pq] ; p2
+ movq m5, m4 ; p2
+ psubusb m4, m2 ; p2-=p3
+ psubusb m2, m5 ; p3-=p2
+ por m4, m2 ; abs(p3 - p2)
+ psubusb m4, m7
+ por m1, m4
+ movq m4, [sq + 2 * pq] ; p1
+ movq m3, m4 ; p1
+ psubusb m4, m5 ; p1-=p2
+ psubusb m5, m3 ; p2-=p1
+ por m4, m5 ; abs(p2 - p1)
+ psubusb m4, m7
+ por m1, m4
+ movq m2, m3 ; p1
+ movq m4, [sq + pq] ; p0
+ movq m5, m4 ; p0
+ psubusb m4, m3 ; p0-=p1
+ psubusb m3, m5 ; p1-=p0
+ por m4, m3 ; abs(p1 - p0)
+ movq [stkreg + t1], m4 ; save to t1
+ psubusb m4, m7
+ por m1, m4
+ movq m3, [s1q] ; q1
+ movq m4, m3 ; q1
+ psubusb m3, m2 ; q1-=p1
+ psubusb m2, m4 ; p1-=q1
+ por m2, m3 ; abs(p1-q1)
+ pand m2, [GLOBAL(tfe)] ; set lsb of each byte to zero
+ psrlw m2, 1 ; abs(p1-q1)/2
+ movq m6, m5 ; p0
+ movq m3, [sq] ; q0
+ psubusb m5, m3 ; p0-=q0
+ psubusb m3, m6 ; q0-=p0
+ por m5, m3 ; abs(p0 - q0)
+ paddusb m5, m5 ; abs(p0-q0)*2
+ paddusb m5, m2 ; abs (p0 - q0) * 2 + abs(p1-q1)/2
+ movq m7, [_blimitq] ; blimit
+ psubusb m5, m7 ; abs (p0 - q0) * 2 +
+ ; abs(p1-q1)/2 > blimit
+ por m1, m5
+ pxor m5, m5
+ pcmpeqb m1, m5 ; mask m1
+
+ ; calculate high edge variance
+ movq m7, [_threshq]
+ movq m4, [stkreg + t0] ; get abs (q1 - q0)
+ psubusb m4, m7
+ movq m3, [stkreg + t1] ; get abs (p1 - p0)
+ psubusb m3, m7
+ paddb m4, m3 ; abs(q1 - q0) > thresh ||
+ ; abs(p1 - p0) > thresh
+ pcmpeqb m4, m5
+ pcmpeqb m5, m5
+ movq m3, [GLOBAL(t80)]
+ pxor m4, m5
+
+ ; start work on filters
+ movq m2, [sq + 2 * pq] ; p1
+ movq m7, [s1q] ; q1
+ pxor m2, m3 ; p1 converted to signed values
+ pxor m7, m3 ; q1 converted to signed values
+ psubsb m2, m7 ; p1 - q1
+ pand m2, m4 ; high var mask (hvm)(p1 - q1)
+ pxor m6, m3 ; p0 converted to signed values
+ pxor m0, m3 ; q0 converted to signed values
+ movq m3, m0 ; q0
+ psubsb m0, m6 ; q0 - p0
+ paddsb m2, m0 ; 1 * (q0 - p0) + hvm(p1 - q1)
+ paddsb m2, m0 ; 2 * (q0 - p0) + hvm(p1 - q1)
+ paddsb m2, m0 ; 3 * (q0 - p0) + hvm(p1 - q1)
+ pand m1, m2 ; mask filter values we don't
+ ; care about
+ movq m2, m1
+ paddsb m1, [GLOBAL(t4)] ; 3* (q0 - p0) + hvm(p1 - q1) + 4
+ paddsb m2, [GLOBAL(t3)] ; 3* (q0 - p0) + hvm(p1 - q1) + 3
+
+ pxor m0, m0
+ pxor m5, m5
+ punpcklbw m0, m2
+ punpckhbw m5, m2
+ psraw m0, 11
+ psraw m5, 11
+ packsswb m0, m5
+ movq m2, m0 ; (3* (q0 - p0) + hvm(p1 - q1)
+ ; + 3) >> 3;
+ pxor m0, m0
+ movq m5, m1 ; abcdefgh
+ punpcklbw m0, m1 ; e0f0g0h0
+ psraw m0, 11 ; sign extended shift right by 3
+ pxor m1, m1
+ punpckhbw m1, m5 ; a0b0c0d0
+ psraw m1, 11 ; sign extended shift right by 3
+ movq m5, m0 ; save results
+
+ packsswb m0, m1 ; (3* (q0 - p0) + hvm(p1 - q1)
+ ; + 4) >>3
+ paddsw m5, [GLOBAL(ones)]
+ paddsw m1, [GLOBAL(ones)]
+ psraw m5, 1
+ psraw m1, 1
+ packsswb m5, m1 ; (3* (q0 - p0) + hvm(p1 - q1)
+ ; + 4) >>4
+ movq m1, [GLOBAL(t80)]
+ pandn m4, m5 ; high edge variance additive
+ paddsb m6, m2 ; p0+= p0 add
+ pxor m6, m1 ; unoffset
+ movq [sq + pq], m6 ; write back
+ movq m6, [sq + 2 * pq] ; p1
+ pxor m6, m1 ; reoffset
+ paddsb m6, m4 ; p1+= p1 add
+ pxor m6, m1 ; unoffset
+ movq [sq + 2 * pq], m6 ; write back
+ psubsb m3, m0 ; q0-= q0 add
+ pxor m3, m1 ; unoffset
+ movq [sq], m3 ; write back
+ psubsb m7, m4 ; q1-= q1 add
+ pxor m7, m1 ; unoffset
+ movq [s1q], m7 ; write back
+ RESTORE_GOT
+ RET
+
+;void vpx_lpf_vertical_4_mmx(unsigned char *src_ptr, int src_pixel_step,
+; const char *blimit, const char *limit,
+; const char *thresh);
+INIT_MMX mmx
+cglobal lpf_vertical_4, 5, 6, 8, 0 - lstacksize, \
+ s, p, _blimit, _limit, _thresh, s1
+ lea sq, [sq + pq * 4 - 4]
+ lea s1q, [sq + pq] ; s1q points to row +1
+ ;transpose
+ movq m6, [ sq + 2 * pq] ; 67 66 65 64 63 62 61 60
+ movq m7, m6 ; 77 76 75 74 73 72 71 70
+ punpckhbw m7, [s1q + 2 * pq] ; 77 67 76 66 75 65 74 64
+ punpcklbw m6, [s1q + 2 * pq] ; 73 63 72 62 71 61 70 60
+ movq m4, [sq] ; 47 46 45 44 43 42 41 40
+ movq m5, m4 ; 47 46 45 44 43 42 41 40
+ punpckhbw m5, [sq + pq] ; 57 47 56 46 55 45 54 44
+ punpcklbw m4, [sq + pq] ; 53 43 52 42 51 41 50 40
+ movq m3, m5 ; 57 47 56 46 55 45 54 44
+ punpckhwd m5, m7 ; 77 67 57 47 76 66 56 46
+ punpcklwd m3, m7 ; 75 65 55 45 74 64 54 44
+ movq m2, m4 ; 53 43 52 42 51 41 50 40
+ punpckhwd m4, m6 ; 73 63 53 43 72 62 52 42
+ punpcklwd m2, m6 ; 71 61 51 41 70 60 50 40
+ neg pq
+ movq m6, [ sq + pq * 2] ; 27 26 25 24 23 22 21 20
+ movq m1, m6 ; 27 26 25 24 23 22 21 20
+ punpckhbw m6, [ sq + pq ] ; 37 27 36 36 35 25 34 24
+ punpcklbw m1, [ sq + pq ] ; 33 23 32 22 31 21 30 20
+ movq m7, [ sq + pq * 4]; ; 07 06 05 04 03 02 01 00
+ punpckhbw m7, [s1q + pq * 4] ; 17 07 16 06 15 05 14 04
+ movq m0, m7 ; 17 07 16 06 15 05 14 04
+ punpckhwd m7, m6 ; 37 27 17 07 36 26 16 06
+ punpcklwd m0, m6 ; 35 25 15 05 34 24 14 04
+ movq m6, m7 ; 37 27 17 07 36 26 16 06
+ punpckhdq m7, m5 ; 77 67 57 47 37 27 17 07 = q3
+ punpckldq m6, m5 ; 76 66 56 46 36 26 16 06 = q2
+ movq m5, m6 ; 76 66 56 46 36 26 16 06
+ psubusb m5, m7 ; q2-q3
+ psubusb m7, m6 ; q3-q2
+ por m7, m5; ; m7=abs (q3-q2)
+ movq m5, m0 ; 35 25 15 05 34 24 14 04
+ punpckhdq m5, m3 ; 75 65 55 45 35 25 15 05 = q1
+ punpckldq m0, m3 ; 74 64 54 44 34 24 15 04 = q0
+ movq m3, m5 ; 75 65 55 45 35 25 15 05 = q1
+ psubusb m3, m6 ; q1-q2
+ psubusb m6, m5 ; q2-q1
+ por m6, m3 ; m6=abs(q2-q1)
+
+ movq [stkreg + q1], m5 ; save q1
+ movq [stkreg + q0], m0 ; save q0
+
+ movq m3, [ sq + pq * 4] ; 07 06 05 04 03 02 01 00
+ punpcklbw m3, [s1q + pq * 4] ; 13 03 12 02 11 01 10 00
+ movq m0, m3 ; 13 03 12 02 11 01 10 00
+ punpcklwd m0, m1 ; 31 21 11 01 30 20 10 00
+ punpckhwd m3, m1 ; 33 23 13 03 32 22 12 02
+ movq m1, m0 ; 31 21 11 01 30 20 10 00
+ punpckldq m0, m2 ; 70 60 50 40 30 20 10 00 =p3
+ punpckhdq m1, m2 ; 71 61 51 41 31 21 11 01 =p2
+ movq m2, m1 ; 71 61 51 41 31 21 11 01 =p2
+ psubusb m2, m0 ; p2-p3
+ psubusb m0, m1 ; p3-p2
+ por m0, m2 ; m0=abs(p3-p2)
+ movq m2, m3 ; 33 23 13 03 32 22 12 02
+ punpckldq m2, m4 ; 72 62 52 42 32 22 12 02 = p1
+ punpckhdq m3, m4 ; 73 63 53 43 33 23 13 03 = p0
+
+ movq [stkreg + p0], m3 ; save p0
+ movq [stkreg + p1], m2 ; save p1
+ movq m5, m2 ; m5 = p1
+ psubusb m2, m1 ; p1-p2
+ psubusb m1, m5 ; p2-p1
+ por m1, m2 ; m1=abs(p2-p1)
+ movq m4, [_limitq]
+ GET_GOT goffsetq
+ psubusb m7, m4
+ psubusb m0, m4
+ psubusb m1, m4
+ psubusb m6, m4
+ por m7, m6
+ por m0, m1
+ por m0, m7 ; abs(q3-q2) > limit ||
+ ; abs(p3-p2) > limit ||
+ ; abs(p2-p1) > limit ||
+ ; abs(q2-q1) > limit
+ movq m1, m5 ; p1
+ movq m7, m3 ; m3=m7=p0
+ psubusb m7, m5 ; p0 - p1
+ psubusb m5, m3 ; p1 - p0
+ por m5, m7 ; abs(p1-p0)
+ movq [stkreg + t0], m5 ; save abs(p1-p0)
+ psubusb m5, m4
+ por m0, m5 ; m0=mask
+ movq m5, [stkreg + q0] ; m5=q0
+ movq m7, [stkreg + q1] ; m7=q1
+ movq m6, m5 ; m6=q0
+ movq m2, m7 ; q1
+ psubusb m5, m7 ; q0-q1
+ psubusb m7, m6 ; q1-q0
+ por m7, m5 ; abs(q1-q0)
+ movq [stkreg + t1], m7 ; save abs(q1-q0)
+ psubusb m7, m4
+ por m0, m7 ; mask
+ movq m5, m2 ; q1
+ psubusb m5, m1 ; q1-=p1
+ psubusb m1, m2 ; p1-=q1
+ por m5, m1 ; abs(p1-q1)
+ pand m5, [GLOBAL(tfe)] ; set lsb of each byte to zero
+ psrlw m5, 1 ; abs(p1-q1)/2
+ movq m4, [_blimitq]
+ movq m1, m3 ; m1=m3=p0
+ movq m7, m6 ; m7=m6=q0
+ psubusb m1, m7 ; p0-q0
+ psubusb m7, m3 ; q0-p0
+ por m1, m7 ; abs(q0-p0)
+ paddusb m1, m1 ; abs(q0-p0)*2
+ paddusb m1, m5 ; abs(p0 - q0)*2 + abs(p1-q1)/2
+ psubusb m1, m4 ; abs(p0 - q0)*2 + abs(p1-q1)/2
+ ; > blimit
+ por m1, m0; ; mask
+ pxor m0, m0
+ pcmpeqb m1, m0
+
+ ; calculate high edge variance
+ movq m7, [_threshq]
+ movq m4, [stkreg + t0] ; get abs (q1 - q0)
+ psubusb m4, m7
+ movq m3, [stkreg + t1] ; get abs (p1 - p0)
+ psubusb m3, m7
+ por m4, m3 ; abs(q1 - q0) > thresh ||
+ ; abs(p1 - p0) > thresh
+ pcmpeqb m4, m0
+ pcmpeqb m0, m0
+ movq m3, [GLOBAL(t80)]
+ pxor m4, m0
+
+ ; start work on filters
+ movq m2, [stkreg + p1]
+ movq m7, [stkreg + q1]
+ movq m6, [stkreg + p0]
+ movq m0, [stkreg + q0]
+ pxor m2, m3
+ pxor m7, m3
+ psubsb m2, m7 ; p1 - q1
+ pand m2, m4 ; high var mask (hvm)(p1 - q1)
+ pxor m6, m3
+ pxor m0, m3
+ movq m3, m0 ; q0
+ psubsb m0, m6 ; q0 - p0
+ paddsb m2, m0 ; 1 * (q0 - p0) + hvm(p1 - q1)
+ paddsb m2, m0 ; 2 * (q0 - p0) + hvm(p1 - q1)
+ paddsb m2, m0 ; 3 * (q0 - p0) + hvm(p1 - q1)
+ pand m1, m2 ; mask filter values we don't
+ ; care about
+ movq m2, m1
+ paddsb m1, [GLOBAL(t4)] ; 3*(q0 - p0) + hvm(p1 - q1) + 4
+ paddsb m2, [GLOBAL(t3)] ; 3*(q0 - p0) + hvm(p1 - q1) + 3
+ pxor m0, m0
+ pxor m5, m5
+ punpcklbw m0, m2
+ punpckhbw m5, m2
+ psraw m0, 11
+ psraw m5, 11
+ packsswb m0, m5
+ movq m2, m0 ; (3*(q0 - p0) + hvm(p1 - q1)
+ ; + 3) >> 3;
+ pxor m0, m0
+ movq m5, m1 ; abcdefgh
+ punpcklbw m0, m1 ; e0f0g0h0
+ psraw m0, 11 ; sign extended shift right by 3
+ pxor m1, m1
+ punpckhbw m1, m5 ; a0b0c0d0
+ psraw m1, 11 ; sign extended shift right by 3
+ movq m5, m0 ; save results
+ packsswb m0, m1 ; (3*(q0 - p0) + hvm(p1 - q1)
+ ; + 4) >>3
+ paddsw m5, [GLOBAL(ones)]
+ paddsw m1, [GLOBAL(ones)]
+ psraw m5, 1
+ psraw m1, 1
+ packsswb m5, m1 ; (3* (q0 - p0) + hvm(p1 - q1)
+ ; + 4) >>4
+ pandn m4, m5 ; high edge variance additive
+ movq m5, [GLOBAL(t80)]
+ paddsb m6, m2 ; p0+= p0 add
+ pxor m6, m5 ; unoffset
+ ; m6=p0
+ movq m1, [stkreg + p1]
+ pxor m1, m5 ; reoffset
+ paddsb m1, m4 ; p1+= p1 add
+ pxor m1, m5 ; unoffset
+ ; m6 = p0 m1 = p1
+ psubsb m3, m0 ; q0-= q0 add
+ pxor m3, m5 ; unoffset
+ ; m3 = q0
+ psubsb m7, m4 ; q1-= q1 add
+ pxor m7, m5 ; unoffset
+ ; m7 = q1
+ ; transpose and write back
+ ; m1 = 72 62 52 42 32 22 12 02
+ ; m6 = 73 63 53 43 33 23 13 03
+ ; m3 = 74 64 54 44 34 24 14 04
+ ; m7 = 75 65 55 45 35 25 15 05
+ movq m2, m1 ; 72 62 52 42 32 22 12 02
+ punpcklbw m2, m6 ; 33 32 23 22 13 12 03 02
+ movq m4, m3 ; 74 64 54 44 34 24 14 04
+ punpckhbw m1, m6 ; 73 72 63 62 53 52 43 42
+ punpcklbw m4, m7 ; 35 34 25 24 15 14 05 04
+ punpckhbw m3, m7 ; 75 74 65 64 55 54 45 44
+ movq m6, m2 ; 33 32 23 22 13 12 03 02
+ punpcklwd m2, m4 ; 15 14 13 12 05 04 03 02
+ punpckhwd m6, m4 ; 35 34 33 32 25 24 23 22
+ movq m5, m1 ; 73 72 63 62 53 52 43 42
+ punpcklwd m1, m3 ; 55 54 53 52 45 44 43 42
+ punpckhwd m5, m3 ; 75 74 73 72 65 64 63 62
+
+ ; m2 = 15 14 13 12 05 04 03 02
+ ; m6 = 35 34 33 32 25 24 23 22
+ ; m5 = 55 54 53 52 45 44 43 42
+ ; m1 = 75 74 73 72 65 64 63 62
+ movd [sq + pq * 4 + 2], m2
+ psrlq m2, 32
+ movd [s1q + pq * 4 + 2], m2
+ movd [sq + pq * 2 + 2], m6
+ psrlq m6, 32
+ movd [sq + pq + 2], m6
+ movd [sq + 2], m1
+ psrlq m1, 32
+ movd [s1q + 2], m1
+ neg pq
+ movd [s1q + pq + 2], m5
+ psrlq m5, 32
+ movd [s1q + pq * 2 + 2], m5
+ RESTORE_GOT
+ RET
diff --git a/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm b/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
index 3fbaa27..b0e99ed 100644
--- a/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
+++ b/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
@@ -538,11 +538,11 @@
movx m1, [srcq + sstrideq ] ;B
movx m6, [srcq + sstride6q ] ;G
punpcklbw m0, m1 ;A B
- movx m7, [rax + sstride6q ] ;H
+ movx m7, [src1q + sstride6q ] ;H
pmaddubsw m0, k0k1
movx m2, [srcq + sstrideq * 2 ] ;C
punpcklbw m6, m7 ;G H
- movx m3, [rax + sstrideq * 2 ] ;D
+ movx m3, [src1q + sstrideq * 2] ;D
pmaddubsw m6, k6k7
movx m4, [srcq + sstrideq * 4 ] ;E
punpcklbw m2, m3 ;C D
diff --git a/vpxenc.c b/vpxenc.c
index f14470a..f24b180 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -804,7 +804,6 @@
int arg_ctrls[ARG_CTRL_CNT_MAX][2];
int arg_ctrl_cnt;
int write_webm;
- int have_kf_max_dist;
#if CONFIG_VP9_HIGHBITDEPTH
// whether to use 16bit internal buffers
int use_16bit_internal;
@@ -1224,7 +1223,6 @@
config->cfg.kf_min_dist = arg_parse_uint(&arg);
} else if (arg_match(&arg, &kf_max_dist, argi)) {
config->cfg.kf_max_dist = arg_parse_uint(&arg);
- config->have_kf_max_dist = 1;
} else if (arg_match(&arg, &kf_disabled, argi)) {
config->cfg.kf_mode = VPX_KF_DISABLED;
#if CONFIG_VP9_HIGHBITDEPTH
@@ -1352,19 +1350,6 @@
}
}
-
-static void set_default_kf_interval(struct stream_state *stream,
- struct VpxEncoderConfig *global) {
- /* Use a max keyframe interval of 5 seconds, if none was
- * specified on the command line.
- */
- if (!stream->config.have_kf_max_dist) {
- double framerate = (double)global->framerate.num / global->framerate.den;
- if (framerate > 0.0)
- stream->config.cfg.kf_max_dist = (unsigned int)(5.0 * framerate);
- }
-}
-
static const char* file_type_to_string(enum VideoFileType t) {
switch (t) {
case FILE_TYPE_RAW: return "RAW";
@@ -2086,8 +2071,6 @@
stream->config.cfg.g_timebase.num = global.framerate.den);
}
- FOREACH_STREAM(set_default_kf_interval(stream, &global));
-
/* Show configuration */
if (global.verbose && pass == 0)
FOREACH_STREAM(show_stream_config(stream, &global, &input));