lavu/buffer: drop USE_ATOMICS
[ffmpeg.git] / libavutil / intreadwrite.h
index cdf1ef4..d54d4b9 100644 (file)
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,9 +47,17 @@ typedef union {
 
 /*
  * Arch-specific headers can provide any combination of
- * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
+ * AV_[RW][BLN](16|24|32|48|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
  * Preprocessor symbols must be defined, even if these are implemented
  * as inline functions.
+ *
+ * R/W means read/write, B/L/N means big/little/native endianness.
+ * The following macros require aligned access, compared to their
+ * unaligned variants: AV_(COPY|SWAP|ZERO)(64|128), AV_[RW]N[8-64]A.
+ * Incorrect usage may range from abysmal performance to crash
+ * depending on the platform.
+ *
+ * The unaligned variants are AV_[RW][BLN][8-64] and AV_COPY*U.
  */
 
 #ifdef HAVE_AV_CONFIG_H
@@ -114,6 +122,18 @@ typedef union {
 #       define AV_WN32(p, v) AV_WB32(p, v)
 #   endif
 
+#   if    defined(AV_RN48) && !defined(AV_RB48)
+#       define AV_RB48(p) AV_RN48(p)
+#   elif !defined(AV_RN48) &&  defined(AV_RB48)
+#       define AV_RN48(p) AV_RB48(p)
+#   endif
+
+#   if    defined(AV_WN48) && !defined(AV_WB48)
+#       define AV_WB48(p, v) AV_WN48(p, v)
+#   elif !defined(AV_WN48) &&  defined(AV_WB48)
+#       define AV_WN48(p, v) AV_WB48(p, v)
+#   endif
+
 #   if    defined(AV_RN64) && !defined(AV_RB64)
 #       define AV_RB64(p) AV_RN64(p)
 #   elif !defined(AV_RN64) &&  defined(AV_RB64)
@@ -164,6 +184,18 @@ typedef union {
 #       define AV_WN32(p, v) AV_WL32(p, v)
 #   endif
 
+#   if    defined(AV_RN48) && !defined(AV_RL48)
+#       define AV_RL48(p) AV_RN48(p)
+#   elif !defined(AV_RN48) &&  defined(AV_RL48)
+#       define AV_RN48(p) AV_RL48(p)
+#   endif
+
+#   if    defined(AV_WN48) && !defined(AV_WL48)
+#       define AV_WL48(p, v) AV_WN48(p, v)
+#   elif !defined(AV_WN48) &&  defined(AV_WL48)
+#       define AV_WN48(p, v) AV_WL48(p, v)
+#   endif
+
 #   if    defined(AV_RN64) && !defined(AV_RL64)
 #       define AV_RL64(p) AV_RN64(p)
 #   elif !defined(AV_RN64) &&  defined(AV_RL64)
@@ -197,6 +229,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
 #   define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
 #   define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
 
+#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64)) && AV_HAVE_FAST_UNALIGNED
+
+#   define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
+#   define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
+
 #elif AV_HAVE_FAST_UNALIGNED
 
 #   define AV_RN(s, p) (((const av_alias##s*)(p))->u##s)
@@ -210,7 +247,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
       ((const uint8_t*)(x))[1])
 #endif
 #ifndef AV_WB16
-#   define AV_WB16(p, d) do {                   \
+#   define AV_WB16(p, val) do {                 \
+        uint16_t d = (val);                     \
         ((uint8_t*)(p))[1] = (d);               \
         ((uint8_t*)(p))[0] = (d)>>8;            \
     } while(0)
@@ -222,7 +260,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
       ((const uint8_t*)(x))[0])
 #endif
 #ifndef AV_WL16
-#   define AV_WL16(p, d) do {                   \
+#   define AV_WL16(p, val) do {                 \
+        uint16_t d = (val);                     \
         ((uint8_t*)(p))[0] = (d);               \
         ((uint8_t*)(p))[1] = (d)>>8;            \
     } while(0)
@@ -236,7 +275,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
                 ((const uint8_t*)(x))[3])
 #endif
 #ifndef AV_WB32
-#   define AV_WB32(p, d) do {                   \
+#   define AV_WB32(p, val) do {                 \
+        uint32_t d = (val);                     \
         ((uint8_t*)(p))[3] = (d);               \
         ((uint8_t*)(p))[2] = (d)>>8;            \
         ((uint8_t*)(p))[1] = (d)>>16;           \
@@ -252,7 +292,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
                 ((const uint8_t*)(x))[0])
 #endif
 #ifndef AV_WL32
-#   define AV_WL32(p, d) do {                   \
+#   define AV_WL32(p, val) do {                 \
+        uint32_t d = (val);                     \
         ((uint8_t*)(p))[0] = (d);               \
         ((uint8_t*)(p))[1] = (d)>>8;            \
         ((uint8_t*)(p))[2] = (d)>>16;           \
@@ -272,7 +313,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
       (uint64_t)((const uint8_t*)(x))[7])
 #endif
 #ifndef AV_WB64
-#   define AV_WB64(p, d) do {                   \
+#   define AV_WB64(p, val) do {                 \
+        uint64_t d = (val);                     \
         ((uint8_t*)(p))[7] = (d);               \
         ((uint8_t*)(p))[6] = (d)>>8;            \
         ((uint8_t*)(p))[5] = (d)>>16;           \
@@ -296,7 +338,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
       (uint64_t)((const uint8_t*)(x))[0])
 #endif
 #ifndef AV_WL64
-#   define AV_WL64(p, d) do {                   \
+#   define AV_WL64(p, val) do {                 \
+        uint64_t d = (val);                     \
         ((uint8_t*)(p))[0] = (d);               \
         ((uint8_t*)(p))[1] = (d)>>8;            \
         ((uint8_t*)(p))[2] = (d)>>16;           \
@@ -430,6 +473,48 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
     } while(0)
 #endif
 
+#ifndef AV_RB48
+#   define AV_RB48(x)                                     \
+    (((uint64_t)((const uint8_t*)(x))[0] << 40) |         \
+     ((uint64_t)((const uint8_t*)(x))[1] << 32) |         \
+     ((uint64_t)((const uint8_t*)(x))[2] << 24) |         \
+     ((uint64_t)((const uint8_t*)(x))[3] << 16) |         \
+     ((uint64_t)((const uint8_t*)(x))[4] <<  8) |         \
+      (uint64_t)((const uint8_t*)(x))[5])
+#endif
+#ifndef AV_WB48
+#   define AV_WB48(p, darg) do {                \
+        uint64_t d = (darg);                    \
+        ((uint8_t*)(p))[5] = (d);               \
+        ((uint8_t*)(p))[4] = (d)>>8;            \
+        ((uint8_t*)(p))[3] = (d)>>16;           \
+        ((uint8_t*)(p))[2] = (d)>>24;           \
+        ((uint8_t*)(p))[1] = (d)>>32;           \
+        ((uint8_t*)(p))[0] = (d)>>40;           \
+    } while(0)
+#endif
+
+#ifndef AV_RL48
+#   define AV_RL48(x)                                     \
+    (((uint64_t)((const uint8_t*)(x))[5] << 40) |         \
+     ((uint64_t)((const uint8_t*)(x))[4] << 32) |         \
+     ((uint64_t)((const uint8_t*)(x))[3] << 24) |         \
+     ((uint64_t)((const uint8_t*)(x))[2] << 16) |         \
+     ((uint64_t)((const uint8_t*)(x))[1] <<  8) |         \
+      (uint64_t)((const uint8_t*)(x))[0])
+#endif
+#ifndef AV_WL48
+#   define AV_WL48(p, darg) do {                \
+        uint64_t d = (darg);                    \
+        ((uint8_t*)(p))[0] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+        ((uint8_t*)(p))[2] = (d)>>16;           \
+        ((uint8_t*)(p))[3] = (d)>>24;           \
+        ((uint8_t*)(p))[4] = (d)>>32;           \
+        ((uint8_t*)(p))[5] = (d)>>40;           \
+    } while(0)
+#endif
+
 /*
  * The AV_[RW]NA macros access naturally aligned data
  * in a type-safe way.
@@ -467,11 +552,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
  * memory locations.
  */
 
-#define AV_COPYU(n, d, s)                                       \
-    do {                                                        \
-        uint##n##_t val = AV_RN##n(s);                          \
-        AV_WN##n(d, val);                                       \
-    } while (0)
+#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s));
 
 #ifndef AV_COPY16U
 #   define AV_COPY16U(d, s) AV_COPYU(16, d, s)