Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 "libavutil/cpu.h"
  20. #include "libavutil/cpu_internal.h"
  21. #include "config.h"
  22.  
  23. #define CORE_FLAG(f) \
  24.     (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE))
  25.  
  26. #define CORE_CPU_FLAGS                          \
  27.     (CORE_FLAG(ARMV5TE) |                       \
  28.      CORE_FLAG(ARMV6)   |                       \
  29.      CORE_FLAG(ARMV6T2) |                       \
  30.      CORE_FLAG(VFP)     |                       \
  31.      CORE_FLAG(VFPV3)   |                       \
  32.      CORE_FLAG(NEON))
  33.  
  34. #if defined __linux__ || defined __ANDROID__
  35.  
  36. #include <stdint.h>
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include "libavutil/avstring.h"
  40.  
  41. #define AT_HWCAP        16
  42.  
  43. /* Relevant HWCAP values from kernel headers */
  44. #define HWCAP_VFP       (1 << 6)
  45. #define HWCAP_EDSP      (1 << 7)
  46. #define HWCAP_THUMBEE   (1 << 11)
  47. #define HWCAP_NEON      (1 << 12)
  48. #define HWCAP_VFPv3     (1 << 13)
  49. #define HWCAP_TLS       (1 << 15)
  50.  
  51. static int get_hwcap(uint32_t *hwcap)
  52. {
  53.     struct { uint32_t a_type; uint32_t a_val; } auxv;
  54.     FILE *f = fopen("/proc/self/auxv", "r");
  55.     int err = -1;
  56.  
  57.     if (!f)
  58.         return -1;
  59.  
  60.     while (fread(&auxv, sizeof(auxv), 1, f) > 0) {
  61.         if (auxv.a_type == AT_HWCAP) {
  62.             *hwcap = auxv.a_val;
  63.             err = 0;
  64.             break;
  65.         }
  66.     }
  67.  
  68.     fclose(f);
  69.     return err;
  70. }
  71.  
  72. static int get_cpuinfo(uint32_t *hwcap)
  73. {
  74.     FILE *f = fopen("/proc/cpuinfo", "r");
  75.     char buf[200];
  76.  
  77.     if (!f)
  78.         return -1;
  79.  
  80.     *hwcap = 0;
  81.     while (fgets(buf, sizeof(buf), f)) {
  82.         if (av_strstart(buf, "Features", NULL)) {
  83.             if (strstr(buf, " edsp "))
  84.                 *hwcap |= HWCAP_EDSP;
  85.             if (strstr(buf, " tls "))
  86.                 *hwcap |= HWCAP_TLS;
  87.             if (strstr(buf, " thumbee "))
  88.                 *hwcap |= HWCAP_THUMBEE;
  89.             if (strstr(buf, " vfp "))
  90.                 *hwcap |= HWCAP_VFP;
  91.             if (strstr(buf, " vfpv3 "))
  92.                 *hwcap |= HWCAP_VFPv3;
  93.             if (strstr(buf, " neon "))
  94.                 *hwcap |= HWCAP_NEON;
  95.             break;
  96.         }
  97.     }
  98.     fclose(f);
  99.     return 0;
  100. }
  101.  
  102. int ff_get_cpu_flags_arm(void)
  103. {
  104.     int flags = CORE_CPU_FLAGS;
  105.     uint32_t hwcap;
  106.  
  107.     if (get_hwcap(&hwcap) < 0)
  108.         if (get_cpuinfo(&hwcap) < 0)
  109.             return flags;
  110.  
  111. #define check_cap(cap, flag) do {               \
  112.         if (hwcap & HWCAP_ ## cap)              \
  113.             flags |= AV_CPU_FLAG_ ## flag;      \
  114.     } while (0)
  115.  
  116.     /* No flags explicitly indicate v6 or v6T2 so check others which
  117.        imply support. */
  118.     check_cap(EDSP,    ARMV5TE);
  119.     check_cap(TLS,     ARMV6);
  120.     check_cap(THUMBEE, ARMV6T2);
  121.     check_cap(VFP,     VFP);
  122.     check_cap(VFPv3,   VFPV3);
  123.     check_cap(NEON,    NEON);
  124.  
  125.     /* The v6 checks above are not reliable so let higher flags
  126.        trickle down. */
  127.     if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))
  128.         flags |= AV_CPU_FLAG_ARMV6T2;
  129.     if (flags & AV_CPU_FLAG_ARMV6T2)
  130.         flags |= AV_CPU_FLAG_ARMV6;
  131.  
  132.     return flags;
  133. }
  134.  
  135. #else
  136.  
  137. int ff_get_cpu_flags_arm(void)
  138. {
  139.     return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE |
  140.            AV_CPU_FLAG_ARMV6   * HAVE_ARMV6   |
  141.            AV_CPU_FLAG_ARMV6T2 * HAVE_ARMV6T2 |
  142.            AV_CPU_FLAG_VFP     * HAVE_VFP     |
  143.            AV_CPU_FLAG_VFPV3   * HAVE_VFPV3   |
  144.            AV_CPU_FLAG_NEON    * HAVE_NEON;
  145. }
  146.  
  147. #endif
  148.