]> git.sesse.net Git - vlc/blobdiff - src/input/decoder.c
Add LGPL license
[vlc] / src / input / decoder.c
index 1c771fc6df79b565d9672a259a767e0e63d05ae8..efee19449af1831b6ac9c7271509088a5c8316fa 100644 (file)
@@ -70,7 +70,6 @@ static void       DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
 
 /* Buffers allocation callbacks for the decoders */
 static aout_buffer_t *aout_new_buffer( decoder_t *, int );
-static void aout_del_buffer( decoder_t *, aout_buffer_t * );
 
 static picture_t *vout_new_buffer( decoder_t * );
 static void vout_del_buffer( decoder_t *, picture_t * );
@@ -121,8 +120,7 @@ struct decoder_owner_sys_t
     vlc_cond_t  wait_acknowledge;
 
     /* -- These variables need locking on write(only) -- */
-    aout_instance_t *p_aout;
-    aout_input_t    *p_aout_input;
+    audio_output_t *p_aout;
 
     vout_thread_t   *p_vout;
 
@@ -214,10 +212,6 @@ aout_buffer_t *decoder_NewAudioBuffer( decoder_t *p_decoder, int i_size )
         return NULL;
     return p_decoder->pf_aout_buffer_new( p_decoder, i_size );
 }
-void decoder_DeleteAudioBuffer( decoder_t *p_decoder, aout_buffer_t *p_buffer )
-{
-    p_decoder->pf_aout_buffer_del( p_decoder, p_buffer );
-}
 
 subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
                                      const subpicture_updater_t *p_dyn )
@@ -428,7 +422,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_InputIsEmpty( 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;
@@ -598,7 +592,7 @@ void input_DecoderWaitBuffering( decoder_t *p_dec )
 
     vlc_mutex_lock( &p_owner->lock );
 
-    while( vlc_object_alive( p_dec ) && p_owner->b_buffering && !p_owner->buffer.b_full )
+    while( p_owner->b_buffering && !p_owner->buffer.b_full )
     {
         block_FifoWake( p_owner->p_fifo );
         vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
@@ -667,7 +661,7 @@ size_t input_DecoderGetFifoSize( decoder_t *p_dec )
 }
 
 void input_DecoderGetObjects( decoder_t *p_dec,
-                              vout_thread_t **pp_vout, aout_instance_t **pp_aout )
+                              vout_thread_t **pp_vout, audio_output_t **pp_aout )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
 
@@ -750,8 +744,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     decoder_owner_sys_t *p_owner;
     es_format_t null_es_format;
 
-    p_dec = vlc_custom_create( p_parent, sizeof( *p_dec ), VLC_OBJECT_DECODER,
-                               "decoder" );
+    p_dec = vlc_custom_create( p_parent, sizeof( *p_dec ), "decoder" );
     if( p_dec == NULL )
         return NULL;
 
@@ -782,7 +775,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;
@@ -803,7 +795,6 @@ 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_buffer_del = aout_del_buffer;
     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;
@@ -815,8 +806,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_dec->pf_get_display_date = DecoderGetDisplayDate;
     p_dec->pf_get_display_rate = DecoderGetDisplayRate;
 
-    vlc_object_attach( p_dec, p_parent );
-
     /* Find a suitable decoder/packetizer module */
     if( !b_packetizer )
         p_dec->p_module = module_need( p_dec, "decoder", "$codec", false );
@@ -828,8 +817,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
         p_dec->b_need_packetized && !p_dec->fmt_in.b_packetized )
     {
         p_owner->p_packetizer =
-            vlc_custom_create( p_parent, sizeof( decoder_t ),
-                               VLC_OBJECT_DECODER, "packetizer" );
+            vlc_custom_create( p_parent, sizeof( decoder_t ), "packetizer" );
         if( p_owner->p_packetizer )
         {
             es_format_Copy( &p_owner->p_packetizer->fmt_in,
@@ -838,8 +826,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
             es_format_Copy( &p_owner->p_packetizer->fmt_out,
                             &null_es_format );
 
-            vlc_object_attach( p_owner->p_packetizer, p_parent );
-
             p_owner->p_packetizer->p_module =
                 module_need( p_owner->p_packetizer,
                              "packetizer", "$packetizer", false );
@@ -938,6 +924,14 @@ static void *DecoderThread( void *p_data )
         {
             int canc = vlc_savecancel();
 
+            if( p_block->i_flags & BLOCK_FLAG_CORE_EOS )
+            {
+                /* calling DecoderProcess() with NULL block will make
+                 * decoders/packetizers flush their buffers */
+                block_Release( p_block );
+                p_block = NULL;
+            }
+
             if( p_dec->b_error )
                 DecoderError( p_dec, p_block );
             else
@@ -983,7 +977,7 @@ static void DecoderFlush( decoder_t *p_dec )
     input_DecoderDecode( p_dec, p_null, false );
 
     /* */
-    while( vlc_object_alive( p_dec ) && p_owner->b_flushing )
+    while( p_owner->b_flushing )
         vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
 }
 
@@ -1060,8 +1054,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 )
     {
@@ -1185,8 +1178,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
                               int *pi_played_sum, int *pi_lost_sum )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
-    aout_instance_t *p_aout = p_owner->p_aout;
-    aout_input_t    *p_aout_input = p_owner->p_aout_input;
+    audio_output_t *p_aout = p_owner->p_aout;
 
     /* */
     if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
@@ -1250,7 +1242,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 )
@@ -1261,9 +1253,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
         {
@@ -1298,13 +1290,12 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
 
     while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
     {
-        aout_instance_t *p_aout = p_owner->p_aout;
-        aout_input_t    *p_aout_input = p_owner->p_aout_input;
+        audio_output_t *p_aout = p_owner->p_aout;
 
         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;
@@ -1314,15 +1305,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;
         }
@@ -1715,8 +1706,7 @@ static void DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block,
         p_sout_block->p_next = NULL;
 
         DecoderFixTs( p_dec, &p_sout_block->i_dts, &p_sout_block->i_pts,
-                      &p_sout_block->i_length,
-                      &p_sout_block->i_rate, INT64_MAX, b_telx );
+                      &p_sout_block->i_length, NULL, INT64_MAX, b_telx );
 
         vlc_mutex_unlock( &p_owner->lock );
 
@@ -1947,7 +1937,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
@@ -2127,7 +2117,9 @@ static void DeleteDecoder( decoder_t * p_dec )
     /* Cleanup */
     if( p_owner->p_aout )
     {
-        aout_DecDelete( p_owner->p_aout, p_owner->p_aout_input );
+        /* TODO: REVISIT gap-less audio */
+        aout_DecFlush( p_owner->p_aout );
+        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 );
@@ -2235,35 +2227,32 @@ 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;
-        aout_instance_t *p_aout = p_owner->p_aout;
+        audio_output_t *p_aout = p_owner->p_aout;
 
         /* Parameters changed, restart the aout */
         vlc_mutex_lock( &p_owner->lock );
 
         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;
-        aout_instance_t *p_aout;
+        audio_output_t *p_aout;
         aout_request_vout_t request_vout;
 
         p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
@@ -2293,22 +2282,19 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
         p_aout = input_resource_RequestAout( p_owner->p_resource, NULL );
         if( p_aout )
         {
-            p_aout_input = aout_DecNew( p_aout, &format,
-                                        &p_dec->fmt_out.audio_replay_gain,
-                                        &request_vout );
-            if( p_aout_input == NULL )
+            aout_FormatPrepare( &format );
+            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 );
@@ -2316,7 +2302,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;
@@ -2326,19 +2312,11 @@ 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;
 }
 
-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 );
-}
-
 static picture_t *vout_new_buffer( decoder_t *p_dec )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;