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

aout: add distinct start/stop callbacks (refs #4787, refs #7601)

This would enable the input manager to hold an audio output plugin at
all times. Then it would be possible to keep track of output devices,
volume, policy and (JACK) routing continuously. For this to work,
outputs will need to be patched so that device selection and volume
handling works even when playing back.

Note though that this commit only introduces the change in the
audio_output_t interface; it does not implement the features above.
parent 157d4a8b
......@@ -140,10 +140,9 @@ struct audio_output
{
VLC_COMMON_MEMBERS
audio_sample_format_t format; /**< Output format (plugin can modify it
only when succesfully probed and not afterward) */
struct aout_sys_t *sys; /**< Output plugin private data */
int (*start) (audio_output_t *, audio_sample_format_t *);
void (*stop) (audio_output_t *);
void (*play)(audio_output_t *, block_t *, mtime_t *); /**< Play callback
- queue a block for playback */
void (*pause)( audio_output_t *, bool, mtime_t ); /**< Pause/resume
......@@ -277,6 +276,7 @@ struct aout_fifo_t
typedef struct
{
vlc_mutex_t lock;
audio_sample_format_t format;
aout_fifo_t partial; /**< Audio blocks before packetization */
aout_fifo_t fifo; /**< Packetized audio blocks */
mtime_t pause_date; /**< Date when paused or VLC_TS_INVALID */
......@@ -285,7 +285,7 @@ typedef struct
bool starving; /**< Whether currently starving (to limit error messages) */
} aout_packet_t;
VLC_DEPRECATED void aout_PacketInit(audio_output_t *, aout_packet_t *, unsigned);
VLC_DEPRECATED void aout_PacketInit(audio_output_t *, aout_packet_t *, unsigned, const audio_sample_format_t *);
VLC_DEPRECATED void aout_PacketDestroy(audio_output_t *);
VLC_DEPRECATED void aout_PacketPlay(audio_output_t *, block_t *, mtime_t *);
......
......@@ -49,25 +49,30 @@ static void Play( audio_output_t *aout, block_t *block, mtime_t *drift )
(void) drift;
}
static int Open( vlc_object_t * p_this )
static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
{
audio_output_t * p_aout = (audio_output_t *)p_this;
p_aout->play = Play;
p_aout->pause = NULL;
p_aout->flush = NULL;
p_aout->volume_set = NULL;
p_aout->mute_set = NULL;
if( AOUT_FMT_SPDIF( &p_aout->format )
&& var_InheritBool( p_this, "spdif" ) )
if (AOUT_FMT_SPDIF(fmt) && var_InheritBool(aout, "spdif"))
{
p_aout->format.i_format = VLC_CODEC_SPDIFL;
p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
p_aout->format.i_frame_length = A52_FRAME_NB;
fmt->i_format = VLC_CODEC_SPDIFL;
fmt->i_bytes_per_frame = AOUT_SPDIF_SIZE;
fmt->i_frame_length = A52_FRAME_NB;
}
else
p_aout->format.i_format = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_S16N;
fmt->i_format = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_S16N;
return VLC_SUCCESS;
}
static int Open(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout->start = Start;
aout->play = Play;
aout->pause = NULL;
aout->flush = NULL;
aout->stop = NULL;
aout->volume_set = NULL;
aout->mute_set = NULL;
return VLC_SUCCESS;
}
......@@ -46,6 +46,7 @@ struct aout_sys_t
void (*reorder) (void *, size_t, unsigned);
float soft_gain;
bool soft_mute;
audio_sample_format_t format;
};
#include "volume.h"
......@@ -159,9 +160,9 @@ static void Flush (audio_output_t *, bool);
static void Reorder71 (void *, size_t, unsigned);
/** Initializes an ALSA playback stream */
static int Open (vlc_object_t *obj)
static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys;
/* Get device name */
char *device = var_InheritString (aout, "alsa-audio-device");
......@@ -169,7 +170,7 @@ static int Open (vlc_object_t *obj)
return VLC_ENOMEM;
snd_pcm_format_t pcm_format; /* ALSA sample format */
vlc_fourcc_t fourcc = aout->format.i_format;
vlc_fourcc_t fourcc = fmt->i_format;
bool spdif = false;
switch (fourcc)
......@@ -223,7 +224,7 @@ static int Open (vlc_object_t *obj)
pcm_format = SND_PCM_FORMAT_U8;
break;
default:
if (AOUT_FMT_SPDIF(&aout->format))
if (AOUT_FMT_SPDIF(fmt))
spdif = var_InheritBool (aout, "spdif");
if (spdif)
{
......@@ -246,14 +247,14 @@ static int Open (vlc_object_t *obj)
/* ALSA channels */
/* XXX: maybe this should be shared with other dumb outputs */
uint32_t map = var_InheritInteger (aout, "alsa-audio-channels");
map &= aout->format.i_physical_channels;
map &= fmt->i_physical_channels;
if (unlikely(map == 0)) /* WTH? */
map = AOUT_CHANS_STEREO;
unsigned channels = popcount (map);
if (channels < aout_FormatNbChannels (&aout->format))
if (channels < aout_FormatNbChannels (fmt))
msg_Dbg (aout, "downmixing from %u to %u channels",
aout_FormatNbChannels (&aout->format), channels);
aout_FormatNbChannels (fmt), channels);
else
msg_Dbg (aout, "keeping %u channels", channels);
......@@ -264,7 +265,7 @@ static int Open (vlc_object_t *obj)
{
unsigned aes3;
switch (aout->format.i_rate)
switch (fmt->i_rate)
{
#define FS(freq) \
case freq: aes3 = IEC958_AES3_CON_FS_ ## freq; break;
......@@ -287,15 +288,6 @@ static int Open (vlc_object_t *obj)
return VLC_ENOMEM;
}
/* Allocate structures */
aout_sys_t *sys = malloc (sizeof (*sys));
if (unlikely(sys == NULL))
{
free (device);
return VLC_ENOMEM;
}
aout->sys = sys;
/* Open the device */
snd_pcm_t *pcm;
/* VLC always has a resampler. No need for ALSA's. */
......@@ -332,7 +324,6 @@ static int Open (vlc_object_t *obj)
_("The audio device \"%s\" could not be used:\n%s."),
device, snd_strerror (val));
free (device);
free (sys);
return VLC_EGENERIC;
}
sys->pcm = pcm;
......@@ -412,16 +403,15 @@ static int Open (vlc_object_t *obj)
}
/* Set sample rate */
unsigned rate = aout->format.i_rate;
unsigned rate = fmt->i_rate;
val = snd_pcm_hw_params_set_rate_near (pcm, hw, &rate, NULL);
if (val)
{
msg_Err (aout, "cannot set sample rate: %s", snd_strerror (val));
goto error;
}
if (aout->format.i_rate != rate)
msg_Dbg (aout, "resampling from %d Hz to %d Hz",
aout->format.i_rate, rate);
if (fmt->i_rate != rate)
msg_Dbg (aout, "resampling from %d Hz to %d Hz", fmt->i_rate, rate);
/* Set buffer size */
param = AOUT_MAX_ADVANCE_TIME;
......@@ -497,29 +487,26 @@ static int Open (vlc_object_t *obj)
}
/* Setup audio_output_t */
aout->format.i_format = fourcc;
aout->format.i_rate = rate;
fmt->i_format = fourcc;
fmt->i_rate = rate;
sys->reorder = NULL;
if (spdif)
{
aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
aout->format.i_frame_length = A52_FRAME_NB;
aout->volume_set = NULL;
aout->mute_set = NULL;
fmt->i_bytes_per_frame = AOUT_SPDIF_SIZE;
fmt->i_frame_length = A52_FRAME_NB;
}
else
{
aout->format.i_original_channels =
aout->format.i_physical_channels = map;
fmt->i_original_channels =
fmt->i_physical_channels = map;
switch (popcount (map))
{
case 8:
sys->reorder = Reorder71;
break;
}
aout_SoftVolumeInit (aout);
}
sys->format = *fmt;
aout->play = Play;
if (snd_pcm_hw_params_can_pause (hw))
......@@ -535,13 +522,13 @@ static int Open (vlc_object_t *obj)
{
vlc_value_t text;
var_Create (obj, "audio-device", VLC_VAR_STRING | VLC_VAR_HASCHOICE);
var_Create (aout, "audio-device", VLC_VAR_STRING | VLC_VAR_HASCHOICE);
text.psz_string = _("Audio Device");
var_Change (obj, "audio-device", VLC_VAR_SETTEXT, &text, NULL);
var_Change (aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL);
GetDevices (obj, device);
GetDevices (VLC_OBJECT(aout), device);
}
var_AddCallback (obj, "audio-device", DeviceChanged, NULL);
var_AddCallback (aout, "audio-device", DeviceChanged, NULL);
free (device);
return 0;
......@@ -549,7 +536,6 @@ static int Open (vlc_object_t *obj)
error:
snd_pcm_close (pcm);
free (device);
free (sys);
return VLC_EGENERIC;
}
......@@ -563,7 +549,7 @@ static void Play (audio_output_t *aout, block_t *block,
if (sys->reorder != NULL)
sys->reorder (block->p_buffer, block->i_nb_samples,
aout->format.i_bitspersample / 8);
sys->format.i_bitspersample / 8);
snd_pcm_t *pcm = sys->pcm;
snd_pcm_sframes_t frames;
......@@ -571,19 +557,19 @@ static void Play (audio_output_t *aout, block_t *block,
if (snd_pcm_delay (pcm, &frames) == 0)
{
mtime_t delay = frames * CLOCK_FREQ / aout->format.i_rate;
mtime_t delay = frames * CLOCK_FREQ / sys->format.i_rate;
delay += mdate () - block->i_pts;
if (state != SND_PCM_STATE_RUNNING)
{
if (delay < 0)
{
if (aout->format.i_format != VLC_CODEC_SPDIFL)
if (sys->format.i_format != VLC_CODEC_SPDIFL)
{
frames = (delay * aout->format.i_rate) / -CLOCK_FREQ;
frames = (delay * sys->format.i_rate) / -CLOCK_FREQ;
msg_Dbg (aout, "prepending %ld zeroes", frames);
void *z = calloc (frames, aout->format.i_bytes_per_frame);
void *z = calloc (frames, sys->format.i_bytes_per_frame);
if (likely(z != NULL))
{
snd_pcm_writei (pcm, z, frames);
......@@ -677,18 +663,16 @@ static void Flush (audio_output_t *aout, bool wait)
/**
* Releases the audio output.
*/
static void Close (vlc_object_t *obj)
static void Stop (audio_output_t *aout)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys;
snd_pcm_t *pcm = aout->sys->pcm;
snd_pcm_t *pcm = sys->pcm;
var_DelCallback (obj, "audio-device", DeviceChanged, NULL);
var_Destroy (obj, "audio-device");
var_DelCallback (aout, "audio-device", DeviceChanged, NULL);
var_Destroy (aout, "audio-device");
snd_pcm_drop (pcm);
snd_pcm_close (pcm);
free (sys);
}
/**
......@@ -837,3 +821,25 @@ static void GetDevices(vlc_object_t *obj, const char *prefs_dev)
}
var_Change(obj, "audio-device", VLC_VAR_SETVALUE, &val, NULL);
}
static int Open(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = malloc (sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
aout->sys = sys;
aout->start = Start;
aout->stop = Stop;
aout_SoftVolumeInit (aout);
return VLC_SUCCESS;
}
static void Close(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys;
free(sys);
}
......@@ -55,13 +55,22 @@ vlc_module_end ()
struct aout_sys_t
{
void *opaque;
int (*setup) (void **, char *, unsigned *, unsigned *);
union
{
void (*cleanup) (void *opaque);
struct
{
unsigned rate:18;
unsigned channels:14;
};
};
void (*play) (void *opaque, const void *data, unsigned count, int64_t pts);
void (*pause) (void *opaque, int64_t pts);
void (*resume) (void *opaque, int64_t pts);
void (*flush) (void *opaque);
void (*drain) (void *opaque);
int (*set_volume) (void *opaque, float vol, bool mute);
void (*cleanup) (void *opaque);
float volume;
bool mute;
};
......@@ -132,109 +141,116 @@ static int SoftMuteSet (audio_output_t *aout, bool mute)
return 0;
}
typedef int (*vlc_audio_format_cb) (void **, char *, unsigned *, unsigned *);
static int Open (vlc_object_t *obj)
static int Start (audio_output_t *aout, audio_sample_format_t *fmt)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = malloc (sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
aout->sys = sys;
sys->opaque = var_InheritAddress (obj, "amem-data");
sys->play = var_InheritAddress (obj, "amem-play");
sys->pause = var_InheritAddress (obj, "amem-pause");
sys->resume = var_InheritAddress (obj, "amem-resume");
sys->flush = var_InheritAddress (obj, "amem-flush");
sys->drain = var_InheritAddress (obj, "amem-drain");
sys->set_volume = var_InheritAddress (obj, "amem-set-volume");
sys->cleanup = NULL; /* defer */
sys->volume = 1.;
sys->mute = false;
if (sys->play == NULL)
goto error;
vlc_audio_format_cb setup = var_InheritAddress (obj, "amem-setup");
aout_sys_t *sys = aout->sys;
char format[5] = "S16N";
unsigned rate, channels;
unsigned channels;
if (setup != NULL)
if (sys->setup != NULL)
{
rate = aout->format.i_rate;
channels = aout_FormatNbChannels(&aout->format);
channels = aout_FormatNbChannels(fmt);
if (setup (&sys->opaque, format, &rate, &channels))
goto error;
/* Only call this callback if setup succeeded */
sys->cleanup = var_InheritAddress (obj, "amem-cleanup");
if (sys->setup (&sys->opaque, format, &fmt->i_rate, &channels))
return VLC_EGENERIC;
}
else
{
rate = var_InheritInteger (obj, "amem-rate");
channels = var_InheritInteger (obj, "amem-channels");
fmt->i_rate = sys->rate;
channels = sys->channels;
}
if (rate == 0 || rate > 192000
if (fmt->i_rate == 0 || fmt->i_rate > 192000
|| channels == 0 || channels > AOUT_CHAN_MAX)
goto error;
return VLC_EGENERIC;
/* TODO: amem-format */
if (strcmp(format, "S16N"))
{
msg_Err (aout, "format not supported");
goto error;
return VLC_EGENERIC;
}
/* channel mapping */
switch (channels)
{
case 1:
aout->format.i_physical_channels = AOUT_CHAN_CENTER;
fmt->i_physical_channels = AOUT_CHAN_CENTER;
break;
case 2:
aout->format.i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
fmt->i_physical_channels = AOUT_CHANS_2_0;
break;
case 3:
aout->format.i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
fmt->i_physical_channels = AOUT_CHANS_2_1;
break;
case 4:
aout->format.i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
fmt->i_physical_channels = AOUT_CHANS_4_0;
break;
case 5:
aout->format.i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
fmt->i_physical_channels = AOUT_CHANS_5_0;
break;
case 6:
aout->format.i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
fmt->i_physical_channels = AOUT_CHANS_5_1;
break;
case 7:
aout->format.i_physical_channels =
fmt->i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT |
AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE;
break;
case 8:
aout->format.i_physical_channels =
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE;
fmt->i_physical_channels = AOUT_CHANS_7_1;
break;
default:
assert(0);
}
aout->format.i_format = VLC_CODEC_S16N;
aout->format.i_rate = rate;
aout->format.i_original_channels = aout->format.i_physical_channels;
fmt->i_format = VLC_CODEC_S16N;
fmt->i_original_channels = fmt->i_physical_channels;
return VLC_SUCCESS;
}
static void Stop (audio_output_t *aout)
{
aout_sys_t *sys = aout->sys;
if (sys->cleanup != NULL)
sys->cleanup (sys->opaque);
}
static int Open (vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = malloc (sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
aout->sys = sys;
sys->opaque = var_InheritAddress (obj, "amem-data");
sys->setup = var_InheritAddress (obj, "amem-setup");
if (sys->setup != NULL)
sys->cleanup = var_InheritAddress (obj, "amem-cleanup");
else
{
sys->rate = var_InheritInteger (obj, "amem-rate");
sys->channels = var_InheritInteger (obj, "amem-channels");
}
sys->play = var_InheritAddress (obj, "amem-play");
sys->pause = var_InheritAddress (obj, "amem-pause");
sys->resume = var_InheritAddress (obj, "amem-resume");
sys->flush = var_InheritAddress (obj, "amem-flush");
sys->drain = var_InheritAddress (obj, "amem-drain");
sys->set_volume = var_InheritAddress (obj, "amem-set-volume");
sys->volume = 1.;
sys->mute = false;
if (sys->play == NULL)
{
free (sys);
return VLC_EGENERIC;
}
aout->start = Start;
aout->stop = Stop;
aout->play = Play;
aout->pause = Pause;
aout->flush = Flush;
......@@ -249,10 +265,6 @@ static int Open (vlc_object_t *obj)
aout->mute_set = SoftMuteSet;
}
return VLC_SUCCESS;
error:
Close (obj);
return VLC_EGENERIC;
}
static void Close (vlc_object_t *obj)
......@@ -260,7 +272,5 @@ static void Close (vlc_object_t *obj)
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys;
if (sys->cleanup != NULL)
sys->cleanup (sys->opaque);
free (sys);
}
......@@ -79,11 +79,10 @@ vlc_module_end ()
* Open: open the audio device
*****************************************************************************/
static int Open ( vlc_object_t *p_this )
static int Start( audio_output_t *aout, audio_sample_format_t *restrict fmt )
{
audio_output_t *p_aout = (audio_output_t *)p_this;
struct aout_sys_t *p_sys = malloc(sizeof(aout_sys_t));
p_aout->sys = p_sys;
aout_sys_t *p_sys = aout->sys;
OSStatus status = 0;
......@@ -120,13 +119,10 @@ static int Open ( vlc_object_t *p_this )
AudioQueueCallback(NULL, p_sys->audioQueue, buffer);
}
/* Volume is entirely done in software. */
aout_SoftVolumeInit( p_aout );
p_aout->format.i_format = VLC_CODEC_S16L;
p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
p_aout->format.i_rate = 44100;
aout_PacketInit(p_aout, &p_sys->packet, FRAME_SIZE);
fmt->i_format = VLC_CODEC_S16L;
fmt->i_physical_channels = AOUT_CHANS_STEREO;
fmt->i_rate = 44100;
aout_PacketInit(p_aout, &p_sys->packet, FRAME_SIZE, fmt);
p_aout->play = aout_PacketPlay;
p_aout->pause = aout_PacketPause;
p_aout->flush = aout_PacketFlush;
......@@ -156,9 +152,8 @@ static block_t *aout_FifoPop2( aout_fifo_t * p_fifo )
/*****************************************************************************
* Close: close the audio device
*****************************************************************************/
static void Close ( vlc_object_t *p_this )
static void Stop ( audio_output_t *p_aout )
{
audio_output_t *p_aout = (audio_output_t *)p_this;
struct aout_sys_t * p_sys = p_aout->sys;
msg_Dbg(p_aout, "Stopping AudioQueue");
......@@ -166,7 +161,6 @@ static void Close ( vlc_object_t *p_this )
msg_Dbg(p_aout, "Disposing of AudioQueue");
AudioQueueDispose(p_sys->audioQueue, false);
aout_PacketDestroy(p_aout);
free (p_sys);
}
void AudioQueueCallback(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
......@@ -195,3 +189,25 @@ void AudioQueueCallback(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferR
}
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
static int Open(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
aout->sys = sys;
aout->start = Start;
aout->stop = Stop;
aout_SoftVolumeInit(aout);
return VLC_SUCCESS;
}
static void Close(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys;
free(sys);
}
......@@ -174,28 +174,16 @@ static void *InitLibrary(struct aout_sys_t *p_sys)
return p_library;
}
static int Open(vlc_object_t *p_this)
static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
{
struct aout_sys_t *p_sys;
audio_output_t *p_aout = (audio_output_t*)(p_this);
struct aout_sys_t *p_sys = aout->sys:
int status, size;
int afSampleRate, afFrameCount, afLatency, minBufCount, minFrameCount;
int stream_type, channel, rate, format;
p_sys = (struct aout_sys_t*) malloc(sizeof(aout_sys_t));
if (!p_sys)
return VLC_ENOMEM;
p_sys->libmedia = InitLibrary(p_sys);
if (!p_sys->libmedia) {
msg_Err(p_aout, "Could not initialize libmedia.so!");
free(p_sys);
return VLC_EGENERIC;
}
/* 4000 <= frequency <= 48000 */
rate = p_aout->format.i_rate;
rate = fmt->i_rate;
if (rate < 4000)
rate = 4000;
if (rate > 48000)
......@@ -204,22 +192,22 @@ static int Open(vlc_object_t *p_this)
stream_type = MUSIC;
/* We can only accept U8 and S16L */
if (p_aout->format.i_format != VLC_CODEC_U8 && p_aout->format.i_format != VLC_CODEC_S16L)
p_aout->format.i_format = VLC_CODEC_S16L;
format = (p_aout->format.i_format == VLC_CODEC_S16L) ? PCM_16_BIT : PCM_8_BIT;
if (fmt->i_format != VLC_CODEC_U8 && fmt->i_format != VLC_CODEC_S16L)
fmt->i_format = VLC_CODEC_S16L;
format = (fmt->i_format == VLC_CODEC_S16L) ? PCM_16_BIT : PCM_8_BIT;
/* TODO: android supports more channels */
p_aout->format.i_original_channels = p_aout->format.i_physical_channels;
switch(aout_FormatNbChannels(&p_aout->format))
fmt->i_original_channels = fmt->i_physical_channels;
switch(aout_FormatNbChannels(fmt))
{
case 1:
channel = CHANNEL_OUT_MONO;
p_aout->format.i_physical_channels = AOUT_CHAN_CENTER;
fmt->i_physical_channels = AOUT_CHAN_CENTER;
break;
case 2:
default:
channel = CHANNEL_OUT_STEREO;
p_aout->format.i_physical_channels = AOUT_CHANS_STEREO;
fmt->i_physical_channels = AOUT_CHANS_STEREO;
break;
}
......@@ -230,8 +218,6 @@ static int Open(vlc_object_t *p_this)
status ^= p_sys->as_getOutputLatency((uint32_t*)(&afLatency), stream_type);
if (status != 0) {
msg_Err(p_aout, "Could not query the AudioStream parameters");
dlclose(p_sys->libmedia);
free(p_sys);
return VLC_EGENERIC;
}
minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate);
......@@ -243,8 +229,6 @@ static int Open(vlc_object_t *p_this)
status = p_sys->at_getMinFrameCount(&minFrameCount, stream_type, rate);
if (status != 0) {
msg_Err(p_aout, "Could not query the AudioTrack parameters");
dlclose(p_sys->libmedia);
free(p_sys);
return VLC_EGENERIC;
}
}
......@@ -253,11 +237,8 @@ static int Open(vlc_object_t *p_this)
/* Sizeof(AudioTrack) == 0x58 (not sure) on 2.2.1, this should be enough */
p_sys->AudioTrack = malloc(SIZE_OF_AUDIOTRACK);
if (!p_sys->AudioTrack) {
dlclose(p_sys->libmedia);
free(p_sys);
if (!p_sys->AudioTrack)
return VLC_ENOMEM;
}
*((uint32_t *) ((uint32_t)p_sys->AudioTrack + SIZE_OF_AUDIOTRACK - 4)) = 0xbaadbaad;
// Higher than android 2.2
......@@ -280,9 +261,7 @@ static int Open(vlc_object_t *p_this)
}
if (status != 0) {
msg_Err(p_aout, "Cannot create AudioTrack!");
dlclose(p_sys->libmedia);
free(p_sys->AudioTrack);
free(p_sys);
return VLC_EGENERIC;
}
......@@ -292,7 +271,7 @@ static int Open(vlc_object_t *p_this)