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.16 2003/01/11 19:33:09 stippi 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 );
109 // return ( PlaylistSize() > 0 );
112 /* status (UNDEF_S, PLAYING_S, PAUSE_S, FORWARD_S, BACKWARD_S,
113 REWIND_S, NOT_STARTED_S, START_S) */
114 int VlcWrapper::InputStatus()
120 return p_input->stream.control.i_status;
123 int VlcWrapper::InputRate()
129 return p_input->stream.control.i_rate;
132 /* tell: location in the current stream (in arbitrary units) */
133 int VlcWrapper::InputTell()
139 return p_input->stream.p_selected_area->i_tell;
142 /* size: total size of the current stream (in arbitrary units) */
143 int VlcWrapper::InputSize()
149 return p_input->stream.p_selected_area->i_size;
152 void VlcWrapper::InputSlower()
154 if( p_input != NULL )
156 input_SetStatus( p_input, INPUT_STATUS_SLOWER );
160 void VlcWrapper::InputFaster()
162 if( p_input != NULL )
164 input_SetStatus( p_input, INPUT_STATUS_FASTER );
168 BList * VlcWrapper::InputGetChannels( int i_cat )
174 const char* fieldName;
180 what = SELECT_CHANNEL;
181 fieldName = "channel";
186 what = SELECT_SUBTITLE;
187 fieldName = "subtitle";
194 vlc_mutex_lock( &p_input->stream.stream_lock );
196 /* find which track is currently playing */
197 es_descriptor_t *p_es = NULL;
198 for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
200 if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
201 p_es = p_input->stream.pp_selected_es[i];
204 /* build a list of all tracks */
205 BList *list = new BList( p_input->stream.i_es_number );
211 message = new BMessage( what );
212 message->AddInt32( fieldName, -1 );
213 menuItem = new BMenuItem( "None", message );
215 menuItem->SetMarked( true );
216 list->AddItem( menuItem );
218 for( i = 0; i < p_input->stream.i_es_number; i++ )
220 if( p_input->stream.pp_es[i]->i_cat == i_cat )
222 message = new BMessage( what );
223 message->AddInt32( fieldName, i );
224 if( strlen( p_input->stream.pp_es[i]->psz_desc ) )
225 trackName = strdup( p_input->stream.pp_es[i]->psz_desc );
227 trackName = "<unknown>";
228 menuItem = new BMenuItem( trackName, message );
229 if( p_input->stream.pp_es[i] == p_es )
230 menuItem->SetMarked( true );
231 list->AddItem( menuItem );
235 vlc_mutex_unlock( &p_input->stream.stream_lock );
242 void VlcWrapper::openFiles( BList* o_files, bool replace )
246 while( ( o_file = (BString *)o_files->LastItem() ) )
248 o_files->RemoveItem(o_files->CountItems() - 1);
249 playlist_Add( p_playlist, o_file->String(),
250 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
255 void VlcWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
257 BString o_source("");
258 o_source << o_type << ":" << o_device ;
260 playlist_Add( p_playlist, o_source.String(),
261 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
266 void VlcWrapper::ToggleLanguage( int i_language )
268 es_descriptor_t * p_es = NULL;
269 es_descriptor_t * p_es_old = NULL;
271 vlc_mutex_lock( &p_input->stream.stream_lock );
272 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
274 if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
276 p_es_old = p_input->stream.pp_selected_es[i];
280 vlc_mutex_unlock( &p_input->stream.stream_lock );
282 if( i_language != -1 )
284 p_es = p_input->stream.pp_es[i_language];
286 if( p_es == p_es_old )
292 input_ToggleES( p_input, p_es_old, VLC_FALSE );
296 input_ToggleES( p_input, p_es, VLC_TRUE );
300 void VlcWrapper::ToggleSubtitle( int i_subtitle )
302 es_descriptor_t * p_es = NULL;
303 es_descriptor_t * p_es_old = NULL;
305 vlc_mutex_lock( &p_input->stream.stream_lock );
306 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
308 if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
310 p_es_old = p_input->stream.pp_selected_es[i];
314 vlc_mutex_unlock( &p_input->stream.stream_lock );
316 if( i_subtitle != -1 )
318 p_es = p_input->stream.pp_es[i_subtitle];
320 if( p_es == p_es_old )
326 input_ToggleES( p_input, p_es_old, VLC_FALSE );
330 input_ToggleES( p_input, p_es, VLC_TRUE );
334 const char* VlcWrapper::getTimeAsString()
336 static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
338 if( p_input == NULL )
343 input_OffsetToTime( p_input,
345 p_input->stream.p_selected_area->i_tell );
347 return(psz_currenttime);
350 float VlcWrapper::getTimeAsFloat()
354 if( p_input != NULL )
356 f_time = (float)p_input->stream.p_selected_area->i_tell /
357 (float)p_input->stream.p_selected_area->i_size;
366 void VlcWrapper::setTimeAsFloat(float f_position)
368 if( p_input != NULL )
371 (long long int)(p_input->stream.p_selected_area->i_size
372 * f_position / SEEKSLIDER_RANGE ),
377 bool VlcWrapper::IsPlaying()
380 bool playing = false;
383 switch ( p_input->stream.control.i_status )
402 /******************************
403 * playlist infos and control *
404 ******************************/
405 int VlcWrapper::PlaylistSize()
407 vlc_mutex_lock( &p_playlist->object_lock );
408 int i_size = p_playlist->i_size;
409 vlc_mutex_unlock( &p_playlist->object_lock );
413 char *VlcWrapper::PlaylistItemName( int i )
415 return p_playlist->pp_items[i]->psz_name;
418 int VlcWrapper::PlaylistCurrent()
420 return p_playlist->i_index;
423 int VlcWrapper::PlaylistStatus()
425 return p_playlist->i_status;
428 bool VlcWrapper::PlaylistPlay()
432 playlist_Play( p_playlist );
437 void VlcWrapper::PlaylistPause()
441 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
445 void VlcWrapper::PlaylistStop()
447 playlist_Stop( p_playlist );
450 void VlcWrapper::PlaylistNext()
452 playlist_Next( p_playlist );
455 void VlcWrapper::PlaylistPrev()
457 playlist_Prev( p_playlist );
460 void VlcWrapper::PlaylistSkip( int i )
462 playlist_Skip( p_playlist, i );
465 void VlcWrapper::PlaylistGoto( int i )
467 playlist_Goto( p_playlist, i );
470 void VlcWrapper::PlaylistLoop()
472 if ( p_intf->p_sys->b_loop )
474 playlist_Delete( p_playlist, p_playlist->i_size - 1 );
478 playlist_Add( p_playlist, "vlc:loop",
479 PLAYLIST_APPEND | PLAYLIST_GO,
482 p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
485 BList * VlcWrapper::PlaylistAsArray()
488 BList* p_list = new BList(p_playlist->i_size);
490 vlc_mutex_lock( &p_playlist->object_lock );
492 for( i = 0; i < p_playlist->i_size; i++ )
494 p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
497 vlc_mutex_unlock( &p_playlist->object_lock );
501 void VlcWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
507 maxIndex = p_playlist->i_size;
509 currentIndex = p_playlist->i_index + 1;
516 void VlcWrapper::PlaylistJumpTo( int pos )
522 int size = playlistSize();
526 if( p_input_bank->pp_input[0] != NULL )
528 // stop current stream
530 // modify current position in playlist
532 p_main->p_playlist->i_index = pos;
539 void VlcWrapper::getNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
541 if ( canSkipPrev && canSkipNext )
543 // init the parameters
544 *canSkipPrev = false;
545 *canSkipNext = false;
547 int pos = PlaylistCurrent();
548 int size = PlaylistSize();
550 // see if we have got a stream going
553 vlc_mutex_lock( &p_input->stream.stream_lock );
555 bool hasTitles = p_input->stream.i_area_nb > 1;
556 int numChapters = p_input->stream.p_selected_area->i_part_nb;
557 bool hasChapters = numChapters > 1;
558 // first, look for chapters
561 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
562 *canSkipNext = p_input->stream.p_selected_area->i_part <
563 p_input->stream.p_selected_area->i_part_nb - 1;
565 // if one of the skip capabilities is false,
566 // make it depend on titles instead
567 if ( !*canSkipPrev && hasTitles )
568 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
569 if ( !*canSkipNext && hasTitles )
570 *canSkipNext = p_input->stream.p_selected_area->i_id <
571 p_input->stream.i_area_nb - 1;
573 vlc_mutex_unlock( &p_input->stream.stream_lock );
575 // last but not least, make capabilities depend on playlist
577 *canSkipPrev = pos > 0;
579 *canSkipNext = pos < size - 1;
583 void VlcWrapper::navigatePrev()
585 bool hasSkiped = false;
587 // see if we have got a stream going
590 // get information from stream (lock it while looking at it)
591 vlc_mutex_lock( &p_input->stream.stream_lock );
593 int currentTitle = p_input->stream.p_selected_area->i_id;
594 int currentChapter = p_input->stream.p_selected_area->i_part;
595 int numTitles = p_input->stream.i_area_nb;
596 bool hasTitles = numTitles > 1;
597 int numChapters = p_input->stream.p_selected_area->i_part_nb;
598 bool hasChapters = numChapters > 1;
600 vlc_mutex_unlock( &p_input->stream.stream_lock );
602 // first, look for chapters
605 // skip to the previous chapter
608 if ( currentChapter >= 0 )
610 toggleChapter( currentChapter );
614 // if we couldn't skip chapters, try titles instead
615 if ( !hasSkiped && hasTitles )
617 // skip to the previous title
619 // disallow area 0 since it is used for video_ts.vob
620 if( currentTitle > 0 )
622 toggleTitle(currentTitle);
628 // last but not least, skip to previous file
633 void VlcWrapper::navigateNext()
635 bool hasSkiped = false;
637 // see if we have got a stream going
640 // get information from stream (lock it while looking at it)
641 vlc_mutex_lock( &p_input->stream.stream_lock );
643 int currentTitle = p_input->stream.p_selected_area->i_id;
644 int currentChapter = p_input->stream.p_selected_area->i_part;
645 int numTitles = p_input->stream.i_area_nb;
646 bool hasTitles = numTitles > 1;
647 int numChapters = p_input->stream.p_selected_area->i_part_nb;
648 bool hasChapters = numChapters > 1;
650 vlc_mutex_unlock( &p_input->stream.stream_lock );
652 // first, look for chapters
655 // skip to the next chapter
657 if ( currentChapter < numChapters )
659 toggleChapter( currentChapter );
663 // if we couldn't skip chapters, try titles instead
664 if ( !hasSkiped && hasTitles )
666 // skip to the next title
668 // disallow area 0 since it is used for video_ts.vob
669 if ( currentTitle < numTitles - 1 )
671 toggleTitle(currentTitle);
677 // last but not least, skip to next file
683 /***************************
684 * audio infos and control *
685 ***************************/
687 unsigned short VlcWrapper::GetVolume()
691 unsigned short i_volume;
692 aout_VolumeGet( p_aout, (audio_volume_t*)&i_volume );
698 void VlcWrapper::SetVolume(int value)
702 if ( p_intf->p_sys->b_mute )
704 p_intf->p_sys->b_mute = 0;
706 aout_VolumeSet( p_aout, value );
710 void VlcWrapper::VolumeMute()
714 aout_VolumeGet( p_aout, &p_intf->p_sys->i_saved_volume );
715 aout_VolumeMute( p_aout, NULL );
716 p_intf->p_sys->b_mute = 1;
720 void VlcWrapper::VolumeRestore()
724 aout_VolumeSet( p_aout, p_intf->p_sys->i_saved_volume );
725 p_intf->p_sys->b_mute = 0;
729 bool VlcWrapper::IsMuted()
731 return p_intf->p_sys->b_mute;
734 bool VlcWrapper::HasAudio()
736 return( p_aout != NULL );
742 bool VlcWrapper::HasTitles()
748 return ( p_input->stream.i_area_nb > 1 );
751 void VlcWrapper::PrevTitle()
754 i_id = p_input->stream.p_selected_area->i_id - 1;
761 void VlcWrapper::NextTitle()
764 i_id = p_input->stream.p_selected_area->i_id + 1;
765 if( i_id < p_input->stream.i_area_nb )
771 bool VlcWrapper::HasChapters()
777 return ( p_input->stream.p_selected_area->i_part_nb > 1 );
780 void VlcWrapper::PrevChapter()
783 i_id = p_input->stream.p_selected_area->i_part - 1;
790 void VlcWrapper::NextChapter()
793 i_id = p_input->stream.p_selected_area->i_part + 1;
800 void VlcWrapper::TitleInfo( int32 ¤tIndex, int32 &maxIndex )
806 vlc_mutex_lock( &p_input->stream.stream_lock );
808 maxIndex = p_input->stream.i_area_nb - 1;
810 currentIndex = p_input->stream.p_selected_area->i_id;
814 vlc_mutex_unlock( &p_input->stream.stream_lock );
818 void VlcWrapper::ChapterInfo( int32 ¤tIndex, int32 &maxIndex )
824 vlc_mutex_lock( &p_input->stream.stream_lock );
826 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
828 currentIndex = p_input->stream.p_selected_area->i_part;
832 vlc_mutex_unlock( &p_input->stream.stream_lock );
836 void VlcWrapper::toggleTitle(int i_title)
838 if( p_input != NULL )
840 input_ChangeArea( p_input,
841 p_input->stream.pp_areas[i_title] );
843 vlc_mutex_lock( &p_input->stream.stream_lock );
845 vlc_mutex_unlock( &p_input->stream.stream_lock );
849 void VlcWrapper::toggleChapter(int i_chapter)
851 if( p_input != NULL )
853 p_input->stream.p_selected_area->i_part = i_chapter;
854 input_ChangeArea( p_input,
855 p_input->stream.p_selected_area );
857 vlc_mutex_lock( &p_input->stream.stream_lock );
858 vlc_mutex_unlock( &p_input->stream.stream_lock );