]> git.sesse.net Git - vlc/blob - modules/gui/beos/VlcWrapper.cpp
ff49421ce03f7e108c6ea7e8dded92bee29227cd
[vlc] / modules / gui / beos / VlcWrapper.cpp
1 /*****************************************************************************
2  * VlcWrapper.cpp: BeOS plugin for vlc (derived from MacOS X port)
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: VlcWrapper.cpp,v 1.15 2003/01/08 02:09:15 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 #include <AppKit.h>
28 #include <InterfaceKit.h>
29 #include <SupportKit.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/intf.h>
33 extern "C" {
34 #include <audio_output.h>
35 #include <aout_internal.h>
36 }
37
38 #include "VlcWrapper.h"
39 #include "MsgVals.h"
40
41 /* constructor */
42 VlcWrapper::VlcWrapper( intf_thread_t *p_interface )
43 {
44     p_intf = p_interface;
45     p_input = NULL;
46     p_aout = NULL;
47     p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
48                                                 FIND_ANYWHERE );
49 }
50
51 /* destructor */
52 VlcWrapper::~VlcWrapper()
53 {
54     if( p_input )
55     {
56         vlc_object_release( p_input );
57     }
58     if( p_playlist )
59     {
60         vlc_object_release( p_playlist );
61     }
62     if( p_aout )
63     {
64         vlc_object_release( p_aout );
65     }
66 }
67
68 /* UpdateInputAndAOut: updates p_input and p_aout, returns true if the
69    interface needs to be updated */
70 bool VlcWrapper::UpdateInputAndAOut()
71 {
72     if( p_input == NULL )
73     {
74         p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
75                                                      FIND_ANYWHERE );
76     }
77     if( p_aout == NULL )
78     {
79         p_aout = (aout_instance_t*)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
80                                                     FIND_ANYWHERE );
81     }
82         
83     if( p_input != NULL )
84     {
85         if( p_input->b_dead )
86         {
87             vlc_object_release( p_input );
88             p_input = NULL;
89             
90             if( p_aout )
91             {
92                 vlc_object_release( p_aout );
93                 p_aout = NULL;
94             }
95         }
96         return true;
97     }
98     return false;
99 }
100
101
102 /***************************
103  * input infos and control *
104  ***************************/
105
106 bool VlcWrapper::HasInput()
107 {
108     return( p_input != NULL );
109 }
110
111 /* status (UNDEF_S, PLAYING_S, PAUSE_S, FORWARD_S, BACKWARD_S,
112    REWIND_S, NOT_STARTED_S, START_S) */
113 int VlcWrapper::InputStatus()
114 {
115     if( !p_input )
116     {
117         return UNDEF_S;
118     }
119     return p_input->stream.control.i_status;
120 }
121
122 int VlcWrapper::InputRate()
123 {
124     if( !p_input )
125     {
126         return DEFAULT_RATE;
127     }
128     return p_input->stream.control.i_rate;
129 }
130
131 /* tell: location in the current stream (in arbitrary units) */
132 int VlcWrapper::InputTell()
133 {
134     if( !p_input )
135     {
136         return -1;
137     }
138     return p_input->stream.p_selected_area->i_tell;
139 }
140
141 /* size: total size of the current stream (in arbitrary units) */
142 int VlcWrapper::InputSize()
143 {
144     if( !p_input )
145     {
146         return -1;
147     }
148     return p_input->stream.p_selected_area->i_size;
149 }
150
151 void VlcWrapper::InputSlower()
152 {
153     if( p_input != NULL )
154     {
155         input_SetStatus( p_input, INPUT_STATUS_SLOWER );
156     }
157 }
158
159 void VlcWrapper::InputFaster()
160 {
161     if( p_input != NULL )
162     {
163         input_SetStatus( p_input, INPUT_STATUS_FASTER );
164     }
165 }
166
167 BList * VlcWrapper::InputGetChannels( int i_cat )
168 {
169     if( p_input )
170     {
171         unsigned int i;
172         uint32 what;
173         const char* fieldName;
174
175         switch( i_cat )
176         {
177             case AUDIO_ES:
178             {
179                 what = SELECT_CHANNEL;
180                 fieldName = "channel";
181                 break;
182             }
183             case SPU_ES:
184             {
185                 what = SELECT_SUBTITLE;
186                 fieldName = "subtitle";
187                 break;
188             }
189             default:
190             return NULL;
191        }
192
193         vlc_mutex_lock( &p_input->stream.stream_lock );
194       
195         /* find which track is currently playing */
196         es_descriptor_t *p_es = NULL;
197         for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
198         {
199             if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
200                 p_es = p_input->stream.pp_selected_es[i];
201         }
202         
203         /* build a list of all tracks */
204         BList *list = new BList( p_input->stream.i_es_number );
205         BMenuItem *menuItem;
206         BMessage *message;
207         char *trackName;
208         
209         /* "None" */
210         message = new BMessage( what );
211         message->AddInt32( fieldName, -1 );
212         menuItem = new BMenuItem( "None", message );
213         if( !p_es )
214             menuItem->SetMarked( true );
215         list->AddItem( menuItem );
216         
217         for( i = 0; i < p_input->stream.i_es_number; i++ )
218         {
219             if( p_input->stream.pp_es[i]->i_cat == i_cat )
220             {
221                 message = new BMessage( what );
222                 message->AddInt32( fieldName, i );
223                 if( strlen( p_input->stream.pp_es[i]->psz_desc ) )
224                     trackName = strdup( p_input->stream.pp_es[i]->psz_desc );
225                 else
226                     trackName = "<unknown>";
227                 menuItem = new BMenuItem( trackName, message );
228                 if( p_input->stream.pp_es[i] == p_es )
229                     menuItem->SetMarked( true );
230                 list->AddItem( menuItem );
231             }
232         }
233         
234         vlc_mutex_unlock( &p_input->stream.stream_lock );
235
236         return list;
237     }
238     return NULL;
239 }
240
241 void VlcWrapper::openFiles( BList* o_files, bool replace )
242 {
243     BString *o_file;
244
245     while( ( o_file = (BString *)o_files->LastItem() ) )
246     {
247         o_files->RemoveItem(o_files->CountItems() - 1);
248         playlist_Add( p_playlist, o_file->String(),
249                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
250         delete o_file;
251     }
252 }
253
254 void VlcWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
255 {
256     BString o_source("");
257     o_source << o_type << ":" << o_device ;
258
259     playlist_Add( p_playlist, o_source.String(),
260                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
261 }
262
263
264
265 void VlcWrapper::ToggleLanguage( int i_language )
266 {
267     es_descriptor_t * p_es = NULL;
268     es_descriptor_t * p_es_old = NULL;
269
270     vlc_mutex_lock( &p_input->stream.stream_lock );
271     for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
272     {
273         if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
274         {
275             p_es_old = p_input->stream.pp_selected_es[i];
276             break;
277         }
278     }
279     vlc_mutex_unlock( &p_input->stream.stream_lock );
280     
281     if( i_language != -1 )
282     {
283         p_es = p_input->stream.pp_es[i_language];
284     }
285     if( p_es == p_es_old )
286     {
287         return;
288     }
289     if( p_es_old )
290     {
291         input_ToggleES( p_input, p_es_old, VLC_FALSE );
292     }
293     if( p_es )
294     {
295         input_ToggleES( p_input, p_es, VLC_TRUE );
296     }
297 }
298
299 void VlcWrapper::ToggleSubtitle( int i_subtitle )
300 {
301     es_descriptor_t * p_es = NULL;
302     es_descriptor_t * p_es_old = NULL;
303
304     vlc_mutex_lock( &p_input->stream.stream_lock );
305     for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
306     {
307         if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
308         {
309             p_es_old = p_input->stream.pp_selected_es[i];
310             break;
311         }
312     }
313     vlc_mutex_unlock( &p_input->stream.stream_lock );
314     
315     if( i_subtitle != -1 )
316     {
317         p_es = p_input->stream.pp_es[i_subtitle];
318     }
319     if( p_es == p_es_old )
320     {
321         return;
322     }
323     if( p_es_old )
324     {
325         input_ToggleES( p_input, p_es_old, VLC_FALSE );
326     }
327     if( p_es )
328     {
329         input_ToggleES( p_input, p_es, VLC_TRUE );
330     }
331 }
332
333 const char*  VlcWrapper::getTimeAsString()
334 {
335     static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
336         
337     if( p_input == NULL )
338     {
339         return ("-:--:--");
340     }     
341    
342     input_OffsetToTime( p_input, 
343                         psz_currenttime, 
344                         p_input->stream.p_selected_area->i_tell );        
345
346     return(psz_currenttime);
347 }
348
349 float  VlcWrapper::getTimeAsFloat()
350 {
351     float f_time = 0.0;
352
353     if( p_input != NULL )
354     {
355         f_time = (float)p_input->stream.p_selected_area->i_tell / 
356                  (float)p_input->stream.p_selected_area->i_size;
357     }    
358     else
359     {
360         f_time = 0.0;
361     }
362     return( f_time );
363 }
364
365 void VlcWrapper::setTimeAsFloat(float f_position)
366 {
367     if( p_input != NULL )
368     {
369         input_Seek( p_input, 
370                    (long long int)(p_input->stream.p_selected_area->i_size
371                        * f_position / SEEKSLIDER_RANGE ), 
372                    INPUT_SEEK_SET);
373     }
374 }
375
376 bool VlcWrapper::IsPlaying()
377 {
378
379         bool playing = false;
380         if ( p_input )
381         {
382                 switch ( p_input->stream.control.i_status )
383                 {
384                         case PLAYING_S:
385                         case FORWARD_S:
386                         case BACKWARD_S:
387                         case START_S:
388                                 playing = true;
389                     break;
390                         case PAUSE_S:
391                         case UNDEF_S:
392                         case NOT_STARTED_S:
393                         default:
394                                 break;
395                 }
396         }
397         return playing;
398
399 }
400
401 /******************************
402  * playlist infos and control *
403  ******************************/
404 int VlcWrapper::PlaylistSize()
405 {
406     vlc_mutex_lock( &p_playlist->object_lock );
407     int i_size = p_playlist->i_size;
408     vlc_mutex_unlock( &p_playlist->object_lock );
409     return i_size;
410 }
411
412 char *VlcWrapper::PlaylistItemName( int i )
413 {
414    return p_playlist->pp_items[i]->psz_name;
415 }
416
417 int VlcWrapper::PlaylistCurrent()
418 {
419     return p_playlist->i_index;
420 }
421
422 int  VlcWrapper::PlaylistStatus()
423 {
424     return p_playlist->i_status;
425 }
426
427 bool VlcWrapper::PlaylistPlay()
428 {
429     if( PlaylistSize() )
430     {
431         playlist_Play( p_playlist );
432     }
433     return( true );
434 }
435
436 void VlcWrapper::PlaylistPause()
437 {
438     if( p_input )
439     {
440         input_SetStatus( p_input, INPUT_STATUS_PAUSE );
441     }
442 }
443
444 void VlcWrapper::PlaylistStop()
445 {
446     playlist_Stop( p_playlist );
447 }
448
449 void VlcWrapper::PlaylistNext()
450 {
451     playlist_Next( p_playlist );
452 }
453
454 void VlcWrapper::PlaylistPrev()
455 {
456     playlist_Prev( p_playlist );
457 }
458
459 void VlcWrapper::PlaylistSkip( int i )
460 {
461     playlist_Skip( p_playlist, i );
462 }
463
464 void VlcWrapper::PlaylistGoto( int i )
465 {
466     playlist_Goto( p_playlist, i );
467 }
468
469 void VlcWrapper::PlaylistLoop()
470 {
471     if ( p_intf->p_sys->b_loop )
472     {
473         playlist_Delete( p_playlist, p_playlist->i_size - 1 );
474     }
475     else
476     {
477         playlist_Add( p_playlist, "vlc:loop",
478                       PLAYLIST_APPEND | PLAYLIST_GO,
479                       PLAYLIST_END );
480     }
481     p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
482 }
483
484 BList * VlcWrapper::PlaylistAsArray()
485
486     int i;
487     BList* p_list = new BList(p_playlist->i_size);
488     
489     vlc_mutex_lock( &p_playlist->object_lock );
490
491     for( i = 0; i < p_playlist->i_size; i++ )
492     {
493         p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
494     }
495
496     vlc_mutex_unlock( &p_playlist->object_lock );
497     return( p_list );
498 }
499
500 void VlcWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
501 {
502         currentIndex = -1;
503         maxIndex = -1;
504         if ( p_playlist )
505         {
506                 maxIndex = p_playlist->i_size;
507                 if ( maxIndex > 0 )
508                         currentIndex = p_playlist->i_index + 1;
509                 else
510                         maxIndex = -1;
511         }
512 }
513
514
515 void VlcWrapper::PlaylistJumpTo( int pos )
516 {
517 #if 0
518         // sanity checks
519         if ( pos < 0 )
520                 pos = 0;
521         int size = playlistSize();
522         if (pos >= size)
523                 pos = size - 1;
524         // weird hack
525     if( p_input_bank->pp_input[0] != NULL )
526                 pos--;
527         // stop current stream
528         playlistStop();
529         // modify current position in playlist
530         playlistLock();
531         p_main->p_playlist->i_index = pos;
532         playlistUnlock();
533         // start playing
534         playlistPlay();
535 #endif
536 }
537
538 void VlcWrapper::getNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
539 {
540         if ( canSkipPrev && canSkipNext )
541         {
542                 // init the parameters
543                 *canSkipPrev = false;
544                 *canSkipNext = false;
545                 // get playlist info
546                 int pos = PlaylistCurrent();
547                 int size = PlaylistSize();
548
549                 // see if we have got a stream going            
550                 if ( p_input )
551                 {
552                         vlc_mutex_lock( &p_input->stream.stream_lock );
553
554                         bool hasTitles = p_input->stream.i_area_nb > 1;
555                         int numChapters = p_input->stream.p_selected_area->i_part_nb;
556                         bool hasChapters = numChapters > 1;
557                         // first, look for chapters
558                         if ( hasChapters )
559                         {
560                                 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
561                                 *canSkipNext = p_input->stream.p_selected_area->i_part <
562                                                                          p_input->stream.p_selected_area->i_part_nb - 1;
563                         }
564                         // if one of the skip capabilities is false,
565                         // make it depend on titles instead
566                         if ( !*canSkipPrev && hasTitles )
567                                 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
568                         if ( !*canSkipNext && hasTitles )
569                                 *canSkipNext = p_input->stream.p_selected_area->i_id <
570                                                    p_input->stream.i_area_nb - 1;
571
572                         vlc_mutex_unlock( &p_input->stream.stream_lock );
573                 }
574                 // last but not least, make capabilities depend on playlist
575                 if ( !*canSkipPrev )
576                         *canSkipPrev = pos > 0;
577                 if ( !*canSkipNext )
578                         *canSkipNext = pos < size - 1;
579         }
580 }
581
582 void VlcWrapper::navigatePrev()
583 {
584         bool hasSkiped = false;
585
586         // see if we have got a stream going            
587         if ( p_input )
588         {
589                 // get information from stream (lock it while looking at it)
590                 vlc_mutex_lock( &p_input->stream.stream_lock );
591
592                 int currentTitle = p_input->stream.p_selected_area->i_id;
593                 int currentChapter = p_input->stream.p_selected_area->i_part;
594                 int numTitles = p_input->stream.i_area_nb;
595                 bool hasTitles = numTitles > 1;
596                 int numChapters = p_input->stream.p_selected_area->i_part_nb;
597                 bool hasChapters = numChapters > 1;
598
599                 vlc_mutex_unlock( &p_input->stream.stream_lock );
600
601                 // first, look for chapters
602                 if ( hasChapters )
603                 {
604                         // skip to the previous chapter
605                         currentChapter--;
606
607                         if ( currentChapter >= 0 )
608                         {
609                                 toggleChapter( currentChapter );
610                                 hasSkiped = true;
611                         }
612                 }
613                 // if we couldn't skip chapters, try titles instead
614                 if ( !hasSkiped && hasTitles )
615                 {
616                         // skip to the previous title
617                         currentTitle--;
618                         // disallow area 0 since it is used for video_ts.vob
619                         if( currentTitle > 0 )
620                         {
621                                 toggleTitle(currentTitle);
622                                 hasSkiped = true;
623                         }
624                 }
625
626         }
627         // last but not least, skip to previous file
628         if ( !hasSkiped )
629                 PlaylistPrev();
630 }
631
632 void VlcWrapper::navigateNext()
633 {
634         bool hasSkiped = false;
635
636         // see if we have got a stream going            
637         if ( p_input )
638         {
639                 // get information from stream (lock it while looking at it)
640                 vlc_mutex_lock( &p_input->stream.stream_lock );
641
642                 int currentTitle = p_input->stream.p_selected_area->i_id;
643                 int currentChapter = p_input->stream.p_selected_area->i_part;
644                 int numTitles = p_input->stream.i_area_nb;
645                 bool hasTitles = numTitles > 1;
646                 int numChapters = p_input->stream.p_selected_area->i_part_nb;
647                 bool hasChapters = numChapters > 1;
648
649                 vlc_mutex_unlock( &p_input->stream.stream_lock );
650
651                 // first, look for chapters
652                 if ( hasChapters )
653                 {
654                         // skip to the next chapter
655                         currentChapter++;
656                         if ( currentChapter < numChapters )
657                         {
658                                 toggleChapter( currentChapter );
659                                 hasSkiped = true;
660                         }
661                 }
662                 // if we couldn't skip chapters, try titles instead
663                 if ( !hasSkiped && hasTitles )
664                 {
665                         // skip to the next title
666                         currentTitle++;
667                         // disallow area 0 since it is used for video_ts.vob
668                         if ( currentTitle < numTitles - 1 )
669                         {
670                                 toggleTitle(currentTitle);
671                                 hasSkiped = true;
672                         }
673                 }
674
675         }
676         // last but not least, skip to next file
677         if ( !hasSkiped )
678                 PlaylistNext();
679 }
680
681
682 /***************************
683  * audio infos and control *
684  ***************************/
685
686 unsigned short VlcWrapper::GetVolume()
687 {
688     if( p_aout != NULL )
689     {
690         unsigned short i_volume;
691         aout_VolumeGet( p_aout, (audio_volume_t*)&i_volume );
692         return i_volume;
693     }
694     return 0;
695 }
696
697 void VlcWrapper::SetVolume(int value)
698 {
699     if( p_aout != NULL )
700     {
701                 if ( p_intf->p_sys->b_mute )
702                 {
703                         p_intf->p_sys->b_mute = 0;
704                 }
705         aout_VolumeSet( p_aout, value );
706     }
707 }
708
709 void VlcWrapper::VolumeMute()
710 {
711     if( p_aout != NULL )
712         {
713             aout_VolumeGet( p_aout, &p_intf->p_sys->i_saved_volume );
714             aout_VolumeMute( p_aout, NULL );
715             p_intf->p_sys->b_mute = 1;
716         }
717 }
718
719 void VlcWrapper::VolumeRestore()
720 {
721     if( p_aout != NULL )
722         {
723         aout_VolumeSet( p_aout, p_intf->p_sys->i_saved_volume );
724         p_intf->p_sys->b_mute = 0;
725         }
726 }
727
728 bool VlcWrapper::IsMuted()
729 {
730     return p_intf->p_sys->b_mute;
731 }
732
733 bool VlcWrapper::HasAudio()
734 {
735     return( p_aout != NULL );
736 }
737
738 /*******
739  * DVD *
740  *******/
741 bool VlcWrapper::HasTitles()
742 {
743     if( !p_input )
744     {
745         return false;
746     }
747     return ( p_input->stream.i_area_nb > 1 );
748 }
749
750 void VlcWrapper::PrevTitle()
751 {
752     int i_id;
753     i_id = p_input->stream.p_selected_area->i_id - 1;
754     if( i_id > 0 )
755     {
756         toggleTitle(i_id);
757     }
758 }
759
760 void VlcWrapper::NextTitle()
761 {
762     unsigned int i_id;
763     i_id = p_input->stream.p_selected_area->i_id + 1;
764     if( i_id < p_input->stream.i_area_nb )
765     {
766         toggleTitle(i_id);
767     }
768 }
769
770 bool VlcWrapper::HasChapters()
771 {
772     if( !p_input )
773     {
774         return false;
775     }
776     return ( p_input->stream.p_selected_area->i_part_nb > 1 );
777 }
778
779 void VlcWrapper::PrevChapter()
780 {
781     int i_id;
782     i_id = p_input->stream.p_selected_area->i_part - 1;
783     if( i_id >= 0 )
784     {
785         toggleChapter(i_id);
786     }
787 }
788
789 void VlcWrapper::NextChapter()
790 {
791     int i_id;
792     i_id = p_input->stream.p_selected_area->i_part + 1;
793     if( i_id >= 0 )
794     {
795         toggleChapter(i_id);
796     }
797 }
798
799 void VlcWrapper::TitleInfo( int32 &currentIndex, int32 &maxIndex )
800 {
801         currentIndex = -1;
802         maxIndex = -1;
803         if ( p_input )
804         {
805                 vlc_mutex_lock( &p_input->stream.stream_lock );
806
807                 maxIndex = p_input->stream.i_area_nb - 1;
808                 if ( maxIndex > 0)
809                         currentIndex = p_input->stream.p_selected_area->i_id;
810                 else
811                         maxIndex = -1;
812
813                 vlc_mutex_unlock( &p_input->stream.stream_lock );
814         }
815 }
816
817 void VlcWrapper::ChapterInfo( int32 &currentIndex, int32 &maxIndex )
818 {
819         currentIndex = -1;
820         maxIndex = -1;
821         if ( p_input )
822         {
823                 vlc_mutex_lock( &p_input->stream.stream_lock );
824
825                 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
826                 if ( maxIndex > 0)
827                         currentIndex = p_input->stream.p_selected_area->i_part;
828                 else
829                         maxIndex = -1;
830
831                 vlc_mutex_unlock( &p_input->stream.stream_lock );
832         }
833 }
834
835 void VlcWrapper::toggleTitle(int i_title)
836 {
837     if( p_input != NULL )
838     {
839         input_ChangeArea( p_input,
840                           p_input->stream.pp_areas[i_title] );
841
842         vlc_mutex_lock( &p_input->stream.stream_lock );
843
844         vlc_mutex_unlock( &p_input->stream.stream_lock );
845     }
846 }
847
848 void VlcWrapper::toggleChapter(int i_chapter)
849 {
850     if( p_input != NULL )
851     {
852         p_input->stream.p_selected_area->i_part = i_chapter;
853         input_ChangeArea( p_input,
854                           p_input->stream.p_selected_area );
855
856         vlc_mutex_lock( &p_input->stream.stream_lock );
857         vlc_mutex_unlock( &p_input->stream.stream_lock );
858     }
859 }