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

aout: hide "input" from decoder

parent 6feb8beb
......@@ -172,17 +172,16 @@ void aout_FormatsPrint( audio_output_t * p_aout, const char * psz_text, const au
bool aout_ChangeFilterString( vlc_object_t *, audio_output_t *, const char *psz_variable, const char *psz_name, bool b_add );
/* From dec.c */
aout_input_t *aout_DecNew(audio_output_t *, const audio_sample_format_t *,
const audio_replay_gain_t *,
const aout_request_vout_t *);
void aout_DecDelete ( audio_output_t *, aout_input_t * );
aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t );
void aout_DecDeleteBuffer( audio_output_t *, aout_input_t *, aout_buffer_t * );
int aout_DecPlay( audio_output_t *, aout_input_t *, aout_buffer_t *, int i_input_rate );
int aout_DecGetResetLost( audio_output_t *, aout_input_t * );
void aout_DecChangePause( audio_output_t *, aout_input_t *, bool b_paused, mtime_t i_date );
void aout_DecFlush( audio_output_t *, aout_input_t * );
bool aout_DecIsEmpty( audio_output_t * p_aout, aout_input_t * p_input );
int aout_DecNew(audio_output_t *, const audio_sample_format_t *,
const audio_replay_gain_t *, const aout_request_vout_t *);
void aout_DecDelete(audio_output_t *);
block_t *aout_DecNewBuffer(audio_output_t *, size_t);
void aout_DecDeleteBuffer(audio_output_t *, block_t *);
int aout_DecPlay(audio_output_t *, block_t *, int i_input_rate);
int aout_DecGetResetLost(audio_output_t *);
void aout_DecChangePause(audio_output_t *, bool b_paused, mtime_t i_date);
void aout_DecFlush(audio_output_t *);
bool aout_DecIsEmpty(audio_output_t *);
/* Audio output locking */
......
......@@ -38,49 +38,48 @@
#include "aout_internal.h"
#include "libvlc.h"
#undef aout_DecNew
/**
* Creates an audio output
*/
aout_input_t *aout_DecNew( audio_output_t *p_aout,
const audio_sample_format_t *p_format,
const audio_replay_gain_t *p_replay_gain,
const aout_request_vout_t *p_request_vout )
int aout_DecNew( audio_output_t *p_aout,
const audio_sample_format_t *p_format,
const audio_replay_gain_t *p_replay_gain,
const aout_request_vout_t *p_request_vout )
{
/* Sanitize audio format */
if( p_format->i_channels > 32 )
{
msg_Err( p_aout, "too many audio channels (%u)",
p_format->i_channels );
return NULL;
return -1;
}
if( p_format->i_channels <= 0 )
{
msg_Err( p_aout, "no audio channels" );
return NULL;
return -1;
}
if( p_format->i_channels != aout_FormatNbChannels( p_format ) )
{
msg_Err( p_aout, "incompatible audio channels count with layout mask" );
return NULL;
return -1;
}
if( p_format->i_rate > 192000 )
{
msg_Err( p_aout, "excessive audio sample frequency (%u)",
p_format->i_rate );
return NULL;
return -1;
}
if( p_format->i_rate < 4000 )
{
msg_Err( p_aout, "too low audio sample frequency (%u)",
p_format->i_rate );
return NULL;
return -1;
}
aout_input_t *p_input = calloc( 1, sizeof(aout_input_t));
if( !p_input )
return NULL;
return -1;
p_input->b_error = true;
......@@ -113,26 +112,27 @@ aout_input_t *aout_DecNew( audio_output_t *p_aout,
owner->input = p_input;
aout_InputNew( p_aout, p_input, p_request_vout );
aout_unlock( p_aout );
return p_input;
return 0;
error:
aout_unlock( p_aout );
free( p_input );
return NULL;
return -1;
}
/*****************************************************************************
* aout_DecDelete : delete a decoder
*****************************************************************************/
void aout_DecDelete( audio_output_t * p_aout, aout_input_t * p_input )
void aout_DecDelete( audio_output_t * p_aout )
{
aout_owner_t *owner = aout_owner (p_aout);
aout_input_t *input;
struct audio_mixer *mixer;
aout_lock( p_aout );
/* Remove the input. */
assert (owner->input == p_input); /* buggy decoder? */
input = owner->input;
aout_InputDelete (p_aout, input);
owner->input = NULL;
aout_InputDelete( p_aout, p_input );
aout_OutputDelete( p_aout );
mixer = owner->volume.mixer;
......@@ -143,7 +143,7 @@ void aout_DecDelete( audio_output_t * p_aout, aout_input_t * p_input )
aout_unlock( p_aout );
aout_MixerDelete (mixer);
free( p_input );
free (input);
}
static void aout_CheckRestart (audio_output_t *aout)
......@@ -191,15 +191,18 @@ error:
/*****************************************************************************
* aout_DecNewBuffer : ask for a new empty buffer
*****************************************************************************/
aout_buffer_t * aout_DecNewBuffer( aout_input_t * p_input,
size_t i_nb_samples )
block_t *aout_DecNewBuffer (audio_output_t *aout, size_t samples)
{
size_t length = i_nb_samples * p_input->input.i_bytes_per_frame
/ p_input->input.i_frame_length;
/* NOTE: the caller is responsible for serializing input change */
aout_owner_t *owner = aout_owner (aout);
aout_input_t *input = owner->input;
size_t length = samples * input->input.i_bytes_per_frame
/ input->input.i_frame_length;
block_t *block = block_Alloc( length );
if( likely(block != NULL) )
{
block->i_nb_samples = i_nb_samples;
block->i_nb_samples = samples;
block->i_pts = block->i_length = 0;
}
return block;
......@@ -208,20 +211,20 @@ aout_buffer_t * aout_DecNewBuffer( aout_input_t * p_input,
/*****************************************************************************
* aout_DecDeleteBuffer : destroy an undecoded buffer
*****************************************************************************/
void aout_DecDeleteBuffer( audio_output_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer )
void aout_DecDeleteBuffer (audio_output_t *aout, block_t *block)
{
(void)p_aout; (void)p_input;
aout_BufferFree( p_buffer );
(void) aout;
aout_BufferFree (block);
}
/*****************************************************************************
* aout_DecPlay : filter & mix the decoded buffer
*****************************************************************************/
int aout_DecPlay( audio_output_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer, int i_input_rate )
int aout_DecPlay (audio_output_t *p_aout, block_t *p_buffer, int i_input_rate)
{
aout_owner_t *owner = aout_owner (p_aout);
aout_input_t *p_input = owner->input;
assert( i_input_rate >= INPUT_RATE_DEFAULT / AOUT_MAX_INPUT_RATE &&
i_input_rate <= INPUT_RATE_DEFAULT * AOUT_MAX_INPUT_RATE );
assert( p_buffer->i_pts > 0 );
......@@ -257,46 +260,53 @@ int aout_DecPlay( audio_output_t * p_aout, aout_input_t * p_input,
return 0;
}
int aout_DecGetResetLost( audio_output_t *p_aout, aout_input_t *p_input )
int aout_DecGetResetLost (audio_output_t *aout)
{
aout_owner_t *owner = aout_owner (aout);
aout_input_t *input = owner->input;
int val;
aout_lock( p_aout );
val = p_input->i_buffer_lost;
p_input->i_buffer_lost = 0;
aout_unlock( p_aout );
aout_lock (aout);
val = input->i_buffer_lost;
input->i_buffer_lost = 0;
aout_unlock (aout);
return val;
}
void aout_DecChangePause( audio_output_t *p_aout, aout_input_t *p_input, bool b_paused, mtime_t i_date )
void aout_DecChangePause (audio_output_t *aout, bool paused, mtime_t date)
{
aout_owner_t *owner = aout_owner (p_aout);
aout_owner_t *owner = aout_owner (aout);
aout_input_t *p_input = owner->input;
aout_lock( p_aout );
assert (owner->input == p_input);
aout_lock (aout);
/* XXX: Should the input date be offset by the pause duration instead? */
date_Set (&p_input->date, VLC_TS_INVALID);
aout_OutputPause( p_aout, b_paused, i_date );
aout_unlock( p_aout );
aout_OutputPause (aout, paused, date);
aout_unlock (aout);
}
void aout_DecFlush( audio_output_t *p_aout, aout_input_t *p_input )
void aout_DecFlush (audio_output_t *aout)
{
aout_lock( p_aout );
date_Set (&p_input->date, VLC_TS_INVALID);
aout_OutputFlush( p_aout, false );
aout_unlock( p_aout );
aout_owner_t *owner = aout_owner (aout);
aout_input_t *input = owner->input;
aout_lock (aout);
date_Set (&input->date, VLC_TS_INVALID);
aout_OutputFlush (aout, false);
aout_unlock (aout);
}
bool aout_DecIsEmpty( audio_output_t * p_aout, aout_input_t * p_input )
bool aout_DecIsEmpty (audio_output_t *aout)
{
aout_owner_t *owner = aout_owner (aout);
aout_input_t *input = owner->input;
mtime_t end_date;
aout_lock( p_aout );
aout_lock (aout);
/* FIXME: tell output to drain */
end_date = date_Get (&p_input->date);
aout_unlock( p_aout );
end_date = date_Get (&input->date);
aout_unlock (aout);
return end_date == VLC_TS_INVALID || end_date <= mdate();
}
......@@ -122,7 +122,6 @@ struct decoder_owner_sys_t
/* -- These variables need locking on write(only) -- */
audio_output_t *p_aout;
aout_input_t *p_aout_input;
vout_thread_t *p_vout;
......@@ -428,7 +427,7 @@ bool input_DecoderIsEmpty( decoder_t * p_dec )
if( p_dec->fmt_out.i_cat == VIDEO_ES && p_owner->p_vout )
b_empty = vout_IsEmpty( p_owner->p_vout );
else if( p_dec->fmt_out.i_cat == AUDIO_ES && p_owner->p_aout )
b_empty = aout_DecIsEmpty( p_owner->p_aout, p_owner->p_aout_input );
b_empty = aout_DecIsEmpty( p_owner->p_aout );
vlc_mutex_unlock( &p_owner->lock );
}
return b_empty;
......@@ -781,7 +780,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
p_owner->p_input = p_input;
p_owner->p_resource = p_resource;
p_owner->p_aout = NULL;
p_owner->p_aout_input = NULL;
p_owner->p_vout = NULL;
p_owner->p_spu_vout = NULL;
p_owner->i_spu_channel = 0;
......@@ -1054,8 +1052,7 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i
if( p_dec->fmt_out.i_cat == AUDIO_ES )
{
if( p_owner->p_aout )
aout_DecChangePause( p_owner->p_aout, p_owner->p_aout_input,
b_paused, i_date );
aout_DecChangePause( p_owner->p_aout, b_paused, i_date );
}
else if( p_dec->fmt_out.i_cat == VIDEO_ES )
{
......@@ -1180,7 +1177,6 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
audio_output_t *p_aout = p_owner->p_aout;
aout_input_t *p_aout_input = p_owner->p_aout_input;
/* */
if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
......@@ -1244,7 +1240,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
vlc_mutex_unlock( &p_owner->lock );
if( !p_aout || !p_aout_input ||
if( !p_aout ||
p_audio->i_pts <= VLC_TS_INVALID ||
i_rate < INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE ||
i_rate > INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE )
......@@ -1255,9 +1251,9 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
if( !b_reject )
{
if( !aout_DecPlay( p_aout, p_aout_input, p_audio, i_rate ) )
if( !aout_DecPlay( p_aout, p_audio, i_rate ) )
*pi_played_sum += 1;
*pi_lost_sum += aout_DecGetResetLost( p_aout, p_aout_input );
*pi_lost_sum += aout_DecGetResetLost( p_aout );
}
else
{
......@@ -1293,12 +1289,11 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
{
audio_output_t *p_aout = p_owner->p_aout;
aout_input_t *p_aout_input = p_owner->p_aout_input;
if( DecoderIsExitRequested( p_dec ) )
{
/* It prevent freezing VLC in case of broken decoder */
aout_DecDeleteBuffer( p_aout, p_aout_input, p_aout_buf );
aout_DecDeleteBuffer( p_aout, p_aout_buf );
if( p_block )
block_Release( p_block );
break;
......@@ -1308,15 +1303,15 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
if( p_owner->i_preroll_end > VLC_TS_INVALID &&
p_aout_buf->i_pts < p_owner->i_preroll_end )
{
aout_DecDeleteBuffer( p_aout, p_aout_input, p_aout_buf );
aout_DecDeleteBuffer( p_aout, p_aout_buf );
continue;
}
if( p_owner->i_preroll_end > VLC_TS_INVALID )
{
msg_Dbg( p_dec, "End of audio preroll" );
if( p_owner->p_aout && p_owner->p_aout_input )
aout_DecFlush( p_owner->p_aout, p_owner->p_aout_input );
if( p_owner->p_aout )
aout_DecFlush( p_owner->p_aout );
/* */
p_owner->i_preroll_end = VLC_TS_INVALID;
}
......@@ -1941,7 +1936,7 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block, bool b_flus
}
if( b_flush && p_owner->p_aout )
aout_DecFlush( p_owner->p_aout, p_owner->p_aout_input );
aout_DecFlush( p_owner->p_aout );
}
/* This function process a subtitle block
......@@ -2121,7 +2116,7 @@ static void DeleteDecoder( decoder_t * p_dec )
/* Cleanup */
if( p_owner->p_aout )
{
aout_DecDelete( p_owner->p_aout, p_owner->p_aout_input );
aout_DecDelete( p_owner->p_aout );
input_resource_RequestAout( p_owner->p_resource, p_owner->p_aout );
if( p_owner->p_input != NULL )
input_SendEventAout( p_owner->p_input );
......@@ -2229,14 +2224,13 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
decoder_owner_sys_t *p_owner = p_dec->p_owner;
aout_buffer_t *p_buffer;
if( p_owner->p_aout_input != NULL &&
if( p_owner->p_aout &&
( p_dec->fmt_out.audio.i_rate != p_owner->audio.i_rate ||
p_dec->fmt_out.audio.i_original_channels !=
p_owner->audio.i_original_channels ||
p_dec->fmt_out.audio.i_bytes_per_frame !=
p_owner->audio.i_bytes_per_frame ) )
{
aout_input_t *p_aout_input = p_owner->p_aout_input;
audio_output_t *p_aout = p_owner->p_aout;
/* Parameters changed, restart the aout */
......@@ -2244,19 +2238,17 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
DecoderFlushBuffering( p_dec );
aout_DecDelete( p_owner->p_aout, p_aout_input );
aout_DecDelete( p_owner->p_aout );
p_owner->p_aout = NULL;
p_owner->p_aout_input = NULL;
vlc_mutex_unlock( &p_owner->lock );
input_resource_RequestAout( p_owner->p_resource, p_aout );
}
if( p_owner->p_aout_input == NULL )
if( p_owner->p_aout == NULL )
{
const int i_force_dolby = var_InheritInteger( p_dec, "force-dolby-surround" );
audio_sample_format_t format;
aout_input_t *p_aout_input;
audio_output_t *p_aout;
aout_request_vout_t request_vout;
......@@ -2288,22 +2280,18 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
if( p_aout )
{
aout_FormatPrepare( &format );
p_aout_input = aout_DecNew( p_aout, &format,
&p_dec->fmt_out.audio_replay_gain,
&request_vout );
if( p_aout_input == NULL )
if( aout_DecNew( p_aout, &format,
&p_dec->fmt_out.audio_replay_gain,
&request_vout ) )
{
input_resource_RequestAout( p_owner->p_resource, p_aout );
p_aout = NULL;
}
}
else
p_aout_input = NULL;
vlc_mutex_lock( &p_owner->lock );
p_owner->p_aout = p_aout;
p_owner->p_aout_input = p_aout_input;
DecoderUpdateFormatLocked( p_dec );
vlc_mutex_unlock( &p_owner->lock );
......@@ -2311,7 +2299,7 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
if( p_owner->p_input != NULL )
input_SendEventAout( p_owner->p_input );
if( p_owner->p_aout_input == NULL )
if( p_aout == NULL )
{
msg_Err( p_dec, "failed to create audio output" );
p_dec->b_error = true;
......@@ -2321,7 +2309,7 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
p_owner->audio.i_bytes_per_frame;
}
p_buffer = aout_DecNewBuffer( p_owner->p_aout_input, i_samples );
p_buffer = aout_DecNewBuffer( p_owner->p_aout, i_samples );
return p_buffer;
}
......@@ -2330,8 +2318,7 @@ static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
aout_DecDeleteBuffer( p_owner->p_aout,
p_owner->p_aout_input, p_buffer );
aout_DecDeleteBuffer( p_owner->p_aout, p_buffer );
}
static picture_t *vout_new_buffer( decoder_t *p_dec )
......
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