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.19 2003/01/14 22:03:38 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 );
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 void VlcWrapper::InputSlower()
134 if( p_input != NULL )
136 input_SetStatus( p_input, INPUT_STATUS_SLOWER );
140 void VlcWrapper::InputFaster()
142 if( p_input != NULL )
144 input_SetStatus( p_input, INPUT_STATUS_FASTER );
148 BList * VlcWrapper::InputGetChannels( int i_cat )
154 const char* fieldName;
160 what = SELECT_CHANNEL;
161 fieldName = "channel";
166 what = SELECT_SUBTITLE;
167 fieldName = "subtitle";
174 vlc_mutex_lock( &p_input->stream.stream_lock );
176 /* find which track is currently playing */
177 es_descriptor_t *p_es = NULL;
178 for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
180 if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
181 p_es = p_input->stream.pp_selected_es[i];
184 /* build a list of all tracks */
185 BList *list = new BList( p_input->stream.i_es_number );
191 message = new BMessage( what );
192 message->AddInt32( fieldName, -1 );
193 menuItem = new BMenuItem( "None", message );
195 menuItem->SetMarked( true );
196 list->AddItem( menuItem );
198 for( i = 0; i < p_input->stream.i_es_number; i++ )
200 if( p_input->stream.pp_es[i]->i_cat == i_cat )
202 message = new BMessage( what );
203 message->AddInt32( fieldName, i );
204 if( strlen( p_input->stream.pp_es[i]->psz_desc ) )
205 trackName = strdup( p_input->stream.pp_es[i]->psz_desc );
207 trackName = "<unknown>";
208 menuItem = new BMenuItem( trackName, message );
209 if( p_input->stream.pp_es[i] == p_es )
210 menuItem->SetMarked( true );
211 list->AddItem( menuItem );
215 vlc_mutex_unlock( &p_input->stream.stream_lock );
222 void VlcWrapper::openFiles( BList* o_files, bool replace )
225 int size = PlaylistSize();
226 bool wasEmpty = ( size < 1 );
228 /* delete current playlist */
231 for( int i = 0; i < size; i++ )
233 playlist_Delete( p_playlist, 0 );
238 while( ( o_file = (BString *)o_files->LastItem() ) )
240 playlist_Add( p_playlist, o_file->String(),
241 PLAYLIST_APPEND, PLAYLIST_END );
242 o_files->RemoveItem(o_files->CountItems() - 1);
245 /* eventually restart playing */
246 if( replace || wasEmpty )
248 playlist_Stop( p_playlist );
249 playlist_Play( p_playlist );
253 void VlcWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
255 BString o_source("");
256 o_source << o_type << ":" << o_device ;
258 playlist_Add( p_playlist, o_source.String(),
259 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
262 void VlcWrapper::LoadSubFile( char * psz_file )
264 config_PutPsz( p_intf, "sub-file", strdup( psz_file ) );
267 void VlcWrapper::ToggleLanguage( int i_language )
269 es_descriptor_t * p_es = NULL;
270 es_descriptor_t * p_es_old = NULL;
272 vlc_mutex_lock( &p_input->stream.stream_lock );
273 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
275 if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
277 p_es_old = p_input->stream.pp_selected_es[i];
281 vlc_mutex_unlock( &p_input->stream.stream_lock );
283 if( i_language != -1 )
285 p_es = p_input->stream.pp_es[i_language];
287 if( p_es == p_es_old )
293 input_ToggleES( p_input, p_es_old, VLC_FALSE );
297 input_ToggleES( p_input, p_es, VLC_TRUE );
301 void VlcWrapper::ToggleSubtitle( int i_subtitle )
303 es_descriptor_t * p_es = NULL;
304 es_descriptor_t * p_es_old = NULL;
306 vlc_mutex_lock( &p_input->stream.stream_lock );
307 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
309 if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
311 p_es_old = p_input->stream.pp_selected_es[i];
315 vlc_mutex_unlock( &p_input->stream.stream_lock );
317 if( i_subtitle != -1 )
319 p_es = p_input->stream.pp_es[i_subtitle];
321 if( p_es == p_es_old )
327 input_ToggleES( p_input, p_es_old, VLC_FALSE );
331 input_ToggleES( p_input, p_es, VLC_TRUE );
335 const char* VlcWrapper::getTimeAsString()
337 static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
339 if( p_input == NULL )
344 input_OffsetToTime( p_input,
346 p_input->stream.p_selected_area->i_tell );
348 return(psz_currenttime);
351 float VlcWrapper::getTimeAsFloat()
355 if( p_input != NULL )
357 f_time = (float)p_input->stream.p_selected_area->i_tell /
358 (float)p_input->stream.p_selected_area->i_size;
367 void VlcWrapper::setTimeAsFloat(float f_position)
369 if( p_input != NULL )
372 (long long int)(p_input->stream.p_selected_area->i_size
373 * f_position / SEEKSLIDER_RANGE ),
378 bool VlcWrapper::IsPlaying()
381 bool playing = false;
384 switch ( p_input->stream.control.i_status )
403 /******************************
404 * playlist infos and control *
405 ******************************/
406 int VlcWrapper::PlaylistSize()
408 vlc_mutex_lock( &p_playlist->object_lock );
409 int i_size = p_playlist->i_size;
410 vlc_mutex_unlock( &p_playlist->object_lock );
414 char *VlcWrapper::PlaylistItemName( int i )
416 return p_playlist->pp_items[i]->psz_name;
419 int VlcWrapper::PlaylistCurrent()
421 return p_playlist->i_index;
424 int VlcWrapper::PlaylistStatus()
426 return p_playlist->i_status;
429 bool VlcWrapper::PlaylistPlay()
433 playlist_Play( p_playlist );
438 void VlcWrapper::PlaylistPause()
442 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
446 void VlcWrapper::PlaylistStop()
448 playlist_Stop( p_playlist );
451 void VlcWrapper::PlaylistNext()
453 playlist_Next( p_playlist );
456 void VlcWrapper::PlaylistPrev()
458 playlist_Prev( p_playlist );
461 void VlcWrapper::PlaylistSkip( int i )
463 playlist_Skip( p_playlist, i );
466 void VlcWrapper::PlaylistGoto( int i )
468 playlist_Goto( p_playlist, i );
471 void VlcWrapper::PlaylistLoop()
473 if ( p_intf->p_sys->b_loop )
475 playlist_Delete( p_playlist, p_playlist->i_size - 1 );
479 playlist_Add( p_playlist, "vlc:loop",
480 PLAYLIST_APPEND | PLAYLIST_GO,
483 p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
486 BList * VlcWrapper::PlaylistAsArray()
489 BList* p_list = new BList(p_playlist->i_size);
491 vlc_mutex_lock( &p_playlist->object_lock );
493 for( i = 0; i < p_playlist->i_size; i++ )
495 p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
498 vlc_mutex_unlock( &p_playlist->object_lock );
502 void VlcWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
508 maxIndex = p_playlist->i_size;
510 currentIndex = p_playlist->i_index + 1;
517 void VlcWrapper::PlaylistJumpTo( int pos )
523 int size = playlistSize();
527 if( p_input_bank->pp_input[0] != NULL )
529 // stop current stream
531 // modify current position in playlist
533 p_main->p_playlist->i_index = pos;
540 void VlcWrapper::getNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
542 if ( canSkipPrev && canSkipNext )
544 // init the parameters
545 *canSkipPrev = false;
546 *canSkipNext = false;
548 int pos = PlaylistCurrent();
549 int size = PlaylistSize();
551 // see if we have got a stream going
554 vlc_mutex_lock( &p_input->stream.stream_lock );
556 bool hasTitles = p_input->stream.i_area_nb > 1;
557 int numChapters = p_input->stream.p_selected_area->i_part_nb;
558 bool hasChapters = numChapters > 1;
559 // first, look for chapters
562 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
563 *canSkipNext = p_input->stream.p_selected_area->i_part <
564 p_input->stream.p_selected_area->i_part_nb - 1;
566 // if one of the skip capabilities is false,
567 // make it depend on titles instead
568 if ( !*canSkipPrev && hasTitles )
569 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
570 if ( !*canSkipNext && hasTitles )
571 *canSkipNext = p_input->stream.p_selected_area->i_id <
572 p_input->stream.i_area_nb - 1;
574 vlc_mutex_unlock( &p_input->stream.stream_lock );
576 // last but not least, make capabilities depend on playlist
578 *canSkipPrev = pos > 0;
580 *canSkipNext = pos < size - 1;
584 void VlcWrapper::navigatePrev()
586 bool hasSkiped = false;
588 // see if we have got a stream going
591 // get information from stream (lock it while looking at it)
592 vlc_mutex_lock( &p_input->stream.stream_lock );
594 int currentTitle = p_input->stream.p_selected_area->i_id;
595 int currentChapter = p_input->stream.p_selected_area->i_part;
596 int numTitles = p_input->stream.i_area_nb;
597 bool hasTitles = numTitles > 1;
598 int numChapters = p_input->stream.p_selected_area->i_part_nb;
599 bool hasChapters = numChapters > 1;
601 vlc_mutex_unlock( &p_input->stream.stream_lock );
603 // first, look for chapters
606 // skip to the previous chapter
609 if ( currentChapter >= 0 )
611 toggleChapter( currentChapter );
615 // if we couldn't skip chapters, try titles instead
616 if ( !hasSkiped && hasTitles )
618 // skip to the previous title
620 // disallow area 0 since it is used for video_ts.vob
621 if( currentTitle > 0 )
623 toggleTitle(currentTitle);
629 // last but not least, skip to previous file
634 void VlcWrapper::navigateNext()
636 bool hasSkiped = false;
638 // see if we have got a stream going
641 // get information from stream (lock it while looking at it)
642 vlc_mutex_lock( &p_input->stream.stream_lock );
644 int currentTitle = p_input->stream.p_selected_area->i_id;
645 int currentChapter = p_input->stream.p_selected_area->i_part;
646 int numTitles = p_input->stream.i_area_nb;
647 bool hasTitles = numTitles > 1;
648 int numChapters = p_input->stream.p_selected_area->i_part_nb;
649 bool hasChapters = numChapters > 1;
651 vlc_mutex_unlock( &p_input->stream.stream_lock );
653 // first, look for chapters
656 // skip to the next chapter
658 if ( currentChapter < numChapters )
660 toggleChapter( currentChapter );
664 // if we couldn't skip chapters, try titles instead
665 if ( !hasSkiped && hasTitles )
667 // skip to the next title
669 // disallow area 0 since it is used for video_ts.vob
670 if ( currentTitle < numTitles - 1 )
672 toggleTitle(currentTitle);
678 // last but not least, skip to next file
684 /***************************
685 * audio infos and control *
686 ***************************/
688 unsigned short VlcWrapper::GetVolume()
692 unsigned short i_volume;
693 aout_VolumeGet( p_aout, (audio_volume_t*)&i_volume );
699 void VlcWrapper::SetVolume(int value)
703 if ( p_intf->p_sys->b_mute )
705 p_intf->p_sys->b_mute = 0;
707 aout_VolumeSet( p_aout, value );
711 void VlcWrapper::VolumeMute()
715 aout_VolumeGet( p_aout, &p_intf->p_sys->i_saved_volume );
716 aout_VolumeMute( p_aout, NULL );
717 p_intf->p_sys->b_mute = 1;
721 void VlcWrapper::VolumeRestore()
725 aout_VolumeSet( p_aout, p_intf->p_sys->i_saved_volume );
726 p_intf->p_sys->b_mute = 0;
730 bool VlcWrapper::IsMuted()
732 return p_intf->p_sys->b_mute;
735 bool VlcWrapper::HasAudio()
737 return( p_aout != NULL );
743 bool VlcWrapper::HasTitles()
749 return ( p_input->stream.i_area_nb > 1 );
752 void VlcWrapper::PrevTitle()
755 i_id = p_input->stream.p_selected_area->i_id - 1;
762 void VlcWrapper::NextTitle()
765 i_id = p_input->stream.p_selected_area->i_id + 1;
766 if( i_id < p_input->stream.i_area_nb )
772 bool VlcWrapper::HasChapters()
778 return ( p_input->stream.p_selected_area->i_part_nb > 1 );
781 void VlcWrapper::PrevChapter()
784 i_id = p_input->stream.p_selected_area->i_part - 1;
791 void VlcWrapper::NextChapter()
794 i_id = p_input->stream.p_selected_area->i_part + 1;
801 void VlcWrapper::TitleInfo( int32 ¤tIndex, int32 &maxIndex )
807 vlc_mutex_lock( &p_input->stream.stream_lock );
809 maxIndex = p_input->stream.i_area_nb - 1;
811 currentIndex = p_input->stream.p_selected_area->i_id;
815 vlc_mutex_unlock( &p_input->stream.stream_lock );
819 void VlcWrapper::ChapterInfo( int32 ¤tIndex, int32 &maxIndex )
825 vlc_mutex_lock( &p_input->stream.stream_lock );
827 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
829 currentIndex = p_input->stream.p_selected_area->i_part;
833 vlc_mutex_unlock( &p_input->stream.stream_lock );
837 void VlcWrapper::toggleTitle(int i_title)
839 if( p_input != NULL )
841 input_ChangeArea( p_input,
842 p_input->stream.pp_areas[i_title] );
844 vlc_mutex_lock( &p_input->stream.stream_lock );
846 vlc_mutex_unlock( &p_input->stream.stream_lock );
850 void VlcWrapper::toggleChapter(int i_chapter)
852 if( p_input != NULL )
854 p_input->stream.p_selected_area->i_part = i_chapter;
855 input_ChangeArea( p_input,
856 p_input->stream.p_selected_area );
858 vlc_mutex_lock( &p_input->stream.stream_lock );
859 vlc_mutex_unlock( &p_input->stream.stream_lock );