vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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 ) _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
