audio-format: add TRUNCATE_RANGE flag
authorWim Taymans <wtaymans@redhat.com>
Tue, 3 Nov 2015 10:59:09 +0000 (11:59 +0100)
committerWim Taymans <wtaymans@redhat.com>
Tue, 3 Nov 2015 11:12:08 +0000 (12:12 +0100)
Add a TRUNCATE_RANGE flag for unpack functions to fill the least
significate bits with 0 (as did the old code). Also add functions
that don't truncate. Use the TRUNC flag in audioconvert for
backwards compatibility for now.

gst-libs/gst/audio/audio-format.c
gst-libs/gst/audio/audio-format.h
gst-libs/gst/audio/gstaudiopack.orc
gst/audioconvert/audioconvert.c

index 783f9e4486b9034ab5c5370b4bf8144f6d608d0d..6358e3283dd9c581627b253386a5475051e3f268 100644 (file)
 
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
 # define audio_orc_unpack_s16le audio_orc_unpack_s16
+# define audio_orc_unpack_s16le_trunc audio_orc_unpack_s16_trunc
 # define audio_orc_unpack_s16be audio_orc_unpack_s16_swap
+# define audio_orc_unpack_s16be_trunc audio_orc_unpack_s16_swap_trunc
 # define audio_orc_unpack_u16le audio_orc_unpack_u16
+# define audio_orc_unpack_u16le_trunc audio_orc_unpack_u16_trunc
 # define audio_orc_unpack_u16be audio_orc_unpack_u16_swap
+# define audio_orc_unpack_u16be_trunc audio_orc_unpack_u16_swap_trunc
 # define audio_orc_unpack_s24_32le audio_orc_unpack_s24_32
 # define audio_orc_unpack_s24_32be audio_orc_unpack_s24_32_swap
 # define audio_orc_unpack_u24_32le audio_orc_unpack_u24_32
 # define audio_orc_pack_f64be audio_orc_pack_f64_swap
 #else
 # define audio_orc_unpack_s16le audio_orc_unpack_s16_swap
+# define audio_orc_unpack_s16le_trunc audio_orc_unpack_s16_swap_trunc
 # define audio_orc_unpack_s16be audio_orc_unpack_s16
+# define audio_orc_unpack_s16be_trunc audio_orc_unpack_s16_trunc
 # define audio_orc_unpack_u16le audio_orc_unpack_u16_swap
+# define audio_orc_unpack_u16le_trunc audio_orc_unpack_u16_swap_trunc
 # define audio_orc_unpack_u16be audio_orc_unpack_u16
+# define audio_orc_unpack_u16be_trunc audio_orc_unpack_u16_trunc
 # define audio_orc_unpack_s24_32le audio_orc_unpack_s24_32_swap
 # define audio_orc_unpack_s24_32be audio_orc_unpack_s24_32
 # define audio_orc_unpack_u24_32le audio_orc_unpack_u24_32_swap
 # define audio_orc_pack_f64be audio_orc_pack_f64
 #endif
 
-#define MAKE_ORC_PACK_UNPACK(fmt) \
-static void unpack_ ##fmt (const GstAudioFormatInfo *info, \
-    GstAudioPackFlags flags, gpointer dest,                \
-    const gpointer data, gint length) {                    \
-  audio_orc_unpack_ ##fmt (dest, data, length);                  \
-}                                                          \
-static void pack_ ##fmt (const GstAudioFormatInfo *info,   \
-    GstAudioPackFlags flags, const gpointer src,           \
-    gpointer data, gint length) {                          \
-  audio_orc_pack_ ##fmt (data, src, length);                     \
+#define MAKE_ORC_PACK_UNPACK(fmt,fmt_t)                         \
+static void unpack_ ##fmt (const GstAudioFormatInfo *info,      \
+    GstAudioPackFlags flags, gpointer dest,                     \
+    const gpointer data, gint length) {                         \
+  if (flags & GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE)               \
+    audio_orc_unpack_ ##fmt_t (dest, data, length);             \
+  else                                                          \
+    audio_orc_unpack_ ##fmt (dest, data, length);               \
+}                                                               \
+static void pack_ ##fmt (const GstAudioFormatInfo *info,        \
+    GstAudioPackFlags flags, const gpointer src,                \
+    gpointer data, gint length) {                               \
+  audio_orc_pack_ ##fmt (data, src, length);                    \
 }
 
 #define PACK_S8 GST_AUDIO_FORMAT_S32, unpack_s8, pack_s8
-MAKE_ORC_PACK_UNPACK (s8)
+MAKE_ORC_PACK_UNPACK (s8, s8_trunc)
 #define PACK_U8 GST_AUDIO_FORMAT_S32, unpack_u8, pack_u8
-    MAKE_ORC_PACK_UNPACK (u8)
+    MAKE_ORC_PACK_UNPACK (u8, u8_trunc)
 #define PACK_S16LE GST_AUDIO_FORMAT_S32, unpack_s16le, pack_s16le
-    MAKE_ORC_PACK_UNPACK (s16le)
+    MAKE_ORC_PACK_UNPACK (s16le, s16le_trunc)
 #define PACK_S16BE GST_AUDIO_FORMAT_S32, unpack_s16be, pack_s16be
-    MAKE_ORC_PACK_UNPACK (s16be)
+    MAKE_ORC_PACK_UNPACK (s16be, s16be_trunc)
 #define PACK_U16LE GST_AUDIO_FORMAT_S32, unpack_u16le, pack_u16le
-    MAKE_ORC_PACK_UNPACK (u16le)
+    MAKE_ORC_PACK_UNPACK (u16le, u16le_trunc)
 #define PACK_U16BE GST_AUDIO_FORMAT_S32, unpack_u16be, pack_u16be
-    MAKE_ORC_PACK_UNPACK (u16be)
+    MAKE_ORC_PACK_UNPACK (u16be, u16be_trunc)
 #define PACK_S24_32LE GST_AUDIO_FORMAT_S32, unpack_s24_32le, pack_s24_32le
-    MAKE_ORC_PACK_UNPACK (s24_32le)
+    MAKE_ORC_PACK_UNPACK (s24_32le, s24_32le)
 #define PACK_S24_32BE GST_AUDIO_FORMAT_S32, unpack_s24_32be, pack_s24_32be
-    MAKE_ORC_PACK_UNPACK (s24_32be)
+    MAKE_ORC_PACK_UNPACK (s24_32be, s24_32be)
 #define PACK_U24_32LE GST_AUDIO_FORMAT_S32, unpack_u24_32le, pack_u24_32le
-    MAKE_ORC_PACK_UNPACK (u24_32le)
+    MAKE_ORC_PACK_UNPACK (u24_32le, u24_32le)
 #define PACK_U24_32BE GST_AUDIO_FORMAT_S32, unpack_u24_32be, pack_u24_32be
-    MAKE_ORC_PACK_UNPACK (u24_32be)
+    MAKE_ORC_PACK_UNPACK (u24_32be, u24_32be)
 #define PACK_S32LE GST_AUDIO_FORMAT_S32, unpack_s32le, pack_s32le
-    MAKE_ORC_PACK_UNPACK (s32le)
+    MAKE_ORC_PACK_UNPACK (s32le, s32le)
 #define PACK_S32BE GST_AUDIO_FORMAT_S32, unpack_s32be, pack_s32be
-    MAKE_ORC_PACK_UNPACK (s32be)
+    MAKE_ORC_PACK_UNPACK (s32be, s32be)
 #define PACK_U32LE GST_AUDIO_FORMAT_S32, unpack_u32le, pack_u32le
-    MAKE_ORC_PACK_UNPACK (u32le)
+    MAKE_ORC_PACK_UNPACK (u32le, u32le)
 #define PACK_U32BE GST_AUDIO_FORMAT_S32, unpack_u32be, pack_u32be
-    MAKE_ORC_PACK_UNPACK (u32be)
+    MAKE_ORC_PACK_UNPACK (u32be, u32be)
 #define SIGNED  (1U<<31)
 /* pack from signed integer 32 to integer */
 #define WRITE24_TO_LE(p,v) p[0] = v & 0xff; p[1] = (v >> 8) & 0xff; p[2] = (v >> 16) & 0xff
@@ -197,13 +208,13 @@ static void pack_ ##name (const GstAudioFormatInfo *info,               \
 #define PACK_U18BE GST_AUDIO_FORMAT_S32, unpack_u18be, pack_u18be
     MAKE_PACK_UNPACK (u18be, 3, SIGNED, 14, READ24_FROM_BE, WRITE24_TO_BE)
 #define PACK_F32LE GST_AUDIO_FORMAT_F64, unpack_f32le, pack_f32le
-    MAKE_ORC_PACK_UNPACK (f32le)
+    MAKE_ORC_PACK_UNPACK (f32le, f32le)
 #define PACK_F32BE GST_AUDIO_FORMAT_F64, unpack_f32be, pack_f32be
-    MAKE_ORC_PACK_UNPACK (f32be)
+    MAKE_ORC_PACK_UNPACK (f32be, f32be)
 #define PACK_F64LE GST_AUDIO_FORMAT_F64, unpack_f64le, pack_f64le
-    MAKE_ORC_PACK_UNPACK (f64le)
+    MAKE_ORC_PACK_UNPACK (f64le, f64le)
 #define PACK_F64BE GST_AUDIO_FORMAT_F64, unpack_f64be, pack_f64be
-    MAKE_ORC_PACK_UNPACK (f64be)
+    MAKE_ORC_PACK_UNPACK (f64be, f64be)
 #define SINT (GST_AUDIO_FORMAT_FLAG_INTEGER | GST_AUDIO_FORMAT_FLAG_SIGNED)
 #define SINT_PACK (SINT | GST_AUDIO_FORMAT_FLAG_UNPACK)
 #define UINT (GST_AUDIO_FORMAT_FLAG_INTEGER)
index d2d07b88687232b1f8661a65aa712262e05b8d59..0fbc4151a36099b0adbac3096ee1337da1a9ece2 100644 (file)
@@ -171,12 +171,18 @@ typedef enum
 /**
  * GstAudioPackFlags:
  * @GST_AUDIO_PACK_FLAG_NONE: No flag
+ * @GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE: When the source has a smaller depth
+ *   than the target format, set the least significant bits of the target
+ *   to 0. This is likely sightly faster but less accurate. When this flag
+ *   is not specified, the most significant bits of the source are duplicated
+ *   in the least significant bits of the destination.
  *
  * The different flags that can be used when packing and unpacking.
  */
 typedef enum
 {
-  GST_AUDIO_PACK_FLAG_NONE       = 0
+  GST_AUDIO_PACK_FLAG_NONE             = 0,
+  GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE   = (1 << 0)
 } GstAudioPackFlags;
 
 /**
index 89b262714530bb7c89863c3b0c59738c0dbb1f48..160c16549473d1debd948ee41dc137abb882b6f6 100644 (file)
@@ -3,53 +3,93 @@
 .dest 4 d1 gint32
 .source 1 s1 guint8
 .const 4 c1 0x80000000
+.temp 4 t3
+
+splatbl t3, s1
+xorl d1, t3, c1
+
+.function audio_orc_unpack_u8_trunc
+.dest 4 d1 gint32
+.source 1 s1 guint8
+.const 4 c1 0x80000000
 .const 4 c2 24
-.temp 2 t2
 .temp 4 t3
 
-convubw t2, s1
-convuwl t3, t2
+splatbl t3, s1
 shll t3, t3, c2
 xorl d1, t3, c1
 
-
 .function audio_orc_unpack_s8
 .dest 4 d1 gint32
 .source 1 s1 guint8
-.const 4 c1 24
+.const 4 c1 0x00808080
 .temp 2 t2
 .temp 4 t3
 
-convubw t2, s1
-convuwl t3, t2
-shll d1, t3, c1
+splatbl t3, s1
+xorl d1, t3, c1
+
+.function audio_orc_unpack_s8_trunc
+.dest 4 d1 gint32
+.source 1 s1 guint8
+.const 4 c1 24
+.temp 4 t3
 
+splatbl t3, s1
+shll d1, t3, c1
 
 .function audio_orc_unpack_u16
 .dest 4 d1 gint32
 .source 2 s1 guint8
+.const 4 c1 0x80000000
+.temp 4 t2
+
+mergewl t2, s1, s1
+xorl d1, t2, c1
+
+.function audio_orc_unpack_u16_trunc
+.dest 4 d1 gint32
+.source 2 s1 guint8
 .const 4 c2 16
 .const 4 c1 0x80000000
 .temp 4 t2
 
-convuwl t2, s1
+mergewl t2, s1, s1
 shll t2, t2, c2
 xorl d1, t2, c1
 
-
 .function audio_orc_unpack_s16
 .dest 4 d1 gint32
 .source 2 s1 guint8
+.const 4 c1 0x00008000
+.temp 4 t2
+
+mergewl t2, s1, s1
+xorl d1, t2, c1
+
+.function audio_orc_unpack_s16_trunc
+.dest 4 d1 gint32
+.source 2 s1 guint8
 .const 4 c1 16
 .temp 4 t2
 
 convuwl t2, s1
 shll d1, t2, c1
 
-
 .function audio_orc_unpack_u16_swap
 .dest 4 d1 gint32
 .source 2 s1 guint8
+.const 4 c1 0x80000000
+.temp 2 t1
+.temp 4 t2
+
+swapw t1, s1
+mergewl t2, t1, t1
+xorl d1, t2, c1
+
+.function audio_orc_unpack_u16_swap_trunc
+.dest 4 d1 gint32
+.source 2 s1 guint8
 .const 4 c2 16
 .const 4 c1 0x80000000
 .temp 2 t1
@@ -60,10 +100,17 @@ convuwl t2, t1
 shll t2, t2, c2
 xorl d1, t2, c1
 
-
 .function audio_orc_unpack_s16_swap
 .dest 4 d1 gint32
 .source 2 s1 guint8
+.temp 2 t1
+
+swapw t1, s1
+mergewl d1, t1, t1
+
+.function audio_orc_unpack_s16_swap_trunc
+.dest 4 d1 gint32
+.source 2 s1 guint8
 .const 4 c1 16
 .temp 2 t1
 .temp 4 t2
@@ -82,7 +129,6 @@ shll d1, t2, c1
 shll t1, s1, c2
 xorl d1, t1, c1
 
-
 .function audio_orc_unpack_s24_32
 .dest 4 d1 gint32
 .source 4 s1 guint8
@@ -90,7 +136,6 @@ xorl d1, t1, c1
 
 shll d1, s1, c1
 
-
 .function audio_orc_unpack_u24_32_swap
 .dest 4 d1 gint32
 .source 4 s1 guint8
index a76e36674c9c4fb037b169ea27131f36ec0d79a5..5ca86d5f2335be166807ee37d24e20d68904f58f 100644 (file)
@@ -234,7 +234,8 @@ audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
     else
       outbuf = tmpbuf;
 
-    ctx->in.finfo->unpack_func (ctx->in.finfo, 0, outbuf, src,
+    ctx->in.finfo->unpack_func (ctx->in.finfo,
+        GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE, outbuf, src,
         samples * ctx->in.channels);
     src = outbuf;
   }