* modules/codec/ffmpeg/*: modified the ffmpeg video codec to use direct
[vlc.git] / modules / gui / beos / VlcWrapper.cpp
1 /*****************************************************************************
2  * intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: VlcWrapper.cpp,v 1.10 2002/10/30 06:12:27 titer Exp $
6  *
7  * Authors: Florian G. Pflug <fgp@phlo.org>
8  *          Jon Lech Johansen <jon-vl@nanocrew.net>
9  *          Tony Casltey <tony@castley.net>
10  *          Stephan Aßmus <stippi@yellowbites.com>
11  *          Eric Petit <titer@videolan.org>
12  *
13  * This program is free software{} you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation{} either version 2 of the License, or
16  * (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY{} without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program{} if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
26  *****************************************************************************/
27 /* VLC headers */
28 #include <SupportKit.h>
29
30 #include <vlc/vlc.h>
31 #include <vlc/intf.h>
32 #include <audio_output.h>
33 #include <aout_internal.h>
34
35 #include "VlcWrapper.h"
36
37 Intf_VLCWrapper::Intf_VLCWrapper(intf_thread_t *p_interface)
38 {
39     p_intf = p_interface;
40 }
41
42 Intf_VLCWrapper::~Intf_VLCWrapper()
43 {
44 }
45     
46 /* playlist control */
47 bool Intf_VLCWrapper::playlistPlay()
48 {
49     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
50
51     vlc_mutex_lock( &p_playlist->object_lock );
52     if( p_playlist->i_size )
53     {
54         vlc_mutex_unlock( &p_playlist->object_lock );
55         playlist_Play( p_playlist );
56     }
57     else
58     {
59         vlc_mutex_unlock( &p_playlist->object_lock );
60     }
61
62     return( true );
63 }
64
65 void Intf_VLCWrapper::playlistPause()
66 {
67     toggle_mute();
68     if( p_intf->p_sys->p_input )
69     {
70         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
71     }
72 }
73
74 void Intf_VLCWrapper::playlistStop()
75 {
76     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
77
78     playlist_Stop( p_playlist );
79 }
80
81 void Intf_VLCWrapper::playlistNext()
82 {
83     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
84
85     playlist_Next( p_playlist );
86 }
87
88 void Intf_VLCWrapper::playlistPrev()
89 {
90     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
91
92     playlist_Prev( p_playlist );
93 }
94
95 void Intf_VLCWrapper::playlistSkip(int i)
96 {
97     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
98
99     playlist_Skip( p_playlist, i );
100 }
101
102 void Intf_VLCWrapper::playlistGoto(int i)
103 {
104     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
105
106     playlist_Goto( p_playlist, i );
107 }
108
109 void Intf_VLCWrapper::playlistJumpTo( int pos )
110 {
111 #if 0
112         // sanity checks
113         if ( pos < 0 )
114                 pos = 0;
115         int size = playlistSize();
116         if (pos >= size)
117                 pos = size - 1;
118         // weird hack
119     if( p_input_bank->pp_input[0] != NULL )
120                 pos--;
121         // stop current stream
122         playlistStop();
123         // modify current position in playlist
124         playlistLock();
125         p_main->p_playlist->i_index = pos;
126         playlistUnlock();
127         // start playing
128         playlistPlay();
129 #endif
130 }
131
132 int Intf_VLCWrapper::playlistCurrentPos()
133 {
134         playlistLock();
135         int pos = p_intf->p_sys->p_playlist->i_index;
136         playlistUnlock();
137         return pos;
138 }
139
140 int Intf_VLCWrapper::playlistSize()
141 {
142         playlistLock();
143         int size = p_intf->p_sys->p_playlist->i_size;
144         playlistUnlock();
145         return size;
146 }
147
148 void Intf_VLCWrapper::playlistLock()
149 {
150         vlc_mutex_lock( &p_intf->p_sys->p_playlist->object_lock );
151 }
152
153 void Intf_VLCWrapper::playlistUnlock()
154 {
155         vlc_mutex_unlock( &p_intf->p_sys->p_playlist->object_lock );
156 }
157
158 void Intf_VLCWrapper::getNavCapabilities( bool* canSkipPrev,
159                                                                                   bool* canSkipNext )
160 {
161         if ( canSkipPrev && canSkipNext )
162         {
163                 // init the parameters
164                 *canSkipPrev = false;
165                 *canSkipNext = false;
166                 // get playlist info
167                 playlistLock();
168                 int pos = p_intf->p_sys->p_playlist->i_index;
169                 int size = p_intf->p_sys->p_playlist->i_size;
170                 playlistUnlock();
171
172                 /* input_thread_t* input = p_input_bank->pp_input[0]; */
173                 input_thread_t* input = p_intf->p_sys->p_input;
174                 // see if we have got a stream going            
175                 if ( input )
176                 {
177                         vlc_mutex_lock( &input->stream.stream_lock );
178
179                         bool hasTitles = input->stream.i_area_nb > 1;
180                         int numChapters = input->stream.p_selected_area->i_part_nb;
181                         bool hasChapters = numChapters > 1;
182                         // first, look for chapters
183                         if ( hasChapters )
184                         {
185                                 *canSkipPrev = input->stream.p_selected_area->i_part > 0;
186                                 *canSkipNext = input->stream.p_selected_area->i_part <
187                                                                          input->stream.p_selected_area->i_part_nb - 1;
188                         }
189                         // if one of the skip capabilities is false,
190                         // make it depend on titles instead
191                         if ( !*canSkipPrev && hasTitles )
192                                 *canSkipPrev = input->stream.p_selected_area->i_id > 1;
193                         if ( !*canSkipNext && hasTitles )
194                                 *canSkipNext = input->stream.p_selected_area->i_id < input->stream.i_area_nb - 1;
195
196                         vlc_mutex_unlock( &input->stream.stream_lock );
197                 }
198                 // last but not least, make capabilities depend on playlist
199                 if ( !*canSkipPrev )
200                         *canSkipPrev = pos > 0;
201                 if ( !*canSkipNext )
202                         *canSkipNext = pos < size - 1;
203         }
204 }
205
206 void Intf_VLCWrapper::navigatePrev()
207 {
208 #if 0
209         bool hasSkiped = false;
210
211         input_thread_t* input = p_input_bank->pp_input[0];
212         // see if we have got a stream going            
213         if ( input )
214         {
215                 // get information from stream (lock it while looking at it)
216                 vlc_mutex_lock( &input->stream.stream_lock );
217
218                 int currentTitle = input->stream.p_selected_area->i_id;
219                 int currentChapter = input->stream.p_selected_area->i_part;
220                 int numTitles = input->stream.i_area_nb;
221                 bool hasTitles = numTitles > 1;
222                 int numChapters = input->stream.p_selected_area->i_part_nb;
223                 bool hasChapters = numChapters > 1;
224
225                 vlc_mutex_unlock( &input->stream.stream_lock );
226
227                 // first, look for chapters
228                 if ( hasChapters )
229                 {
230                         // skip to the previous chapter
231                         currentChapter--;
232
233                         if ( currentChapter >= 0 )
234                         {
235                                 toggleChapter( currentChapter );
236                                 hasSkiped = true;
237                         }
238                 }
239                 // if we couldn't skip chapters, try titles instead
240                 if ( !hasSkiped && hasTitles )
241                 {
242                         // skip to the previous title
243                         currentTitle--;
244                         // disallow area 0 since it is used for video_ts.vob
245                         if( currentTitle > 0 )
246                         {
247                                 toggleTitle(currentTitle);
248                                 hasSkiped = true;
249                         }
250                 }
251
252         }
253         // last but not least, skip to previous file
254         if ( !hasSkiped )
255                 playlistPrev();
256 #endif
257 }
258
259 void Intf_VLCWrapper::navigateNext()
260 {
261 #if 0
262         bool hasSkiped = false;
263
264         input_thread_t* input = p_input_bank->pp_input[0];
265         // see if we have got a stream going            
266         if ( input )
267         {
268                 // get information from stream (lock it while looking at it)
269                 vlc_mutex_lock( &input->stream.stream_lock );
270
271                 int currentTitle = input->stream.p_selected_area->i_id;
272                 int currentChapter = input->stream.p_selected_area->i_part;
273                 int numTitles = input->stream.i_area_nb;
274                 bool hasTitles = numTitles > 1;
275                 int numChapters = input->stream.p_selected_area->i_part_nb;
276                 bool hasChapters = numChapters > 1;
277
278                 vlc_mutex_unlock( &input->stream.stream_lock );
279
280                 // first, look for chapters
281                 if ( hasChapters )
282                 {
283                         // skip to the next chapter
284                         currentChapter++;
285                         if ( currentChapter < numChapters )
286                         {
287                                 toggleChapter( currentChapter );
288                                 hasSkiped = true;
289                         }
290                 }
291                 // if we couldn't skip chapters, try titles instead
292                 if ( !hasSkiped && hasTitles )
293                 {
294                         // skip to the next title
295                         currentTitle++;
296                         // disallow area 0 since it is used for video_ts.vob
297                         if ( currentTitle < numTitles - 1 )
298                         {
299                                 toggleTitle(currentTitle);
300                                 hasSkiped = true;
301                         }
302                 }
303
304         }
305         // last but not least, skip to next file
306         if ( !hasSkiped )
307                 playlistNext();
308 #endif
309 }
310
311
312 //void Intf_VLCWrapper::channelNext()
313 //{
314 //    intf_thread_t * p_intf = p_main->p_intf;
315 //
316 //    p_intf->p_sys->i_channel++;
317 //
318 //    intf_WarnMsg( 3, "intf info: joining channel %d", p_intf->p_sys->i_channel );
319 //
320 //    vlc_mutex_lock( &p_intf->change_lock );
321 //
322 //    network_ChannelJoin( p_intf->p_sys->i_channel );
323 //    p_intf->pf_manage( p_intf );
324 //
325 //    vlc_mutex_unlock( &p_intf->change_lock );
326 //}
327 //
328 //void Intf_VLCWrapper::channelPrev()
329 //{
330 //    intf_thread_t * p_intf = p_main->p_intf;
331 //
332 //    if ( p_intf->p_sys->i_channel )
333 //    {
334 //        p_intf->p_sys->i_channel--;
335 //    }
336 //
337 //    intf_WarnMsg( 3, "intf info: joining channel %d", p_intf->p_sys->i_channel );
338 //
339 //    vlc_mutex_lock( &p_intf->change_lock );
340 //
341 //    network_ChannelJoin( p_intf->p_sys->i_channel );
342 //    p_intf->pf_manage( p_intf );
343 //
344 //    vlc_mutex_unlock( &p_intf->change_lock );
345 //
346 //}
347
348 void Intf_VLCWrapper::loop()
349 {
350     if ( p_intf->p_sys->b_loop )
351     {
352         playlist_Delete( p_intf->p_sys->p_playlist,
353                          p_intf->p_sys->p_playlist->i_size - 1 );
354     }
355     else
356     {
357         playlist_Add( p_intf->p_sys->p_playlist, "vlc:loop",
358                       PLAYLIST_APPEND | PLAYLIST_GO,
359                       PLAYLIST_END );
360     }
361     p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
362 }
363
364
365     /* playback control */
366 void Intf_VLCWrapper::playSlower()
367 {
368     if( p_intf->p_sys->p_input != NULL )
369     {
370         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
371     }
372     if (p_intf->p_sys->p_input->stream.control.i_rate == DEFAULT_RATE)
373     {
374         toggle_mute(  );
375     }
376     else
377     {
378         toggle_mute ( );
379     }
380 }
381
382 void Intf_VLCWrapper::playFaster()
383 {
384     if( p_intf->p_sys->p_input != NULL )
385     {
386         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
387     }
388     if (p_intf->p_sys->p_input->stream.control.i_rate == DEFAULT_RATE)
389     {
390         toggle_mute(  );
391     }
392     else
393     {
394         toggle_mute ( );
395     }
396 }
397
398 void Intf_VLCWrapper::volume_mute()
399 {
400     if( p_intf->p_sys->p_aout != NULL )
401     {
402             if( !p_intf->p_sys->b_mute )
403                 {
404                     p_intf->p_sys->i_saved_volume = p_intf->p_sys->p_aout->output.i_volume;
405                     p_intf->p_sys->p_aout->output.i_volume = 0;
406                     p_intf->p_sys->b_mute = 1;
407                 }
408     }
409
410 }
411
412 void Intf_VLCWrapper::volume_restore()
413 {
414     if( p_intf->p_sys->p_aout != NULL )
415     {
416             p_intf->p_sys->p_aout->output.i_volume = p_intf->p_sys->i_saved_volume;
417                 p_intf->p_sys->i_saved_volume = 0;
418             p_intf->p_sys->b_mute = 0;
419     }
420
421 }
422
423 void Intf_VLCWrapper::set_volume(int value)
424 {
425     if( p_intf->p_sys->p_aout != NULL )
426     {
427                 // make sure value is within bounds
428                 if (value < 0)
429                         value = 0;
430                 if (value > AOUT_VOLUME_MAX)
431                         value = AOUT_VOLUME_MAX;
432                 vlc_mutex_lock( &p_intf->p_sys->p_aout->mixer_lock );
433                 // unmute volume if muted
434                 if ( p_intf->p_sys->b_mute )
435                 {
436                         p_intf->p_sys->b_mute = 0;
437             p_intf->p_sys->p_aout->output.i_volume = value;
438                 }
439                 vlc_mutex_unlock( &p_intf->p_sys->p_aout->mixer_lock );
440     }
441 }
442
443 void Intf_VLCWrapper::toggle_mute()
444 {
445     if( p_intf->p_sys->p_aout != NULL )
446         {
447             if ( p_intf->p_sys->b_mute )
448             {
449                 volume_restore();
450             }
451             else
452             {
453                 volume_mute();
454             }
455         }
456 }
457
458 bool Intf_VLCWrapper::is_muted()
459 {
460         bool muted = true;
461         
462     if( p_intf->p_sys->p_aout != NULL )
463         {
464                 vlc_mutex_lock( &p_intf->p_sys->p_aout->mixer_lock );
465                 if( p_intf->p_sys->p_aout->output.i_volume > 0 )
466                 {
467                         muted = false;
468                 }
469                 vlc_mutex_unlock( &p_intf->p_sys->p_aout->mixer_lock );
470 // unfortunately, this is not reliable!
471 //              return p_main->p_intf->p_sys->b_mute;
472         }
473         return muted;
474 }
475
476 bool Intf_VLCWrapper::is_playing()
477 {
478
479         bool playing = false;
480         if ( p_intf->p_sys->p_input )
481         {
482                 switch ( p_intf->p_sys->p_input->stream.control.i_status )
483                 {
484                         case PLAYING_S:
485                         case FORWARD_S:
486                         case BACKWARD_S:
487                         case START_S:
488                                 playing = true;
489                     break;
490                         case PAUSE_S:
491                         case UNDEF_S:
492                         case NOT_STARTED_S:
493                         default:
494                                 break;
495                 }
496         }
497         return playing;
498
499 }
500
501 void Intf_VLCWrapper::maxvolume()
502 {
503     if( p_intf->p_sys->p_aout != NULL )
504     {
505             if( p_intf->p_sys->b_mute )
506             {
507                 p_intf->p_sys->i_saved_volume = AOUT_VOLUME_MAX;
508             }
509             else
510             {
511                 p_intf->p_sys->p_aout->output.i_volume = AOUT_VOLUME_MAX;
512             }
513     }
514 }
515
516 bool Intf_VLCWrapper::has_audio()
517 {
518     return( p_intf->p_sys->p_aout != NULL );
519 }
520
521     /* playback info */
522
523 const char*  Intf_VLCWrapper::getTimeAsString()
524 {
525     static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
526         
527     if( p_intf->p_sys->p_input == NULL )
528     {
529         return ("-:--:--");
530     }     
531    
532     input_OffsetToTime( p_intf->p_sys->p_input, 
533                         psz_currenttime, 
534                         p_intf->p_sys->p_input->stream.p_selected_area->i_tell );        
535
536     return(psz_currenttime);
537 }
538
539 float  Intf_VLCWrapper::getTimeAsFloat()
540 {
541     float f_time = 0.0;
542
543     if( p_intf->p_sys->p_input != NULL )
544     {
545         f_time = (float)p_intf->p_sys->p_input->stream.p_selected_area->i_tell / 
546                  (float)p_intf->p_sys->p_input->stream.p_selected_area->i_size;
547     }    
548     else
549     {
550         f_time = 0.0;
551     }
552     return( f_time );
553 }
554
555 void   Intf_VLCWrapper::setTimeAsFloat(float f_position)
556 {
557     if( p_intf->p_sys->p_input != NULL )
558     {
559         input_Seek( p_intf->p_sys->p_input, 
560                    (long long int)(p_intf->p_sys->p_input->stream.p_selected_area->i_size
561                        * f_position / SEEKSLIDER_RANGE ), 
562                    INPUT_SEEK_SET);
563     }
564 }
565
566 /* bool   Intf_VLCWrapper::playlistPlaying()
567
568     return( !p_intf->p_sys->p_playlist->b_stopped );
569 } */
570
571 BList  *Intf_VLCWrapper::playlistAsArray()
572
573     int i;
574     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
575
576     BList* p_list = new BList(p_playlist->i_size);
577     
578     vlc_mutex_lock( &p_playlist->object_lock );
579
580     for( i = 0; i < p_playlist->i_size; i++ )
581     {
582         p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
583     }
584
585     vlc_mutex_unlock( &p_playlist->object_lock );
586     return( p_list );
587 }
588
589 // getPlaylistInfo
590 void
591 Intf_VLCWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
592 {
593         currentIndex = -1;
594         maxIndex = -1;
595         if ( playlist_t* list = (playlist_t*)p_intf->p_sys->p_playlist )
596         {
597                 maxIndex = list->i_size;
598                 if ( maxIndex > 0 )
599                         currentIndex = list->i_index + 1;
600                 else
601                         maxIndex = -1;
602         }
603 }
604
605 // getTitleInfo
606 void  
607 Intf_VLCWrapper::getTitleInfo( int32& currentIndex, int32& maxIndex )
608 {
609         currentIndex = -1;
610         maxIndex = -1;
611         if ( input_thread_t* input = p_intf->p_sys->p_input )
612         {
613                 vlc_mutex_lock( &input->stream.stream_lock );
614
615                 maxIndex = input->stream.i_area_nb - 1;
616                 if ( maxIndex > 0)
617                         currentIndex = input->stream.p_selected_area->i_id;
618                 else
619                         maxIndex = -1;
620
621                 vlc_mutex_unlock( &input->stream.stream_lock );
622         }
623 }
624
625 // getChapterInfo
626 void
627 Intf_VLCWrapper::getChapterInfo( int32& currentIndex, int32& maxIndex )
628 {
629         currentIndex = -1;
630         maxIndex = -1;
631         if ( input_thread_t* input = p_intf->p_sys->p_input )
632         {
633                 vlc_mutex_lock( &input->stream.stream_lock );
634
635                 maxIndex = input->stream.p_selected_area->i_part_nb - 1;
636                 if ( maxIndex > 0)
637                         currentIndex = input->stream.p_selected_area->i_part;
638                 else
639                         maxIndex = -1;
640
641                 vlc_mutex_unlock( &input->stream.stream_lock );
642         }
643 }
644
645     /* open file/disc/network */
646 void Intf_VLCWrapper::openFiles( BList* o_files, bool replace )
647 {
648     BString *o_file;
649     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
650
651     while( ( o_file = (BString *)o_files->LastItem() ) )
652     {
653         o_files->RemoveItem(o_files->CountItems() - 1);
654         playlist_Add( p_playlist, o_file->String(),
655                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
656         delete o_file;
657     }
658 }
659
660 void Intf_VLCWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
661 {
662     BString o_source("");
663     o_source << o_type << ":" << o_device ;
664
665     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
666     playlist_Add( p_playlist, o_source.String(),
667                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
668 }
669
670 void Intf_VLCWrapper::openNet(BString o_addr, int i_port)
671 {
672 }
673
674 void Intf_VLCWrapper::openNetChannel(BString o_addr, int i_port)
675 {
676 }
677
678 void Intf_VLCWrapper::openNetHTTP(BString o_addr)
679 {
680 }
681
682
683     /* menus management */
684 void Intf_VLCWrapper::toggleProgram(int i_program){}
685
686 void Intf_VLCWrapper::toggleTitle(int i_title)
687 {
688     if( p_intf->p_sys->p_input != NULL )
689     {
690         input_ChangeArea( p_intf->p_sys->p_input,
691                           p_intf->p_sys->p_input->stream.pp_areas[i_title] );
692
693         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
694
695         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
696     }
697 }
698
699 void Intf_VLCWrapper::toggleChapter(int i_chapter)
700 {
701     if( p_intf->p_sys->p_input != NULL )
702     {
703         p_intf->p_sys->p_input->stream.p_selected_area->i_part = i_chapter;
704         input_ChangeArea( p_intf->p_sys->p_input,
705                           p_intf->p_sys->p_input->stream.p_selected_area );
706
707         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
708         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
709     }
710 }
711
712 void Intf_VLCWrapper::toggleLanguage(int i_language)
713 {
714
715     int32 i_old = -1;
716     int i_cat = AUDIO_ES;
717
718     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
719     for( int i = 0; i < p_intf->p_sys->p_input->stream.i_selected_es_number ; i++ )
720     {
721         if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == i_cat )
722         {
723             i_old = i;
724             break;
725         }
726     }
727     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
728
729     msg_Info( p_intf, "Old: %d,  New: %d", i_old, i_language);
730     if( i_language != -1 )
731     {
732         input_ToggleES( p_intf->p_sys->p_input, 
733                         p_intf->p_sys->p_input->stream.pp_selected_es[i_language],
734                         VLC_TRUE );
735     }
736
737     if( (i_old != -1) && (i_old != i_language) )
738     {
739         input_ToggleES( p_intf->p_sys->p_input, 
740                         p_intf->p_sys->p_input->stream.pp_selected_es[i_old],
741                         VLC_FALSE );
742     }
743 }
744
745 void Intf_VLCWrapper::toggleSubtitle(int i_subtitle)
746 {
747     int32 i_old = -1;
748     int i_cat = SPU_ES;
749
750     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
751     for( int i = 0; i < p_intf->p_sys->p_input->stream.i_selected_es_number ; i++ )
752     {
753         if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == i_cat )
754         {
755             i_old = i;
756             break;
757         }
758     }
759     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
760     
761     msg_Info( p_intf, "Old: %d,  New: %d", i_old, i_subtitle);
762     if( i_subtitle != -1 )
763     {
764         input_ToggleES( p_intf->p_sys->p_input, 
765                         p_intf->p_sys->p_input->stream.pp_selected_es[i_subtitle],
766                         VLC_TRUE );
767     }
768
769     if( (i_old != -1) && (i_old != i_subtitle) )
770     {
771         input_ToggleES( p_intf->p_sys->p_input, 
772                         p_intf->p_sys->p_input->stream.pp_selected_es[i_old],
773                         VLC_FALSE );
774     }
775 }
776
777 int  Intf_VLCWrapper::inputGetStatus()
778 {
779     return p_intf->p_sys->p_playlist->i_status;
780 }