Spaces:
Runtime error
Runtime error
/* | |
* This file is part of FFmpeg. | |
* | |
* FFmpeg is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU Lesser General Public | |
* License as published by the Free Software Foundation; either | |
* version 2.1 of the License, or (at your option) any later version. | |
* | |
* FFmpeg is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* Lesser General Public License for more details. | |
* | |
* You should have received a copy of the GNU Lesser General Public | |
* License along with FFmpeg; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
/** | |
* This function MAY rely on signal() or fork() in order to make sure AltiVec | |
* is present. | |
*/ | |
int ff_get_cpu_flags_ppc(void) | |
{ | |
ULONG result = 0; | |
extern struct ExecIFace *IExec; | |
IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE); | |
if (result == VECTORTYPE_ALTIVEC) | |
return AV_CPU_FLAG_ALTIVEC; | |
return 0; | |
int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC}; | |
int sels[2] = {CTL_HW, HW_VECTORUNIT}; | |
int has_vu = 0; | |
size_t len = sizeof(has_vu); | |
int err; | |
err = sysctl(sels, 2, &has_vu, &len, NULL, 0); | |
if (err == 0) | |
return has_vu ? AV_CPU_FLAG_ALTIVEC : 0; | |
return 0; | |
// The linux kernel could have the altivec support disabled | |
// even if the cpu has it. | |
int i, ret = 0; | |
int fd = open("/proc/self/auxv", O_RDONLY); | |
unsigned long buf[64] = { 0 }; | |
ssize_t count; | |
if (fd < 0) | |
return 0; | |
while ((count = read(fd, buf, sizeof(buf))) > 0) { | |
for (i = 0; i < count / sizeof(*buf); i += 2) { | |
if (buf[i] == AT_NULL) | |
goto out; | |
if (buf[i] == AT_HWCAP) { | |
if (buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC) | |
ret = AV_CPU_FLAG_ALTIVEC; | |
if (buf[i + 1] & PPC_FEATURE_HAS_VSX) | |
ret |= AV_CPU_FLAG_VSX; | |
if (ret & AV_CPU_FLAG_VSX) | |
av_assert0(ret & AV_CPU_FLAG_ALTIVEC); | |
} else if (buf[i] == AT_HWCAP2) { | |
if (buf[i + 1] & PPC_FEATURE2_ARCH_2_07) | |
ret |= AV_CPU_FLAG_POWER8; | |
} | |
} | |
} | |
out: | |
close(fd); | |
return ret; | |
int ret = 0; | |
int proc_ver; | |
// Support of mfspr PVR emulation added in Linux 2.6.17. | |
__asm__ volatile("mfspr %0, 287" : "=r" (proc_ver)); | |
proc_ver >>= 16; | |
if (proc_ver & 0x8000 || | |
proc_ver == PVR_G4_7400 || | |
proc_ver == PVR_G5_970 || | |
proc_ver == PVR_G5_970FX || | |
proc_ver == PVR_G5_970MP || | |
proc_ver == PVR_G5_970GX || | |
proc_ver == PVR_POWER6 || | |
proc_ver == PVR_POWER7 || | |
proc_ver == PVR_POWER8 || | |
proc_ver == PVR_CELL_PPU) | |
ret = AV_CPU_FLAG_ALTIVEC; | |
if (proc_ver == PVR_POWER7 || | |
proc_ver == PVR_POWER8) | |
ret |= AV_CPU_FLAG_VSX; | |
if (proc_ver == PVR_POWER8) | |
ret |= AV_CPU_FLAG_POWER8; | |
return ret; | |
// Since we were compiled for AltiVec, just assume we have it | |
// until someone comes up with a proper way (not involving signal hacks). | |
return AV_CPU_FLAG_ALTIVEC; | |
return 0; | |
} | |
size_t ff_get_cpu_max_align_ppc(void) | |
{ | |
int flags = av_get_cpu_flags(); | |
if (flags & (AV_CPU_FLAG_ALTIVEC | | |
AV_CPU_FLAG_VSX | | |
AV_CPU_FLAG_POWER8)) | |
return 16; | |
return 8; | |
} | |