[vlc-commits] decoder: separate aout initialization from buffer allocation
Rémi Denis-Courmont
git at videolan.org
Fri Jul 26 18:50:49 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Jul 26 19:36:53 2013 +0300| [492dfdd5061e46cdb7251ddd17aa31c95bb3a7f4] | committer: Rémi Denis-Courmont
decoder: separate aout initialization from buffer allocation
This has two benefits:
- allow zero copy in audio decoders,
- allow negotiation of the output formats (potentially for S/PDIF).
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=492dfdd5061e46cdb7251ddd17aa31c95bb3a7f4
---
include/vlc_codec.h | 18 ++++++++++++---
modules/stream_out/transcode/audio.c | 28 ++++--------------------
src/input/decoder.c | 40 ++++++++++++++++------------------
3 files changed, 38 insertions(+), 48 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index b9a89d4..1e7c8a6 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -108,9 +108,8 @@ struct decoder_t
*/
int i_extra_picture_buffers;
- /* Audio output callbacks
- * XXX use decoder_NewAudioBuffer/decoder_DeleteAudioBuffer */
- block_t *(*pf_aout_buffer_new)( decoder_t *, int );
+ /* Audio output callbacks */
+ int (*pf_aout_format_update)( decoder_t * );
/* SPU output callbacks
* XXX use decoder_NewSubpicture and decoder_DeleteSubpicture */
@@ -205,6 +204,19 @@ VLC_API void decoder_LinkPicture( decoder_t *, picture_t * );
VLC_API void decoder_UnlinkPicture( decoder_t *, picture_t * );
/**
+ * This function notifies the audio output pipeline of a new audio output
+ * format (fmt_out.audio). If there is currently no audio output or if the
+ * audio output format has changed, a new audio output will be set up.
+ * @return 0 if the audio output is working, -1 if not. */
+static inline int decoder_UpdateAudioFormat( decoder_t *dec )
+{
+ if( dec->pf_aout_format_update != NULL )
+ return dec->pf_aout_format_update( dec );
+ else
+ return -1;
+}
+
+/**
* This function will return a new audio buffer usable by a decoder as an
* output buffer. You have to release it using decoder_DeleteAudioBuffer
* or by returning it to the caller as a pf_decode_audio return value.
diff --git a/modules/stream_out/transcode/audio.c b/modules/stream_out/transcode/audio.c
index c36781c..f87a89b 100644
--- a/modules/stream_out/transcode/audio.c
+++ b/modules/stream_out/transcode/audio.c
@@ -46,30 +46,10 @@ static const int pi_channels_maps[6] =
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
};
-static block_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
+static int audio_update_format( decoder_t *p_dec )
{
- block_t *p_block;
- int i_size;
-
- if( p_dec->fmt_out.audio.i_bitspersample )
- {
- i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
- p_dec->fmt_out.audio.i_channels;
- }
- else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
- p_dec->fmt_out.audio.i_frame_length )
- {
- i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
- p_dec->fmt_out.audio.i_frame_length;
- }
- else
- {
- i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
- }
-
- p_block = block_Alloc( i_size );
- p_block->i_nb_samples = i_samples;
- return p_block;
+ aout_FormatPrepare( &p_dec->fmt_out.audio );
+ return 0;
}
int transcode_audio_new( sout_stream_t *p_stream,
@@ -87,7 +67,7 @@ int transcode_audio_new( sout_stream_t *p_stream,
id->p_decoder->fmt_out.i_extra = 0;
id->p_decoder->fmt_out.p_extra = 0;
id->p_decoder->pf_decode_audio = NULL;
- id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
+ id->p_decoder->pf_aout_format_update = audio_update_format;
/* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
id->p_decoder->p_module =
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 9c09681..d2e6fb3 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -69,13 +69,11 @@ static void DecoderFlushBuffering( decoder_t * );
static void DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
/* Buffers allocation callbacks for the decoders */
-static block_t *aout_new_buffer( decoder_t *, int );
-
static picture_t *vout_new_buffer( decoder_t * );
static void vout_del_buffer( decoder_t *, picture_t * );
static void vout_link_picture( decoder_t *, picture_t * );
static void vout_unlink_picture( decoder_t *, picture_t * );
-
+static int aout_update_format( decoder_t * );
static subpicture_t *spu_new_buffer( decoder_t *, const subpicture_updater_t * );
static void spu_del_buffer( decoder_t *, subpicture_t * );
@@ -206,11 +204,20 @@ void decoder_UnlinkPicture( decoder_t *p_decoder, picture_t *p_picture )
p_decoder->pf_picture_unlink( p_decoder, p_picture );
}
-block_t *decoder_NewAudioBuffer( decoder_t *p_decoder, int i_size )
+block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples )
{
- if( !p_decoder->pf_aout_buffer_new )
+ if( decoder_UpdateAudioFormat( dec ) )
return NULL;
- return p_decoder->pf_aout_buffer_new( p_decoder, i_size );
+
+ size_t length = samples * dec->fmt_out.audio.i_bytes_per_frame
+ / dec->fmt_out.audio.i_frame_length;
+ block_t *block = block_Alloc( length );
+ if( likely(block != NULL) )
+ {
+ block->i_nb_samples = samples;
+ block->i_pts = block->i_length = 0;
+ }
+ return block;
}
subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
@@ -795,7 +802,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
}
/* Set buffers allocation callbacks for the decoders */
- p_dec->pf_aout_buffer_new = aout_new_buffer;
+ p_dec->pf_aout_format_update = aout_update_format;
p_dec->pf_vout_buffer_new = vout_new_buffer;
p_dec->pf_vout_buffer_del = vout_del_buffer;
p_dec->pf_picture_link = vout_link_picture;
@@ -2177,7 +2184,7 @@ static vout_thread_t *aout_request_vout( void *p_private,
return p_vout;
}
-static block_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
+static int aout_update_format( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
block_t *p_buffer;
@@ -2207,6 +2214,7 @@ static block_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
p_owner->audio = p_dec->fmt_out.audio;
+ aout_FormatPrepare( &p_owner->audio );
memcpy( &format, &p_owner->audio, sizeof( audio_sample_format_t ) );
if( i_force_dolby &&
@@ -2232,7 +2240,6 @@ static block_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
p_aout = input_resource_GetAout( p_owner->p_resource );
if( p_aout )
{
- aout_FormatPrepare( &format );
if( aout_DecNew( p_aout, &format,
&p_dec->fmt_out.audio_replay_gain,
&request_vout ) )
@@ -2258,23 +2265,14 @@ static block_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
{
msg_Err( p_dec, "failed to create audio output" );
p_dec->b_error = true;
- return NULL;
+ return -1;
}
- aout_FormatPrepare( &p_owner->audio );
p_dec->fmt_out.audio.i_bytes_per_frame =
p_owner->audio.i_bytes_per_frame;
+ p_dec->fmt_out.audio.i_frame_length = p_owner->audio.i_frame_length;
}
-
- size_t length = i_samples * p_owner->audio.i_bytes_per_frame
- / p_owner->audio.i_frame_length;
- block_t *block = block_Alloc( length );
- if( likely(block != NULL) )
- {
- block->i_nb_samples = i_samples;
- block->i_pts = block->i_length = 0;
- }
- return block;
+ return 0;
}
static picture_t *vout_new_buffer( decoder_t *p_dec )
More information about the vlc-commits
mailing list