summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild/make/Makefile2
-rw-r--r--build/make/obj_int_extract.c673
-rw-r--r--vp8/encoder/firstpass.c188
-rw-r--r--vp8/encoder/onyx_if.c285
-rw-r--r--vp8/encoder/onyx_int.h1
-rw-r--r--vp8/encoder/rdopt.c2
-rw-r--r--vp8/encoder/x86/variance_impl_sse2.asm388
-rw-r--r--vp8/encoder/x86/variance_impl_ssse3.asm348
-rw-r--r--vp8/encoder/x86/variance_mmx.c140
-rw-r--r--vp8/encoder/x86/variance_sse2.c191
-rw-r--r--vp8/encoder/x86/variance_ssse3.c116
-rw-r--r--vp8/encoder/x86/variance_x86.h4
-rw-r--r--vp8/encoder/x86/x86_csystemdependent.c2
-rw-r--r--vp8/vp8cx.mk2
-rwxr-xr-xvpxenc.c4
15 files changed, 1509 insertions, 837 deletions
diff --git a/build/make/Makefile b/build/make/Makefile
index 40fa6d50c..62d139ea4 100755
--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -153,7 +153,7 @@ endif
#
obj_int_extract: build/make/obj_int_extract.c
$(if $(quiet),echo " [HOSTCC] $@")
- $(qexec)$(HOSTCC) -I. -o $@ $<
+ $(qexec)$(HOSTCC) -I. -I$(SRC_PATH_BARE) -o $@ $<
CLEAN-OBJS += obj_int_extract
#
diff --git a/build/make/obj_int_extract.c b/build/make/obj_int_extract.c
index 3c54b248f..22c5cf2ab 100644
--- a/build/make/obj_int_extract.c
+++ b/build/make/obj_int_extract.c
@@ -14,7 +14,7 @@
#include "vpx_config.h"
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
#include <io.h>
#include <share.h>
#include "vpx/vpx_integer.h"
@@ -59,20 +59,47 @@ int parse_macho(uint8_t *base_buf, size_t sz)
struct mach_header header;
uint8_t *buf = base_buf;
int base_data_section = 0;
-
+ int bits = 0;
+
+ /* We can read in mach_header for 32 and 64 bit architectures
+ * because it's identical to mach_header_64 except for the last
+ * element (uint32_t reserved), which we don't use. Then, when
+ * we know which architecture we're looking at, increment buf
+ * appropriately.
+ */
memcpy(&header, buf, sizeof(struct mach_header));
- buf += sizeof(struct mach_header);
- if (header.magic != MH_MAGIC)
+ if (header.magic == MH_MAGIC)
{
- log_msg("Bad magic number for object file. 0x%x expected, 0x%x found.\n",
- header.magic, MH_MAGIC);
- goto bail;
+ if (header.cputype == CPU_TYPE_ARM
+ || header.cputype == CPU_TYPE_X86)
+ {
+ bits = 32;
+ buf += sizeof(struct mach_header);
+ }
+ else
+ {
+ log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_[ARM|X86].\n");
+ goto bail;
+ }
}
-
- if (header.cputype != CPU_TYPE_ARM)
+ else if (header.magic == MH_MAGIC_64)
+ {
+ if (header.cputype == CPU_TYPE_X86_64)
+ {
+ bits = 64;
+ buf += sizeof(struct mach_header_64);
+ }
+ else
+ {
+ log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_X86_64.\n");
+ goto bail;
+ }
+ }
+ else
{
- log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_ARM.\n");
+ log_msg("Bad magic number for object file. 0x%x or 0x%x expected, 0x%x found.\n",
+ MH_MAGIC, MH_MAGIC_64, header.magic);
goto bail;
}
@@ -85,8 +112,6 @@ int parse_macho(uint8_t *base_buf, size_t sz)
for (i = 0; i < header.ncmds; i++)
{
struct load_command lc;
- struct symtab_command sc;
- struct segment_command seg_c;
memcpy(&lc, buf, sizeof(struct load_command));
@@ -94,50 +119,99 @@ int parse_macho(uint8_t *base_buf, size_t sz)
{
uint8_t *seg_buf = buf;
struct section s;
+ struct segment_command seg_c;
- memcpy(&seg_c, buf, sizeof(struct segment_command));
-
+ memcpy(&seg_c, seg_buf, sizeof(struct segment_command));
seg_buf += sizeof(struct segment_command);
- for (j = 0; j < seg_c.nsects; j++)
+ /* Although each section is given it's own offset, nlist.n_value
+ * references the offset of the first section. This isn't
+ * apparent without debug information because the offset of the
+ * data section is the same as the first section. However, with
+ * debug sections mixed in, the offset of the debug section
+ * increases but n_value still references the first section.
+ */
+ if (seg_c.nsects < 1)
{
- memcpy(&s, seg_buf + (j * sizeof(struct section)), sizeof(struct section));
+ log_msg("Not enough sections\n");
+ goto bail;
+ }
+
+ memcpy(&s, seg_buf, sizeof(struct section));
+ base_data_section = s.offset;
+ }
+ else if (lc.cmd == LC_SEGMENT_64)
+ {
+ uint8_t *seg_buf = buf;
+ struct section_64 s;
+ struct segment_command_64 seg_c;
+
+ memcpy(&seg_c, seg_buf, sizeof(struct segment_command_64));
+ seg_buf += sizeof(struct segment_command_64);
- // Need to get this offset which is the start of the symbol table
- // before matching the strings up with symbols.
- base_data_section = s.offset;
+ /* Explanation in LG_SEGMENT */
+ if (seg_c.nsects < 1)
+ {
+ log_msg("Not enough sections\n");
+ goto bail;
}
+
+ memcpy(&s, seg_buf, sizeof(struct section_64));
+ base_data_section = s.offset;
}
else if (lc.cmd == LC_SYMTAB)
{
- uint8_t *sym_buf = base_buf;
- uint8_t *str_buf = base_buf;
-
if (base_data_section != 0)
{
+ struct symtab_command sc;
+ uint8_t *sym_buf = base_buf;
+ uint8_t *str_buf = base_buf;
+
memcpy(&sc, buf, sizeof(struct symtab_command));
if (sc.cmdsize != sizeof(struct symtab_command))
+ {
log_msg("Can't find symbol table!\n");
+ goto bail;
+ }
sym_buf += sc.symoff;
str_buf += sc.stroff;
for (j = 0; j < sc.nsyms; j++)
{
- struct nlist nl;
- int val;
+ /* Location of string is cacluated each time from the
+ * start of the string buffer. On darwin the symbols
+ * are prefixed by "_", so we bump the pointer by 1.
+ * The target value is defined as an int in asm_*_offsets.c,
+ * which is 4 bytes on all targets we currently use.
+ */
+ if (bits == 32)
+ {
+ struct nlist nl;
+ int val;
- memcpy(&nl, sym_buf + (j * sizeof(struct nlist)), sizeof(struct nlist));
+ memcpy(&nl, sym_buf, sizeof(struct nlist));
+ sym_buf += sizeof(struct nlist);
- val = *((int *)(base_buf + base_data_section + nl.n_value));
+ memcpy(&val, base_buf + base_data_section + nl.n_value,
+ sizeof(val));
+ printf("%-40s EQU %5d\n",
+ str_buf + nl.n_un.n_strx + 1, val);
+ }
+ else /* if (bits == 64) */
+ {
+ struct nlist_64 nl;
+ int val;
- // Location of string is cacluated each time from the
- // start of the string buffer. On darwin the symbols
- // are prefixed by "_". On other platforms it is not
- // so it needs to be removed. That is the reason for
- // the +1.
- printf("%-40s EQU %5d\n", str_buf + nl.n_un.n_strx + 1, val);
+ memcpy(&nl, sym_buf, sizeof(struct nlist_64));
+ sym_buf += sizeof(struct nlist_64);
+
+ memcpy(&val, base_buf + base_data_section + nl.n_value,
+ sizeof(val));
+ printf("%-40s EQU %5d\n",
+ str_buf + nl.n_un.n_strx + 1, val);
+ }
}
}
}
@@ -218,7 +292,7 @@ bail:
return EXIT_FAILURE;
}
-#else
+#elif defined(__ELF__)
#include "elf.h"
#define COPY_STRUCT(dst, buf, ofst, sz) do {\
@@ -237,212 +311,420 @@ bail:
typedef struct
{
- uint8_t *buf; /* Buffer containing ELF data */
- size_t sz; /* Buffer size */
- int le_data; /* Data is little-endian */
- Elf32_Ehdr hdr;
+ uint8_t *buf; /* Buffer containing ELF data */
+ size_t sz; /* Buffer size */
+ int le_data; /* Data is little-endian */
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ int bits; /* 32 or 64 */
+ Elf32_Ehdr hdr32;
+ Elf64_Ehdr hdr64;
} elf_obj_t;
-int parse_elf32_header(elf_obj_t *elf)
+int parse_elf_header(elf_obj_t *elf)
{
int res;
- /* Verify ELF32 header */
- COPY_STRUCT(&elf->hdr, elf->buf, 0, elf->sz);
- res = elf->hdr.e_ident[EI_MAG0] == ELFMAG0;
- res &= elf->hdr.e_ident[EI_MAG1] == ELFMAG1;
- res &= elf->hdr.e_ident[EI_MAG2] == ELFMAG2;
- res &= elf->hdr.e_ident[EI_MAG3] == ELFMAG3;
- res &= elf->hdr.e_ident[EI_CLASS] == ELFCLASS32;
- res &= elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB
- || elf->hdr.e_ident[EI_DATA] == ELFDATA2MSB;
+ /* Verify ELF Magic numbers */
+ COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz);
+ res = elf->e_ident[EI_MAG0] == ELFMAG0;
+ res &= elf->e_ident[EI_MAG1] == ELFMAG1;
+ res &= elf->e_ident[EI_MAG2] == ELFMAG2;
+ res &= elf->e_ident[EI_MAG3] == ELFMAG3;
+ res &= elf->e_ident[EI_CLASS] == ELFCLASS32
+ || elf->e_ident[EI_CLASS] == ELFCLASS64;
+ res &= elf->e_ident[EI_DATA] == ELFDATA2LSB;
if (!res) goto bail;
- elf->le_data = elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB;
-
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_type);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_machine);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_version);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_entry);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phoff);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shoff);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_flags);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_ehsize);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phentsize);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phnum);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shentsize);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shnum);
- ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shstrndx);
+ elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB;
+
+ /* Read in relevant values */
+ if (elf->e_ident[EI_CLASS] == ELFCLASS32)
+ {
+ elf->bits = 32;
+ COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz);
+
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx);
+ }
+ else /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */
+ {
+ elf->bits = 64;
+ COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz);
+
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum);
+ ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx);
+ }
+
return 0;
bail:
+ log_msg("Failed to parse ELF file header");
return 1;
}
-int parse_elf32_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr)
+int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hdr64)
{
- if (idx >= elf->hdr.e_shnum)
- goto bail;
+ if (hdr32)
+ {
+ if (idx >= elf->hdr32.e_shnum)
+ goto bail;
+
+ COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsize,
+ elf->sz);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign);
+ ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize);
+ }
+ else /* if (hdr64) */
+ {
+ if (idx >= elf->hdr64.e_shnum)
+ goto bail;
+
+ COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_shentsize,
+ elf->sz);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign);
+ ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize);
+ }
- COPY_STRUCT(hdr, elf->buf, elf->hdr.e_shoff + idx * elf->hdr.e_shentsize,
- elf->sz);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_name);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_type);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_flags);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addr);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_offset);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_size);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_link);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_info);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addralign);
- ENDIAN_ASSIGN_IN_PLACE(hdr->sh_entsize);
return 0;
bail:
return 1;
}
-char *parse_elf32_string_table(elf_obj_t *elf, int s_idx, int idx)
+char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx)
{
- Elf32_Shdr shdr;
-
- if (parse_elf32_section(elf, s_idx, &shdr))
+ if (elf->bits == 32)
{
- log_msg("Failed to parse ELF string table: section %d, index %d\n",
- s_idx, idx);
- return "";
+ Elf32_Shdr shdr;
+
+ if (parse_elf_section(elf, s_idx, &shdr, NULL))
+ {
+ log_msg("Failed to parse ELF string table: section %d, index %d\n",
+ s_idx, idx);
+ return "";
+ }
+
+ return (char *)(elf->buf + shdr.sh_offset + idx);
}
+ else /* if (elf->bits == 64) */
+ {
+ Elf64_Shdr shdr;
- return (char *)(elf->buf + shdr.sh_offset + idx);
+ if (parse_elf_section(elf, s_idx, NULL, &shdr))
+ {
+ log_msg("Failed to parse ELF string table: section %d, index %d\n",
+ s_idx, idx);
+ return "";
+ }
+
+ return (char *)(elf->buf + shdr.sh_offset + idx);
+ }
}
-int parse_elf32_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym)
+int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_Sym *sym64)
{
- COPY_STRUCT(sym, elf->buf, ofst, elf->sz);
- ENDIAN_ASSIGN_IN_PLACE(sym->st_name);
- ENDIAN_ASSIGN_IN_PLACE(sym->st_value);
- ENDIAN_ASSIGN_IN_PLACE(sym->st_size);
- ENDIAN_ASSIGN_IN_PLACE(sym->st_info);
- ENDIAN_ASSIGN_IN_PLACE(sym->st_other);
- ENDIAN_ASSIGN_IN_PLACE(sym->st_shndx);
+ if (sym32)
+ {
+ COPY_STRUCT(sym32, elf->buf, ofst, elf->sz);
+ ENDIAN_ASSIGN_IN_PLACE(sym32->st_name);
+ ENDIAN_ASSIGN_IN_PLACE(sym32->st_value);
+ ENDIAN_ASSIGN_IN_PLACE(sym32->st_size);
+ ENDIAN_ASSIGN_IN_PLACE(sym32->st_info);
+ ENDIAN_ASSIGN_IN_PLACE(sym32->st_other);
+ ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx);
+ }
+ else /* if (sym64) */
+ {
+ COPY_STRUCT(sym64, elf->buf, ofst, elf->sz);
+ ENDIAN_ASSIGN_IN_PLACE(sym64->st_name);
+ ENDIAN_ASSIGN_IN_PLACE(sym64->st_value);
+ ENDIAN_ASSIGN_IN_PLACE(sym64->st_size);
+ ENDIAN_ASSIGN_IN_PLACE(sym64->st_info);
+ ENDIAN_ASSIGN_IN_PLACE(sym64->st_other);
+ ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx);
+ }
return 0;
bail:
return 1;
}
-int parse_elf32(uint8_t *buf, size_t sz, output_fmt_t mode)
+int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode)
{
- elf_obj_t elf;
- Elf32_Shdr shdr;
+ elf_obj_t elf;
unsigned int ofst;
- int i;
- Elf32_Off strtab_off; /* save String Table offset for later use */
+ int i;
+ Elf32_Off strtab_off32;
+ Elf64_Off strtab_off64; /* save String Table offset for later use */
memset(&elf, 0, sizeof(elf));
elf.buf = buf;
elf.sz = sz;
/* Parse Header */
- if (parse_elf32_header(&elf))
- {
- log_msg("Parse error: File does not appear to be valid ELF32\n");
- return 1;
- }
+ if (parse_elf_header(&elf))
+ goto bail;
- for (i = 0; i < elf.hdr.e_shnum; i++)
+ if (elf.bits == 32)
{
- parse_elf32_section(&elf, i, &shdr);
-
- if (shdr.sh_type == SHT_STRTAB)
+ Elf32_Shdr shdr;
+ for (i = 0; i < elf.hdr32.e_shnum; i++)
{
- char strtsb_name[128];
-
- strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
+ parse_elf_section(&elf, i, &shdr, NULL);
- if (!(strcmp(strtsb_name, ".shstrtab")))
+ if (shdr.sh_type == SHT_STRTAB)
{
- log_msg("found section: %s\n", strtsb_name);
- strtab_off = shdr.sh_offset;
- break;
+ char strtsb_name[128];
+
+ strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
+
+ if (!(strcmp(strtsb_name, ".shstrtab")))
+ {
+ /* log_msg("found section: %s\n", strtsb_name); */
+ strtab_off32 = shdr.sh_offset;
+ break;
+ }
}
}
}
-
- /* Parse all Symbol Tables */
- for (i = 0; i < elf.hdr.e_shnum; i++)
+ else /* if (elf.bits == 64) */
{
-
- parse_elf32_section(&elf, i, &shdr);
-
- if (shdr.sh_type == SHT_SYMTAB)
+ Elf64_Shdr shdr;
+ for (i = 0; i < elf.hdr64.e_shnum; i++)
{
- for (ofst = shdr.sh_offset;
- ofst < shdr.sh_offset + shdr.sh_size;
- ofst += shdr.sh_entsize)
- {
- Elf32_Sym sym;
+ parse_elf_section(&elf, i, NULL, &shdr);
- parse_elf32_symbol(&elf, ofst, &sym);
+ if (shdr.sh_type == SHT_STRTAB)
+ {
+ char strtsb_name[128];
- /* For all OBJECTS (data objects), extract the value from the
- * proper data segment.
- */
- if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
- log_msg("found data object %s\n",
- parse_elf32_string_table(&elf,
- shdr.sh_link,
- sym.st_name));
+ strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
- if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
- && sym.st_size == 4)
+ if (!(strcmp(strtsb_name, ".shstrtab")))
{
- Elf32_Shdr dhdr;
- int32_t val;
- char section_name[128];
-
- parse_elf32_section(&elf, sym.st_shndx, &dhdr);
+ /* log_msg("found section: %s\n", strtsb_name); */
+ strtab_off64 = shdr.sh_offset;
+ break;
+ }
+ }
+ }
+ }
- /* For explanition - refer to _MSC_VER version of code */
- strcpy(section_name, (char *)(elf.buf + strtab_off + dhdr.sh_name));
- log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type);
+ /* Parse all Symbol Tables */
+ if (elf.bits == 32)
+ {
+ Elf32_Shdr shdr;
+ for (i = 0; i < elf.hdr32.e_shnum; i++)
+ {
+ parse_elf_section(&elf, i, &shdr, NULL);
- if (!(strcmp(section_name, ".bss")))
- {
- val = 0;
- }
- else
+ if (shdr.sh_type == SHT_SYMTAB)
+ {
+ for (ofst = shdr.sh_offset;
+ ofst < shdr.sh_offset + shdr.sh_size;
+ ofst += shdr.sh_entsize)
+ {
+ Elf32_Sym sym;
+
+ parse_elf_symbol(&elf, ofst, &sym, NULL);
+
+ /* For all OBJECTS (data objects), extract the value from the
+ * proper data segment.
+ */
+ /* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
+ log_msg("found data object %s\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name));
+ */
+
+ if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
+ && sym.st_size == 4)
{
- memcpy(&val,
- elf.buf + dhdr.sh_offset + sym.st_value,
- sizeof(val));
+ Elf32_Shdr dhdr;
+ int val = 0;
+ char section_name[128];
+
+ parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL);
+
+ /* For explanition - refer to _MSC_VER version of code */
+ strcpy(section_name, (char *)(elf.buf + strtab_off32 + dhdr.sh_name));
+ /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
+
+ if (strcmp(section_name, ".bss"))
+ {
+ if (sizeof(val) != sym.st_size)
+ {
+ /* The target value is declared as an int in
+ * asm_*_offsets.c, which is 4 bytes on all
+ * targets we currently use. Complain loudly if
+ * this is not true.
+ */
+ log_msg("Symbol size is wrong\n");
+ goto bail;
+ }
+
+ memcpy(&val,
+ elf.buf + dhdr.sh_offset + sym.st_value,
+ sym.st_size);
+ }
+
+ if (!elf.le_data)
+ {
+ log_msg("Big Endian data not supported yet!\n");
+ goto bail;
+ }
+
+ switch (mode)
+ {
+ case OUTPUT_FMT_RVDS:
+ printf("%-40s EQU %5d\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name),
+ val);
+ break;
+ case OUTPUT_FMT_GAS:
+ printf(".equ %-40s, %5d\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name),
+ val);
+ break;
+ default:
+ printf("%s = %d\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name),
+ val);
+ }
}
+ }
+ }
+ }
+ }
+ else /* if (elf.bits == 64) */
+ {
+ Elf64_Shdr shdr;
+ for (i = 0; i < elf.hdr64.e_shnum; i++)
+ {
+ parse_elf_section(&elf, i, NULL, &shdr);
- if (!elf.le_data)
- {
- log_msg("Big Endian data not supported yet!\n");
- goto bail;
- }\
-
- switch (mode)
+ if (shdr.sh_type == SHT_SYMTAB)
+ {
+ for (ofst = shdr.sh_offset;
+ ofst < shdr.sh_offset + shdr.sh_size;
+ ofst += shdr.sh_entsize)
+ {
+ Elf64_Sym sym;
+
+ parse_elf_symbol(&elf, ofst, NULL, &sym);
+
+ /* For all OBJECTS (data objects), extract the value from the
+ * proper data segment.
+ */
+ /* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
+ log_msg("found data object %s\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name));
+ */
+
+ if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT
+ && sym.st_size == 4)
{
- case OUTPUT_FMT_RVDS:
- printf("%-40s EQU %5d\n",
- parse_elf32_string_table(&elf,
- shdr.sh_link,
- sym.st_name),
- val);
- break;
- case OUTPUT_FMT_GAS:
- printf(".equ %-40s, %5d\n",
- parse_elf32_string_table(&elf,
- shdr.sh_link,
- sym.st_name),
- val);
- break;
- default:
- printf("%s = %d\n",
- parse_elf32_string_table(&elf,
- shdr.sh_link,
- sym.st_name),
- val);
+ Elf64_Shdr dhdr;
+ int val = 0;
+ char section_name[128];
+
+ parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr);
+
+ /* For explanition - refer to _MSC_VER version of code */
+ strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name));
+ /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
+
+ if ((strcmp(section_name, ".bss")))
+ {
+ if (sizeof(val) != sym.st_size)
+ {
+ /* The target value is declared as an int in
+ * asm_*_offsets.c, which is 4 bytes on all
+ * targets we currently use. Complain loudly if
+ * this is not true.
+ */
+ log_msg("Symbol size is wrong\n");
+ goto bail;
+ }
+
+ memcpy(&val,
+ elf.buf + dhdr.sh_offset + sym.st_value,
+ sym.st_size);
+ }
+
+ if (!elf.le_data)
+ {
+ log_msg("Big Endian data not supported yet!\n");
+ goto bail;
+ }
+
+ switch (mode)
+ {
+ case OUTPUT_FMT_RVDS:
+ printf("%-40s EQU %5d\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name),
+ val);
+ break;
+ case OUTPUT_FMT_GAS:
+ printf(".equ %-40s, %5d\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name),
+ val);
+ break;
+ default:
+ printf("%s = %d\n",
+ parse_elf_string_table(&elf,
+ shdr.sh_link,
+ sym.st_name),
+ val);
+ }
}
}
}
@@ -454,7 +736,7 @@ int parse_elf32(uint8_t *buf, size_t sz, output_fmt_t mode)
return 0;
bail:
- log_msg("Parse error: File does not appear to be valid ELF32\n");
+ log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n");
return 1;
}
@@ -521,8 +803,7 @@ int main(int argc, char **argv)
goto bail;
}
- res = parse_elf32(file_buf, stat_buf.st_size, mode);
- //res = parse_coff(file_buf, stat_buf.st_size);
+ res = parse_elf(file_buf, stat_buf.st_size, mode);
free(file_buf);
if (!res)
@@ -535,7 +816,7 @@ bail:
#endif
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
/* See "Microsoft Portable Executable and Common Object File Format Specification"
for reference.
*/
@@ -549,7 +830,6 @@ int parse_coff(unsigned __int8 *buf, size_t sz)
unsigned int i;
unsigned __int8 *ptr;
unsigned __int32 symoffset;
- FILE *fp;
char **sectionlist; //this array holds all section names in their correct order.
//it is used to check if the symbol is in .bss or .data section.
@@ -590,14 +870,6 @@ int parse_coff(unsigned __int8 *buf, size_t sz)
//log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
//log_msg("COFF: raw data pointer ofset for section .data is %u\n", sectionrawdata_ptr);
- fp = fopen("assembly_offsets.asm", "w");
-
- if (fp == NULL)
- {
- perror("open file");
- goto bail;
- }
-
/* The compiler puts the data with non-zero offset in .data section, but puts the data with
zero offset in .bss section. So, if the data in in .bss section, set offset=0.
Note from Wiki: In an object module compiled from C, the bss section contains
@@ -631,13 +903,13 @@ int parse_coff(unsigned __int8 *buf, size_t sz)
char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
strncpy(name, ptr, 8);
//log_msg("COFF: Parsing symbol %s\n",name);
- fprintf(fp, "%-40s EQU ", name);
+ printf("%-40s EQU ", name + 1);
}
else
{
//log_msg("COFF: Parsing symbol %s\n",
// buf + strtab_ptr + get_le32(ptr+4));
- fprintf(fp, "%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4));
+ printf("%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4) + 1);
}
if (!(strcmp(sectionlist[section-1], ".bss")))
@@ -654,14 +926,13 @@ int parse_coff(unsigned __int8 *buf, size_t sz)
//log_msg(" Address: %u\n",get_le32(ptr+8));
//log_msg(" Offset: %u\n", symoffset);
- fprintf(fp, "%5d\n", symoffset);
+ printf("%5d\n", symoffset);
}
ptr += 18;
}
- fprintf(fp, " END\n");
- fclose(fp);
+ printf(" END\n");
for (i = 0; i < nsections; i++)
{
@@ -711,11 +982,7 @@ int main(int argc, char **argv)
else
f = argv[1];
- if (_sopen_s(&fd, f, _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE))
- {
- perror("Unable to open file");
- goto bail;
- }
+ fd = _sopen(f, _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE);
if (_fstat(fd, &stat_buf))
{
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index e0b2a8a45..d2cc8482e 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -312,7 +312,9 @@ void vp8_output_stats(const VP8_COMP *cpi,
FILE *fpfile;
fpfile = fopen("firstpass.stt", "a");
- fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.0f\n",
+ fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
+ " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.0f"
+ " %12.4f\n",
stats->frame,
stats->intra_error,
stats->coded_error,
@@ -320,6 +322,7 @@ void vp8_output_stats(const VP8_COMP *cpi,
stats->pcnt_inter,
stats->pcnt_motion,
stats->pcnt_second_ref,
+ stats->pcnt_neutral,
stats->MVr,
stats->mvr_abs,
stats->MVc,
@@ -327,7 +330,8 @@ void vp8_output_stats(const VP8_COMP *cpi,
stats->MVrv,
stats->MVcv,
stats->mv_in_out_count,
- stats->count);
+ stats->count,
+ stats->duration);
fclose(fpfile);
@@ -359,6 +363,7 @@ void vp8_zero_stats(FIRSTPASS_STATS *section)
section->pcnt_inter = 0.0;
section->pcnt_motion = 0.0;
section->pcnt_second_ref = 0.0;
+ section->pcnt_neutral = 0.0;
section->MVr = 0.0;
section->mvr_abs = 0.0;
section->MVc = 0.0;
@@ -378,6 +383,7 @@ void vp8_accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
section->pcnt_inter += frame->pcnt_inter;
section->pcnt_motion += frame->pcnt_motion;
section->pcnt_second_ref += frame->pcnt_second_ref;
+ section->pcnt_neutral += frame->pcnt_neutral;
section->MVr += frame->MVr;
section->mvr_abs += frame->mvr_abs;
section->MVc += frame->MVc;
@@ -398,6 +404,7 @@ void vp8_avg_stats(FIRSTPASS_STATS *section)
section->ssim_weighted_pred_err /= section->count;
section->pcnt_inter /= section->count;
section->pcnt_second_ref /= section->count;
+ section->pcnt_neutral /= section->count;
section->pcnt_motion /= section->count;
section->MVr /= section->count;
section->mvr_abs /= section->count;
@@ -570,6 +577,7 @@ void vp8_first_pass(VP8_COMP *cpi)
int intercount = 0;
int second_ref_count = 0;
int intrapenalty = 256;
+ int neutral_count = 0;
int sum_in_vectors = 0;
@@ -726,6 +734,17 @@ void vp8_first_pass(VP8_COMP *cpi)
if (motion_error <= this_error)
{
+ // Keep a count of cases where the inter and intra were
+ // very close and very low. This helps with scene cut
+ // detection for example in cropped clips with black bars
+ // at the sides or top and bottom.
+ if( (((this_error-intrapenalty) * 9) <=
+ (motion_error*10)) &&
+ (this_error < (2*intrapenalty)) )
+ {
+ neutral_count++;
+ }
+
d->bmi.mv.as_mv.row <<= 3;
d->bmi.mv.as_mv.col <<= 3;
this_error = motion_error;
@@ -854,6 +873,7 @@ void vp8_first_pass(VP8_COMP *cpi)
fps.pcnt_inter = 1.0 * (double)intercount / cm->MBs;
fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs;
+ fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs;
if (mvcount > 0)
{
@@ -1341,7 +1361,7 @@ void vp8_end_second_pass(VP8_COMP *cpi)
// This function gives and estimate of how badly we believe
// the predicition quality is decaying from frame to frame.
-double gf_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
+double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
{
double prediction_decay_rate;
double motion_decay;
@@ -1376,6 +1396,52 @@ double gf_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
return prediction_decay_rate;
}
+// Function to test for a condition where a complex transition is followed
+// by a static section. For example in slide shows where there is a fade
+// between slides. This is to help with more optimal kf and gf positioning.
+BOOL detect_transition_to_still(
+ VP8_COMP *cpi,
+ int frame_interval,
+ int still_interval,
+ double loop_decay_rate,
+ double decay_accumulator )
+{
+ BOOL trans_to_still = FALSE;
+
+ // Break clause to detect very still sections after motion
+ // For example a static image after a fade or other transition
+ // instead of a clean scene cut.
+ if ( (frame_interval > MIN_GF_INTERVAL) &&
+ (loop_decay_rate >= 0.999) &&
+ (decay_accumulator < 0.9) )
+ {
+ int j;
+ FIRSTPASS_STATS * position = cpi->stats_in;
+ FIRSTPASS_STATS tmp_next_frame;
+ double decay_rate;
+
+ // Look ahead a few frames to see if static condition
+ // persists...
+ for ( j = 0; j < still_interval; j++ )
+ {
+ if (EOF == vp8_input_stats(cpi, &tmp_next_frame))
+ break;
+
+ decay_rate = get_prediction_decay_rate(cpi, &tmp_next_frame);
+ if ( decay_rate < 0.999 )
+ break;
+ }
+ // Reset file position
+ reset_fpf_position(cpi, position);
+
+ // Only if it does do we signal a transition to still
+ if ( j == still_interval )
+ trans_to_still = TRUE;
+ }
+
+ return trans_to_still;
+}
+
// Analyse and define a gf/arf group .
static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
{
@@ -1528,7 +1594,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
if (r > GF_RMAX)
r = GF_RMAX;
- loop_decay_rate = gf_prediction_decay_rate(cpi, &next_frame);
+ loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
// Cumulative effect of decay
decay_accumulator = decay_accumulator * loop_decay_rate;
@@ -1537,48 +1603,13 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
boost_score += (decay_accumulator * r);
// Break clause to detect very still sections after motion
- // For example a staic image after a fade or other transition
- // instead of a clean key frame.
- if ( (i > MIN_GF_INTERVAL) &&
- (loop_decay_rate >= 0.999) &&
- (decay_accumulator < 0.9) )
+ // For example a staic image after a fade or other transition.
+ if ( detect_transition_to_still( cpi, i, 5,
+ loop_decay_rate, decay_accumulator ) )
{
- int j;
- FIRSTPASS_STATS * position = cpi->stats_in;
- FIRSTPASS_STATS tmp_next_frame;
- double decay_rate;
-
- // Look ahead a few frames to see if static condition
- // persists...
- for ( j = 0; j < 4; j++ )
- {
- if (EOF == vp8_input_stats(cpi, &tmp_next_frame))
- break;
-
- decay_rate = gf_prediction_decay_rate(cpi, &tmp_next_frame);
- if ( decay_rate < 0.999 )
- break;
- }
- reset_fpf_position(cpi, position); // Reset file position
-
- // Force GF not alt ref
- if ( j == 4 )
- {
- if (0)
- {
- FILE *f = fopen("fadegf.stt", "a");
- fprintf(f, " %8d %8d %10.4f %10.4f %10.4f\n",
- cpi->common.current_video_frame+i, i,
- loop_decay_rate, decay_accumulator,
- boost_score );
- fclose(f);
- }
-
- allow_alt_ref = FALSE;
-
- boost_score = old_boost_score;
- break;
- }
+ allow_alt_ref = FALSE;
+ boost_score = old_boost_score;
+ break;
}
// Break out conditions.
@@ -2285,7 +2316,7 @@ static BOOL test_candidate_kf(VP8_COMP *cpi, FIRSTPASS_STATS *last_frame, FIRST
(next_frame->pcnt_second_ref < 0.10) &&
((this_frame->pcnt_inter < 0.05) ||
(
- (this_frame->pcnt_inter < .25) &&
+ ((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .25) &&
((this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) &&
((fabs(last_frame->coded_error - this_frame->coded_error) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > .40) ||
(fabs(last_frame->intra_error - this_frame->intra_error) / DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > .40) ||
@@ -2332,7 +2363,9 @@ static BOOL test_candidate_kf(VP8_COMP *cpi, FIRSTPASS_STATS *last_frame, FIRST
// Test various breakout clauses
if ((local_next_frame.pcnt_inter < 0.05) ||
(next_iiratio < 1.5) ||
- ((local_next_frame.pcnt_inter < 0.20) && (next_iiratio < 3.0)) ||
+ (((local_next_frame.pcnt_inter -
+ local_next_frame.pcnt_neutral) < 0.20) &&
+ (next_iiratio < 3.0)) ||
((boost_score - old_boost_score) < 0.5) ||
(local_next_frame.intra_error < 200)
)
@@ -2363,13 +2396,13 @@ static BOOL test_candidate_kf(VP8_COMP *cpi, FIRSTPASS_STATS *last_frame, FIRST
}
void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
{
- int i;
+ int i,j;
FIRSTPASS_STATS last_frame;
FIRSTPASS_STATS first_frame;
FIRSTPASS_STATS next_frame;
FIRSTPASS_STATS *start_position;
- double decay_accumulator = 0;
+ double decay_accumulator = 1.0;
double boost_score = 0;
double old_boost_score = 0.0;
double loop_decay_rate;
@@ -2379,6 +2412,7 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
double kf_group_intra_err = 0.0;
double kf_group_coded_err = 0.0;
double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
+ double recent_loop_decay[8] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
vpx_memset(&next_frame, 0, sizeof(next_frame)); // assure clean
@@ -2407,6 +2441,7 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
kf_mod_err = calculate_modified_err(cpi, this_frame);
// find the next keyframe
+ i = 0;
while (cpi->stats_in < cpi->stats_in_end)
{
// Accumulate kf group error
@@ -2425,9 +2460,34 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
if (cpi->oxcf.auto_key
&& lookup_next_frame_stats(cpi, &next_frame) != EOF)
{
+ // Normal scene cut check
if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
break;
+ // How fast is prediction quality decaying
+ loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
+
+ // We want to know something about the recent past... rather than
+ // as used elsewhere where we are concened with decay in prediction
+ // quality since the last GF or KF.
+ recent_loop_decay[i%8] = loop_decay_rate;
+ decay_accumulator = 1.0;
+ for (j = 0; j < 8; j++)
+ {
+ decay_accumulator = decay_accumulator * recent_loop_decay[j];
+ }
+
+ // Special check for transition or high motion followed by a
+ // to a static scene.
+ if ( detect_transition_to_still( cpi, i,
+ (cpi->key_frame_frequency-i),
+ loop_decay_rate,
+ decay_accumulator ) )
+ {
+ break;
+ }
+
+
// Step on to the next frame
cpi->frames_to_key ++;
@@ -2437,6 +2497,8 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
break;
} else
cpi->frames_to_key ++;
+
+ i++;
}
// If there is a max kf interval set by the user we must obey it.
@@ -2588,32 +2650,8 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
if (r > RMAX)
r = RMAX;
- // Adjust loop decay rate
- //if ( next_frame.pcnt_inter < loop_decay_rate )
- loop_decay_rate = next_frame.pcnt_inter;
-
- // High % motion -> somewhat higher decay rate
- motion_pct = next_frame.pcnt_motion;
- motion_decay = (1.0 - (motion_pct / 20.0));
- if (motion_decay < loop_decay_rate)
- loop_decay_rate = motion_decay;
-
- // Adjustment to decay rate based on speed of motion
- {
- double this_mv_rabs;
- double this_mv_cabs;
- double distance_factor;
-
- this_mv_rabs = fabs(next_frame.mvr_abs * motion_pct);
- this_mv_cabs = fabs(next_frame.mvc_abs * motion_pct);
-
- distance_factor = sqrt((this_mv_rabs * this_mv_rabs) +
- (this_mv_cabs * this_mv_cabs)) / 250.0;
- distance_factor = ((distance_factor > 1.0)
- ? 0.0 : (1.0 - distance_factor));
- if (distance_factor < loop_decay_rate)
- loop_decay_rate = distance_factor;
- }
+ // How fast is prediction quality decaying
+ loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
decay_accumulator = decay_accumulator * loop_decay_rate;
decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 39610a73f..797e18b30 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -1517,252 +1517,29 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->oxcf = *oxcf;
- switch (cpi->oxcf.Mode)
- {
-
- case MODE_REALTIME:
- cpi->pass = 0;
- cpi->compressor_speed = 2;
-
- if (cpi->oxcf.cpu_used < -16)
- {
- cpi->oxcf.cpu_used = -16;
- }
-
- if (cpi->oxcf.cpu_used > 16)
- cpi->oxcf.cpu_used = 16;
-
- break;
-
-#if !(CONFIG_REALTIME_ONLY)
- case MODE_GOODQUALITY:
- cpi->pass = 0;
- cpi->compressor_speed = 1;
-
- if (cpi->oxcf.cpu_used < -5)
- {
- cpi->oxcf.cpu_used = -5;
- }
-
- if (cpi->oxcf.cpu_used > 5)
- cpi->oxcf.cpu_used = 5;
-
- break;
-
- case MODE_BESTQUALITY:
- cpi->pass = 0;
- cpi->compressor_speed = 0;
- break;
-
- case MODE_FIRSTPASS:
- cpi->pass = 1;
- cpi->compressor_speed = 1;
- break;
- case MODE_SECONDPASS:
- cpi->pass = 2;
- cpi->compressor_speed = 1;
-
- if (cpi->oxcf.cpu_used < -5)
- {
- cpi->oxcf.cpu_used = -5;
- }
-
- if (cpi->oxcf.cpu_used > 5)
- cpi->oxcf.cpu_used = 5;
-
- break;
- case MODE_SECONDPASS_BEST:
- cpi->pass = 2;
- cpi->compressor_speed = 0;
- break;
-#endif
- }
-
- if (cpi->pass == 0)
- cpi->auto_worst_q = 1;
-
- cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
- cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q];
- cpi->oxcf.cq_level = q_trans[cpi->oxcf.cq_level];
-
- if (oxcf->fixed_q >= 0)
- {
- if (oxcf->worst_allowed_q < 0)
- cpi->oxcf.fixed_q = q_trans[0];
- else
- cpi->oxcf.fixed_q = q_trans[oxcf->worst_allowed_q];
-
- if (oxcf->alt_q < 0)
- cpi->oxcf.alt_q = q_trans[0];
- else
- cpi->oxcf.alt_q = q_trans[oxcf->alt_q];
-
- if (oxcf->key_q < 0)
- cpi->oxcf.key_q = q_trans[0];
- else
- cpi->oxcf.key_q = q_trans[oxcf->key_q];
-
- if (oxcf->gold_q < 0)
- cpi->oxcf.gold_q = q_trans[0];
- else
- cpi->oxcf.gold_q = q_trans[oxcf->gold_q];
-
- }
-
- cpi->baseline_gf_interval = cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
- cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
-
- //cpi->use_golden_frame_only = 0;
- //cpi->use_last_frame_only = 0;
- cm->refresh_golden_frame = 0;
- cm->refresh_last_frame = 1;
- cm->refresh_entropy_probs = 1;
-
- if (cpi->oxcf.token_partitions >= 0 && cpi->oxcf.token_partitions <= 3)
- cm->multi_token_partition = (TOKEN_PARTITION) cpi->oxcf.token_partitions;
-
- setup_features(cpi);
-
- {
- int i;
-
- for (i = 0; i < MAX_MB_SEGMENTS; i++)
- cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
- }
-
- // At the moment the first order values may not be > MAXQ
- if (cpi->oxcf.fixed_q > MAXQ)
- cpi->oxcf.fixed_q = MAXQ;
-
- // local file playback mode == really big buffer
- if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK)
- {
- cpi->oxcf.starting_buffer_level = 60000;
- cpi->oxcf.optimal_buffer_level = 60000;
- cpi->oxcf.maximum_buffer_size = 240000;
-
- }
-
-
// Convert target bandwidth from Kbit/s to Bit/s
cpi->oxcf.target_bandwidth *= 1000;
cpi->oxcf.starting_buffer_level =
rescale(cpi->oxcf.starting_buffer_level,
cpi->oxcf.target_bandwidth, 1000);
- if (cpi->oxcf.optimal_buffer_level == 0)
- cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
- else
- cpi->oxcf.optimal_buffer_level =
- rescale(cpi->oxcf.optimal_buffer_level,
- cpi->oxcf.target_bandwidth, 1000);
-
- if (cpi->oxcf.maximum_buffer_size == 0)
- cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8;
- else
- cpi->oxcf.maximum_buffer_size =
- rescale(cpi->oxcf.maximum_buffer_size,
- cpi->oxcf.target_bandwidth, 1000);
-
- cpi->buffer_level = cpi->oxcf.starting_buffer_level;
+ cpi->buffer_level = cpi->oxcf.starting_buffer_level;
cpi->bits_off_target = cpi->oxcf.starting_buffer_level;
- vp8_new_frame_rate(cpi, cpi->oxcf.frame_rate);
- cpi->worst_quality = cpi->oxcf.worst_allowed_q;
cpi->active_worst_quality = cpi->oxcf.worst_allowed_q;
- cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q;
- cpi->best_quality = cpi->oxcf.best_allowed_q;
cpi->active_best_quality = cpi->oxcf.best_allowed_q;
- cpi->cq_target_quality = cpi->oxcf.cq_level;
-
- cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
+ cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q;
cpi->rolling_target_bits = cpi->av_per_frame_bandwidth;
cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth;
- cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth;
- cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth;
+ cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth;
+ cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth;
cpi->total_actual_bits = 0;
- cpi->total_target_vs_actual = 0;
-
- // Only allow dropped frames in buffered mode
- cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode;
+ cpi->total_target_vs_actual = 0;
- cm->filter_type = (LOOPFILTERTYPE) cpi->filter_type;
-
- if (!cm->use_bilinear_mc_filter)
- cm->mcomp_filter_type = SIXTAP;
- else
- cm->mcomp_filter_type = BILINEAR;
-
- cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
-
- cm->Width = cpi->oxcf.Width ;
- cm->Height = cpi->oxcf.Height ;
-
- cpi->intra_frame_target = (4 * (cm->Width + cm->Height) / 15) * 1000; // As per VP8
-
- cm->horiz_scale = cpi->horiz_scale;
- cm->vert_scale = cpi->vert_scale ;
-
- // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
- if (cpi->oxcf.Sharpness > 7)
- cpi->oxcf.Sharpness = 7;
-
- cm->sharpness_level = cpi->oxcf.Sharpness;
-
- if (cm->horiz_scale != NORMAL || cm->vert_scale != NORMAL)
- {
- int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
- int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
-
- Scale2Ratio(cm->horiz_scale, &hr, &hs);
- Scale2Ratio(cm->vert_scale, &vr, &vs);
-
- // always go to the next whole number
- cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs;
- cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
- }
-
- if (((cm->Width + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_width ||
- ((cm->Height + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_height ||
- cm->yv12_fb[cm->lst_fb_idx].y_width == 0)
- {
- alloc_raw_frame_buffers(cpi);
- vp8_alloc_compressor_data(cpi);
- }
-
- // Clamp KF frame size to quarter of data rate
- if (cpi->intra_frame_target > cpi->target_bandwidth >> 2)
- cpi->intra_frame_target = cpi->target_bandwidth >> 2;
-
- if (cpi->oxcf.fixed_q >= 0)
- {
- cpi->last_q[0] = cpi->oxcf.fixed_q;
- cpi->last_q[1] = cpi->oxcf.fixed_q;
- }
-
- cpi->Speed = cpi->oxcf.cpu_used;
-
- // force to allowlag to 0 if lag_in_frames is 0;
- if (cpi->oxcf.lag_in_frames == 0)
- {
- cpi->oxcf.allow_lag = 0;
- }
- // Limit on lag buffers as these are not currently dynamically allocated
- else if (cpi->oxcf.lag_in_frames > MAX_LAG_BUFFERS)
- cpi->oxcf.lag_in_frames = MAX_LAG_BUFFERS;
-
- // YX Temp
- cpi->last_alt_ref_sei = -1;
- cpi->is_src_frame_alt_ref = 0;
- cpi->is_next_src_alt_ref = 0;
-
-#if 0
- // Experimental RD Code
- cpi->frame_distortion = 0;
- cpi->last_frame_distortion = 0;
-#endif
+ // change includes all joint functionality
+ vp8_change_config(ptr, oxcf);
#if VP8_TEMPORAL_ALT_REF
@@ -1779,12 +1556,6 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
#endif
}
-/*
- * This function needs more clean up, i.e. be more tuned torwards
- * change_config rather than init_config !!!!!!!!!!!!!!!!
- * YX - 5/28/2009
- *
- */
void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
{
@@ -1935,10 +1706,6 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
// Convert target bandwidth from Kbit/s to Bit/s
cpi->oxcf.target_bandwidth *= 1000;
- cpi->oxcf.starting_buffer_level =
- rescale(cpi->oxcf.starting_buffer_level,
- cpi->oxcf.target_bandwidth, 1000);
-
if (cpi->oxcf.optimal_buffer_level == 0)
cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
else
@@ -1953,29 +1720,36 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
rescale(cpi->oxcf.maximum_buffer_size,
cpi->oxcf.target_bandwidth, 1000);
- cpi->buffer_level = cpi->oxcf.starting_buffer_level;
- cpi->bits_off_target = cpi->oxcf.starting_buffer_level;
-
vp8_new_frame_rate(cpi, cpi->oxcf.frame_rate);
cpi->worst_quality = cpi->oxcf.worst_allowed_q;
- cpi->active_worst_quality = cpi->oxcf.worst_allowed_q;
- cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q;
cpi->best_quality = cpi->oxcf.best_allowed_q;
- cpi->active_best_quality = cpi->oxcf.best_allowed_q;
- cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
- cpi->cq_target_quality = cpi->oxcf.cq_level;
+ // active values should only be modified if out of new range
+ if (cpi->active_worst_quality > cpi->oxcf.worst_allowed_q)
+ {
+ cpi->active_worst_quality = cpi->oxcf.worst_allowed_q;
+ }
+ // less likely
+ else if (cpi->active_worst_quality < cpi->oxcf.best_allowed_q)
+ {
+ cpi->active_worst_quality = cpi->oxcf.best_allowed_q;
+ }
+ if (cpi->active_best_quality < cpi->oxcf.best_allowed_q)
+ {
+ cpi->active_best_quality = cpi->oxcf.best_allowed_q;
+ }
+ // less likely
+ else if (cpi->active_best_quality > cpi->oxcf.worst_allowed_q)
+ {
+ cpi->active_best_quality = cpi->oxcf.worst_allowed_q;
+ }
- cpi->rolling_target_bits = cpi->av_per_frame_bandwidth;
- cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth;
- cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth;
- cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth;
+ cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
- cpi->total_actual_bits = 0;
- cpi->total_target_vs_actual = 0;
+ cpi->cq_target_quality = cpi->oxcf.cq_level;
// Only allow dropped frames in buffered mode
- cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode;
+ cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode;
cm->filter_type = (LOOPFILTERTYPE) cpi->filter_type;
@@ -3542,6 +3316,7 @@ static void encode_frame_to_data_rate
int drop_mark50 = drop_mark / 4;
int drop_mark25 = drop_mark / 8;
+
// Clear down mmx registers to allow floating point in what follows
vp8_clear_system_state();
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index b66131d15..6d0cbd9fc 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -99,6 +99,7 @@ typedef struct
double pcnt_inter;
double pcnt_motion;
double pcnt_second_ref;
+ double pcnt_neutral;
double MVr;
double mvr_abs;
double MVc;
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 8aaca0917..b0dcfe0a4 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1968,7 +1968,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
else
cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
}
- else if (vp8_ref_frame_order[mode_index] == SPLITMV)
+ else if (vp8_mode_order[mode_index] == SPLITMV)
cpi->zbin_mode_boost = 0;
else
cpi->zbin_mode_boost = MV_ZBIN_BOOST;
diff --git a/vp8/encoder/x86/variance_impl_sse2.asm b/vp8/encoder/x86/variance_impl_sse2.asm
index 6cdc47bc9..c2c30deb2 100644
--- a/vp8/encoder/x86/variance_impl_sse2.asm
+++ b/vp8/encoder/x86/variance_impl_sse2.asm
@@ -627,6 +627,10 @@ filter_block2d_bil_var_sse2_loop:
filter_block2d_bil_var_sse2_sp_only:
movsxd rdx, dword ptr arg(6) ; yoffset
+
+ cmp rdx, 0 ; skip all if both xoffset=0 and yoffset=0
+ je filter_block2d_bil_var_sse2_full_pixel
+
shl rdx, 5
lea rdx, [rdx + rcx] ; VFilter
@@ -671,6 +675,35 @@ filter_block2d_bil_sp_only_loop:
jmp filter_block2d_bil_variance
+filter_block2d_bil_var_sse2_full_pixel:
+ mov rsi, arg(0) ;ref_ptr
+ mov rdi, arg(2) ;src_ptr
+ movsxd rcx, dword ptr arg(4) ;Height
+ movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
+ movsxd rbx, dword ptr arg(3) ;src_pixels_per_line
+ pxor xmm0, xmm0 ;
+
+filter_block2d_bil_full_pixel_loop:
+ movq xmm1, QWORD PTR [rsi] ;
+ punpcklbw xmm1, xmm0 ;
+
+ movq xmm2, QWORD PTR [rdi] ;
+ punpcklbw xmm2, xmm0 ;
+
+ psubw xmm1, xmm2 ;
+ paddw xmm6, xmm1 ;
+
+ pmaddwd xmm1, xmm1 ;
+ paddd xmm7, xmm1 ;
+
+ lea rsi, [rsi + rax] ;ref_pixels_per_line
+ lea rdi, [rdi + rbx] ;src_pixels_per_line
+
+ sub rcx, 1 ;
+ jnz filter_block2d_bil_full_pixel_loop ;
+
+ jmp filter_block2d_bil_variance
+
filter_block2d_bil_var_sse2_fp_only:
mov rsi, arg(0) ;ref_ptr
mov rdi, arg(2) ;src_ptr
@@ -757,7 +790,7 @@ filter_block2d_bil_variance:
ret
-;void vp8_half_horiz_vert_variance16x_h_sse2
+;void vp8_half_horiz_vert_variance8x_h_sse2
;(
; unsigned char *ref_ptr,
; int ref_pixels_per_line,
@@ -767,8 +800,8 @@ filter_block2d_bil_variance:
; int *sum,
; unsigned int *sumsquared
;)
-global sym(vp8_half_horiz_vert_variance16x_h_sse2)
-sym(vp8_half_horiz_vert_variance16x_h_sse2):
+global sym(vp8_half_horiz_vert_variance8x_h_sse2)
+sym(vp8_half_horiz_vert_variance8x_h_sse2):
push rbp
mov rbp, rsp
SHADOW_ARGS_TO_STACK 7
@@ -802,7 +835,7 @@ sym(vp8_half_horiz_vert_variance16x_h_sse2):
add rsi, r8
%endif
-vp8_half_horiz_vert_variance16x_h_1:
+vp8_half_horiz_vert_variance8x_h_1:
movq xmm1, QWORD PTR [rsi] ;
movq xmm2, QWORD PTR [rsi+1] ;
@@ -830,7 +863,7 @@ vp8_half_horiz_vert_variance16x_h_1:
%endif
sub rcx, 1 ;
- jnz vp8_half_horiz_vert_variance16x_h_1 ;
+ jnz vp8_half_horiz_vert_variance8x_h_1 ;
movdq2q mm6, xmm6 ;
movdq2q mm7, xmm7 ;
@@ -877,8 +910,123 @@ vp8_half_horiz_vert_variance16x_h_1:
pop rbp
ret
+;void vp8_half_horiz_vert_variance16x_h_sse2
+;(
+; unsigned char *ref_ptr,
+; int ref_pixels_per_line,
+; unsigned char *src_ptr,
+; int src_pixels_per_line,
+; unsigned int Height,
+; int *sum,
+; unsigned int *sumsquared
+;)
+global sym(vp8_half_horiz_vert_variance16x_h_sse2)
+sym(vp8_half_horiz_vert_variance16x_h_sse2):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 7
+ SAVE_XMM
+ GET_GOT rbx
+ push rsi
+ push rdi
+ ; end prolog
-;void vp8_half_vert_variance16x_h_sse2
+ pxor xmm6, xmm6 ; error accumulator
+ pxor xmm7, xmm7 ; sse eaccumulator
+ mov rsi, arg(0) ;ref_ptr ;
+
+ mov rdi, arg(2) ;src_ptr ;
+ movsxd rcx, dword ptr arg(4) ;Height ;
+ movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
+ movsxd rdx, dword ptr arg(3) ;src_pixels_per_line
+
+ pxor xmm0, xmm0 ;
+
+ movdqu xmm5, XMMWORD PTR [rsi]
+ movdqu xmm3, XMMWORD PTR [rsi+1]
+ pavgb xmm5, xmm3 ; xmm5 = avg(xmm1,xmm3) horizontal line 1
+
+ lea rsi, [rsi + rax]
+
+vp8_half_horiz_vert_variance16x_h_1:
+ movdqu xmm1, XMMWORD PTR [rsi] ;
+ movdqu xmm2, XMMWORD PTR [rsi+1] ;
+ pavgb xmm1, xmm2 ; xmm1 = avg(xmm1,xmm3) horizontal line i+1
+
+ pavgb xmm5, xmm1 ; xmm = vertical average of the above
+
+ movdqa xmm4, xmm5
+ punpcklbw xmm5, xmm0 ; xmm5 = words of above
+ punpckhbw xmm4, xmm0
+
+ movq xmm3, QWORD PTR [rdi] ; xmm3 = d0,d1,d2..d7
+ punpcklbw xmm3, xmm0 ; xmm3 = words of above
+ psubw xmm5, xmm3 ; xmm5 -= xmm3
+
+ movq xmm3, QWORD PTR [rdi+8]
+ punpcklbw xmm3, xmm0
+ psubw xmm4, xmm3
+
+ paddw xmm6, xmm5 ; xmm6 += accumulated column differences
+ paddw xmm6, xmm4
+ pmaddwd xmm5, xmm5 ; xmm5 *= xmm5
+ pmaddwd xmm4, xmm4
+ paddd xmm7, xmm5 ; xmm7 += accumulated square column differences
+ paddd xmm7, xmm4
+
+ movdqa xmm5, xmm1 ; save xmm1 for use on the next row
+
+ lea rsi, [rsi + rax]
+ lea rdi, [rdi + rdx]
+
+ sub rcx, 1 ;
+ jnz vp8_half_horiz_vert_variance16x_h_1 ;
+
+ pxor xmm1, xmm1
+ pxor xmm5, xmm5
+
+ punpcklwd xmm0, xmm6
+ punpckhwd xmm1, xmm6
+ psrad xmm0, 16
+ psrad xmm1, 16
+ paddd xmm0, xmm1
+ movdqa xmm1, xmm0
+
+ movdqa xmm6, xmm7
+ punpckldq xmm6, xmm5
+ punpckhdq xmm7, xmm5
+ paddd xmm6, xmm7
+
+ punpckldq xmm0, xmm5
+ punpckhdq xmm1, xmm5
+ paddd xmm0, xmm1
+
+ movdqa xmm7, xmm6
+ movdqa xmm1, xmm0
+
+ psrldq xmm7, 8
+ psrldq xmm1, 8
+
+ paddd xmm6, xmm7
+ paddd xmm0, xmm1
+
+ mov rsi, arg(5) ;[Sum]
+ mov rdi, arg(6) ;[SSE]
+
+ movd [rsi], xmm0
+ movd [rdi], xmm6
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ RESTORE_GOT
+ RESTORE_XMM
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+
+;void vp8_half_vert_variance8x_h_sse2
;(
; unsigned char *ref_ptr,
; int ref_pixels_per_line,
@@ -888,8 +1036,8 @@ vp8_half_horiz_vert_variance16x_h_1:
; int *sum,
; unsigned int *sumsquared
;)
-global sym(vp8_half_vert_variance16x_h_sse2)
-sym(vp8_half_vert_variance16x_h_sse2):
+global sym(vp8_half_vert_variance8x_h_sse2)
+sym(vp8_half_vert_variance8x_h_sse2):
push rbp
mov rbp, rsp
SHADOW_ARGS_TO_STACK 7
@@ -912,7 +1060,7 @@ sym(vp8_half_vert_variance16x_h_sse2):
movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
pxor xmm0, xmm0 ;
-vp8_half_vert_variance16x_h_1:
+vp8_half_vert_variance8x_h_1:
movq xmm5, QWORD PTR [rsi] ; xmm5 = s0,s1,s2..s8
movq xmm3, QWORD PTR [rsi+rax] ; xmm3 = s1,s2,s3..s9
@@ -936,7 +1084,7 @@ vp8_half_vert_variance16x_h_1:
%endif
sub rcx, 1 ;
- jnz vp8_half_vert_variance16x_h_1 ;
+ jnz vp8_half_vert_variance8x_h_1 ;
movdq2q mm6, xmm6 ;
movdq2q mm7, xmm7 ;
@@ -983,8 +1131,115 @@ vp8_half_vert_variance16x_h_1:
pop rbp
ret
+;void vp8_half_vert_variance16x_h_sse2
+;(
+; unsigned char *ref_ptr,
+; int ref_pixels_per_line,
+; unsigned char *src_ptr,
+; int src_pixels_per_line,
+; unsigned int Height,
+; int *sum,
+; unsigned int *sumsquared
+;)
+global sym(vp8_half_vert_variance16x_h_sse2)
+sym(vp8_half_vert_variance16x_h_sse2):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 7
+ SAVE_XMM
+ GET_GOT rbx
+ push rsi
+ push rdi
+ ; end prolog
+
+ pxor xmm6, xmm6 ; error accumulator
+ pxor xmm7, xmm7 ; sse eaccumulator
+ mov rsi, arg(0) ;ref_ptr
+
+ mov rdi, arg(2) ;src_ptr
+ movsxd rcx, dword ptr arg(4) ;Height
+ movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
+ movsxd rdx, dword ptr arg(3) ;src_pixels_per_line
+
+ movdqu xmm5, XMMWORD PTR [rsi]
+ lea rsi, [rsi + rax ]
+ pxor xmm0, xmm0
+
+vp8_half_vert_variance16x_h_1:
+ movdqu xmm3, XMMWORD PTR [rsi]
+
+ pavgb xmm5, xmm3 ; xmm5 = avg(xmm1,xmm3)
+ movdqa xmm4, xmm5
+ punpcklbw xmm5, xmm0
+ punpckhbw xmm4, xmm0
+
+ movq xmm2, QWORD PTR [rdi]
+ punpcklbw xmm2, xmm0
+ psubw xmm5, xmm2
+ movq xmm2, QWORD PTR [rdi+8]
+ punpcklbw xmm2, xmm0
+ psubw xmm4, xmm2
+
+ paddw xmm6, xmm5 ; xmm6 += accumulated column differences
+ paddw xmm6, xmm4
+ pmaddwd xmm5, xmm5 ; xmm5 *= xmm5
+ pmaddwd xmm4, xmm4
+ paddd xmm7, xmm5 ; xmm7 += accumulated square column differences
+ paddd xmm7, xmm4
+
+ movdqa xmm5, xmm3
+
+ lea rsi, [rsi + rax]
+ lea rdi, [rdi + rdx]
+
+ sub rcx, 1
+ jnz vp8_half_vert_variance16x_h_1
+
+ pxor xmm1, xmm1
+ pxor xmm5, xmm5
+
+ punpcklwd xmm0, xmm6
+ punpckhwd xmm1, xmm6
+ psrad xmm0, 16
+ psrad xmm1, 16
+ paddd xmm0, xmm1
+ movdqa xmm1, xmm0
+
+ movdqa xmm6, xmm7
+ punpckldq xmm6, xmm5
+ punpckhdq xmm7, xmm5
+ paddd xmm6, xmm7
+
+ punpckldq xmm0, xmm5
+ punpckhdq xmm1, xmm5
+ paddd xmm0, xmm1
+
+ movdqa xmm7, xmm6
+ movdqa xmm1, xmm0
+
+ psrldq xmm7, 8
+ psrldq xmm1, 8
+
+ paddd xmm6, xmm7
+ paddd xmm0, xmm1
+
+ mov rsi, arg(5) ;[Sum]
+ mov rdi, arg(6) ;[SSE]
+
+ movd [rsi], xmm0
+ movd [rdi], xmm6
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ RESTORE_GOT
+ RESTORE_XMM
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
-;void vp8_half_horiz_variance16x_h_sse2
+;void vp8_half_horiz_variance8x_h_sse2
;(
; unsigned char *ref_ptr,
; int ref_pixels_per_line,
@@ -994,8 +1249,8 @@ vp8_half_vert_variance16x_h_1:
; int *sum,
; unsigned int *sumsquared
;)
-global sym(vp8_half_horiz_variance16x_h_sse2)
-sym(vp8_half_horiz_variance16x_h_sse2):
+global sym(vp8_half_horiz_variance8x_h_sse2)
+sym(vp8_half_horiz_variance8x_h_sse2):
push rbp
mov rbp, rsp
SHADOW_ARGS_TO_STACK 7
@@ -1017,7 +1272,7 @@ sym(vp8_half_horiz_variance16x_h_sse2):
movsxd rcx, dword ptr arg(4) ;Height ;
pxor xmm0, xmm0 ;
-vp8_half_horiz_variance16x16_1:
+vp8_half_horiz_variance8x_h_1:
movq xmm5, QWORD PTR [rsi] ; xmm5 = s0,s1,s2..s8
movq xmm3, QWORD PTR [rsi+1] ; xmm3 = s1,s2,s3..s9
@@ -1040,7 +1295,7 @@ vp8_half_horiz_variance16x16_1:
add rdi, r9
%endif
sub rcx, 1 ;
- jnz vp8_half_horiz_variance16x16_1 ;
+ jnz vp8_half_horiz_variance8x_h_1 ;
movdq2q mm6, xmm6 ;
movdq2q mm7, xmm7 ;
@@ -1087,6 +1342,109 @@ vp8_half_horiz_variance16x16_1:
pop rbp
ret
+;void vp8_half_horiz_variance16x_h_sse2
+;(
+; unsigned char *ref_ptr,
+; int ref_pixels_per_line,
+; unsigned char *src_ptr,
+; int src_pixels_per_line,
+; unsigned int Height,
+; int *sum,
+; unsigned int *sumsquared
+;)
+global sym(vp8_half_horiz_variance16x_h_sse2)
+sym(vp8_half_horiz_variance16x_h_sse2):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 7
+ SAVE_XMM
+ GET_GOT rbx
+ push rsi
+ push rdi
+ ; end prolog
+
+ pxor xmm6, xmm6 ; error accumulator
+ pxor xmm7, xmm7 ; sse eaccumulator
+ mov rsi, arg(0) ;ref_ptr ;
+
+ mov rdi, arg(2) ;src_ptr ;
+ movsxd rcx, dword ptr arg(4) ;Height ;
+ movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
+ movsxd rdx, dword ptr arg(3) ;src_pixels_per_line
+
+ pxor xmm0, xmm0 ;
+
+vp8_half_horiz_variance16x_h_1:
+ movdqu xmm5, XMMWORD PTR [rsi] ; xmm5 = s0,s1,s2..s15
+ movdqu xmm3, XMMWORD PTR [rsi+1] ; xmm3 = s1,s2,s3..s16
+
+ pavgb xmm5, xmm3 ; xmm5 = avg(xmm1,xmm3)
+ movdqa xmm1, xmm5
+ punpcklbw xmm5, xmm0 ; xmm5 = words of above
+ punpckhbw xmm1, xmm0
+
+ movq xmm3, QWORD PTR [rdi] ; xmm3 = d0,d1,d2..d7
+ punpcklbw xmm3, xmm0 ; xmm3 = words of above
+ movq xmm2, QWORD PTR [rdi+8]
+ punpcklbw xmm2, xmm0
+
+ psubw xmm5, xmm3 ; xmm5 -= xmm3
+ psubw xmm1, xmm2
+ paddw xmm6, xmm5 ; xmm6 += accumulated column differences
+ paddw xmm6, xmm1
+ pmaddwd xmm5, xmm5 ; xmm5 *= xmm5
+ pmaddwd xmm1, xmm1
+ paddd xmm7, xmm5 ; xmm7 += accumulated square column differences
+ paddd xmm7, xmm1
+
+ lea rsi, [rsi + rax]
+ lea rdi, [rdi + rdx]
+
+ sub rcx, 1 ;
+ jnz vp8_half_horiz_variance16x_h_1 ;
+
+ pxor xmm1, xmm1
+ pxor xmm5, xmm5
+
+ punpcklwd xmm0, xmm6
+ punpckhwd xmm1, xmm6
+ psrad xmm0, 16
+ psrad xmm1, 16
+ paddd xmm0, xmm1
+ movdqa xmm1, xmm0
+
+ movdqa xmm6, xmm7
+ punpckldq xmm6, xmm5
+ punpckhdq xmm7, xmm5
+ paddd xmm6, xmm7
+
+ punpckldq xmm0, xmm5
+ punpckhdq xmm1, xmm5
+ paddd xmm0, xmm1
+
+ movdqa xmm7, xmm6
+ movdqa xmm1, xmm0
+
+ psrldq xmm7, 8
+ psrldq xmm1, 8
+
+ paddd xmm6, xmm7
+ paddd xmm0, xmm1
+
+ mov rsi, arg(5) ;[Sum]
+ mov rdi, arg(6) ;[SSE]
+
+ movd [rsi], xmm0
+ movd [rdi], xmm6
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ RESTORE_GOT
+ RESTORE_XMM
+ UNSHADOW_ARGS
+ pop rbp
+ ret
SECTION_RODATA
; short xmm_bi_rd[8] = { 64, 64, 64, 64,64, 64, 64, 64};
diff --git a/vp8/encoder/x86/variance_impl_ssse3.asm b/vp8/encoder/x86/variance_impl_ssse3.asm
new file mode 100644
index 000000000..b1976328d
--- /dev/null
+++ b/vp8/encoder/x86/variance_impl_ssse3.asm
@@ -0,0 +1,348 @@
+;
+; Copyright (c) 2010 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.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%define xmm_filter_shift 7
+
+
+;void vp8_filter_block2d_bil_var_ssse3
+;(
+; unsigned char *ref_ptr,
+; int ref_pixels_per_line,
+; unsigned char *src_ptr,
+; int src_pixels_per_line,
+; unsigned int Height,
+; int xoffset,
+; int yoffset,
+; int *sum,
+; unsigned int *sumsquared;;
+;
+;)
+;Note: The filter coefficient at offset=0 is 128. Since the second register
+;for Pmaddubsw is signed bytes, we must calculate zero offset seperately.
+global sym(vp8_filter_block2d_bil_var_ssse3)
+sym(vp8_filter_block2d_bil_var_ssse3):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 9
+ SAVE_XMM
+ GET_GOT rbx
+ push rsi
+ push rdi
+ push rbx
+ ; end prolog
+
+ pxor xmm6, xmm6
+ pxor xmm7, xmm7
+
+ lea rcx, [GLOBAL(vp8_bilinear_filters_ssse3)]
+ movsxd rax, dword ptr arg(5) ; xoffset
+
+ cmp rax, 0 ; skip first_pass filter if xoffset=0
+ je filter_block2d_bil_var_ssse3_sp_only
+
+ shl rax, 4 ; point to filter coeff with xoffset
+ lea rax, [rax + rcx] ; HFilter
+
+ movsxd rdx, dword ptr arg(6) ; yoffset
+
+ cmp rdx, 0 ; skip second_pass filter if yoffset=0
+ je filter_block2d_bil_var_ssse3_fp_only
+
+ shl rdx, 4
+ lea rdx, [rdx + rcx] ; VFilter
+
+ mov rsi, arg(0) ;ref_ptr
+ mov rdi, arg(2) ;src_ptr
+ movsxd rcx, dword ptr arg(4) ;Height
+
+ movdqu xmm0, XMMWORD PTR [rsi]
+ movdqu xmm1, XMMWORD PTR [rsi+1]
+ movdqa xmm2, xmm0
+
+ punpcklbw xmm0, xmm1
+ punpckhbw xmm2, xmm1
+ pmaddubsw xmm0, [rax]
+ pmaddubsw xmm2, [rax]
+
+ paddw xmm0, [GLOBAL(xmm_bi_rd)]
+ paddw xmm2, [GLOBAL(xmm_bi_rd)]
+ psraw xmm0, xmm_filter_shift
+ psraw xmm2, xmm_filter_shift
+
+ packuswb xmm0, xmm2
+
+ movsxd rbx, dword ptr arg(1) ;ref_pixels_per_line
+ lea rsi, [rsi + rbx]
+%if ABI_IS_32BIT=0
+ movsxd r9, dword ptr arg(3) ;src_pixels_per_line
+%endif
+
+filter_block2d_bil_var_ssse3_loop:
+ movdqu xmm1, XMMWORD PTR [rsi]
+ movdqu xmm2, XMMWORD PTR [rsi+1]
+ movdqa xmm3, xmm1
+
+ punpcklbw xmm1, xmm2
+ punpckhbw xmm3, xmm2
+ pmaddubsw xmm1, [rax]
+ pmaddubsw xmm3, [rax]
+
+ paddw xmm1, [GLOBAL(xmm_bi_rd)]
+ paddw xmm3, [GLOBAL(xmm_bi_rd)]
+ psraw xmm1, xmm_filter_shift
+ psraw xmm3, xmm_filter_shift
+ packuswb xmm1, xmm3
+
+ movdqa xmm2, xmm0
+ movdqa xmm0, xmm1
+ movdqa xmm3, xmm2
+
+ punpcklbw xmm2, xmm1
+ punpckhbw xmm3, xmm1
+ pmaddubsw xmm2, [rdx]
+ pmaddubsw xmm3, [rdx]
+
+ paddw xmm2, [GLOBAL(xmm_bi_rd)]
+ paddw xmm3, [GLOBAL(xmm_bi_rd)]
+ psraw xmm2, xmm_filter_shift
+ psraw xmm3, xmm_filter_shift
+
+ movq xmm1, QWORD PTR [rdi]
+ pxor xmm4, xmm4
+ punpcklbw xmm1, xmm4
+ movq xmm5, QWORD PTR [rdi+8]
+ punpcklbw xmm5, xmm4
+
+ psubw xmm2, xmm1
+ psubw xmm3, xmm5
+ paddw xmm6, xmm2
+ paddw xmm6, xmm3
+ pmaddwd xmm2, xmm2
+ pmaddwd xmm3, xmm3
+ paddd xmm7, xmm2
+ paddd xmm7, xmm3
+
+ lea rsi, [rsi + rbx] ;ref_pixels_per_line
+%if ABI_IS_32BIT
+ add rdi, dword ptr arg(3) ;src_pixels_per_line
+%else
+ lea rdi, [rdi + r9]
+%endif
+
+ sub rcx, 1
+ jnz filter_block2d_bil_var_ssse3_loop
+
+ jmp filter_block2d_bil_variance
+
+filter_block2d_bil_var_ssse3_sp_only:
+ movsxd rdx, dword ptr arg(6) ; yoffset
+
+ cmp rdx, 0 ; Both xoffset =0 and yoffset=0
+ je filter_block2d_bil_var_ssse3_full_pixel
+
+ shl rdx, 4
+ lea rdx, [rdx + rcx] ; VFilter
+
+ mov rsi, arg(0) ;ref_ptr
+ mov rdi, arg(2) ;src_ptr
+ movsxd rcx, dword ptr arg(4) ;Height
+ movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
+
+ movdqu xmm1, XMMWORD PTR [rsi]
+ movdqa xmm0, xmm1
+
+ movsxd rbx, dword ptr arg(3) ;src_pixels_per_line
+ lea rsi, [rsi + rax]
+
+filter_block2d_bil_sp_only_loop:
+ movdqu xmm3, XMMWORD PTR [rsi]
+ movdqa xmm2, xmm1
+ movdqa xmm0, xmm3
+
+ punpcklbw xmm1, xmm3
+ punpckhbw xmm2, xmm3
+ pmaddubsw xmm1, [rdx]
+ pmaddubsw xmm2, [rdx]
+
+ paddw xmm1, [GLOBAL(xmm_bi_rd)]
+ paddw xmm2, [GLOBAL(xmm_bi_rd)]
+ psraw xmm1, xmm_filter_shift
+ psraw xmm2, xmm_filter_shift
+
+ movq xmm3, QWORD PTR [rdi]
+ pxor xmm4, xmm4
+ punpcklbw xmm3, xmm4
+ movq xmm5, QWORD PTR [rdi+8]
+ punpcklbw xmm5, xmm4
+
+ psubw xmm1, xmm3
+ psubw xmm2, xmm5
+ paddw xmm6, xmm1
+ paddw xmm6, xmm2
+ pmaddwd xmm1, xmm1
+ pmaddwd xmm2, xmm2
+ paddd xmm7, xmm1
+ paddd xmm7, xmm2
+
+ movdqa xmm1, xmm0
+ lea rsi, [rsi + rax] ;ref_pixels_per_line
+ lea rdi, [rdi + rbx] ;src_pixels_per_line
+
+ sub rcx, 1
+ jnz filter_block2d_bil_sp_only_loop
+
+ jmp filter_block2d_bil_variance
+
+filter_block2d_bil_var_ssse3_full_pixel:
+ mov rsi, arg(0) ;ref_ptr
+ mov rdi, arg(2) ;src_ptr
+ movsxd rcx, dword ptr arg(4) ;Height
+ movsxd rax, dword ptr arg(1) ;ref_pixels_per_line
+ movsxd rbx, dword ptr arg(3) ;src_pixels_per_line
+ pxor xmm0, xmm0
+
+filter_block2d_bil_full_pixel_loop:
+ movq xmm1, QWORD PTR [rsi]
+ punpcklbw xmm1, xmm0
+ movq xmm2, QWORD PTR [rsi+8]
+ punpcklbw xmm2, xmm0
+
+ movq xmm3, QWORD PTR [rdi]
+ punpcklbw xmm3, xmm0
+ movq xmm4, QWORD PTR [rdi+8]
+ punpcklbw xmm4, xmm0
+
+ psubw xmm1, xmm3
+ psubw xmm2, xmm4
+ paddw xmm6, xmm1
+ paddw xmm6, xmm2
+ pmaddwd xmm1, xmm1
+ pmaddwd xmm2, xmm2
+ paddd xmm7, xmm1
+ paddd xmm7, xmm2
+
+ lea rsi, [rsi + rax] ;ref_pixels_per_line
+ lea rdi, [rdi + rbx] ;src_pixels_per_line
+ sub rcx, 1
+ jnz filter_block2d_bil_full_pixel_loop
+
+ jmp filter_block2d_bil_variance
+
+filter_block2d_bil_var_ssse3_fp_only:
+ mov rsi, arg(0) ;ref_ptr
+ mov rdi, arg(2) ;src_ptr
+ movsxd rcx, dword ptr arg(4) ;Height
+ movsxd rdx, dword ptr arg(1) ;ref_pixels_per_line
+
+ pxor xmm0, xmm0
+ movsxd rbx, dword ptr arg(3) ;src_pixels_per_line
+
+filter_block2d_bil_fp_only_loop:
+ movdqu xmm1, XMMWORD PTR [rsi]
+ movdqu xmm2, XMMWORD PTR [rsi+1]
+ movdqa xmm3, xmm1
+
+ punpcklbw xmm1, xmm2
+ punpckhbw xmm3, xmm2
+ pmaddubsw xmm1, [rax]
+ pmaddubsw xmm3, [rax]
+
+ paddw xmm1, [GLOBAL(xmm_bi_rd)]
+ paddw xmm3, [GLOBAL(xmm_bi_rd)]
+ psraw xmm1, xmm_filter_shift
+ psraw xmm3, xmm_filter_shift
+
+ movq xmm2, XMMWORD PTR [rdi]
+ pxor xmm4, xmm4
+ punpcklbw xmm2, xmm4
+ movq xmm5, QWORD PTR [rdi+8]
+ punpcklbw xmm5, xmm4
+
+ psubw xmm1, xmm2
+ psubw xmm3, xmm5
+ paddw xmm6, xmm1
+ paddw xmm6, xmm3
+ pmaddwd xmm1, xmm1
+ pmaddwd xmm3, xmm3
+ paddd xmm7, xmm1
+ paddd xmm7, xmm3
+
+ lea rsi, [rsi + rdx]
+ lea rdi, [rdi + rbx] ;src_pixels_per_line
+
+ sub rcx, 1
+ jnz filter_block2d_bil_fp_only_loop
+
+ jmp filter_block2d_bil_variance
+
+filter_block2d_bil_variance:
+ pxor xmm0, xmm0
+ pxor xmm1, xmm1
+ pxor xmm5, xmm5
+
+ punpcklwd xmm0, xmm6
+ punpckhwd xmm1, xmm6
+ psrad xmm0, 16
+ psrad xmm1, 16
+ paddd xmm0, xmm1
+ movdqa xmm1, xmm0
+
+ movdqa xmm6, xmm7
+ punpckldq xmm6, xmm5
+ punpckhdq xmm7, xmm5
+ paddd xmm6, xmm7
+
+ punpckldq xmm0, xmm5
+ punpckhdq xmm1, xmm5
+ paddd xmm0, xmm1
+
+ movdqa xmm7, xmm6
+ movdqa xmm1, xmm0
+
+ psrldq xmm7, 8
+ psrldq xmm1, 8
+
+ paddd xmm6, xmm7
+ paddd xmm0, xmm1
+
+ mov rsi, arg(7) ;[Sum]
+ mov rdi, arg(8) ;[SSE]
+
+ movd [rsi], xmm0
+ movd [rdi], xmm6
+
+ ; begin epilog
+ pop rbx
+ pop rdi
+ pop rsi
+ RESTORE_GOT
+ RESTORE_XMM
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+
+SECTION_RODATA
+align 16
+xmm_bi_rd:
+ times 8 dw 64
+align 16
+vp8_bilinear_filters_ssse3:
+ times 8 db 128, 0
+ times 8 db 112, 16
+ times 8 db 96, 32
+ times 8 db 80, 48
+ times 8 db 64, 64
+ times 8 db 48, 80
+ times 8 db 32, 96
+ times 8 db 16, 112
diff --git a/vp8/encoder/x86/variance_mmx.c b/vp8/encoder/x86/variance_mmx.c
index 6eed98e07..07358c0c7 100644
--- a/vp8/encoder/x86/variance_mmx.c
+++ b/vp8/encoder/x86/variance_mmx.c
@@ -456,146 +456,6 @@ unsigned int vp8_sub_pixel_variance8x16_mmx
return (xxsum - ((xsum * xsum) >> 7));
}
-unsigned int vp8_i_variance16x16_mmx(
- const unsigned char *src_ptr,
- int source_stride,
- const unsigned char *ref_ptr,
- int recon_stride,
- unsigned int *sse)
-{
- unsigned int sse0, sse1, sse2, sse3, var;
- int sum0, sum1, sum2, sum3, avg;
-
-
- vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
- vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
- vp8_get8x8var_mmx(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse2, &sum2) ;
- vp8_get8x8var_mmx(src_ptr + (source_stride >> 1) + 8, source_stride, ref_ptr + (recon_stride >> 1) + 8, recon_stride, &sse3, &sum3);
-
- var = sse0 + sse1 + sse2 + sse3;
- avg = sum0 + sum1 + sum2 + sum3;
- *sse = var;
- return (var - ((avg * avg) >> 8));
-
-}
-
-unsigned int vp8_i_variance8x16_mmx(
- const unsigned char *src_ptr,
- int source_stride,
- const unsigned char *ref_ptr,
- int recon_stride,
- unsigned int *sse)
-{
- unsigned int sse0, sse1, var;
- int sum0, sum1, avg;
- vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
- vp8_get8x8var_mmx(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse1, &sum1) ;
-
- var = sse0 + sse1;
- avg = sum0 + sum1;
-
- *sse = var;
- return (var - ((avg * avg) >> 7));
-
-}
-
-unsigned int vp8_i_sub_pixel_variance16x16_mmx
-(
- const unsigned char *src_ptr,
- int src_pixels_per_line,
- int xoffset,
- int yoffset,
- const unsigned char *dst_ptr,
- int dst_pixels_per_line,
- unsigned int *sse
-)
-{
- int xsum0, xsum1;
- unsigned int xxsum0, xxsum1;
- int f2soffset = (src_pixels_per_line >> 1);
- int f2doffset = (dst_pixels_per_line >> 1);
-
-
- vp8_filter_block2d_bil_var_mmx(
- src_ptr, src_pixels_per_line,
- dst_ptr, dst_pixels_per_line, 8,
- vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
- &xsum0, &xxsum0
- );
-
-
- vp8_filter_block2d_bil_var_mmx(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 8,
- vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
- &xsum1, &xxsum1
- );
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
-
- vp8_filter_block2d_bil_var_mmx(
- src_ptr + f2soffset, src_pixels_per_line,
- dst_ptr + f2doffset, dst_pixels_per_line, 8,
- vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
- &xsum1, &xxsum1
- );
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
-
- vp8_filter_block2d_bil_var_mmx(
- src_ptr + f2soffset + 8, src_pixels_per_line,
- dst_ptr + f2doffset + 8, dst_pixels_per_line, 8,
- vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
- &xsum1, &xxsum1
- );
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
- *sse = xxsum0;
- return (xxsum0 - ((xsum0 * xsum0) >> 8));
-}
-
-
-unsigned int vp8_i_sub_pixel_variance8x16_mmx
-(
- const unsigned char *src_ptr,
- int src_pixels_per_line,
- int xoffset,
- int yoffset,
- const unsigned char *dst_ptr,
- int dst_pixels_per_line,
- unsigned int *sse
-)
-{
- int xsum0, xsum1;
- unsigned int xxsum0, xxsum1;
- int f2soffset = (src_pixels_per_line >> 1);
- int f2doffset = (dst_pixels_per_line >> 1);
-
-
- vp8_filter_block2d_bil_var_mmx(
- src_ptr, src_pixels_per_line,
- dst_ptr, dst_pixels_per_line, 8,
- vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
- &xsum0, &xxsum0
- );
-
-
- vp8_filter_block2d_bil_var_mmx(
- src_ptr + f2soffset, src_pixels_per_line,
- dst_ptr + f2doffset, dst_pixels_per_line, 8,
- vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
- &xsum1, &xxsum1
- );
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
- *sse = xxsum0;
- return (xxsum0 - ((xsum0 * xsum0) >> 7));
-}
-
unsigned int vp8_variance_halfpixvar16x16_h_mmx(
const unsigned char *src_ptr,
diff --git a/vp8/encoder/x86/variance_sse2.c b/vp8/encoder/x86/variance_sse2.c
index 7cf6a6308..0edda3062 100644
--- a/vp8/encoder/x86/variance_sse2.c
+++ b/vp8/encoder/x86/variance_sse2.c
@@ -81,6 +81,16 @@ void vp8_filter_block2d_bil_var_sse2
int *sum,
unsigned int *sumsquared
);
+void vp8_half_horiz_vert_variance8x_h_sse2
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int *sum,
+ unsigned int *sumsquared
+);
void vp8_half_horiz_vert_variance16x_h_sse2
(
const unsigned char *ref_ptr,
@@ -91,6 +101,16 @@ void vp8_half_horiz_vert_variance16x_h_sse2
int *sum,
unsigned int *sumsquared
);
+void vp8_half_horiz_variance8x_h_sse2
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int *sum,
+ unsigned int *sumsquared
+);
void vp8_half_horiz_variance16x_h_sse2
(
const unsigned char *ref_ptr,
@@ -101,6 +121,16 @@ void vp8_half_horiz_variance16x_h_sse2
int *sum,
unsigned int *sumsquared
);
+void vp8_half_vert_variance8x_h_sse2
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int *sum,
+ unsigned int *sumsquared
+);
void vp8_half_vert_variance16x_h_sse2
(
const unsigned char *ref_ptr,
@@ -262,21 +292,21 @@ unsigned int vp8_sub_pixel_variance8x8_wmt
if (xoffset == 4 && yoffset == 0)
{
- vp8_half_horiz_variance16x_h_sse2(
+ vp8_half_horiz_variance8x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 8,
&xsum, &xxsum);
}
else if (xoffset == 0 && yoffset == 4)
{
- vp8_half_vert_variance16x_h_sse2(
+ vp8_half_vert_variance8x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 8,
&xsum, &xxsum);
}
else if (xoffset == 4 && yoffset == 4)
{
- vp8_half_horiz_vert_variance16x_h_sse2(
+ vp8_half_horiz_vert_variance8x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 8,
&xsum, &xxsum);
@@ -317,11 +347,6 @@ unsigned int vp8_sub_pixel_variance16x16_wmt
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum0, &xxsum0);
-
- vp8_half_horiz_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 16,
- &xsum1, &xxsum1);
}
else if (xoffset == 0 && yoffset == 4)
{
@@ -329,11 +354,6 @@ unsigned int vp8_sub_pixel_variance16x16_wmt
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum0, &xxsum0);
-
- vp8_half_vert_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 16,
- &xsum1, &xxsum1);
}
else if (xoffset == 4 && yoffset == 4)
{
@@ -341,11 +361,6 @@ unsigned int vp8_sub_pixel_variance16x16_wmt
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum0, &xxsum0);
-
- vp8_half_horiz_vert_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 16,
- &xsum1, &xxsum1);
}
else
{
@@ -356,17 +371,16 @@ unsigned int vp8_sub_pixel_variance16x16_wmt
&xsum0, &xxsum0
);
-
vp8_filter_block2d_bil_var_sse2(
src_ptr + 8, src_pixels_per_line,
dst_ptr + 8, dst_pixels_per_line, 16,
xoffset, yoffset,
&xsum1, &xxsum1
);
+ xsum0 += xsum1;
+ xxsum0 += xxsum1;
}
- xsum0 += xsum1;
- xxsum0 += xxsum1;
*sse = xxsum0;
return (xxsum0 - ((xsum0 * xsum0) >> 8));
}
@@ -406,11 +420,6 @@ unsigned int vp8_sub_pixel_variance16x8_wmt
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 8,
&xsum0, &xxsum0);
-
- vp8_half_horiz_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 8,
- &xsum1, &xxsum1);
}
else if (xoffset == 0 && yoffset == 4)
{
@@ -418,11 +427,6 @@ unsigned int vp8_sub_pixel_variance16x8_wmt
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 8,
&xsum0, &xxsum0);
-
- vp8_half_vert_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 8,
- &xsum1, &xxsum1);
}
else if (xoffset == 4 && yoffset == 4)
{
@@ -430,11 +434,6 @@ unsigned int vp8_sub_pixel_variance16x8_wmt
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 8,
&xsum0, &xxsum0);
-
- vp8_half_horiz_vert_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 8,
- &xsum1, &xxsum1);
}
else
{
@@ -449,11 +448,10 @@ unsigned int vp8_sub_pixel_variance16x8_wmt
dst_ptr + 8, dst_pixels_per_line, 8,
xoffset, yoffset,
&xsum1, &xxsum1);
+ xsum0 += xsum1;
+ xxsum0 += xxsum1;
}
- xsum0 += xsum1;
- xxsum0 += xxsum1;
-
*sse = xxsum0;
return (xxsum0 - ((xsum0 * xsum0) >> 7));
}
@@ -474,21 +472,21 @@ unsigned int vp8_sub_pixel_variance8x16_wmt
if (xoffset == 4 && yoffset == 0)
{
- vp8_half_horiz_variance16x_h_sse2(
+ vp8_half_horiz_variance8x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum, &xxsum);
}
else if (xoffset == 0 && yoffset == 4)
{
- vp8_half_vert_variance16x_h_sse2(
+ vp8_half_vert_variance8x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum, &xxsum);
}
else if (xoffset == 4 && yoffset == 4)
{
- vp8_half_horiz_vert_variance16x_h_sse2(
+ vp8_half_horiz_vert_variance8x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum, &xxsum);
@@ -506,81 +504,6 @@ unsigned int vp8_sub_pixel_variance8x16_wmt
return (xxsum - ((xsum * xsum) >> 7));
}
-unsigned int vp8_i_variance16x16_wmt(
- const unsigned char *src_ptr,
- int source_stride,
- const unsigned char *ref_ptr,
- int recon_stride,
- unsigned int *sse)
-{
- unsigned int sse0, sse1, sse2, sse3, var;
- int sum0, sum1, sum2, sum3, avg;
-
-
- vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
- vp8_get8x8var_sse2(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
- vp8_get8x8var_sse2(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse2, &sum2) ;
- vp8_get8x8var_sse2(src_ptr + (source_stride >> 1) + 8, source_stride, ref_ptr + (recon_stride >> 1) + 8, recon_stride, &sse3, &sum3);
-
- var = sse0 + sse1 + sse2 + sse3;
- avg = sum0 + sum1 + sum2 + sum3;
-
- *sse = var;
- return (var - ((avg * avg) >> 8));
-
-}
-
-unsigned int vp8_i_variance8x16_wmt(
- const unsigned char *src_ptr,
- int source_stride,
- const unsigned char *ref_ptr,
- int recon_stride,
- unsigned int *sse)
-{
- unsigned int sse0, sse1, var;
- int sum0, sum1, avg;
- vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
- vp8_get8x8var_sse2(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse1, &sum1) ;
-
- var = sse0 + sse1;
- avg = sum0 + sum1;
-
- *sse = var;
- return (var - ((avg * avg) >> 7));
-
-}
-
-
-unsigned int vp8_i_sub_pixel_variance16x16_wmt
-(
- const unsigned char *src_ptr,
- int src_pixels_per_line,
- int xoffset,
- int yoffset,
- const unsigned char *dst_ptr,
- int dst_pixels_per_line,
- unsigned int *sse
-)
-{
- return vp8_sub_pixel_variance16x16_wmt(src_ptr, (src_pixels_per_line >> 1), xoffset, yoffset, dst_ptr, (dst_pixels_per_line >> 1), sse);
-}
-
-
-unsigned int vp8_i_sub_pixel_variance8x16_wmt
-(
- const unsigned char *src_ptr,
- int src_pixels_per_line,
- int xoffset,
- int yoffset,
- const unsigned char *dst_ptr,
- int dst_pixels_per_line,
- unsigned int *sse
-)
-{
-
- return vp8_sub_pixel_variance8x16_wmt(src_ptr, (src_pixels_per_line >> 1), xoffset, yoffset, dst_ptr, (dst_pixels_per_line >> 1), sse);
-}
-
unsigned int vp8_variance_halfpixvar16x16_h_wmt(
const unsigned char *src_ptr,
@@ -589,21 +512,14 @@ unsigned int vp8_variance_halfpixvar16x16_h_wmt(
int dst_pixels_per_line,
unsigned int *sse)
{
- int xsum0, xsum1;
- unsigned int xxsum0, xxsum1;
+ int xsum0;
+ unsigned int xxsum0;
vp8_half_horiz_variance16x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum0, &xxsum0);
- vp8_half_horiz_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 16,
- &xsum1, &xxsum1);
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
*sse = xxsum0;
return (xxsum0 - ((xsum0 * xsum0) >> 8));
}
@@ -616,21 +532,13 @@ unsigned int vp8_variance_halfpixvar16x16_v_wmt(
int dst_pixels_per_line,
unsigned int *sse)
{
- int xsum0, xsum1;
- unsigned int xxsum0, xxsum1;
-
+ int xsum0;
+ unsigned int xxsum0;
vp8_half_vert_variance16x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum0, &xxsum0);
- vp8_half_vert_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 16,
- &xsum1, &xxsum1);
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
*sse = xxsum0;
return (xxsum0 - ((xsum0 * xsum0) >> 8));
}
@@ -643,21 +551,14 @@ unsigned int vp8_variance_halfpixvar16x16_hv_wmt(
int dst_pixels_per_line,
unsigned int *sse)
{
- int xsum0, xsum1;
- unsigned int xxsum0, xxsum1;
+ int xsum0;
+ unsigned int xxsum0;
vp8_half_horiz_vert_variance16x_h_sse2(
src_ptr, src_pixels_per_line,
dst_ptr, dst_pixels_per_line, 16,
&xsum0, &xxsum0);
- vp8_half_horiz_vert_variance16x_h_sse2(
- src_ptr + 8, src_pixels_per_line,
- dst_ptr + 8, dst_pixels_per_line, 16,
- &xsum1, &xxsum1);
-
- xsum0 += xsum1;
- xxsum0 += xxsum1;
*sse = xxsum0;
return (xxsum0 - ((xsum0 * xsum0) >> 8));
}
diff --git a/vp8/encoder/x86/variance_ssse3.c b/vp8/encoder/x86/variance_ssse3.c
new file mode 100644
index 000000000..d50ae3ade
--- /dev/null
+++ b/vp8/encoder/x86/variance_ssse3.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 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.
+ */
+
+
+#include "vp8/encoder/variance.h"
+#include "vp8/common/pragmas.h"
+#include "vpx_ports/mem.h"
+
+extern unsigned int vp8_get16x16var_sse2
+(
+ const unsigned char *src_ptr,
+ int source_stride,
+ const unsigned char *ref_ptr,
+ int recon_stride,
+ unsigned int *SSE,
+ int *Sum
+);
+extern void vp8_half_horiz_vert_variance16x_h_sse2
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int *sum,
+ unsigned int *sumsquared
+);
+extern void vp8_half_horiz_variance16x_h_sse2
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int *sum,
+ unsigned int *sumsquared
+);
+extern void vp8_half_vert_variance16x_h_sse2
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int *sum,
+ unsigned int *sumsquared
+);
+extern void vp8_filter_block2d_bil_var_ssse3
+(
+ const unsigned char *ref_ptr,
+ int ref_pixels_per_line,
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ unsigned int Height,
+ int xoffset,
+ int yoffset,
+ int *sum,
+ unsigned int *sumsquared
+);
+
+unsigned int vp8_sub_pixel_variance16x16_ssse3
+(
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ int xoffset,
+ int yoffset,
+ const unsigned char *dst_ptr,
+ int dst_pixels_per_line,
+ unsigned int *sse
+)
+{
+ int xsum0, xsum1;
+ unsigned int xxsum0, xxsum1;
+
+ // note we could avoid these if statements if the calling function
+ // just called the appropriate functions inside.
+ if (xoffset == 4 && yoffset == 0)
+ {
+ vp8_half_horiz_variance16x_h_sse2(
+ src_ptr, src_pixels_per_line,
+ dst_ptr, dst_pixels_per_line, 16,
+ &xsum0, &xxsum0);
+ }
+ else if (xoffset == 0 && yoffset == 4)
+ {
+ vp8_half_vert_variance16x_h_sse2(
+ src_ptr, src_pixels_per_line,
+ dst_ptr, dst_pixels_per_line, 16,
+ &xsum0, &xxsum0);
+ }
+ else if (xoffset == 4 && yoffset == 4)
+ {
+ vp8_half_horiz_vert_variance16x_h_sse2(
+ src_ptr, src_pixels_per_line,
+ dst_ptr, dst_pixels_per_line, 16,
+ &xsum0, &xxsum0);
+ }
+ else
+ {
+ vp8_filter_block2d_bil_var_ssse3(
+ src_ptr, src_pixels_per_line,
+ dst_ptr, dst_pixels_per_line, 16,
+ xoffset, yoffset,
+ &xsum0, &xxsum0);
+ }
+
+ *sse = xxsum0;
+ return (xxsum0 - ((xsum0 * xsum0) >> 8));
+}
diff --git a/vp8/encoder/x86/variance_x86.h b/vp8/encoder/x86/variance_x86.h
index 6bea15ebc..1e2fb3490 100644
--- a/vp8/encoder/x86/variance_x86.h
+++ b/vp8/encoder/x86/variance_x86.h
@@ -286,6 +286,7 @@ extern prototype_sad_multi_dif_address(vp8_sad4x4x4d_sse3);
#if HAVE_SSSE3
extern prototype_sad_multi_same_address(vp8_sad16x16x3_ssse3);
extern prototype_sad_multi_same_address(vp8_sad16x8x3_ssse3);
+extern prototype_subpixvariance(vp8_sub_pixel_variance16x16_ssse3);
#if !CONFIG_RUNTIME_CPU_DETECT
#undef vp8_variance_sad16x16x3
@@ -294,6 +295,9 @@ extern prototype_sad_multi_same_address(vp8_sad16x8x3_ssse3);
#undef vp8_variance_sad16x8x3
#define vp8_variance_sad16x8x3 vp8_sad16x8x3_ssse3
+#undef vp8_variance_subpixvar16x16
+#define vp8_variance_subpixvar16x16 vp8_sub_pixel_variance16x16_ssse3
+
#endif
#endif
diff --git a/vp8/encoder/x86/x86_csystemdependent.c b/vp8/encoder/x86/x86_csystemdependent.c
index 61c603229..c7639a7e4 100644
--- a/vp8/encoder/x86/x86_csystemdependent.c
+++ b/vp8/encoder/x86/x86_csystemdependent.c
@@ -334,6 +334,8 @@ void vp8_arch_x86_encoder_init(VP8_COMP *cpi)
cpi->rtcd.variance.sad16x16x3 = vp8_sad16x16x3_ssse3;
cpi->rtcd.variance.sad16x8x3 = vp8_sad16x8x3_ssse3;
+ cpi->rtcd.variance.subpixvar16x16 = vp8_sub_pixel_variance16x16_ssse3;
+
cpi->rtcd.quantize.fastquantb = vp8_fast_quantize_b_ssse3;
}
diff --git a/vp8/vp8cx.mk b/vp8/vp8cx.mk
index ed2feddae..c0ae250f5 100644
--- a/vp8/vp8cx.mk
+++ b/vp8/vp8cx.mk
@@ -110,6 +110,8 @@ VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/subtract_sse2.asm
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/temporal_filter_apply_sse2.asm
VP8_CX_SRCS-$(HAVE_SSE3) += encoder/x86/sad_sse3.asm
VP8_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/sad_ssse3.asm
+VP8_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/variance_ssse3.c
+VP8_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/variance_impl_ssse3.asm
VP8_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/quantize_ssse3.asm
VP8_CX_SRCS-$(HAVE_SSE4_1) += encoder/x86/sad_sse4.asm
VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/quantize_mmx.asm
diff --git a/vpxenc.c b/vpxenc.c
index d0f4c2348..7b8de1171 100755
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -163,8 +163,8 @@ int stats_open_file(stats_io_t *stats, const char *fpf, int pass)
if (!stats->buf.buf)
{
- fprintf(stderr, "Failed to allocate first-pass stats buffer (%d bytes)\n",
- stats->buf_alloc_sz);
+ fprintf(stderr, "Failed to allocate first-pass stats buffer (%lu bytes)\n",
+ (unsigned long)stats->buf_alloc_sz);
exit(EXIT_FAILURE);
}