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