[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