FFmpeg
Loading...
Searching...
No Matches
cpu.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "config.h"
20
21#ifdef __APPLE__
22#include <sys/sysctl.h>
23#elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
24#ifdef __FreeBSD__
25#include <machine/cpu.h>
26#endif
27#include <sys/auxv.h>
28#elif defined(__linux__)
29#include <asm/cputable.h>
30#include <linux/auxvec.h>
31#include <fcntl.h>
32#if HAVE_UNISTD_H
33#include <unistd.h>
34#endif
35#elif defined(__NetBSD__) || defined(__OpenBSD__)
36#include <sys/types.h>
37#include <sys/sysctl.h>
38#include <machine/cpu.h>
39#elif defined(__AMIGAOS4__)
40#include <exec/exec.h>
41#include <interfaces/exec.h>
42#include <proto/exec.h>
43#endif /* __APPLE__ */
44
45#include "libavutil/avassert.h"
46#include "libavutil/cpu.h"
48
49#ifndef AT_HWCAP
50#define AT_HWCAP 16
51#endif
52#ifndef AT_HWCAP2
53#define AT_HWCAP2 26
54#endif
55
56#define HWCAP_PPC_VSX (1U << 7)
57#define HWCAP_PPC_ALTIVEC (1U << 28)
58#define HWCAP2_PPC_ARCH_2_07 (1U << 31)
59
60/**
61 * This function MAY rely on signal() or fork() in order to make sure AltiVec
62 * is present.
63 */
65{
66#if HAVE_ALTIVEC
67#ifdef __AMIGAOS4__
68 ULONG result = 0;
69 extern struct ExecIFace *IExec;
70
71 IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
72 if (result == VECTORTYPE_ALTIVEC)
74 return 0;
75#elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
76 int flags = 0;
77
78 unsigned long hwcap = ff_getauxval(AT_HWCAP);
79 unsigned long hwcap2 = ff_getauxval(AT_HWCAP2);
80
81 if (hwcap & HWCAP_PPC_ALTIVEC)
83 if (hwcap & HWCAP_PPC_VSX)
85 if (hwcap2 & HWCAP2_PPC_ARCH_2_07)
87
88 return flags;
89#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__)
90#if defined(__NetBSD__) || defined(__OpenBSD__)
91 int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC};
92#else
93 int sels[2] = {CTL_HW, HW_VECTORUNIT};
94#endif
95 int has_vu = 0;
96 size_t len = sizeof(has_vu);
97 int err;
98
99 err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
100
101 if (err == 0)
102 return has_vu ? AV_CPU_FLAG_ALTIVEC : 0;
103 return 0;
104#elif defined(__linux__)
105 // The linux kernel could have the altivec support disabled
106 // even if the cpu has it.
107 int i, ret = 0;
108 int fd = open("/proc/self/auxv", O_RDONLY);
109 unsigned long buf[64] = { 0 };
110 ssize_t count;
111
112 if (fd < 0)
113 return 0;
114
115 while ((count = read(fd, buf, sizeof(buf))) > 0) {
116 for (i = 0; i < count / sizeof(*buf); i += 2) {
117 if (buf[i] == AT_NULL)
118 goto out;
119 if (buf[i] == AT_HWCAP) {
120 if (buf[i + 1] & HWCAP_PPC_ALTIVEC)
122 if (buf[i + 1] & HWCAP_PPC_VSX)
123 ret |= AV_CPU_FLAG_VSX;
124 if (ret & AV_CPU_FLAG_VSX)
126 }
127 else if (buf[i] == AT_HWCAP2) {
128 if (buf[i + 1] & HWCAP2_PPC_ARCH_2_07)
129 ret |= AV_CPU_FLAG_POWER8;
130 }
131 }
132 }
133
134out:
135 close(fd);
136 return ret;
137#else
138 // Since we were compiled for AltiVec, just assume we have it
139 // until someone comes up with a proper way (not involving signal hacks).
140 return AV_CPU_FLAG_ALTIVEC;
141#endif /* __AMIGAOS4__ */
142#endif /* HAVE_ALTIVEC */
143 return 0;
144}
145
147{
148 int flags = av_get_cpu_flags();
149
153 return 16;
154
155 return 8;
156}
static FILE * out
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
static uint32_t BS_FUNC read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
size_t ff_get_cpu_max_align_ppc(void)
Definition cpu.c:146
int ff_get_cpu_flags_ppc(void)
This function MAY rely on signal() or fork() in order to make sure AltiVec is present.
Definition cpu.c:64
unsigned long ff_getauxval(unsigned long type)
Definition cpu.c:309
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition cpu.c:109
#define AV_CPU_FLAG_VSX
ISA 2.06.
Definition cpu.h:65
#define AV_CPU_FLAG_POWER8
ISA 2.07.
Definition cpu.h:66
#define AV_CPU_FLAG_ALTIVEC
standard
Definition cpu.h:64
#define HWCAP2_PPC_ARCH_2_07
Definition cpu.c:58
#define HWCAP_PPC_ALTIVEC
Definition cpu.c:57
#define AT_HWCAP2
Definition cpu.c:53
#define AT_HWCAP
Definition cpu.c:50
#define HWCAP_PPC_VSX
Definition cpu.c:56
int len