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 $
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>
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.
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.
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 *****************************************************************************/
28 #include <InterfaceKit.h>
29 #include <SupportKit.h>
34 #include <audio_output.h>
35 #include <aout_internal.h>
38 #include "VlcWrapper.h"
42 VlcWrapper::VlcWrapper( intf_thread_t *p_interface )
47 p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
52 VlcWrapper::~VlcWrapper()
56 vlc_object_release( p_input );
60 vlc_object_release( p_playlist );
64 vlc_object_release( p_aout );
68 /* UpdateInputAndAOut: updates p_input and p_aout, returns true if the
69 interface needs to be updated */
70 bool VlcWrapper::UpdateInputAndAOut()
74 p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
79 p_aout = (aout_instance_t*)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
87 vlc_object_release( p_input );
92 vlc_object_release( p_aout );
102 /***************************
103 * input infos and control *
104 ***************************/
106 bool VlcWrapper::HasInput()
108 return( p_input != NULL );
111 /* status (UNDEF_S, PLAYING_S, PAUSE_S, FORWARD_S, BACKWARD_S,
112 REWIND_S, NOT_STARTED_S, START_S) */
113 int VlcWrapper::InputStatus()
119 return p_input->stream.control.i_status;
122 int VlcWrapper::InputRate()
128 return p_input->stream.control.i_rate;
131 /* tell: location in the current stream (in arbitrary units) */
132 int VlcWrapper::InputTell()
138 return p_input->stream.p_selected_area->i_tell;
141 /* size: total size of the current stream (in arbitrary units) */
142 int VlcWrapper::InputSize()
148 return p_input->stream.p_selected_area->i_size;
151 void VlcWrapper::InputSlower()
153 if( p_input != NULL )
155 input_SetStatus( p_input, INPUT_STATUS_SLOWER );
159 void VlcWrapper::InputFaster()
161 if( p_input != NULL )
163 input_SetStatus( p_input, INPUT_STATUS_FASTER );
167 BList * VlcWrapper::InputGetChannels( int i_cat )
173 const char* fieldName;
179 what = SELECT_CHANNEL;
180 fieldName = "channel";
185 what = SELECT_SUBTITLE;
186 fieldName = "subtitle";
193 vlc_mutex_lock( &p_input->stream.stream_lock );
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++ )
199 if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
200 p_es = p_input->stream.pp_selected_es[i];
203 /* build a list of all tracks */
204 BList *list = new BList( p_input->stream.i_es_number );
210 message = new BMessage( what );
211 message->AddInt32( fieldName, -1 );
212 menuItem = new BMenuItem( "None", message );
214 menuItem->SetMarked( true );
215 list->AddItem( menuItem );
217 for( i = 0; i < p_input->stream.i_es_number; i++ )
219 if( p_input->stream.pp_es[i]->i_cat == i_cat )
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 );
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 );
234 vlc_mutex_unlock( &p_input->stream.stream_lock );
241 void VlcWrapper::openFiles( BList* o_files, bool replace )
245 while( ( o_file = (BString *)o_files->LastItem() ) )
247 o_files->RemoveItem(o_files->CountItems() - 1);
248 playlist_Add( p_playlist, o_file->String(),
249 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
254 void VlcWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
256 BString o_source("");
257 o_source << o_type << ":" << o_device ;
259 playlist_Add( p_playlist, o_source.String(),
260 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
265 void VlcWrapper::ToggleLanguage( int i_language )
267 es_descriptor_t * p_es = NULL;
268 es_descriptor_t * p_es_old = NULL;
270 vlc_mutex_lock( &p_input->stream.stream_lock );
271 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
273 if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
275 p_es_old = p_input->stream.pp_selected_es[i];
279 vlc_mutex_unlock( &p_input->stream.stream_lock );
281 if( i_language != -1 )
283 p_es = p_input->stream.pp_es[i_language];
285 if( p_es == p_es_old )
291 input_ToggleES( p_input, p_es_old, VLC_FALSE );
295 input_ToggleES( p_input, p_es, VLC_TRUE );
299 void VlcWrapper::ToggleSubtitle( int i_subtitle )
301 es_descriptor_t * p_es = NULL;
302 es_descriptor_t * p_es_old = NULL;
304 vlc_mutex_lock( &p_input->stream.stream_lock );
305 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
307 if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
309 p_es_old = p_input->stream.pp_selected_es[i];
313 vlc_mutex_unlock( &p_input->stream.stream_lock );
315 if( i_subtitle != -1 )
317 p_es = p_input->stream.pp_es[i_subtitle];
319 if( p_es == p_es_old )
325 input_ToggleES( p_input, p_es_old, VLC_FALSE );
329 input_ToggleES( p_input, p_es, VLC_TRUE );
333 const char* VlcWrapper::getTimeAsString()
335 static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
337 if( p_input == NULL )
342 input_OffsetToTime( p_input,
344 p_input->stream.p_selected_area->i_tell );
346 return(psz_currenttime);
349 float VlcWrapper::getTimeAsFloat()
353 if( p_input != NULL )
355 f_time = (float)p_input->stream.p_selected_area->i_tell /
356 (float)p_input->stream.p_selected_area->i_size;
365 void VlcWrapper::setTimeAsFloat(float f_position)
367 if( p_input != NULL )
370 (long long int)(p_input->stream.p_selected_area->i_size
371 * f_position / SEEKSLIDER_RANGE ),
376 bool VlcWrapper::IsPlaying()
379 bool playing = false;
382 switch ( p_input->stream.control.i_status )
401 /******************************
402 * playlist infos and control *
403 ******************************/
404 int VlcWrapper::PlaylistSize()
406 vlc_mutex_lock( &p_playlist->object_lock );
407 int i_size = p_playlist->i_size;
408 vlc_mutex_unlock( &p_playlist->object_lock );
412 char *VlcWrapper::PlaylistItemName( int i )
414 return p_playlist->pp_items[i]->psz_name;
417 int VlcWrapper::PlaylistCurrent()
419 return p_playlist->i_index;
422 int VlcWrapper::PlaylistStatus()
424 return p_playlist->i_status;
427 bool VlcWrapper::PlaylistPlay()
431 playlist_Play( p_playlist );
436 void VlcWrapper::PlaylistPause()
440 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
444 void VlcWrapper::PlaylistStop()
446 playlist_Stop( p_playlist );
449 void VlcWrapper::PlaylistNext()
451 playlist_Next( p_playlist );
454 void VlcWrapper::PlaylistPrev()
456 playlist_Prev( p_playlist );
459 void VlcWrapper::PlaylistSkip( int i )
461 playlist_Skip( p_playlist, i );
464 void VlcWrapper::PlaylistGoto( int i )
466 playlist_Goto( p_playlist, i );
469 void VlcWrapper::PlaylistLoop()
471 if ( p_intf->p_sys->b_loop )
473 playlist_Delete( p_playlist, p_playlist->i_size - 1 );
477 playlist_Add( p_playlist, "vlc:loop",
478 PLAYLIST_APPEND | PLAYLIST_GO,
481 p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
484 BList * VlcWrapper::PlaylistAsArray()
487 BList* p_list = new BList(p_playlist->i_size);
489 vlc_mutex_lock( &p_playlist->object_lock );
491 for( i = 0; i < p_playlist->i_size; i++ )
493 p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
496 vlc_mutex_unlock( &p_playlist->object_lock );
500 void VlcWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
506 maxIndex = p_playlist->i_size;
508 currentIndex = p_playlist->i_index + 1;
515 void VlcWrapper::PlaylistJumpTo( int pos )
521 int size = playlistSize();
525 if( p_input_bank->pp_input[0] != NULL )
527 // stop current stream
529 // modify current position in playlist
531 p_main->p_playlist->i_index = pos;
538 void VlcWrapper::getNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
540 if ( canSkipPrev && canSkipNext )
542 // init the parameters
543 *canSkipPrev = false;
544 *canSkipNext = false;
546 int pos = PlaylistCurrent();
547 int size = PlaylistSize();
549 // see if we have got a stream going
552 vlc_mutex_lock( &p_input->stream.stream_lock );
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
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;
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;
572 vlc_mutex_unlock( &p_input->stream.stream_lock );
574 // last but not least, make capabilities depend on playlist
576 *canSkipPrev = pos > 0;
578 *canSkipNext = pos < size - 1;
582 void VlcWrapper::navigatePrev()
584 bool hasSkiped = false;
586 // see if we have got a stream going
589 // get information from stream (lock it while looking at it)
590 vlc_mutex_lock( &p_input->stream.stream_lock );
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;
599 vlc_mutex_unlock( &p_input->stream.stream_lock );
601 // first, look for chapters
604 // skip to the previous chapter
607 if ( currentChapter >= 0 )
609 toggleChapter( currentChapter );
613 // if we couldn't skip chapters, try titles instead
614 if ( !hasSkiped && hasTitles )
616 // skip to the previous title
618 // disallow area 0 since it is used for video_ts.vob
619 if( currentTitle > 0 )
621 toggleTitle(currentTitle);
627 // last but not least, skip to previous file
632 void VlcWrapper::navigateNext()
634 bool hasSkiped = false;
636 // see if we have got a stream going
639 // get information from stream (lock it while looking at it)
640 vlc_mutex_lock( &p_input->stream.stream_lock );
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;
649 vlc_mutex_unlock( &p_input->stream.stream_lock );
651 // first, look for chapters
654 // skip to the next chapter
656 if ( currentChapter < numChapters )
658 toggleChapter( currentChapter );
662 // if we couldn't skip chapters, try titles instead
663 if ( !hasSkiped && hasTitles )
665 // skip to the next title
667 // disallow area 0 since it is used for video_ts.vob
668 if ( currentTitle < numTitles - 1 )
670 toggleTitle(currentTitle);
676 // last but not least, skip to next file
682 /***************************
683 * audio infos and control *
684 ***************************/
686 unsigned short VlcWrapper::GetVolume()
690 unsigned short i_volume;
691 aout_VolumeGet( p_aout, (audio_volume_t*)&i_volume );
697 void VlcWrapper::SetVolume(int value)
701 if ( p_intf->p_sys->b_mute )
703 p_intf->p_sys->b_mute = 0;
705 aout_VolumeSet( p_aout, value );
709 void VlcWrapper::VolumeMute()
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;
719 void VlcWrapper::VolumeRestore()
723 aout_VolumeSet( p_aout, p_intf->p_sys->i_saved_volume );
724 p_intf->p_sys->b_mute = 0;
728 bool VlcWrapper::IsMuted()
730 return p_intf->p_sys->b_mute;
733 bool VlcWrapper::HasAudio()
735 return( p_aout != NULL );
741 bool VlcWrapper::HasTitles()
747 return ( p_input->stream.i_area_nb > 1 );
750 void VlcWrapper::PrevTitle()
753 i_id = p_input->stream.p_selected_area->i_id - 1;
760 void VlcWrapper::NextTitle()
763 i_id = p_input->stream.p_selected_area->i_id + 1;
764 if( i_id < p_input->stream.i_area_nb )
770 bool VlcWrapper::HasChapters()
776 return ( p_input->stream.p_selected_area->i_part_nb > 1 );
779 void VlcWrapper::PrevChapter()
782 i_id = p_input->stream.p_selected_area->i_part - 1;
789 void VlcWrapper::NextChapter()
792 i_id = p_input->stream.p_selected_area->i_part + 1;
799 void VlcWrapper::TitleInfo( int32 ¤tIndex, int32 &maxIndex )
805 vlc_mutex_lock( &p_input->stream.stream_lock );
807 maxIndex = p_input->stream.i_area_nb - 1;
809 currentIndex = p_input->stream.p_selected_area->i_id;
813 vlc_mutex_unlock( &p_input->stream.stream_lock );
817 void VlcWrapper::ChapterInfo( int32 ¤tIndex, int32 &maxIndex )
823 vlc_mutex_lock( &p_input->stream.stream_lock );
825 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
827 currentIndex = p_input->stream.p_selected_area->i_part;
831 vlc_mutex_unlock( &p_input->stream.stream_lock );
835 void VlcWrapper::toggleTitle(int i_title)
837 if( p_input != NULL )
839 input_ChangeArea( p_input,
840 p_input->stream.pp_areas[i_title] );
842 vlc_mutex_lock( &p_input->stream.stream_lock );
844 vlc_mutex_unlock( &p_input->stream.stream_lock );
848 void VlcWrapper::toggleChapter(int i_chapter)
850 if( p_input != NULL )
852 p_input->stream.p_selected_area->i_part = i_chapter;
853 input_ChangeArea( p_input,
854 p_input->stream.p_selected_area );
856 vlc_mutex_lock( &p_input->stream.stream_lock );
857 vlc_mutex_unlock( &p_input->stream.stream_lock );