]> git.sesse.net Git - vlc/commitdiff
* Added support for some terribly braindead DVD subtitles in Kenshin
authorSam Hocevar <sam@videolan.org>
Mon, 7 May 2001 04:42:42 +0000 (04:42 +0000)
committerSam Hocevar <sam@videolan.org>
Mon, 7 May 2001 04:42:42 +0000 (04:42 +0000)
    which do not have a "stop display" command. Anime fans rejoice!
  * Fixed the BeOS interface to use p_aout_bank instead of p_main->p_aout.
  * Coding-style butchery (mostly tabs).

13 files changed:
include/video.h
plugins/beos/intf_beos.cpp
plugins/dvd/dvd_ifo.c
plugins/dvd/input_dvd.c
plugins/mpeg/input_ps.c
plugins/sdl/vout_sdl.c
plugins/x11/vout_xvideo.c
src/ac3_decoder/ac3_parse.c
src/misc/mtime.c
src/misc/netutils.c
src/spu_decoder/spu_decoder.c
src/spu_decoder/spu_decoder.h
src/video_output/video_output.c

index 8373d4500b7a1d631a2d02f10636fea1d745c366..c2990ef166561d8b4c808eda8db60a234947705d 100644 (file)
@@ -4,7 +4,7 @@
  * includes all common video types and constants.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video.h,v 1.29 2001/03/21 13:42:33 sam Exp $
+ * $Id: video.h,v 1.30 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -123,9 +123,10 @@ typedef struct subpicture_s
     int             i_size;                                     /* data size */
     struct subpicture_s *   p_next;         /* next subtitle to be displayed */
 
-    /* Other properties */
-    mtime_t         begin_date;                 /* beginning of display date */
-    mtime_t         end_date;                         /* end of display date */
+    /* Date properties */
+    mtime_t         i_start;                    /* beginning of display date */
+    mtime_t         i_stop;                           /* end of display date */
+    boolean_t       b_ephemer;             /* does the subtitle have a TTL ? */
 
     /* Display properties - these properties are only indicative and may be
      * changed by the video output thread, or simply ignored depending of the
index 554fb903a9cdbf7a2c50e88028bfe4db6a9f20f0..003b21a39daf3b3dfba92f0803884296ee7135ba 100644 (file)
@@ -2,7 +2,7 @@
  * intf_beos.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: intf_beos.cpp,v 1.27 2001/05/01 04:18:17 sam Exp $
+ * $Id: intf_beos.cpp,v 1.28 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -13,7 +13,7 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -100,135 +100,140 @@ typedef struct intf_sys_s
 /*****************************************************************************
  * InterfaceWindow
  *****************************************************************************/
-InterfaceWindow::InterfaceWindow( BRect frame, const char *name , intf_thread_t  *p_interface )
-    : BWindow(frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
-       B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK |B_ASYNCHRONOUS_CONTROLS)
+
+InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
+                                  intf_thread_t  *p_interface )
+    : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
+               B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
+                | B_ASYNCHRONOUS_CONTROLS )
 {
     file_panel = NULL;
     p_intf = p_interface;
-       BRect ButtonRect;
-       float xStart = 5.0;
-       float yStart = 20.0;
+    BRect ButtonRect;
+    float xStart = 5.0;
+    float yStart = 20.0;
 
     SetName( "interface" );
     SetTitle(VOUT_TITLE " (BeOS interface)");
     BRect rect(0, 0, 0, 0);
-    
-    BMenuBar *menu_bar; 
+
+    BMenuBar *menu_bar;
     menu_bar = new BMenuBar(rect, "main menu");
     AddChild( menu_bar );
 
-       BMenu *mFile; 
-       BMenu *mAudio;
-       CDMenu *cd_menu;
-       
-       BMenuItem *mItem;
-
-       menu_bar->AddItem( mFile = new BMenu("File") );
-       menu_bar->ResizeToPreferred();
-       mFile->AddItem(mItem = new BMenuItem("Open File" B_UTF8_ELLIPSIS, new BMessage(OPEN_FILE), 'O'));
-       cd_menu = new CDMenu("Open Disc");
-       mFile->AddItem(cd_menu);
-       mFile->AddSeparatorItem();
-       mFile->AddItem(mItem = new BMenuItem("About" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED), 'A'));
-       mItem->SetTarget( be_app );
-       mFile->AddItem(mItem = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
-
-       menu_bar->AddItem ( mAudio = new BMenu("Audio") );
-       menu_bar->ResizeToPreferred();
-       mAudio->AddItem( new LanguageMenu("Language", AUDIO_ES, p_intf) );
-       mAudio->AddItem( new LanguageMenu("Subtitles", SPU_ES, p_intf) );
-       
+    BMenu *mFile;
+    BMenu *mAudio;
+    CDMenu *cd_menu;
+
+    BMenuItem *mItem;
+
+    menu_bar->AddItem( mFile = new BMenu( "File" ) );
+    menu_bar->ResizeToPreferred();
+    mFile->AddItem( mItem = new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
+                                           new BMessage(OPEN_FILE), 'O') );
+    cd_menu = new CDMenu( "Open Disc" );
+    mFile->AddItem( cd_menu );
+    mFile->AddSeparatorItem();
+    mFile->AddItem( mItem = new BMenuItem( "About" B_UTF8_ELLIPSIS,
+                                       new BMessage(B_ABOUT_REQUESTED), 'A') );
+    mItem->SetTarget( be_app );
+    mFile->AddItem(mItem = new BMenuItem( "Quit",
+                                        new BMessage(B_QUIT_REQUESTED), 'Q') );
+
+    menu_bar->AddItem ( mAudio = new BMenu( "Audio" ) );
+    menu_bar->ResizeToPreferred();
+    mAudio->AddItem( new LanguageMenu( "Language", AUDIO_ES, p_intf ) );
+    mAudio->AddItem( new LanguageMenu( "Subtitles", SPU_ES, p_intf ) );
+
 
     rect = Bounds();
-    rect.top += menu_bar->Bounds().IntegerHeight()+1;
+    rect.top += menu_bar->Bounds().IntegerHeight() + 1;
 
     BBox* p_view;
-       p_view = new BBox( rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER );
-       p_view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
-    
-       /* Buttons */
-       /* Slow play */
-       ButtonRect.SetLeftTop(BPoint(xStart, yStart));
-       ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
-       xStart += kRewindBitmapWidth;
-       TransportButton* p_slow = new TransportButton(ButtonRect, B_EMPTY_STRING,
-                                                                                       kSkipBackBitmapBits,
-                                                                                       kPressedSkipBackBitmapBits,
-                                                                                       kDisabledSkipBackBitmapBits,
-                                                                                       new BMessage(SLOWER_PLAY));
-       p_view->AddChild( p_slow );
-
-       /* Play Pause */
-       ButtonRect.SetLeftTop(BPoint(xStart, yStart));
-       ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kPlayButtonSize);
-       xStart += kPlayPauseBitmapWidth + 1.0;
-       PlayPauseButton* p_play = new PlayPauseButton(ButtonRect, B_EMPTY_STRING,
-                                                                                       kPlayButtonBitmapBits,
-                                                                                       kPressedPlayButtonBitmapBits,
-                                                                                       kDisabledPlayButtonBitmapBits,
-                                                                                       kPlayingPlayButtonBitmapBits,
-                                                                                       kPressedPlayingPlayButtonBitmapBits,
-                                                                                       kPausedPlayButtonBitmapBits,
-                                                                                       kPressedPausedPlayButtonBitmapBits,
-                                                                                       new BMessage(START_PLAYBACK));
-   
-       p_view->AddChild( p_play );
-       p_play->SetPlaying();
-
-       /* Fast Foward */
-       ButtonRect.SetLeftTop(BPoint(xStart, yStart));
-       ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
-       xStart += kRewindBitmapWidth;
-       TransportButton* p_fast = new TransportButton(ButtonRect, B_EMPTY_STRING,
-                                                                                       kSkipForwardBitmapBits,
-                                                                                       kPressedSkipForwardBitmapBits,
-                                                                                       kDisabledSkipForwardBitmapBits,
-                                                                                       new BMessage(FASTER_PLAY));
-       p_view->AddChild( p_fast );
-
-       /* Stop */
-       ButtonRect.SetLeftTop(BPoint(xStart, yStart));
-       ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kStopButtonSize);
-       xStart += kStopBitmapWidth;
-       TransportButton* p_stop = new TransportButton(ButtonRect, B_EMPTY_STRING,
-                                                                                       kStopButtonBitmapBits,
-                                                                                       kPressedStopButtonBitmapBits,
-                                                                                       kDisabledStopButtonBitmapBits,
-                                                                                       new BMessage(STOP_PLAYBACK));
-       p_view->AddChild( p_stop );
-
-       ButtonRect.SetLeftTop(BPoint(xStart + 5, yStart + 6));
-       ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSpeakerButtonSize);
-       xStart += kSpeakerIconBitmapWidth;
-       TransportButton* p_mute = new TransportButton(ButtonRect, B_EMPTY_STRING,
-                                                                                       kSpeakerIconBits,
-                                                                                       kPressedSpeakerIconBits,
-                                                                                       kSpeakerIconBits,
-                                                                                       new BMessage(VOLUME_MUTE));
-
-       p_view->AddChild( p_mute );
-       /* Seek Status */       
+    p_view = new BBox( rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER );
+    p_view->SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR) );
+
+    /* Buttons */
+    /* Slow play */
+    ButtonRect.SetLeftTop(BPoint(xStart, yStart));
+    ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
+    xStart += kRewindBitmapWidth;
+    TransportButton* p_slow = new TransportButton(ButtonRect, B_EMPTY_STRING,
+                                            kSkipBackBitmapBits,
+                                            kPressedSkipBackBitmapBits,
+                                            kDisabledSkipBackBitmapBits,
+                                            new BMessage(SLOWER_PLAY));
+    p_view->AddChild( p_slow );
+
+    /* Play Pause */
+    ButtonRect.SetLeftTop(BPoint(xStart, yStart));
+    ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kPlayButtonSize);
+    xStart += kPlayPauseBitmapWidth + 1.0;
+    PlayPauseButton* p_play = new PlayPauseButton(ButtonRect, B_EMPTY_STRING,
+                                            kPlayButtonBitmapBits,
+                                            kPressedPlayButtonBitmapBits,
+                                            kDisabledPlayButtonBitmapBits,
+                                            kPlayingPlayButtonBitmapBits,
+                                            kPressedPlayingPlayButtonBitmapBits,
+                                            kPausedPlayButtonBitmapBits,
+                                            kPressedPausedPlayButtonBitmapBits,
+                                            new BMessage(START_PLAYBACK));
+
+    p_view->AddChild( p_play );
+    p_play->SetPlaying();
+
+    /* Fast Foward */
+    ButtonRect.SetLeftTop(BPoint(xStart, yStart));
+    ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
+    xStart += kRewindBitmapWidth;
+    TransportButton* p_fast = new TransportButton(ButtonRect, B_EMPTY_STRING,
+                                            kSkipForwardBitmapBits,
+                                            kPressedSkipForwardBitmapBits,
+                                            kDisabledSkipForwardBitmapBits,
+                                            new BMessage(FASTER_PLAY));
+    p_view->AddChild( p_fast );
+
+    /* Stop */
+    ButtonRect.SetLeftTop(BPoint(xStart, yStart));
+    ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kStopButtonSize);
+    xStart += kStopBitmapWidth;
+    TransportButton* p_stop = new TransportButton(ButtonRect, B_EMPTY_STRING,
+                                            kStopButtonBitmapBits,
+                                            kPressedStopButtonBitmapBits,
+                                            kDisabledStopButtonBitmapBits,
+                                            new BMessage(STOP_PLAYBACK));
+    p_view->AddChild( p_stop );
+
+    ButtonRect.SetLeftTop(BPoint(xStart + 5, yStart + 6));
+    ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSpeakerButtonSize);
+    xStart += kSpeakerIconBitmapWidth;
+
+    TransportButton* p_mute = new TransportButton(ButtonRect, B_EMPTY_STRING,
+                                            kSpeakerIconBits,
+                                            kPressedSpeakerIconBits,
+                                            kSpeakerIconBits,
+                                            new BMessage(VOLUME_MUTE));
+
+    p_view->AddChild( p_mute );
+
+    /* Seek Status */
     rgb_color fill_color = {0,255,0};
-       p_seek = new SeekSlider(BRect(5,2,255,15), this, 0, 100,
-                                               B_TRIANGLE_THUMB);
-       p_seek->SetValue(0);
-       p_seek->UseFillColor(true, &fill_color);
+    p_seek = new SeekSlider(BRect(5,2,255,15), this, 0, 100,
+                        B_TRIANGLE_THUMB);
+    p_seek->SetValue(0);
+    p_seek->UseFillColor(true, &fill_color);
     p_view->AddChild( p_seek );
 
-       /* Volume Slider */     
-       p_vol = new MediaSlider(BRect(xStart,20,255,30), new BMessage(VOLUME_CHG),
-                                                       0, VOLUME_MAX);
-       p_vol->SetValue(VOLUME_DEFAULT);
-       p_vol->UseFillColor(true, &fill_color);
+    /* Volume Slider */
+    p_vol = new MediaSlider(BRect(xStart,20,255,30), new BMessage(VOLUME_CHG),
+                            0, VOLUME_MAX);
+    p_vol->SetValue(VOLUME_DEFAULT);
+    p_vol->UseFillColor(true, &fill_color);
     p_view->AddChild( p_vol );
-    
-       /* Set size and Show */
+
+    /* Set size and Show */
     AddChild( p_view );
-       ResizeTo(260,50 + menu_bar->Bounds().IntegerHeight()+1);
+    ResizeTo(260,50 + menu_bar->Bounds().IntegerHeight()+1);
     Show();
 }
 
@@ -241,156 +246,208 @@ InterfaceWindow::~InterfaceWindow()
  *****************************************************************************/
 void InterfaceWindow::MessageReceived( BMessage * p_message )
 {
-       int vol_val = p_vol->Value();   // remember the current volume
-       static int playback_status;             // remember playback state
-       
-       BAlert *alert;
-       Activate();
+    int vol_val = p_vol->Value();    // remember the current volume
+    static int playback_status;      // remember playback state
+    int     i_index;
+    BAlert *alert;
+
+    Activate();
+
     switch( p_message->what )
     {
 //    case B_ABOUT_REQUESTED:
-//             alert = new BAlert(VOUT_TITLE, "BeOS " VOUT_TITLE "\n\n<www.videolan.org>", "Ok");
-//         alert->Go();
-//         break;      
-    
+//        alert = new BAlert(VOUT_TITLE, "BeOS " VOUT_TITLE "\n\n<www.videolan.org>", "Ok");
+//        alert->Go();
+//        break;
+
     case OPEN_FILE:
-       if(file_panel)
-               {
-               file_panel->Show();
-               break;
-               }
-       file_panel = new BFilePanel();
-       file_panel->SetTarget(this);
-       file_panel->Show();
-       break;
+        if( file_panel )
+        {
+            file_panel->Show();
+            break;
+        }
+        file_panel = new BFilePanel();
+        file_panel->SetTarget( this );
+        file_panel->Show();
+        break;
 
     case OPEN_DVD:
-           const char **device;
-           char device_method_and_name[B_FILE_NAME_LENGTH + 4];
-           if(p_message->FindString("device", device) != B_ERROR)
-               {
-               sprintf(device_method_and_name, "dvd:%s", *device); 
-               intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, device_method_and_name );
-               }
-       break;
+        const char **ppsz_device;
+        char psz_method[ B_FILE_NAME_LENGTH + 4 ];
+
+        if( p_message->FindString("device", ppsz_device) != B_ERROR )
+        {
+            snprintf( psz_method, B_FILE_NAME_LENGTH + 4,
+                      "dvd:%s", *ppsz_device );
+            psz_method[ B_FILE_NAME_LENGTH + 4 - 1 ] = '\0';
+
+            intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_method );
+        }
+        break;
 
     case STOP_PLAYBACK:
-       // this currently stops playback not nicely
-               if (p_intf->p_input != NULL )
-               {
-                       // silence the sound, otherwise very horrible
-                       if (p_main->p_aout != NULL)
-                       {
-                               p_main->p_aout->i_vol = 0;
-                       }
-                       snooze(400000);
-                       input_SetStatus(p_intf->p_input, INPUT_STATUS_END);
-               }
-       break;
-       case START_PLAYBACK:
-               // starts playing in normal mode
-//             if (p_intf->p_input != NULL )
-//             {                       
-//                     if (p_main->p_aout != NULL)
-//                     {
-//                             p_main->p_aout->i_vol = vol_val;
-//                     }
-//                     snooze(400000);
-//                     input_SetStatus(p_intf->p_input, INPUT_STATUS_PLAY);
-//                     playback_status = PLAYING;
-//             } 
-//             break;
-       case PAUSE_PLAYBACK:
-               // pause the playback
-               if (p_intf->p_input != NULL )
-               {
-                       // mute the volume if currently playing
-                       if (playback_status == PLAYING)
-                       {
-                               if (p_main->p_aout != NULL)
-                               {
-                                       p_main->p_aout->i_vol = 0;
-                               }
-                               playback_status = PAUSED;
-                       }
-                       else
-                       // restore the volume
-                       {
-                               if (p_main->p_aout != NULL)
-                               {
-                                       p_main->p_aout->i_vol = vol_val;
-                               }
-                               playback_status = PLAYING;
-                       }
-                       snooze(400000);
-                       input_SetStatus(p_intf->p_input, INPUT_STATUS_PAUSE);
-               }
-               break;
-       case FASTER_PLAY:
-               // cycle the fast playback modes
-               if (p_intf->p_input != NULL )
-               {
-                       if (p_main->p_aout != NULL)
-                       {
-                               p_main->p_aout->i_vol = 0;
-                       }
-                       snooze(400000);
-                       input_SetStatus(p_intf->p_input, INPUT_STATUS_FASTER);
-               }
-               break;
-       case SLOWER_PLAY:
-               // cycle the slow playback modes
-               if (p_intf->p_input != NULL )
-               {
-                       if (p_main->p_aout != NULL)
-                       {
-                               p_main->p_aout->i_vol = 0;
-                       }
-                       snooze(400000);
-                       input_SetStatus(p_intf->p_input, INPUT_STATUS_SLOWER);
-               }
-               break;
-       case SEEK_PLAYBACK:
-               // handled by semaphores;
-               break;
-       case VOLUME_CHG:
-               // adjust the volume
-        if (p_main->p_aout != NULL) 
+        // this currently stops playback not nicely
+        if( p_intf->p_input != NULL )
+        {
+            // silence the sound, otherwise very horrible
+            vlc_mutex_lock( &p_aout_bank->lock );
+            for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+            {
+                p_aout_bank->pp_aout[i_index]->i_savedvolume = p_aout_bank->pp_aout[i_index]->i_volume;
+                p_aout_bank->pp_aout[i_index]->i_volume = 0;
+            }
+            vlc_mutex_unlock( &p_aout_bank->lock );
+
+            snooze( 400000 );
+            input_SetStatus( p_intf->p_input, INPUT_STATUS_END );
+        }
+        break;
+
+    case START_PLAYBACK:
+        // starts playing in normal mode
+//        if (p_intf->p_input != NULL )
+//
+//            if (p_main->p_aout != NULL)
+//            {
+//                p_main->p_aout->i_vol = vol_val;
+//            }
+//            snooze(400000);
+//            input_SetStatus(p_intf->p_input, INPUT_STATUS_PLAY);
+//            playback_status = PLAYING;
+//        }
+//        break;
+
+    case PAUSE_PLAYBACK:
+        // pause the playback
+        if( p_intf->p_input != NULL )
+        {
+            // mute the volume if currently playing
+            if( playback_status == PLAYING )
+            {
+                vlc_mutex_lock( &p_aout_bank->lock );
+                for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+                {
+                    p_aout_bank->pp_aout[i_index]->i_savedvolume =
+                                       p_aout_bank->pp_aout[i_index]->i_volume;
+                    p_aout_bank->pp_aout[i_index]->i_volume = 0;
+                }
+                vlc_mutex_unlock( &p_aout_bank->lock );
+                playback_status = PAUSED;
+            }
+            else
+            // restore the volume
+            {
+                vlc_mutex_lock( &p_aout_bank->lock );
+                for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+                {
+                    p_aout_bank->pp_aout[i_index]->i_volume =
+                                  p_aout_bank->pp_aout[i_index]->i_savedvolume;
+                    p_aout_bank->pp_aout[i_index]->i_savedvolume = 0;
+                }
+                vlc_mutex_unlock( &p_aout_bank->lock );
+                playback_status = PLAYING;
+            }
+
+            snooze( 400000 );
+            input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
+        }
+        break;
+
+    case FASTER_PLAY:
+        // cycle the fast playback modes
+        if( p_intf->p_input != NULL )
+        {
+            vlc_mutex_lock( &p_aout_bank->lock );
+            for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+            {
+                p_aout_bank->pp_aout[i_index]->i_savedvolume =
+                                       p_aout_bank->pp_aout[i_index]->i_volume;
+                p_aout_bank->pp_aout[i_index]->i_volume = 0;
+            }
+            vlc_mutex_unlock( &p_aout_bank->lock );
+
+            snooze( 400000 );
+            input_SetStatus( p_intf->p_input, INPUT_STATUS_FASTER );
+        }
+        break;
+
+    case SLOWER_PLAY:
+        // cycle the slow playback modes
+        if (p_intf->p_input != NULL )
+        {
+            vlc_mutex_lock( &p_aout_bank->lock );
+            for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+            {
+                p_aout_bank->pp_aout[i_index]->i_savedvolume =
+                                       p_aout_bank->pp_aout[i_index]->i_volume;
+                p_aout_bank->pp_aout[i_index]->i_volume = 0;
+            }
+            vlc_mutex_unlock( &p_aout_bank->lock );
+
+            snooze( 400000 );
+            input_SetStatus( p_intf->p_input, INPUT_STATUS_SLOWER );
+        }
+        break;
+
+    case SEEK_PLAYBACK:
+        // handled by semaphores;
+        break;
+
+    case VOLUME_CHG:
+        // adjust the volume
+        vlc_mutex_lock( &p_aout_bank->lock );
+        for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+        {
+            if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
+            {
+                p_aout_bank->pp_aout[i_index]->i_savedvolume = vol_val;
+            }
+            else
+            {
+                p_aout_bank->pp_aout[i_index]->i_volume = vol_val;
+            }
+        }
+        vlc_mutex_unlock( &p_aout_bank->lock );
+        break;
+
+    case VOLUME_MUTE:
+        // mute
+        vlc_mutex_lock( &p_aout_bank->lock );
+        for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
+        {
+            if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
+            {
+                p_aout_bank->pp_aout[i_index]->i_volume =
+                                  p_aout_bank->pp_aout[i_index]->i_savedvolume;
+                p_aout_bank->pp_aout[i_index]->i_savedvolume = 0;
+            }
+            else
+            {
+                p_aout_bank->pp_aout[i_index]->i_savedvolume =
+                                       p_aout_bank->pp_aout[i_index]->i_volume;
+                p_aout_bank->pp_aout[i_index]->i_volume = 0;
+            }
+        }
+        vlc_mutex_unlock( &p_aout_bank->lock );
+        break;
+
+    case SELECT_CHANNEL:
+        {
+            int32 i = p_message->FindInt32( "channel" );
+            input_ChangeES( p_intf->p_input,
+                            p_intf->p_input->stream.pp_es[i], 1 );
+        }
+        break;
+
+    case SELECT_SUBTITLE:
         {
-                       p_main->p_aout->i_vol = vol_val;
-               }
-               break;
-       case VOLUME_MUTE:
-               // mute
-        if (p_main->p_aout != NULL) 
-           {
-                       if (p_main->p_aout->i_vol == 0)
-                       {
-                               p_vol->SetEnabled(true);
-                               p_main->p_aout->i_vol = vol_val;
-                       }       
-                       else
-                       {
-                               p_vol->SetEnabled(false);
-                               p_main->p_aout->i_vol = 0;
-                       }
-               }
-               break;
-       case SELECT_CHANNEL:
-               {
-                       int32 i = p_message->FindInt32("channel");
-                       input_ChangeES(p_intf->p_input, 
-                                       p_intf->p_input->stream.pp_es[i], 1);
-               }
-               break;
-       case SELECT_SUBTITLE:
-               {
-                       int32 i = p_message->FindInt32("subtitle");
-                       input_ChangeES(p_intf->p_input, 
-                                       p_intf->p_input->stream.pp_es[i], 2);
-               }
-               break;
-       case B_REFS_RECEIVED:
+            int32 i = p_message->FindInt32( "subtitle" );
+            input_ChangeES( p_intf->p_input,
+                            p_intf->p_input->stream.pp_es[i], 2 );
+        }
+        break;
+
+    case B_REFS_RECEIVED:
     case B_SIMPLE_DATA:
         {
             entry_ref ref;
@@ -403,6 +460,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
 
         }
         break;
+
     default:
         BWindow::MessageReceived( p_message );
         break;
@@ -423,7 +481,7 @@ bool InterfaceWindow::QuitRequested()
  * CDMenu::CDMenu
  *****************************************************************************/
 CDMenu::CDMenu(const char *name)
-       : BMenu(name)
+      : BMenu(name)
 {
 }
 
@@ -439,87 +497,110 @@ CDMenu::~CDMenu()
  *****************************************************************************/
 void CDMenu::AttachedToWindow(void)
 {
-       while (RemoveItem((long int)0) != NULL);  // remove all items
-       GetCD("/dev/disk");
-       BMenu::AttachedToWindow();
+    while (RemoveItem((long int)0) != NULL);  // remove all items
+    GetCD("/dev/disk");
+    BMenu::AttachedToWindow();
 }
 
 /*****************************************************************************
  * CDMenu::GetCD
  *****************************************************************************/
-int CDMenu::GetCD(const char *directory)
-{ 
-       BDirectory dir; 
-       dir.SetTo(directory); 
-       if(dir.InitCheck() != B_NO_ERROR) { 
-               return B_ERROR; 
-       } 
-       dir.Rewind(); 
-       BEntry entry; 
-       while(dir.GetNextEntry(&entry) >= 0) { 
-               BPath path; 
-               const char *name; 
-               entry_ref e; 
-               
-               if(entry.GetPath(&path) != B_NO_ERROR) 
-                       continue; 
-               name = path.Path(); 
-               
-               
-               if(entry.GetRef(&e) != B_NO_ERROR) 
-                       continue; 
-
-               if(entry.IsDirectory()) { 
-                       if(strcmp(e.name, "floppy") == 0) 
-                               continue; // ignore floppy (it is not silent) 
-                       int devfd = GetCD(name);
-                       if(devfd >= 0)
-                               {
-                               return devfd;
-                               }
-               } 
-               else { 
-                       int devfd; 
-                       device_geometry g;
-                       status_t m;
-
-                       if(strcmp(e.name, "raw") != 0) 
-                               continue; // ignore partitions 
-
-                       devfd = open(name, O_RDONLY); 
-                       if(devfd < 0) 
-                               continue; 
-
-                       if(ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) {
-                               if(g.device_type == B_CD) //ensure the drive is a CD-ROM
-                               { 
-                                       if(ioctl(devfd, B_GET_MEDIA_STATUS, &m, sizeof(m)) >= 0 )
-                                               if(m == B_NO_ERROR) //ensure media is present
-                                                       {
-                                                       BMessage *msg;
-                                                       msg = new BMessage(OPEN_DVD);
-                                                       msg->AddString("device", name);
-                                                       BMenuItem *menu_item;
-                                                       menu_item = new BMenuItem(name, msg);
-                                                       AddItem(menu_item);
-                                                       continue;
-                                                       }
-                               }
-                       }
-                       close(devfd);
-               } 
-       }
-       return B_ERROR;
+int CDMenu::GetCD( const char *directory )
+{
+    int i_dev;
+    BDirectory dir;
+    dir.SetTo( directory );
+
+    if( dir.InitCheck() != B_NO_ERROR )
+    {
+        return B_ERROR;
+    }
+
+    dir.Rewind();
+    BEntry entry;
+
+    while( dir.GetNextEntry(&entry) >= 0 )
+    {
+        const char *name;
+        entry_ref e;
+        BPath path;
+
+        if( entry.GetPath(&path) != B_NO_ERROR )
+        {
+            continue;
+        }
+
+        name = path.Path();
+
+        if( entry.GetRef(&e) != B_NO_ERROR )
+        {
+            continue;
+        }
+
+        if( entry.IsDirectory() )
+        {
+            if( strcmp(e.name, "floppy") == 0 )
+            {
+                continue; // ignore floppy (it is not silent)
+            }
+
+            i_dev = GetCD( name );
+
+            if( i_dev >= 0 )
+            {
+                return i_dev;
+            }
+        }
+        else
+        {
+            device_geometry g;
+            status_t m;
+
+            if( strcmp(e.name, "raw") != 0 )
+            {
+                continue; // ignore partitions
+            }
+
+            i_dev = open( name, O_RDONLY );
+
+            if( i_dev < 0 )
+            {
+                continue;
+            }
+
+            if( ioctl(i_dev, B_GET_GEOMETRY, &g, sizeof(g)) >= 0 )
+            {
+                if( g.device_type == B_CD ) //ensure the drive is a CD-ROM
+                {
+                    if( ioctl(i_dev, B_GET_MEDIA_STATUS, &m, sizeof(m)) >= 0 )
+                    {
+                        if( m == B_NO_ERROR ) //ensure media is present
+                        {
+                            BMessage *msg;
+                            msg = new BMessage( OPEN_DVD );
+                            msg->AddString( "device", name );
+                            BMenuItem *menu_item;
+                            menu_item = new BMenuItem( name, msg );
+                            AddItem( menu_item );
+                            continue;
+                        }
+                    }
+                }
+            }
+            close( i_dev );
+        }
+    }
+    return B_ERROR;
 }
 
 /*****************************************************************************
  * LanguageMenu::LanguageMenu
  *****************************************************************************/
 LanguageMenu::LanguageMenu(const char *name, int menu_kind, intf_thread_t  *p_interface)
-       :BMenu(name)
+    :BMenu(name)
 {
-       kind = menu_kind;
-       p_intf = p_interface;
+    kind = menu_kind;
+    p_intf = p_interface;
 }
 
 /*****************************************************************************
@@ -534,68 +615,71 @@ LanguageMenu::~LanguageMenu()
  *****************************************************************************/
 void LanguageMenu::AttachedToWindow(void)
 {
-       while (RemoveItem((long int)0) != NULL); // remove all items
-       SetRadioMode(true);
-       GetChannels();
-       BMenu::AttachedToWindow();
+    while( RemoveItem((long int)0) != NULL )
+    {
+        ; // remove all items
+    }
+
+    SetRadioMode(true);
+    GetChannels();
+    BMenu::AttachedToWindow();
 }
 
 /*****************************************************************************
  * LanguageMenu::GetChannels
  *****************************************************************************/
 int LanguageMenu::GetChannels()
-{ 
-       char*   psz_name;
-       bool    b_active;
-       bool    b_found;
-       int32   i;
-       es_descriptor_t *p_es;
-       
-       if (p_intf->p_input == NULL)
-               return 1;
-               
-       for (i = 0; i < p_intf->p_input->stream.i_selected_es_number; i++)
-       {
-               if (kind ==
-                       p_intf->p_input->stream.pp_selected_es[i]->i_cat)
-               {
-                       p_es = p_intf->p_input->stream.pp_selected_es[i];
-               }
-       }               
-       for (i = 0; i < p_intf->p_input->stream.i_es_number; i++)
-       {
-               if (kind == p_intf->p_input->stream.pp_es[i]->i_cat)
-               {
-                       psz_name = p_intf->p_input->stream.pp_es[i]->psz_desc;
-                       BMessage *msg;
-                       if (kind == AUDIO_ES) //audio
-                       {
-                               msg = new BMessage(SELECT_CHANNEL);
-                               msg->AddInt32("channel", i);
-                       }
-                       else
-                       {
-                               msg = new BMessage(SELECT_SUBTITLE);
-                               msg->AddInt32("subtitle", i);
-                       }
-                       BMenuItem *menu_item;
-                       menu_item = new BMenuItem(psz_name, msg);
-                       AddItem(menu_item);
-                       b_active = (p_es == p_intf->p_input->stream.pp_es[i]);
-                       menu_item->SetMarked(b_active);
-               }
-       }
-}
+{
+    char  *psz_name;
+    bool   b_active;
+    bool   b_found;
+    int    i;
+    es_descriptor_t *p_es;
 
+    if( p_intf->p_input == NULL )
+    {
+        return 1;
+    }
+
+    for( i = 0; i < p_intf->p_input->stream.i_selected_es_number; i++ )
+    {
+        if( kind == p_intf->p_input->stream.pp_selected_es[i]->i_cat )
+        {
+            p_es = p_intf->p_input->stream.pp_selected_es[i];
+        }
+    }
+
+    for( i = 0; i < p_intf->p_input->stream.i_es_number; i++ )
+    {
+        if( kind == p_intf->p_input->stream.pp_es[i]->i_cat )
+        {
+            psz_name = p_intf->p_input->stream.pp_es[i]->psz_desc;
+            BMessage *msg;
+            if( kind == AUDIO_ES ) //audio
+            {
+                msg = new BMessage(SELECT_CHANNEL);
+                msg->AddInt32("channel", i);
+            }
+            else
+            {
+                msg = new BMessage(SELECT_SUBTITLE);
+                msg->AddInt32("subtitle", i);
+            }
+            BMenuItem *menu_item;
+            menu_item = new BMenuItem(psz_name, msg);
+            AddItem(menu_item);
+            b_active = (p_es == p_intf->p_input->stream.pp_es[i]);
+            menu_item->SetMarked(b_active);
+        }
+    }
+}
 
 /*****************************************************************************
  * MediaSlider
  *****************************************************************************/
-MediaSlider::MediaSlider(BRect frame,
-                                               BMessage *message,
-                                               int32 minValue,
-                                               int32 maxValue)
-                                       :BSlider(frame, NULL, NULL, message, minValue, maxValue)
+MediaSlider::MediaSlider( BRect frame, BMessage *p_message,
+                          int32 i_min, int32 i_max )
+            :BSlider(frame, NULL, NULL, p_message, i_min, i_max )
 {
 
 }
@@ -607,38 +691,47 @@ MediaSlider::~MediaSlider()
 
 void MediaSlider::DrawThumb(void)
 {
-       BRect r;
-       BView *v;
-
-       rgb_color black = {0,0,0};
-       r = ThumbFrame();
-       v = OffscreenView();
-       if(IsEnabled())
-               v->SetHighColor(black);
-       else
-               v->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
-       r.InsetBy(r.IntegerWidth()/4, r.IntegerHeight()/(4 * r.IntegerWidth() / r.IntegerHeight()));
-       v->StrokeEllipse(r);
-       if(IsEnabled())
-               v->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
-       else
-               v->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
-       r.InsetBy(1,1);
-       v->FillEllipse(r);
+    BRect r;
+    BView *v;
+
+    rgb_color black = {0,0,0};
+    r = ThumbFrame();
+    v = OffscreenView();
+
+    if(IsEnabled())
+    {
+        v->SetHighColor(black);
+    }
+    else
+    {
+        v->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
+    }
+
+    r.InsetBy(r.IntegerWidth()/4, r.IntegerHeight()/(4 * r.IntegerWidth() / r.IntegerHeight()));
+    v->StrokeEllipse(r);
+
+    if(IsEnabled())
+    {
+        v->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+    }
+    else
+    {
+        v->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
+    }
+
+    r.InsetBy(1,1);
+    v->FillEllipse(r);
 }
 
 /*****************************************************************************
  * SeekSlider
  *****************************************************************************/
-SeekSlider::SeekSlider(BRect frame,
-                               InterfaceWindow *owner,
-                               int32 minValue,
-                               int32 maxValue,
-                               thumb_style thumbType = B_TRIANGLE_THUMB)
-                       :MediaSlider(frame, NULL, minValue, maxValue)
+SeekSlider::SeekSlider( BRect frame, InterfaceWindow *p_owner, int32 i_min,
+                        int32 i_max, thumb_style thumbType = B_TRIANGLE_THUMB )
+           :MediaSlider( frame, NULL, i_min, i_max )
 {
-       fOwner = owner;
-       fMouseDown = false;
+    fOwner = p_owner;
+    fMouseDown = false;
 }
 
 SeekSlider::~SeekSlider()
@@ -650,9 +743,9 @@ SeekSlider::~SeekSlider()
  *****************************************************************************/
 void SeekSlider::MouseDown(BPoint where)
 {
-       BSlider::MouseDown(where);
-       fOwner->fScrubSem = create_sem(1, "Vlc::fScrubSem");
-       fMouseDown = true;                                      
+    BSlider::MouseDown(where);
+    fOwner->fScrubSem = create_sem(1, "Vlc::fScrubSem");
+    fMouseDown = true;
 }
 
 /*****************************************************************************
@@ -660,10 +753,10 @@ void SeekSlider::MouseDown(BPoint where)
  *****************************************************************************/
 void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
 {
-       BSlider::MouseMoved(where, code, message);
-       if (!fMouseDown)
-               return;
-       release_sem(fOwner->fScrubSem);
+    BSlider::MouseMoved(where, code, message);
+    if (!fMouseDown)
+        return;
+    release_sem(fOwner->fScrubSem);
 }
 
 /*****************************************************************************
@@ -671,12 +764,12 @@ void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
  *****************************************************************************/
 void SeekSlider::MouseUp(BPoint where)
 {
-       BSlider::MouseUp(where);
-       delete_sem(fOwner->fScrubSem);
-       fOwner->fScrubSem = B_ERROR;
-       fMouseDown = false;                                     
+    BSlider::MouseUp(where);
+    delete_sem(fOwner->fScrubSem);
+    fOwner->fScrubSem = B_ERROR;
+    fMouseDown = false;
 }
-       
+
 
 extern "C"
 {
@@ -730,7 +823,7 @@ static int intf_Open( intf_thread_t *p_intf )
     rect.left += 50;
     rect.right = rect.left + 350;
     delete screen;
-    
+
     /* Allocate instance and initialize some members */
     p_intf->p_sys = (intf_sys_t*) malloc( sizeof( intf_sys_t ) );
     if( p_intf->p_sys == NULL )
@@ -739,7 +832,7 @@ static int intf_Open( intf_thread_t *p_intf )
         return( 1 );
     }
     p_intf->p_sys->i_key = -1;
-    
+
     /* Create the interface window */
     p_intf->p_sys->p_window =
         new InterfaceWindow( rect,
@@ -750,7 +843,7 @@ static int intf_Open( intf_thread_t *p_intf )
         intf_ErrMsg( "error: cannot allocate memory for InterfaceWindow" );
         return( 1 );
     }
-    
+
     return( 0 );
 }
 
@@ -761,7 +854,7 @@ static void intf_Close( intf_thread_t *p_intf )
 {
     /* Destroy the interface window */
     p_intf->p_sys->p_window->Lock();
-    p_intf->p_sys->p_window->Quit();    
+    p_intf->p_sys->p_window->Quit();
 
     /* Destroy structure */
     free( p_intf->p_sys );
@@ -773,39 +866,37 @@ static void intf_Close( intf_thread_t *p_intf )
  *****************************************************************************/
 static void intf_Run( intf_thread_t *p_intf )
 {
-       
-       float progress;
-       bool seekNeeded = false;
-       
+    float progress;
+    bool seekNeeded = false;
+
     while( !p_intf->b_die )
     {
-
         /* Manage core vlc functions through the callback */
         p_intf->pf_manage( p_intf );
 
-           /* Manage the slider */
-           if( p_intf->p_input != NULL && p_intf->p_sys->p_window != NULL)
-       {
-            if (acquire_sem(p_intf->p_sys->p_window->fScrubSem) == B_OK)
-                       {
-                               seekNeeded = true;
-                       }               
+        /* Manage the slider */
+        if( p_intf->p_input != NULL && p_intf->p_sys->p_window != NULL)
+        {
+            if( acquire_sem(p_intf->p_sys->p_window->fScrubSem) == B_OK )
+            {
+                seekNeeded = true;
+            }
 
-                       if (seekNeeded)
+            if( seekNeeded )
             {
-               uint32 seekTo = (p_intf->p_sys->p_window->p_seek->Value() * 
-                               p_intf->p_input->stream.p_selected_area->i_size) / 100;
-                               input_Seek( p_intf->p_input, seekTo );
-                               seekNeeded = false;             
+                uint32 seekTo = (p_intf->p_sys->p_window->p_seek->Value() *
+                        p_intf->p_input->stream.p_selected_area->i_size) / 100;
+                input_Seek( p_intf->p_input, seekTo );
+                seekNeeded = false;
             }
-                       else if (p_intf->p_sys->p_window->Lock())
+            else if( p_intf->p_sys->p_window->Lock() )
             {
-                   progress = (100. * p_intf->p_input->stream.p_selected_area->i_tell) /
-                                       p_intf->p_input->stream.p_selected_area->i_size;
-                   p_intf->p_sys->p_window->p_seek->SetValue(progress);
-                   p_intf->p_sys->p_window->Unlock();
-               }
-         }
+                progress = (100. * p_intf->p_input->stream.p_selected_area->i_tell) /
+                            p_intf->p_input->stream.p_selected_area->i_size;
+                p_intf->p_sys->p_window->p_seek->SetValue(progress);
+                p_intf->p_sys->p_window->Unlock();
+            }
+        }
 
         /* Wait a bit */
         msleep( INTF_IDLE_SLEEP );
@@ -813,3 +904,4 @@ static void intf_Run( intf_thread_t *p_intf )
 }
 
 } /* extern "C" */
+
index 9666b24e67158626883066d40205ff80c36afe0c..6d520f0ae672ec386f6aadbefbc8a025e2d9dc85 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_ifo.c: Functions for ifo parsing
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.c,v 1.25 2001/05/07 03:14:09 stef Exp $
+ * $Id: dvd_ifo.c,v 1.26 2001/05/07 04:42:42 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -111,7 +111,7 @@ static __inline__ u32 ReadDouble( ifo_t * p_ifo, u8* pi_buffer,
     if( *pp_current > pi_buffer + DVD_LB_SIZE - 4 )
     {
         *pp_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos + DVD_LB_SIZE);
-//     intf_WarnMsg( 1, "new buffer in double @ %lld", p_ifo->i_pos );
+//        intf_WarnMsg( 1, "new buffer in double @ %lld", p_ifo->i_pos );
     }
 
     i_ret = U32_AT(*pp_current);
@@ -1343,7 +1343,7 @@ static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, off_t i_pos )
         p_cell_inf->p_cell_map[i].i_cell_id = ReadByte( p_ifo, pi_buffer, &p_current );
         DumpBits( p_ifo, pi_buffer, &p_current, 1 );
         p_cell_inf->p_cell_map[i].i_start_sector = ReadDouble( p_ifo, pi_buffer, &p_current );
-//     fprintf(stderr, "sector[%d] %d (%lld)\n", i,ntohl(*(u32*)(p_current)), p_ifo->i_pos);
+//        fprintf(stderr, "sector[%d] %d (%lld)\n", i,ntohl(*(u32*)(p_current)), p_ifo->i_pos);
         p_cell_inf->p_cell_map[i].i_end_sector = ReadDouble( p_ifo, pi_buffer, &p_current );
     }
     
index e9e034cf28c47ac6dfdba35dfa4521fc6f22b3c2..69eba23e0163b725eeeac019a806ce5a87e56f50 100644 (file)
@@ -10,7 +10,7 @@
  *  -dvd_udf to find files
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.56 2001/05/07 03:14:09 stef Exp $
+ * $Id: input_dvd.c,v 1.57 2001/05/07 04:42:42 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -667,14 +667,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         {
             p_dvd->i_cell = vts.cell_inf.i_cell_nb - 1;
         }
-       
-                       
+
         p_dvd->i_sector = 0;
         p_dvd->i_size = DVD_LB_SIZE *
           (off_t)( vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
         intf_WarnMsg( 2, "dvd info: stream size 1: %lld @ %d", p_dvd->i_size,
                       vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
-       
+
         if( DVDChapterSelect( p_dvd, 1 ) < 0 )
         {
             intf_ErrMsg( "dvd error: can't find first chapter" );
@@ -1222,7 +1221,7 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
     /* Find first title cell which is inside program cell */
     if( DVDFindCell( p_dvd ) < 0 )
     {
-       /* no following cell : we're at eof */
+        /* no following cell : we're at eof */
         intf_ErrMsg( "dvd error: cell seeking failed" );
         p_input->b_error = 1;
         return;
@@ -1285,7 +1284,7 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
 }
 
 #define cell  p_dvd->p_ifo->vts.cell_inf
-               
+
 /*****************************************************************************
  * DVDFindCell: adjust the title cell index with the program cell
  *****************************************************************************/
@@ -1403,7 +1402,7 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
 
     /* start is : beginning of vts vobs + offset to vob x */
     p_dvd->i_start = p_dvd->i_title_start +
-                    DVD_LB_SIZE * (off_t)( p_dvd->i_sector );
+                         DVD_LB_SIZE * (off_t)( p_dvd->i_sector );
 
     /* Position the fd pointer on the right address */
     p_dvd->i_start = lseek( p_dvd->i_fd, p_dvd->i_start, SEEK_SET );
index 00c633c80fd63854d2e892f485072410a9e90a3b..be1f7356599d862710ce6f2e9bbc0d2dc6cb5539 100644 (file)
@@ -2,7 +2,7 @@
  * input_ps.c: PS demux and packet management
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ps.c,v 1.21 2001/05/07 03:14:09 stef Exp $
+ * $Id: input_ps.c,v 1.22 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Cyril Deguet <asmax@via.ecp.fr>
@@ -146,7 +146,7 @@ static int PSProbe( probedata_t *p_data )
 static void PSInit( input_thread_t * p_input )
 {
     thread_ps_data_t *  p_method;
-    packet_cache_t *   p_packet_cache;
+    packet_cache_t *    p_packet_cache;
 
     if( (p_method =
          (thread_ps_data_t *)malloc( sizeof(thread_ps_data_t) )) == NULL )
@@ -173,8 +173,8 @@ static void PSInit( input_thread_t * p_input )
     if ( p_packet_cache->data.p_stack == NULL )
     {
         intf_ErrMsg( "Out of memory" );
-       p_input->b_error = 1;
-       return;
+        p_input->b_error = 1;
+        return;
     }
     p_packet_cache->data.l_index = 0;
     
@@ -602,7 +602,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
         /* Checks whether the buffer cache is empty */
         if( p_cache->small.l_index == 0 )
         {
-           /* Allocates a new packet */
+            /* Allocates a new packet */
             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
             {
                 intf_DbgMsg( "Out of memory" );
@@ -625,7 +625,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
                 free( p_data );
                 return NULL;
             }
-               /* Reallocates the packet if it is too small or too large */
+            /* Reallocates the packet if it is too small or too large */
             if( p_cache->small.p_stack[l_index].l_size < l_size ||
                 p_cache->small.p_stack[l_index].l_size > 2*l_size )
             {
@@ -645,7 +645,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
         /* Checks whether the buffer cache is empty */
         if( p_cache->large.l_index == 0 )
         {
-           /* Allocates a new packet */
+            /* Allocates a new packet */
             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
             {
                 intf_ErrMsg( "Out of memory" );
@@ -668,7 +668,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
                 free( p_data );
                 return NULL;
             }
-               /* Reallocates the packet if it is too small or too large */
+            /* Reallocates the packet if it is too small or too large */
             if( p_cache->large.p_stack[l_index].l_size < l_size ||
                 p_cache->large.p_stack[l_index].l_size > 2*l_size )
             {
@@ -679,7 +679,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
             {
                 p_data->l_size = p_cache->large.p_stack[l_index].l_size;
             }
-           }
+        }
     }
 
     /* Initialize data */
@@ -689,7 +689,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
     p_data->p_payload_end = p_data->p_buffer + l_size;
 
     return( p_data );
-       
+
 }
 
 
@@ -734,7 +734,7 @@ static pes_packet_t * NewPES( void * p_packet_cache )
             return NULL;
         }
     }
-       
+
     p_pes->b_data_alignment = p_pes->b_discontinuity =
         p_pes->i_pts = p_pes->i_dts = 0;
     p_pes->i_pes_size = 0;
@@ -762,7 +762,7 @@ static void DeletePacket( void * p_packet_cache,
     }
 #endif
 
-       ASSERT( p_data );
+    ASSERT( p_data );
 
     /* Checks whether the data cache is full */
     if ( p_cache->data.l_index < DATA_CACHE_SIZE )
@@ -789,7 +789,7 @@ static void DeletePacket( void * p_packet_cache,
 #endif
             }
         }
-       else
+        else
         {
             /* Checks whether the large buffer cache is full */
             if ( p_cache->large.l_index < LARGE_CACHE_SIZE )
@@ -813,7 +813,7 @@ static void DeletePacket( void * p_packet_cache,
     {
         /* Cache full: the packet must be freed */
         free( p_data->p_buffer );
-       free( p_data );
+        free( p_data );
 #ifdef TRACE_INPUT
         intf_DbgMsg( "PS input: data packet freed" );
 #endif
@@ -854,7 +854,7 @@ static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
     /* Checks whether the PES cache is full */
     if ( p_cache->pes.l_index < PES_CACHE_SIZE )
     {
-       /* Cache not full: store the packet in it */
+        /* Cache not full: store the packet in it */
         p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes;
     }
     else
index 3d45702d5bc08a02057a3008565f1aa5bfc4d381..0fc2e47291e75fa521e9df398f732a3bdda73a32 100644 (file)
@@ -2,7 +2,7 @@
  * vout_sdl.c: SDL video output display method
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vout_sdl.c,v 1.50 2001/05/07 03:14:09 stef Exp $
+ * $Id: vout_sdl.c,v 1.51 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Pierre Baillet <oct@zoy.org>
@@ -162,7 +162,7 @@ static int vout_Create( vout_thread_t *p_vout )
     /* Win32 SDL implementation doesn't support SDL_INIT_EVENTTHREAD yet*/
                 | SDL_INIT_EVENTTHREAD
 #endif
-               | SDL_INIT_NOPARACHUTE ) < 0 )
+                | SDL_INIT_NOPARACHUTE ) < 0 )
     {
         intf_ErrMsg( "vout error: can't initialize SDL (%s)", SDL_GetError() );
         free( p_vout->p_sys );
index 525acd3bafd6c9ee3d36a037dd66ca9a17dfc19a..caa7c85a84be251bfdbb270f59f73f7c0d3f9bd3 100644 (file)
@@ -2,7 +2,7 @@
  * vout_xvideo.c: Xvideo video output display method
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
- * $Id: vout_xvideo.c,v 1.15 2001/05/07 03:14:09 stef Exp $
+ * $Id: vout_xvideo.c,v 1.16 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Shane Harper <shanegh@optusnet.com.au>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -1060,7 +1060,7 @@ static void XVideoOutputCoords( const picture_t *p_pic, const boolean_t scale,
                 *h = win_w * 9 / 16;
                 break;
 
-           case AR_221_1_PICTURE:
+            case AR_221_1_PICTURE:
                 *h = win_w * 100 / 221;
                 break;
 
index 032d2deb88222ac3ea459a58c366f37788623dce..08fb51736fbbef9c029bc359cc253fca636a731e 100644 (file)
@@ -2,7 +2,7 @@
  * ac3_parse.c: ac3 parsing procedures
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: ac3_parse.c,v 1.20 2001/05/06 04:32:02 sam Exp $
+ * $Id: ac3_parse.c,v 1.21 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Aaron Holtzman <aholtzma@engr.uvic.ca>
@@ -810,7 +810,7 @@ void parse_bsi_stats (ac3dec_t * p_ac3dec) /*Some stats */
 {  
     struct mixlev_s
     {
-           float clev;
+        float clev;
         char *desc;
     };
     static const char *service_ids[8] = 
@@ -835,10 +835,10 @@ void parse_bsi_stats (ac3dec_t * p_ac3dec) /*Some stats */
     
     if ( !i )
     {
-/*             if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
-                       printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
-               if (p_ac3dec->bsi.acmod & 0x4)
-                       printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
+/*      if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
+               printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
+        if (p_ac3dec->bsi.acmod & 0x4)
+               printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
  */
         intf_Msg ( "(ac3dec_parsebsi) %s %d.%d Mode",
                 service_ids[p_ac3dec->bsi.bsmod],
@@ -855,19 +855,19 @@ void parse_audblk_stats (ac3dec_t * p_ac3dec)
     char *exp_strat_tbl[4] = {"R   ","D15 ","D25 ","D45 "};
     u32 i;
 
-       intf_ErrMsg ("(ac3dec_parseaudblk) ");
-       intf_ErrMsg ("%s ",p_ac3dec->audblk.cplinu ? "cpl on" : "cpl off");
-       intf_ErrMsg ("%s ",p_ac3dec->audblk.baie? "bai" : " ");
-       intf_ErrMsg ("%s ",p_ac3dec->audblk.snroffste? "snroffst" : " ");
-       intf_ErrMsg ("%s ",p_ac3dec->audblk.deltbaie? "deltba" : " ");
-       intf_ErrMsg ("%s ",p_ac3dec->audblk.phsflginu? "phsflg" : " ");
-       intf_ErrMsg ("(%s %s %s %s %s) ",exp_strat_tbl[p_ac3dec->audblk.chexpstr[0]],
-               exp_strat_tbl[p_ac3dec->audblk.chexpstr[1]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[2]],
-               exp_strat_tbl[p_ac3dec->audblk.chexpstr[3]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[4]]);
-       intf_ErrMsg ("[");
-       for(i=0;i<p_ac3dec->bsi.nfchans;i++)
-               intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]);
-       intf_ErrMsg ("]");
-
-       intf_ErrMsg ("\n");
+    intf_ErrMsg ("(ac3dec_parseaudblk) ");
+        intf_ErrMsg ("%s ",p_ac3dec->audblk.cplinu ? "cpl on" : "cpl off");
+        intf_ErrMsg ("%s ",p_ac3dec->audblk.baie? "bai" : " ");
+        intf_ErrMsg ("%s ",p_ac3dec->audblk.snroffste? "snroffst" : " ");
+        intf_ErrMsg ("%s ",p_ac3dec->audblk.deltbaie? "deltba" : " ");
+        intf_ErrMsg ("%s ",p_ac3dec->audblk.phsflginu? "phsflg" : " ");
+        intf_ErrMsg ("(%s %s %s %s %s) ",exp_strat_tbl[p_ac3dec->audblk.chexpstr[0]],
+                exp_strat_tbl[p_ac3dec->audblk.chexpstr[1]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[2]],
+                exp_strat_tbl[p_ac3dec->audblk.chexpstr[3]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[4]]);
+        intf_ErrMsg ("[");
+        for(i=0;i<p_ac3dec->bsi.nfchans;i++)
+                intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]);
+        intf_ErrMsg ("]");
+
+        intf_ErrMsg ("\n");
 }
index 5b02400d9ff349554ccf1533088a1e336d49ccb2..e0204f95cc5ca4e8f81d92345ba8cfad666f061e 100644 (file)
@@ -3,7 +3,7 @@
  * Functions are prototyped in mtime.h.
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: mtime.c,v 1.17 2001/04/28 03:36:25 sam Exp $
+ * $Id: mtime.c,v 1.18 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -94,7 +94,7 @@ mtime_t mdate( void )
     {
         /* Microsecond resolution */
         QueryPerformanceCounter((LARGE_INTEGER *)&usec_time);
-       usec_time /= (freq/1000000);
+        usec_time /= (freq/1000000);
     }
     return( usec_time );
 
index bf73a854db32c3801753fc77a620136814bef741..a3fe1c170b362d4628fc3a36c3d8d97c3db74a65 100644 (file)
@@ -2,7 +2,7 @@
  * netutils.c: various network functions
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: netutils.c,v 1.28 2001/04/28 03:36:25 sam Exp $
+ * $Id: netutils.c,v 1.29 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Benoit Steiner <benny@via.ecp.fr>
@@ -245,7 +245,7 @@ int network_ChannelJoin( int i_channel_id )
     int                 i_nbanswer;
     char                i_answer;
     fd_set              s_rfds;
-    unsigned int       i_rc;
+    unsigned int        i_rc;
  
     if( ! p_main->b_channels )
     {
index e534dd347de7d84900eb4954d2f9ca6fda95596a..9e2faf4a23ecf87e8ac103ab46cbc65da9e8c9db 100644 (file)
@@ -2,7 +2,7 @@
  * spu_decoder.c : spu decoder thread
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: spu_decoder.c,v 1.41 2001/05/07 03:14:09 stef Exp $
+ * $Id: spu_decoder.c,v 1.42 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -49,8 +49,6 @@
 
 #include "spu_decoder.h"
 
-#include "main.h" /* XXX: remove this later */
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -88,14 +86,12 @@ vlc_thread_t spudec_CreateThread( vdec_config_t * p_config )
 
     p_spudec->p_fifo = p_config->decoder_config.p_decoder_fifo;
 
-    /* XXX: The vout request and fifo opening will eventually be here */
-
-    /* Spawn an audio output if there is none */
+    /* Spawn a video output if there is none */
     vlc_mutex_lock( &p_vout_bank->lock );
 
     if( p_vout_bank->i_count == 0 )
     {
-        intf_Msg( "spudec: no vout present, spawning one" );
+        intf_WarnMsg( 1, "spudec: no vout present, spawning one" );
 
         p_spudec->p_vout = vout_CreateThread( NULL );
 
@@ -275,9 +271,13 @@ static void ParsePacket( spudec_thread_t *p_spudec )
     subpicture_t * p_spu;
     u8           * p_src;
 
+    intf_WarnMsg( 3, "spudec: trying to gather a 0x%.2x long subtitle",
+                  p_spudec->i_spu_size );
+
     /* We cannot display a subpicture with no date */
     if( DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts == 0 )
     {
+        intf_WarnMsg( 3, "spudec error: subtitle without a date" );
         return;
     }
 
@@ -294,9 +294,8 @@ static void ParsePacket( spudec_thread_t *p_spudec )
         return;
     }
 
-    /* Get display time now. If we do it later, we may miss a PTS. */
-    p_spu->begin_date = p_spu->end_date
-                    = DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
+    /* Get display time now. If we do it later, we may miss the PTS. */
+    p_spudec->i_pts = DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
 
     /* Allocate the temporary buffer we will parse */
     p_src = malloc( p_spudec->i_rle_size );
@@ -313,7 +312,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
 
 #if 0
     /* Dump the subtitle info */
-    intf_WarnHexDump( 0, p_spu->p_data, p_spudec->i_rle_size );
+    intf_WarnHexDump( 5, p_spu->p_data, p_spudec->i_rle_size );
 #endif
 
     /* Getting the control part */
@@ -333,9 +332,11 @@ static void ParsePacket( spudec_thread_t *p_spudec )
         return;
     }
 
-    intf_WarnMsg( 3, "spudec: got a valid %ix%i subtitle at (%i,%i), "
-                     "RLE offsets: 0x%x 0x%x",
-                  p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y,
+    intf_WarnMsg( 3, "spudec: valid subtitle, size: %ix%i, position: %i,%i",
+                  p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y );
+                     
+    intf_WarnMsg( 3, "spudec: total size: 0x%x, RLE offsets: 0x%x 0x%x",
+                  p_spudec->i_spu_size,
                   p_spu->type.spu.i_offset[0], p_spu->type.spu.i_offset[1] );
 
     /* SPU is finished - we can ask the video output to display it */
@@ -359,20 +360,24 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
     int i_index = p_spudec->i_rle_size + 4;
 
     /* The next start-of-control-sequence index and the previous one */
-    int i_next_index = 0, i_prev_index;
+    int i_next_seq, i_cur_seq;
 
     /* Command time and date */
     u8  i_command;
     int i_date;
 
+    /* Initialize the structure */
+    p_spu->i_start = p_spu->i_stop = 0;
+    p_spu->b_ephemer = 0;
+
     do
     {
         /* Get the control sequence date */
         i_date = GetBits( &p_spudec->bit_stream, 16 );
  
         /* Next offset */
-        i_prev_index = i_next_index;
-        i_next_index = GetBits( &p_spudec->bit_stream, 16 );
+        i_cur_seq = i_index;
+        i_next_seq = GetBits( &p_spudec->bit_stream, 16 );
  
         /* Skip what we just read */
         i_index += 4;
@@ -385,22 +390,26 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
             switch( i_command )
             {
                 case SPU_CMD_FORCE_DISPLAY:
+
                     /* 00 (force displaying) */
+                    intf_ErrMsg( "spudec: \"force display\" command" );
+                    intf_ErrMsg( "spudec: send mail to <sam@zoy.org> if you "
+                                         "want to help debugging this" );
                     break;
  
                 /* Convert the dates in seconds to PTS values */
                 case SPU_CMD_START_DISPLAY:
  
                     /* 01 (start displaying) */
-                    p_spu->begin_date += ( i_date * 11000 );
+                    p_spu->i_start = p_spudec->i_pts + ( i_date * 11000 );
  
                     break;
  
                 case SPU_CMD_STOP_DISPLAY:
  
                     /* 02 (stop displaying) */
-                    p_spu->end_date += ( i_date * 11000 );
+                    p_spu->i_stop = p_spudec->i_pts + ( i_date * 11000 );
  
                     break;
  
@@ -463,13 +472,13 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
 
         } while( i_command != SPU_CMD_END );
 
-    } while( i_index == i_next_index );
+    } while( i_index == i_next_seq );
 
-    /* Check that the last index matches the previous one */
-    if( i_next_index != i_prev_index )
+    /* Check that the next sequence index matches the current one */
+    if( i_next_seq != i_cur_seq )
     {
         intf_ErrMsg( "spudec error: index mismatch (0x%.4x != 0x%.4x)",
-                     i_next_index, i_prev_index );
+                     i_next_seq, i_cur_seq );
         return( 1 );
     }
 
@@ -480,18 +489,26 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
         return( 1 );
     }
 
+    if( !p_spu->i_start )
+    {
+        intf_ErrMsg( "spudec error: no `start display' command" );
+    }
+
+    if( !p_spu->i_stop )
+    {
+        /* This subtitle will live for 5 seconds or until the next subtitle */
+        p_spu->i_stop = p_spu->i_start + 500 * 11000;
+        p_spu->b_ephemer = 1;
+    }
+
     /* Get rid of padding bytes */
     switch( p_spudec->i_spu_size - i_index )
     {
         case 1:
-
             RemoveBits( &p_spudec->bit_stream, 8 );
             i_index++;
-
         case 0:
-
             /* Zero or one padding byte, quite usual */
-
             break;
 
         default:
index 4aa67ba67de076d9ff117f440338dfaeb820c1cd..a7277d0e23caacc5cfd7d3426c5d302133aa9d16 100644 (file)
@@ -2,7 +2,7 @@
  * spu_decoder.h : sub picture unit decoder thread interface
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: spu_decoder.h,v 1.7 2001/03/21 13:42:34 sam Exp $
+ * $Id: spu_decoder.h,v 1.8 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -47,6 +47,7 @@ typedef struct spudec_thread_s
     /*
      * Private properties
      */
+    mtime_t             i_pts;                     /* presentation timestamp */
     int                 i_spu_size;            /* size of current SPU packet */
     int                 i_rle_size;                  /* size of the RLE part */
     subpicture_t *      p_spu;
index db2afe16f4ff2d7e56b8b1e5633fdbf604ad31c1..bb558f87ad39c1f0725f27e6449f8a4264f5fabc 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously oppened video output thread.
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: video_output.c,v 1.125 2001/05/07 03:14:10 stef Exp $
+ * $Id: video_output.c,v 1.126 2001/05/07 04:42:42 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -214,14 +214,16 @@ vout_thread_t * vout_CreateThread   ( int *pi_status )
      * will be initialized later in InitThread */
     for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++)
     {
-        p_vout->p_picture[i_index].i_type   =   EMPTY_PICTURE;
-        p_vout->p_picture[i_index].i_status =   FREE_PICTURE;
+        p_vout->p_picture[i_index].i_type   = EMPTY_PICTURE;
+        p_vout->p_picture[i_index].i_status = FREE_PICTURE;
     }
+
     for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++)
     {
-        p_vout->p_subpicture[i_index].i_type  = EMPTY_SUBPICTURE;
-        p_vout->p_subpicture[i_index].i_status= FREE_SUBPICTURE;
+        p_vout->p_subpicture[i_index].i_type   = EMPTY_SUBPICTURE;
+        p_vout->p_subpicture[i_index].i_status = FREE_SUBPICTURE;
     }
+
     p_vout->i_pictures = 0;
 
     /* Create and initialize system-dependant method - this function issues its
@@ -232,6 +234,7 @@ vout_thread_t * vout_CreateThread   ( int *pi_status )
         free( p_vout );
         return( NULL );
     }
+
     intf_WarnMsg( 3, "actual configuration: %dx%d, %d/%d bpp (%d Bpl), "
                   "masks: 0x%x/0x%x/0x%x",
                   p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
@@ -337,15 +340,15 @@ void vout_DestroyThread( vout_thread_t *p_vout, int *pi_status )
 /*****************************************************************************
  * vout_DisplaySubPicture: display a subpicture unit
  *****************************************************************************
- * Remove the reservation flag of an subpicture, which will cause it to be ready
+ * Remove the reservation flag of a subpicture, which will cause it to be ready
  * for display. The picture does not need to be locked, since it is ignored by
  * the output thread if is reserved.
  *****************************************************************************/
 void  vout_DisplaySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
 {
 #ifdef TRACE_VOUT
-    char        psz_begin_date[MSTRTIME_MAX_SIZE]; /* buffer for date string */
-    char        psz_end_date[MSTRTIME_MAX_SIZE];   /* buffer for date string */
+    char        psz_start[ MSTRTIME_MAX_SIZE ];    /* buffer for date string */
+    char        psz_stop[ MSTRTIME_MAX_SIZE ];     /* buffer for date string */
 #endif
 
 #ifdef DEBUG
@@ -364,8 +367,8 @@ void  vout_DisplaySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
     /* Send subpicture information */
     intf_DbgMsg("subpicture %p: type=%d, begin date=%s, end date=%s",
                 p_subpic, p_subpic->i_type,
-                mstrtime( psz_begin_date, p_subpic->begin_date ),
-                mstrtime( psz_end_date, p_subpic->end_date ) );
+                mstrtime( psz_start, p_subpic->i_start ),
+                mstrtime( psz_stop, p_subpic->i_stop ) );
 #endif
 }
 
@@ -1065,6 +1068,7 @@ static void RunThread( vout_thread_t *p_vout)
                 display_date =  0;
             }
         }
+
         /*
          * Find the subpictures to display - this operation does not need
          * lock, since only READY_SUBPICTURE are handled. If no picture
@@ -1090,9 +1094,6 @@ static void RunThread( vout_thread_t *p_vout)
             p_vout->last_display_date = display_date;
             p_vout->p_rendered_pic = p_pic;
 
-
-
-
             /* Set picture dimensions and clear buffer */
             SetBufferPicture( p_vout, p_pic );
 
@@ -1951,6 +1952,43 @@ static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
 {
     p_vout_font_t       p_font;                                 /* text font */
     int                 i_width, i_height;          /* subpicture dimensions */
+    mtime_t             i_date = mdate();
+
+    subpicture_t       *p_ephemer = NULL;
+    subpicture_t       *p_tmp = p_subpic;
+
+    /* Look for the youngest ephemer */
+    while( p_tmp != NULL )
+    {
+        if( p_tmp->i_type == DVD_SUBPICTURE && p_tmp->b_ephemer
+             && i_date >= p_tmp->i_start && i_date <= p_tmp->i_stop )
+       {
+            if( p_ephemer == NULL || p_tmp->i_start < p_ephemer->i_start )
+           {
+                p_ephemer = p_tmp;
+           }
+        }
+
+        p_tmp = p_tmp->p_next;
+    }
+
+    /* If we found an ephemer, kill it if we find a more recent one */
+    if( p_ephemer != NULL )
+    {
+        p_tmp = p_subpic;
+
+        while( p_tmp != NULL )
+        {
+            if( p_tmp->i_type == DVD_SUBPICTURE
+                 && i_date >= p_tmp->i_start && i_date >= p_tmp->i_start
+                 && p_tmp != p_ephemer && p_tmp->i_start > p_ephemer->i_start )
+            {
+                p_ephemer->i_stop = 0;
+            }
+
+            p_tmp = p_tmp->p_next;
+        }
+    }
 
     while( p_subpic != NULL )
     {
@@ -1958,12 +1996,12 @@ static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
         {
         case DVD_SUBPICTURE:                          /* DVD subpicture unit */
             /* test if the picture really has to be displayed */
-            if( mdate() < p_subpic->begin_date )
+            if( i_date < p_subpic->i_start )
             {
                 /* not yet, see you later */
                 break;
             }
-            if( mdate() > p_subpic->end_date )
+            if( i_date > p_subpic->i_stop )
             {
                 /* too late, destroying the subpic */
                 vout_DestroySubPicture( p_vout, p_subpic );
@@ -1973,6 +2011,7 @@ static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
                             p_subpic, p_vout->i_bytes_per_pixel,
                             p_vout->i_bytes_per_line );
             break;
+
         case TEXT_SUBPICTURE:                            /* single line text */
             /* Select default font if not specified */
             p_font = p_subpic->type.text.p_font;
@@ -2003,11 +2042,12 @@ static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
             }
             break;
 
-#ifdef DEBUG
         default:
+#ifdef DEBUG
             intf_ErrMsg( "error: unknown subpicture %p type %d",
                          p_subpic, p_subpic->i_type );
 #endif
+            break;
         }
 
         p_subpic = p_subpic->p_next;