audio-format: add TRUNCATE_RANGE flag

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.
This commit is contained in:
Wim Taymans 2015-11-03 11:59:09 +01:00
parent 914aa4aed1
commit 801f7ca464
4 changed files with 108 additions and 45 deletions

View File

@ -35,9 +35,13 @@
#if G_BYTE_ORDER == G_LITTLE_ENDIAN #if G_BYTE_ORDER == G_LITTLE_ENDIAN
# define audio_orc_unpack_s16le audio_orc_unpack_s16 # 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 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 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 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_32le audio_orc_unpack_s24_32
# define audio_orc_unpack_s24_32be audio_orc_unpack_s24_32_swap # 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_unpack_u24_32le audio_orc_unpack_u24_32
@ -68,9 +72,13 @@
# define audio_orc_pack_f64be audio_orc_pack_f64_swap # define audio_orc_pack_f64be audio_orc_pack_f64_swap
#else #else
# define audio_orc_unpack_s16le audio_orc_unpack_s16_swap # 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 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 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 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_32le audio_orc_unpack_s24_32_swap
# define audio_orc_unpack_s24_32be audio_orc_unpack_s24_32 # 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_unpack_u24_32le audio_orc_unpack_u24_32_swap
@ -101,46 +109,49 @@
# define audio_orc_pack_f64be audio_orc_pack_f64 # define audio_orc_pack_f64be audio_orc_pack_f64
#endif #endif
#define MAKE_ORC_PACK_UNPACK(fmt) \ #define MAKE_ORC_PACK_UNPACK(fmt,fmt_t) \
static void unpack_ ##fmt (const GstAudioFormatInfo *info, \ static void unpack_ ##fmt (const GstAudioFormatInfo *info, \
GstAudioPackFlags flags, gpointer dest, \ GstAudioPackFlags flags, gpointer dest, \
const gpointer data, gint length) { \ const gpointer data, gint length) { \
audio_orc_unpack_ ##fmt (dest, data, length); \ if (flags & GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE) \
} \ audio_orc_unpack_ ##fmt_t (dest, data, length); \
static void pack_ ##fmt (const GstAudioFormatInfo *info, \ else \
GstAudioPackFlags flags, const gpointer src, \ audio_orc_unpack_ ##fmt (dest, data, length); \
gpointer data, gint length) { \ } \
audio_orc_pack_ ##fmt (data, src, 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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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) #define SIGNED (1U<<31)
/* pack from signed integer 32 to integer */ /* 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 #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 #define PACK_U18BE GST_AUDIO_FORMAT_S32, unpack_u18be, pack_u18be
MAKE_PACK_UNPACK (u18be, 3, SIGNED, 14, READ24_FROM_BE, WRITE24_TO_BE) MAKE_PACK_UNPACK (u18be, 3, SIGNED, 14, READ24_FROM_BE, WRITE24_TO_BE)
#define PACK_F32LE GST_AUDIO_FORMAT_F64, unpack_f32le, pack_f32le #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 #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 #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 #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 (GST_AUDIO_FORMAT_FLAG_INTEGER | GST_AUDIO_FORMAT_FLAG_SIGNED)
#define SINT_PACK (SINT | GST_AUDIO_FORMAT_FLAG_UNPACK) #define SINT_PACK (SINT | GST_AUDIO_FORMAT_FLAG_UNPACK)
#define UINT (GST_AUDIO_FORMAT_FLAG_INTEGER) #define UINT (GST_AUDIO_FORMAT_FLAG_INTEGER)

View File

@ -171,12 +171,18 @@ typedef enum
/** /**
* GstAudioPackFlags: * GstAudioPackFlags:
* @GST_AUDIO_PACK_FLAG_NONE: No flag * @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. * The different flags that can be used when packing and unpacking.
*/ */
typedef enum typedef enum
{ {
GST_AUDIO_PACK_FLAG_NONE = 0 GST_AUDIO_PACK_FLAG_NONE = 0,
GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE = (1 << 0)
} GstAudioPackFlags; } GstAudioPackFlags;
/** /**

View File

@ -3,53 +3,93 @@
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 1 s1 guint8 .source 1 s1 guint8
.const 4 c1 0x80000000 .const 4 c1 0x80000000
.const 4 c2 24
.temp 2 t2
.temp 4 t3 .temp 4 t3
convubw t2, s1 splatbl t3, s1
convuwl t3, t2
shll t3, t3, c2
xorl d1, t3, c1 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 4 t3
splatbl t3, s1
shll t3, t3, c2
xorl d1, t3, c1
.function audio_orc_unpack_s8 .function audio_orc_unpack_s8
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 1 s1 guint8 .source 1 s1 guint8
.const 4 c1 24 .const 4 c1 0x00808080
.temp 2 t2 .temp 2 t2
.temp 4 t3 .temp 4 t3
convubw t2, s1 splatbl t3, s1
convuwl t3, t2 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 shll d1, t3, c1
.function audio_orc_unpack_u16 .function audio_orc_unpack_u16
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 2 s1 guint8 .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 c2 16
.const 4 c1 0x80000000 .const 4 c1 0x80000000
.temp 4 t2 .temp 4 t2
convuwl t2, s1 mergewl t2, s1, s1
shll t2, t2, c2 shll t2, t2, c2
xorl d1, t2, c1 xorl d1, t2, c1
.function audio_orc_unpack_s16 .function audio_orc_unpack_s16
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 2 s1 guint8 .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 .const 4 c1 16
.temp 4 t2 .temp 4 t2
convuwl t2, s1 convuwl t2, s1
shll d1, t2, c1 shll d1, t2, c1
.function audio_orc_unpack_u16_swap .function audio_orc_unpack_u16_swap
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 2 s1 guint8 .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 c2 16
.const 4 c1 0x80000000 .const 4 c1 0x80000000
.temp 2 t1 .temp 2 t1
@ -60,10 +100,17 @@ convuwl t2, t1
shll t2, t2, c2 shll t2, t2, c2
xorl d1, t2, c1 xorl d1, t2, c1
.function audio_orc_unpack_s16_swap .function audio_orc_unpack_s16_swap
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 2 s1 guint8 .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 .const 4 c1 16
.temp 2 t1 .temp 2 t1
.temp 4 t2 .temp 4 t2
@ -82,7 +129,6 @@ shll d1, t2, c1
shll t1, s1, c2 shll t1, s1, c2
xorl d1, t1, c1 xorl d1, t1, c1
.function audio_orc_unpack_s24_32 .function audio_orc_unpack_s24_32
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 4 s1 guint8 .source 4 s1 guint8
@ -90,7 +136,6 @@ xorl d1, t1, c1
shll d1, s1, c1 shll d1, s1, c1
.function audio_orc_unpack_u24_32_swap .function audio_orc_unpack_u24_32_swap
.dest 4 d1 gint32 .dest 4 d1 gint32
.source 4 s1 guint8 .source 4 s1 guint8

View File

@ -234,7 +234,8 @@ audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
else else
outbuf = tmpbuf; 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); samples * ctx->in.channels);
src = outbuf; src = outbuf;
} }