Commit 6ba3c4be authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

aout: remove FI32 intermediate-only codec

With hardware FPU, FI32 was only used within the mad decoder and
internally converted to FL32. With software FPU, FI32 did not work
properly as the S16N conversion was broken (at least since VLC1.1.0).
parent 69aa24b5
...@@ -76,10 +76,6 @@ ...@@ -76,10 +76,6 @@
|| ((p_format)->i_format == VLC_CODEC_A52) \ || ((p_format)->i_format == VLC_CODEC_A52) \
|| ((p_format)->i_format == VLC_CODEC_DTS) ) || ((p_format)->i_format == VLC_CODEC_DTS) )
typedef int32_t vlc_fixed_t;
#define FIXED32_FRACBITS 28
#define FIXED32_ONE (1 << FIXED32_FRACBITS)
/* Values used for the audio-device and audio-channels object variables */ /* Values used for the audio-device and audio-channels object variables */
#define AOUT_VAR_MONO 1 #define AOUT_VAR_MONO 1
#define AOUT_VAR_STEREO 2 #define AOUT_VAR_STEREO 2
......
...@@ -338,7 +338,6 @@ ...@@ -338,7 +338,6 @@
#define VLC_CODEC_MULAW VLC_FOURCC('m','l','a','w') #define VLC_CODEC_MULAW VLC_FOURCC('m','l','a','w')
#define VLC_CODEC_DAT12 VLC_FOURCC('L','P','1','2') #define VLC_CODEC_DAT12 VLC_FOURCC('L','P','1','2')
#define VLC_CODEC_S24DAUD VLC_FOURCC('d','a','u','d') #define VLC_CODEC_S24DAUD VLC_FOURCC('d','a','u','d')
#define VLC_CODEC_FI32 VLC_FOURCC('f','i','3','2')
#define VLC_CODEC_TWINVQ VLC_FOURCC('T','W','I','N') #define VLC_CODEC_TWINVQ VLC_FOURCC('T','W','I','N')
#define VLC_CODEC_BMVAUDIO VLC_FOURCC('B','M','V','A') #define VLC_CODEC_BMVAUDIO VLC_FOURCC('B','M','V','A')
#define VLC_CODEC_ULEAD_DV_AUDIO_NTSC VLC_FOURCC('m','s',0x02,0x15) #define VLC_CODEC_ULEAD_DV_AUDIO_NTSC VLC_FOURCC('m','s',0x02,0x15)
......
...@@ -49,7 +49,6 @@ $Id$ ...@@ -49,7 +49,6 @@ $Id$
* atmo: Ambilight-like video-output * atmo: Ambilight-like video-output
* au: AU file demuxer * au: AU file demuxer
* audio_format: helper module for audio transcoding * audio_format: helper module for audio transcoding
* audio_format_neon: helper module for audio transcoding using NEON assembly
* audiobargraph_a: audiobargraph audio plugin * audiobargraph_a: audiobargraph audio plugin
* audiobargraph_v: audiobargraph video plugin * audiobargraph_v: audiobargraph video plugin
* audioqueue: Audio Output based on AudioQueue API for iOS * audioqueue: Audio Output based on AudioQueue API for iOS
......
/*****************************************************************************
* audio_format.c: NEON assembly optimized audio conversions
*****************************************************************************
* Copyright (C) 2009 Rémi Denis-Courmont
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
#include <vlc_filter.h>
#include <vlc_cpu.h>
#include <assert.h>
static int Open (vlc_object_t *);
vlc_module_begin ()
set_description (N_("ARM NEON audio format conversions") )
set_capability ("audio converter", 20)
set_callbacks (Open, NULL)
vlc_module_end ()
//static block_t *Do_F32_S32 (filter_t *, block_t *);
static block_t *Do_S32_S16 (filter_t *, block_t *);
static int Open (vlc_object_t *obj)
{
filter_t *filter = (filter_t *)obj;
if (!vlc_CPU_ARM_NEON())
return VLC_EGENERIC;
if (!AOUT_FMTS_SIMILAR (&filter->fmt_in.audio, &filter->fmt_out.audio))
return VLC_EGENERIC;
switch (filter->fmt_in.audio.i_format)
{
#if 0
case VLC_CODEC_FL32:
switch (filter->fmt_out.audio.i_format)
{
case VLC_CODEC_FI32:
filter->pf_audio_filter = Do_F32_S32;
break;
default:
return VLC_EGENERIC;
}
break;
#endif
case VLC_CODEC_FI32:
switch (filter->fmt_out.audio.i_format)
{
case VLC_CODEC_S16N:
filter->pf_audio_filter = Do_S32_S16;
break;
default:
return VLC_EGENERIC;
}
break;
default:
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
#if 0
/**
* Single-precision floating point to signed fixed point conversion.
*/
static block_t *Do_F32_S32 (filter_t *filter, block_t *inbuf)
{
unsigned nb_samples = inbuf->i_nb_samples
* aout_FormatNbChannels (&filter->fmt_in.audio);
int32_t *outp = (int32_t *)inbuf->p_buffer;
int32_t *endp = outp + nb_samples;
if (nb_samples & 1)
{
asm volatile (
"vldr.32 s0, [%[outp]]\n"
"vcvt.s32.f32 d0, d0, #28\n"
"vstr.32 s0, [%[outp]]\n"
:
: [outp] "r" (outp)
: "d0", "memory");
outp++;
}
if (nb_samples & 2)
asm volatile (
"vld1.f32 {d0}, [%[outp]]\n"
"vcvt.s32.f32 d0, d0, #28\n"
"vst1.s32 {d0}, [%[outp]]!\n"
: [outp] "+r" (outp)
:
: "d0", "memory");
if (nb_samples & 4)
asm volatile (
"vld1.f32 {q0}, [%[outp]]\n"
"vcvt.s32.f32 q0, q0, #28\n"
"vst1.s32 {q0}, [%[outp]]!\n"
: [outp] "+r" (outp)
:
: "q0", "memory");
while (outp != endp)
asm volatile (
"vld1.f32 {q0-q1}, [%[outp]]\n"
"vcvt.s32.f32 q0, q0, #28\n"
"vcvt.s32.f32 q1, q1, #28\n"
"vst1.s32 {q0-q1}, [%[outp]]!\n"
: [outp] "+r" (outp)
:
: "q0", "q1", "memory");
return inbuf;
}
#endif
extern void s32_s16_neon_unaligned (int16_t *out, const int32_t *in,
unsigned nb) asm("s32_s16_neon_unaligned");
extern void s32_s16_neon (int16_t *out, const int32_t *in,
unsigned nb) asm("s32_s16_neon");
/**
* Signed 32-bits fixed point to signed 16-bits integer
*/
static block_t *Do_S32_S16 (filter_t *filter, block_t *inbuf)
{
const int32_t *in = (int32_t *)inbuf->p_buffer;
int16_t *out = (int16_t *)in;
unsigned nb;
nb = ((-(uintptr_t)in) & 12) >> 2;
out += nb; /* fix up misalignment */
inbuf->p_buffer += 2 * nb;
s32_s16_neon_unaligned (out, in, nb);
in += nb;
out += nb;
nb = inbuf->i_nb_samples
* aout_FormatNbChannels (&filter->fmt_in.audio) - nb;
assert (!(((uintptr_t)in) & 15));
assert (!(((uintptr_t)out) & 15));
s32_s16_neon (out, in, nb);
inbuf->i_buffer /= 2;
return inbuf;
}
@*****************************************************************************
@ neon_s32_s16.S : ARM NEONv1 fi32 to s16n audio sample conversion
@*****************************************************************************
@ Copyright (C) 2009 Rémi Denis-Courmont
@
@ This program 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.
@
@ This program 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 this program; if not, write to the Free Software Foundation,
@ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
@****************************************************************************/
.arch armv6
.fpu neon
.text
#define OUT r0
#define IN r1
#define N r2
#define BUF r3
#define HALF ip
.align 2
.global s32_s16_neon
.type s32_s16_neon, %function
@ Converts fixed-point 32-bits to signed 16-bits
@ Input and output must be on 128-bits boundary
s32_s16_neon:
pld [IN]
2:
cmp N, #8
blt s32_s16_neon_unaligned
vld1.s32 {q8-q9}, [IN,:128]!
3: @ Main loop
pld [IN, #64]
sub N, #8
vqrshrn.s32 d16, q8, #13
vqrshrn.s32 d17, q9, #13
cmp N, #8
blt 4f
vld1.s32 {q10-q11}, [IN,:128]!
sub N, #8
vqrshrn.s32 d18, q10, #13
vqrshrn.s32 d19, q11, #13
cmp N, #8
blt 5f
vld1.s32 {q12-q13}, [IN,:128]!
sub N, #8
vqrshrn.s32 d20, q12, #13
vqrshrn.s32 d21, q13, #13
vst1.s16 {d16-d19}, [OUT,:128]!
cmp N, #8
blt 6f
vld1.s32 {q8-q9}, [IN,:128]!
vst1.s16 {d20-d21}, [OUT,:128]!
b 3b
4:
vst1.s16 {d16-d17}, [OUT,:128]!
b 7f
5:
vst1.s16 {d16-d19}, [OUT,:128]!
b 7f
6:
vst1.s16 {d20-d21}, [OUT,:128]!
7:
cmp N, #4
blt s32_s16_neon_unaligned
vld1.s32 {q8}, [IN,:128]!
sub N, #4
vqrshrn.s32 d16, q8, #13
vst1.s16 {d16}, [OUT,:64]!
@ Fall through for last 0-3 samples
.global s32_s16_neon_unaligned
.type s32_s16_neon_unaligned, %function
@ Converts fixed-point 32-bits to signed 16-bits
@ Input must be on 32-bits boundary, output on 16-bits
s32_s16_neon_unaligned:
mov HALF, #4096
1:
cmp N, #0
bxeq lr
ldr BUF, [IN]
add IN, #4
add OUT, #2
qadd BUF, HALF, BUF
sub N, #1
ssat BUF, #16, BUF, asr #13
strh BUF, [OUT, #-2]
b 1b
...@@ -257,32 +257,6 @@ static block_t *S32toFl32(filter_t *filter, block_t *b) ...@@ -257,32 +257,6 @@ static block_t *S32toFl32(filter_t *filter, block_t *b)
*dst++ = (float)(*src++) / 2147483648.0; *dst++ = (float)(*src++) / 2147483648.0;
return b; return b;
} }
static block_t *Fi32toFl32(filter_t *filter, block_t *b)
{
VLC_UNUSED(filter);
vlc_fixed_t *src = (vlc_fixed_t *)b->p_buffer;
float *dst = (float *)src;
for (int i = b->i_buffer / 4; i--;)
*dst++ = *src++ / (float)FIXED32_ONE;
return b;
}
static block_t *Fi32toS16(filter_t *filter, block_t *b)
{
VLC_UNUSED(filter);
vlc_fixed_t *src = (vlc_fixed_t *)b->p_buffer;
int16_t *dst = (int16_t *)src;
for (int i = b->i_buffer / 4; i--;) {
const vlc_fixed_t v = *src++;
if (v >= FIXED32_ONE)
*dst++ = INT16_MAX;
else if (v <= -FIXED32_ONE)
*dst++ = INT16_MIN;
else
*dst++ = v >> (FIXED32_FRACBITS - 15);
}
b->i_buffer /= 2;
return b;
}
/* */ /* */
static void U8toS16(block_t *bdst, const block_t *bsrc) static void U8toS16(block_t *bdst, const block_t *bsrc)
...@@ -326,8 +300,6 @@ static const struct { ...@@ -326,8 +300,6 @@ static const struct {
cvt_direct_t convert; cvt_direct_t convert;
} cvt_directs[] = { } cvt_directs[] = {
{ VLC_CODEC_FL64, VLC_CODEC_S16N, Fl64toS16 }, { VLC_CODEC_FL64, VLC_CODEC_S16N, Fl64toS16 },
{ VLC_CODEC_FI32, VLC_CODEC_FL32, Fi32toFl32 },
{ VLC_CODEC_FI32, VLC_CODEC_S16N, Fi32toS16 },
{ VLC_CODEC_S32N, VLC_CODEC_FL32, S32toFl32 }, { VLC_CODEC_S32N, VLC_CODEC_FL32, S32toFl32 },
{ VLC_CODEC_S32N, VLC_CODEC_S16N, S32toS16 }, { VLC_CODEC_S32N, VLC_CODEC_S16N, S32toS16 },
......
...@@ -114,26 +114,9 @@ static int transcode_audio_filter_chain_build( sout_stream_t *p_stream, filter_c ...@@ -114,26 +114,9 @@ static int transcode_audio_filter_chain_build( sout_stream_t *p_stream, filter_c
if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) ) if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
{ {
/* If that fails, try going through fi32 */ msg_Err( p_stream, "Failed to find conversion filter to floating point" );
current.i_codec =
current.audio.i_format = VLC_CODEC_FI32;
aout_FormatPrepare( &current.audio );
if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
{
msg_Err( p_stream, "Failed to find conversion filter to fi32" );
return VLC_EGENERIC;
}
current = *filter_chain_GetFmtOut( p_chain );
current.i_codec =
current.audio.i_format = VLC_CODEC_FL32;
aout_FormatPrepare( &current.audio );
if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
{
msg_Err( p_stream, "Failed to find conversion filter to fl32" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
}
current = *filter_chain_GetFmtOut( p_chain ); current = *filter_chain_GetFmtOut( p_chain );
} }
......
...@@ -277,7 +277,6 @@ modules/access/vcdx/vcdplayer.c ...@@ -277,7 +277,6 @@ modules/access/vcdx/vcdplayer.c
modules/access/vcdx/vcdplayer.h modules/access/vcdx/vcdplayer.h
modules/access/vdr.c modules/access/vdr.c
modules/access/zip/zipstream.c modules/access/zip/zipstream.c
modules/arm_neon/audio_format.c
modules/arm_neon/chroma_yuv.c modules/arm_neon/chroma_yuv.c
modules/arm_neon/simple_channel_mixer.c modules/arm_neon/simple_channel_mixer.c
modules/arm_neon/volume.c modules/arm_neon/volume.c
......
...@@ -69,7 +69,6 @@ unsigned int aout_BitsPerSample( vlc_fourcc_t i_format ) ...@@ -69,7 +69,6 @@ unsigned int aout_BitsPerSample( vlc_fourcc_t i_format )
case VLC_CODEC_S32B: case VLC_CODEC_S32B:
case VLC_CODEC_F32L: case VLC_CODEC_F32L:
case VLC_CODEC_F32B: case VLC_CODEC_F32B:
case VLC_CODEC_FI32:
return 32; return 32;
case VLC_CODEC_F64L: case VLC_CODEC_F64L:
......
...@@ -141,7 +141,7 @@ static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters, ...@@ -141,7 +141,7 @@ static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters,
if (n == max) if (n == max)
goto overflow; goto overflow;
filter_t *f = TryFormat (obj, VLC_CODEC_FI32, &input); filter_t *f = TryFormat (obj, VLC_CODEC_S32N, &input);
if (f == NULL) if (f == NULL)
f = TryFormat (obj, VLC_CODEC_FL32, &input); f = TryFormat (obj, VLC_CODEC_FL32, &input);
if (f == NULL) if (f == NULL)
......
...@@ -1313,9 +1313,6 @@ static const staticentry_t p_list_audio[] = { ...@@ -1313,9 +1313,6 @@ static const staticentry_t p_list_audio[] = {
B(VLC_CODEC_S24DAUD, "PCM DAUD"), B(VLC_CODEC_S24DAUD, "PCM DAUD"),
A("daud"), A("daud"),
B(VLC_CODEC_FI32, "32 bits fixed float"),
A("fi32"),
B(VLC_CODEC_F32L, "32 bits float LE"), B(VLC_CODEC_F32L, "32 bits float LE"),
A("f32l"), A("f32l"),
A("fl32"), A("fl32"),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment