]> git.sesse.net Git - vlc/blobdiff - src/input/es_out.c
* modules/audio_output/directx.c: backported directx audio output fix from trunk...
[vlc] / src / input / es_out.c
index 08823b3c5d6677ba6c213a18160a93f1b948a1d8..8faf35d125ce6462cd3e8258cb42185126d7bdca 100644 (file)
@@ -1,10 +1,11 @@
 /*****************************************************************************
  * es_out.c: Es Out handler for input.
  *****************************************************************************
- * Copyright (C) 2003-2004 VideoLAN
+ * Copyright (C) 2003-2004 the VideoLAN team
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -63,7 +64,10 @@ struct es_out_id_t
     int       i_id;
     es_out_pgrm_t *p_pgrm;
 
-    /* */
+    /* Signal a discontinuity in the timeline for every PID */
+    vlc_bool_t b_discontinuity;
+
+    /* Misc. */
     int64_t i_preroll_end;
 
     /* Channel in the track type */
@@ -276,7 +280,8 @@ void input_EsOutDiscontinuity( es_out_t *out, vlc_bool_t b_audio )
     for( i = 0; i < p_sys->i_es; i++ )
     {
         es_out_id_t *es = p_sys->es[i];
-
+        es->b_discontinuity = VLC_TRUE; /* signal discontinuity */
+        
         /* Send a dummy block to let decoder know that
          * there is a discontinuity */
         if( es->p_dec && ( !b_audio || es->fmt.i_cat == AUDIO_ES ) )
@@ -499,7 +504,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group )
 /* EsOutDelProgram:
  *  Delete a program
  */
-static void EsOutProgramDel( es_out_t *out, int i_group )
+static int EsOutProgramDel( es_out_t *out, int i_group )
 {
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
@@ -516,13 +521,14 @@ static void EsOutProgramDel( es_out_t *out, int i_group )
         }
     }
 
-    if( p_pgrm == NULL ) return;
+    if( p_pgrm == NULL )
+        return VLC_EGENERIC;
 
     if( p_pgrm->i_es )
     {
         msg_Dbg( p_input, "can't delete program %d which still has %i ES",
                  i_group, p_pgrm->i_es );
-        return;
+        return VLC_EGENERIC;
     }
 
     TAB_REMOVE( p_sys->i_pgrm, p_sys->pgrm, p_pgrm );
@@ -538,6 +544,8 @@ static void EsOutProgramDel( es_out_t *out, int i_group )
     var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
 
     var_SetBool( p_sys->p_input, "intf-change", VLC_TRUE );
+
+    return VLC_SUCCESS;
 }
 
 /* EsOutProgramMeta:
@@ -666,6 +674,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     es->p_pgrm = p_pgrm;
     es_format_Copy( &es->fmt, fmt );
     es->i_preroll_end = -1;
+    es->b_discontinuity = VLC_FALSE;
 
     switch( fmt->i_cat )
     {
@@ -675,6 +684,11 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
 
     case VIDEO_ES:
         es->i_channel = p_sys->i_video;
+        if( fmt->video.i_frame_rate && fmt->video.i_frame_rate_base )
+            vlc_ureduce( &es->fmt.video.i_frame_rate,
+                         &es->fmt.video.i_frame_rate_base,
+                         fmt->video.i_frame_rate,
+                         fmt->video.i_frame_rate_base, 0 );
         break;
 
     case SPU_ES:
@@ -1044,6 +1058,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
 static void EsOutDel( es_out_t *out, es_out_id_t *es )
 {
     es_out_sys_t *p_sys = out->p_sys;
+    vlc_bool_t b_reselect = VLC_FALSE;
+    int i;
 
     /* We don't try to reselect */
     if( es->p_dec )
@@ -1057,10 +1073,12 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
     es->p_pgrm->i_es--;
     if( es->p_pgrm->i_es == 0 )
     {
-        msg_Warn( p_sys->p_input, "Program doesn't contain anymore ES, "
-                  "TODO cleaning ?" );
+        msg_Dbg( p_sys->p_input, "Program doesn't contain anymore ES" );
     }
 
+    if( p_sys->p_es_audio == es || p_sys->p_es_video == es ||
+        p_sys->p_es_sub == es ) b_reselect = VLC_TRUE;
+
     if( p_sys->p_es_audio == es ) p_sys->p_es_audio = NULL;
     if( p_sys->p_es_video == es ) p_sys->p_es_video = NULL;
     if( p_sys->p_es_sub   == es ) p_sys->p_es_sub   = NULL;
@@ -1078,6 +1096,14 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
             break;
     }
 
+    /* Re-select another track when needed */
+    if( b_reselect )
+        for( i = 0; i < p_sys->i_es; i++ )
+        {
+            if( es->fmt.i_cat == p_sys->es[i]->fmt.i_cat )
+                EsOutSelect( out, p_sys->es[i], VLC_FALSE );
+        }
+
     if( es->psz_language )
         free( es->psz_language );
     if( es->psz_language_code )
@@ -1363,6 +1389,12 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
             EsOutProgramMeta( out, i_group, p_meta );
             return VLC_SUCCESS;
         }
+        case ES_OUT_DEL_GROUP:
+        {
+            int i_group = (int)va_arg( args, int );
+
+            return EsOutProgramDel( out, i_group );
+        }
 
         default:
             msg_Err( p_sys->p_input, "unknown query in es_out_Control" );