summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/aclib/accore.c
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/transcode/transcode-1.1.7/aclib/accore.c
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/transcode/transcode-1.1.7/aclib/accore.c')
-rw-r--r--debian/transcode/transcode-1.1.7/aclib/accore.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/aclib/accore.c b/debian/transcode/transcode-1.1.7/aclib/accore.c
new file mode 100644
index 00000000..ec7ea2dd
--- /dev/null
+++ b/debian/transcode/transcode-1.1.7/aclib/accore.c
@@ -0,0 +1,320 @@
+/*
+ * accore.c -- core aclib functions
+ * Written by Andrew Church <achurch@achurch.org>
+ *
+ * This file is part of transcode, a video stream processing tool.
+ * transcode is free software, distributable under the terms of the GNU
+ * General Public License (version 2 or later). See the file COPYING
+ * for details.
+ */
+
+#include "ac.h"
+#include "ac_internal.h"
+#include "imgconvert.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(ARCH_X86) || defined(ARCH_X86_64)
+static int cpuinfo_x86(void);
+#endif
+
+/*************************************************************************/
+
+/* Library initialization function. Determines CPU features, then calls
+ * all initialization subfunctions with appropriate flags. Returns 1 on
+ * success, 0 on failure. This function can be called multiple times to
+ * change the set of acceleration features to be used. */
+
+int ac_init(int accel)
+{
+ accel &= ac_cpuinfo();
+ if (!ac_average_init(accel)
+ || !ac_imgconvert_init(accel)
+ || !ac_memcpy_init(accel)
+ || !ac_rescale_init(accel)
+ ) {
+ return 0;
+ }
+ return 1;
+}
+
+/*************************************************************************/
+
+/* Returns the set of acceleration features supported by this CPU. */
+
+int ac_cpuinfo(void)
+{
+#if defined(ARCH_X86) || defined(ARCH_X86_64)
+ return cpuinfo_x86();
+#else
+ return 0;
+#endif
+}
+
+/*************************************************************************/
+
+/* Returns the endianness of this CPU (AC_BIG_ENDIAN or AC_LITTLE_ENDIAN). */
+
+int ac_endian(void)
+{
+ volatile int test;
+
+ test = 1;
+ if (*((uint8_t *)&test))
+ return AC_LITTLE_ENDIAN;
+ else
+ return AC_BIG_ENDIAN;
+}
+
+/*************************************************************************/
+
+/* Utility routine to convert a set of flags to a descriptive string. The
+ * string is stored in a static buffer overwritten each call. `filter'
+ * selects whether to filter out flags not supported by the CPU. */
+
+const char *ac_flagstotext(int accel)
+{
+ static char retbuf[1000];
+ if (!accel)
+ return "none";
+ snprintf(retbuf, sizeof(retbuf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ accel & AC_SSE5 ? " sse5" : "",
+ accel & AC_SSE4A ? " sse4a" : "",
+ accel & AC_SSE42 ? " sse42" : "",
+ accel & AC_SSE41 ? " sse41" : "",
+ accel & AC_SSSE3 ? " ssse3" : "",
+ accel & AC_SSE3 ? " sse3" : "",
+ accel & AC_SSE2 ? " sse2" : "",
+ accel & AC_SSE ? " sse" : "",
+ accel & AC_3DNOWEXT ? " 3dnowext" : "",
+ accel & AC_3DNOW ? " 3dnow" : "",
+ accel & AC_MMXEXT ? " mmxext" : "",
+ accel & AC_MMX ? " mmx" : "",
+ accel & AC_CMOVE ? " cmove" : "",
+ accel & (AC_IA32ASM|AC_AMD64ASM) ? " asm" : "");
+ return *retbuf ? retbuf+1 : retbuf; /* skip initial space */
+}
+
+/* Utility routine to parse a comma-separate descriptive string to the
+ corrisponding flag. The reverse of ac_flagstotext.
+ Returns 1 on success, 0 on failure */
+
+#define AC_FLAG_LEN 16
+
+int ac_parseflags(const char *text, int *accel)
+{
+ int parsed = 1, done = 0;
+ if (!text || !accel)
+ return 0;
+#if defined(ARCH_X86) || defined(ARCH_X86_64)
+ *accel = 0;
+
+ while (parsed && !done) {
+ char buf[AC_FLAG_LEN + 1] = { '\0' };
+ const char *comma = strchr(text, ',');
+ if (!comma) {
+ strncpy(buf, text, AC_FLAG_LEN);
+ done = 1;
+ } else {
+ /* parse the remaining and exit*/
+ size_t len = (comma - text);
+ if (len > AC_FLAG_LEN)
+ len = AC_FLAG_LEN;
+ strncpy(buf, text, len);
+ }
+//fprintf(stderr, "(%s) buf=[%s]\n", __func__, buf);
+ if (strcasecmp(buf, "C") == 0) // dummy for "no accel"
+ *accel |= 0;
+#ifdef ARCH_X86
+ else if (strcasecmp(buf, "asm" ) == 0)
+ *accel |= AC_IA32ASM;
+#endif
+#ifdef ARCH_X86_64
+ else if (strcasecmp(buf, "asm" ) == 0)
+ *accel |= AC_AMD64ASM;
+#endif
+ else if (strcasecmp(buf, "mmx" ) == 0)
+ *accel |= AC_MMX;
+ else if (strcasecmp(buf, "mmxext" ) == 0)
+ *accel |= AC_MMXEXT;
+ else if (strcasecmp(buf, "3dnow" ) == 0)
+ *accel |= AC_3DNOW;
+ else if (strcasecmp(buf, "3dnowext") == 0)
+ *accel |= AC_3DNOWEXT;
+ else if (strcasecmp(buf, "sse" ) == 0)
+ *accel |= AC_SSE;
+ else if (strcasecmp(buf, "sse2" ) == 0)
+ *accel |= AC_SSE2;
+ else if (strcasecmp(buf, "sse3" ) == 0)
+ *accel |= AC_SSE3;
+ else if (strcasecmp(buf, "ssse3" ) == 0)
+ *accel |= AC_SSSE3;
+ else if (strcasecmp(buf, "sse41" ) == 0)
+ *accel |= AC_SSE41;
+ else if (strcasecmp(buf, "sse42" ) == 0)
+ *accel |= AC_SSE42;
+ else if (strcasecmp(buf, "sse4a" ) == 0)
+ *accel |= AC_SSE4A;
+ else if (strcasecmp(buf, "sse5" ) == 0)
+ *accel |= AC_SSE5;
+ else
+ parsed = 0;
+ text = comma + 1;
+ }
+#endif
+ return parsed;
+}
+
+#undef AC_FLAG_LEN
+
+/*************************************************************************/
+/*************************************************************************/
+
+/* Private functions to return acceleration flags corresponding to available
+ * CPU features for various CPUs. Currently only x86 is supported. */
+
+/*************************************************************************/
+
+#if defined(ARCH_X86) || defined(ARCH_X86_64)
+
+#ifdef ARCH_X86_64
+# define EAX "%%rax"
+# define EBX "%%rbx"
+# define ESI "%%rsi"
+# define PUSHF "pushfq"
+# define POPF "popfq"
+#else
+# define EAX "%%eax"
+# define EBX "%%ebx"
+# define ESI "%%esi"
+# define PUSHF "pushfl"
+# define POPF "popfl"
+#endif
+
+/* Macro to execute the CPUID instruction with EAX = func. Results are
+ * placed in ret_a (EAX), ret_b (EBX), ret_c (ECX), and ret_d (EDX), which
+ * must be lvalues. Note that we save and restore EBX (RBX on x86-64)
+ * because it is the PIC register. */
+#define CPUID(func,ret_a,ret_b,ret_c,ret_d) \
+ asm("mov "EBX", "ESI"; cpuid; xchg "EBX", "ESI \
+ : "=a" (ret_a), "=S" (ret_b), "=c" (ret_c), "=d" (ret_d) \
+ : "a" (func))
+
+/* Various CPUID flags. The second word of the macro name indicates the
+ * function (1: function 1, X1: function 0x80000001) and register (D: EDX)
+ * to which the value belongs. */
+#define CPUID_1D_CMOVE (1UL<<15)
+#define CPUID_1D_MMX (1UL<<23)
+#define CPUID_1D_SSE (1UL<<25)
+#define CPUID_1D_SSE2 (1UL<<26)
+#define CPUID_1C_SSE3 (1UL<< 0)
+#define CPUID_1C_SSSE3 (1UL<< 9)
+#define CPUID_1C_SSE41 (1UL<<19)
+#define CPUID_1C_SSE42 (1UL<<20)
+#define CPUID_X1D_AMD_MMXEXT (1UL<<22) /* AMD only */
+#define CPUID_X1D_AMD_3DNOW (1UL<<31) /* AMD only */
+#define CPUID_X1D_AMD_3DNOWEXT (1UL<<30) /* AMD only */
+#define CPUID_X1D_CYRIX_MMXEXT (1UL<<24) /* Cyrix only */
+#define CPUID_X1C_AMD_SSE4A (1UL<< 6) /* AMD only */
+#define CPUID_X1C_AMD_SSE5 (1UL<<11) /* AMD only */
+
+static int cpuinfo_x86(void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ uint32_t cpuid_max, cpuid_ext_max; /* Maximum CPUID function numbers */
+ union {
+ char string[13];
+ struct { uint32_t ebx, edx, ecx; } regs;
+ } cpu_vendor; /* 12-byte CPU vendor string + trailing null */
+ uint32_t cpuid_1D, cpuid_1C, cpuid_X1C, cpuid_X1D;
+ int accel;
+
+ /* First see if the CPUID instruction is even available. We try to
+ * toggle bit 21 (ID) of the flags register; if the bit changes, then
+ * CPUID is available. */
+ asm(PUSHF" \n\
+ pop "EAX" \n\
+ mov %%eax, %%edx \n\
+ xor $0x200000, %%eax \n\
+ push "EAX" \n\
+ "POPF" \n\
+ "PUSHF" \n\
+ pop "EAX" \n\
+ xor %%edx, %%eax"
+ : "=a" (eax) : : "edx");
+ if (!eax)
+ return 0;
+
+ /* Determine the maximum function number available, and save the vendor
+ * string */
+ CPUID(0, cpuid_max, ebx, ecx, edx);
+ cpu_vendor.regs.ebx = ebx;
+ cpu_vendor.regs.ecx = ecx;
+ cpu_vendor.regs.edx = edx;
+ cpu_vendor.string[12] = 0;
+ cpuid_ext_max = 0; /* FIXME: how do early CPUs respond to 0x80000000? */
+ CPUID(0x80000000, cpuid_ext_max, ebx, ecx, edx);
+
+ /* Read available features */
+ cpuid_1D = cpuid_1C = cpuid_X1C = cpuid_X1D = 0;
+ if (cpuid_max >= 1)
+ CPUID(1, eax, ebx, cpuid_1C, cpuid_1D);
+ if (cpuid_ext_max >= 0x80000001)
+ CPUID(0x80000001, eax, ebx, cpuid_X1C, cpuid_X1D);
+
+ /* Convert to acceleration flags */
+#ifdef ARCH_X86_64
+ accel = AC_AMD64ASM; /* but not IA32! (register size issues) */
+#else
+ accel = AC_IA32ASM;
+#endif
+ if (cpuid_1D & CPUID_1D_CMOVE)
+ accel |= AC_CMOVE;
+ if (cpuid_1D & CPUID_1D_MMX)
+ accel |= AC_MMX;
+ if (cpuid_1D & CPUID_1D_SSE)
+ accel |= AC_SSE;
+ if (cpuid_1D & CPUID_1D_SSE2)
+ accel |= AC_SSE2;
+ if (cpuid_1C & CPUID_1C_SSE3)
+ accel |= AC_SSE3;
+ if (cpuid_1C & CPUID_1C_SSSE3)
+ accel |= AC_SSSE3;
+ if (cpuid_1C & CPUID_1C_SSE41)
+ accel |= AC_SSE41;
+ if (cpuid_1C & CPUID_1C_SSE42)
+ accel |= AC_SSE42;
+ if (strcmp(cpu_vendor.string, "AuthenticAMD") == 0) {
+ if (cpuid_X1D & CPUID_X1D_AMD_MMXEXT)
+ accel |= AC_MMXEXT;
+ if (cpuid_X1D & CPUID_X1D_AMD_3DNOW)
+ accel |= AC_3DNOW;
+ if (cpuid_X1D & CPUID_X1D_AMD_3DNOWEXT)
+ accel |= AC_3DNOWEXT;
+ if (cpuid_X1C & CPUID_X1C_AMD_SSE4A)
+ accel |= AC_SSE4A;
+ if (cpuid_X1C & CPUID_X1C_AMD_SSE5)
+ accel |= AC_SSE5;
+ } else if (strcmp(cpu_vendor.string, "CyrixInstead") == 0) {
+ if (cpuid_X1D & CPUID_X1D_CYRIX_MMXEXT)
+ accel |= AC_MMXEXT;
+ }
+
+ /* And return */
+ return accel;
+}
+
+#endif /* ARCH_X86 || ARCH_X86_64 */
+
+/*************************************************************************/
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * c-file-offsets: ((case-label . *) (statement-case-intro . *))
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */