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.22 2003/01/27 10:29:22 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 int VlcWrapper::InputStatus()
117 return p_input->stream.control.i_status;
120 int VlcWrapper::InputRate()
126 return p_input->stream.control.i_rate;
129 void VlcWrapper::InputSlower()
131 if( p_input != NULL )
133 input_SetStatus( p_input, INPUT_STATUS_SLOWER );
137 void VlcWrapper::InputFaster()
139 if( p_input != NULL )
141 input_SetStatus( p_input, INPUT_STATUS_FASTER );
145 BList * VlcWrapper::GetChannels( int i_cat )
151 const char* fieldName;
157 what = SELECT_CHANNEL;
158 fieldName = "channel";
163 what = SELECT_SUBTITLE;
164 fieldName = "subtitle";
171 vlc_mutex_lock( &p_input->stream.stream_lock );
173 /* find which track is currently playing */
174 es_descriptor_t *p_es = NULL;
175 for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
177 if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
178 p_es = p_input->stream.pp_selected_es[i];
181 /* build a list of all tracks */
182 BList *list = new BList( p_input->stream.i_es_number );
188 message = new BMessage( what );
189 message->AddInt32( fieldName, -1 );
190 menuItem = new BMenuItem( "None", message );
192 menuItem->SetMarked( true );
193 list->AddItem( menuItem );
195 for( i = 0; i < p_input->stream.i_es_number; i++ )
197 if( p_input->stream.pp_es[i]->i_cat == i_cat )
199 message = new BMessage( what );
200 message->AddInt32( fieldName, i );
201 if( strlen( p_input->stream.pp_es[i]->psz_desc ) )
202 trackName = strdup( p_input->stream.pp_es[i]->psz_desc );
204 trackName = "<unknown>";
205 menuItem = new BMenuItem( trackName, message );
206 if( p_input->stream.pp_es[i] == p_es )
207 menuItem->SetMarked( true );
208 list->AddItem( menuItem );
212 vlc_mutex_unlock( &p_input->stream.stream_lock );
219 void VlcWrapper::ToggleLanguage( int i_language )
221 es_descriptor_t * p_es = NULL;
222 es_descriptor_t * p_es_old = NULL;
224 vlc_mutex_lock( &p_input->stream.stream_lock );
225 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
227 if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
229 p_es_old = p_input->stream.pp_selected_es[i];
233 vlc_mutex_unlock( &p_input->stream.stream_lock );
235 if( i_language != -1 )
237 p_es = p_input->stream.pp_es[i_language];
239 if( p_es == p_es_old )
245 input_ToggleES( p_input, p_es_old, VLC_FALSE );
249 input_ToggleES( p_input, p_es, VLC_TRUE );
253 void VlcWrapper::ToggleSubtitle( int i_subtitle )
255 es_descriptor_t * p_es = NULL;
256 es_descriptor_t * p_es_old = NULL;
258 vlc_mutex_lock( &p_input->stream.stream_lock );
259 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
261 if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
263 p_es_old = p_input->stream.pp_selected_es[i];
267 vlc_mutex_unlock( &p_input->stream.stream_lock );
269 if( i_subtitle != -1 )
271 p_es = p_input->stream.pp_es[i_subtitle];
273 if( p_es == p_es_old )
279 input_ToggleES( p_input, p_es_old, VLC_FALSE );
283 input_ToggleES( p_input, p_es, VLC_TRUE );
287 const char * VlcWrapper::GetTimeAsString()
289 static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
291 if( p_input == NULL )
296 input_OffsetToTime( p_input,
298 p_input->stream.p_selected_area->i_tell );
300 return(psz_currenttime);
303 float VlcWrapper::GetTimeAsFloat()
307 if( p_input != NULL )
309 f_time = (float)p_input->stream.p_selected_area->i_tell /
310 (float)p_input->stream.p_selected_area->i_size;
319 void VlcWrapper::SetTimeAsFloat( float f_position )
321 if( p_input != NULL )
324 (long long int)(p_input->stream.p_selected_area->i_size
325 * f_position / SEEKSLIDER_RANGE ),
330 bool VlcWrapper::IsPlaying()
333 bool playing = false;
336 switch ( p_input->stream.control.i_status )
359 void VlcWrapper::OpenFiles( BList* o_files, bool replace )
362 int size = PlaylistSize();
363 bool wasEmpty = ( size < 1 );
365 /* delete current playlist */
368 for( int i = 0; i < size; i++ )
370 playlist_Delete( p_playlist, 0 );
375 while( ( o_file = (BString *)o_files->LastItem() ) )
377 playlist_Add( p_playlist, o_file->String(),
378 PLAYLIST_APPEND, PLAYLIST_END );
379 o_files->RemoveItem(o_files->CountItems() - 1);
382 /* eventually restart playing */
383 if( replace || wasEmpty )
385 playlist_Stop( p_playlist );
386 playlist_Play( p_playlist );
390 void VlcWrapper::OpenDisc(BString o_type, BString o_device, int i_title, int i_chapter)
392 if( p_intf->p_sys->b_dvdmenus )
393 o_device.Prepend( "dvd:" );
395 o_device.Prepend( "dvdold:" );
396 playlist_Add( p_playlist, o_device.String(),
397 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
400 int VlcWrapper::PlaylistSize()
402 vlc_mutex_lock( &p_playlist->object_lock );
403 int i_size = p_playlist->i_size;
404 vlc_mutex_unlock( &p_playlist->object_lock );
408 char * VlcWrapper::PlaylistItemName( int i )
410 return p_playlist->pp_items[i]->psz_name;
413 int VlcWrapper::PlaylistCurrent()
415 return p_playlist->i_index;
418 bool VlcWrapper::PlaylistPlay()
422 playlist_Play( p_playlist );
427 void VlcWrapper::PlaylistPause()
431 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
435 void VlcWrapper::PlaylistStop()
437 playlist_Stop( p_playlist );
440 void VlcWrapper::PlaylistNext()
442 playlist_Next( p_playlist );
445 void VlcWrapper::PlaylistPrev()
447 playlist_Prev( p_playlist );
450 void VlcWrapper::GetPlaylistInfo( int32& currentIndex, int32& maxIndex )
456 maxIndex = p_playlist->i_size;
458 currentIndex = p_playlist->i_index + 1;
464 void VlcWrapper::PlaylistJumpTo( int pos )
466 playlist_Goto( p_playlist, pos );
469 void VlcWrapper::GetNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
471 if ( canSkipPrev && canSkipNext )
473 // init the parameters
474 *canSkipPrev = false;
475 *canSkipNext = false;
477 int pos = PlaylistCurrent();
478 int size = PlaylistSize();
480 // see if we have got a stream going
483 vlc_mutex_lock( &p_input->stream.stream_lock );
485 bool hasTitles = p_input->stream.i_area_nb > 1;
486 int numChapters = p_input->stream.p_selected_area->i_part_nb;
487 bool hasChapters = numChapters > 1;
488 // first, look for chapters
491 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
492 *canSkipNext = p_input->stream.p_selected_area->i_part <
493 p_input->stream.p_selected_area->i_part_nb - 1;
495 // if one of the skip capabilities is false,
496 // make it depend on titles instead
497 if ( !*canSkipPrev && hasTitles )
498 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
499 if ( !*canSkipNext && hasTitles )
500 *canSkipNext = p_input->stream.p_selected_area->i_id <
501 p_input->stream.i_area_nb - 1;
503 vlc_mutex_unlock( &p_input->stream.stream_lock );
505 // last but not least, make capabilities depend on playlist
507 *canSkipPrev = pos > 0;
509 *canSkipNext = pos < size - 1;
513 void VlcWrapper::NavigatePrev()
515 bool hasSkiped = false;
517 // see if we have got a stream going
520 // get information from stream (lock it while looking at it)
521 vlc_mutex_lock( &p_input->stream.stream_lock );
523 int currentTitle = p_input->stream.p_selected_area->i_id;
524 int currentChapter = p_input->stream.p_selected_area->i_part;
525 int numTitles = p_input->stream.i_area_nb;
526 bool hasTitles = numTitles > 1;
527 int numChapters = p_input->stream.p_selected_area->i_part_nb;
528 bool hasChapters = numChapters > 1;
530 vlc_mutex_unlock( &p_input->stream.stream_lock );
532 // first, look for chapters
535 // skip to the previous chapter
538 if ( currentChapter >= 0 )
540 ToggleChapter( currentChapter );
544 // if we couldn't skip chapters, try titles instead
545 if ( !hasSkiped && hasTitles )
547 // skip to the previous title
549 // disallow area 0 since it is used for video_ts.vob
550 if( currentTitle > 0 )
552 ToggleTitle(currentTitle);
558 // last but not least, skip to previous file
563 void VlcWrapper::NavigateNext()
565 bool hasSkiped = false;
567 // see if we have got a stream going
570 // get information from stream (lock it while looking at it)
571 vlc_mutex_lock( &p_input->stream.stream_lock );
573 int currentTitle = p_input->stream.p_selected_area->i_id;
574 int currentChapter = p_input->stream.p_selected_area->i_part;
575 int numTitles = p_input->stream.i_area_nb;
576 bool hasTitles = numTitles > 1;
577 int numChapters = p_input->stream.p_selected_area->i_part_nb;
578 bool hasChapters = numChapters > 1;
580 vlc_mutex_unlock( &p_input->stream.stream_lock );
582 // first, look for chapters
585 // skip to the next chapter
587 if ( currentChapter < numChapters )
589 ToggleChapter( currentChapter );
593 // if we couldn't skip chapters, try titles instead
594 if ( !hasSkiped && hasTitles )
596 // skip to the next title
598 // disallow area 0 since it is used for video_ts.vob
599 if ( currentTitle < numTitles - 1 )
601 ToggleTitle(currentTitle);
607 // last but not least, skip to next file
617 bool VlcWrapper::HasAudio()
619 return( p_aout != NULL );
622 unsigned short VlcWrapper::GetVolume()
626 unsigned short i_volume;
627 aout_VolumeGet( p_aout, (audio_volume_t*)&i_volume );
633 void VlcWrapper::SetVolume(int value)
637 if ( p_intf->p_sys->b_mute )
639 p_intf->p_sys->b_mute = 0;
641 aout_VolumeSet( p_aout, value );
645 void VlcWrapper::VolumeMute()
649 aout_VolumeGet( p_aout, &p_intf->p_sys->i_saved_volume );
650 aout_VolumeMute( p_aout, NULL );
651 p_intf->p_sys->b_mute = 1;
655 void VlcWrapper::VolumeRestore()
659 aout_VolumeSet( p_aout, p_intf->p_sys->i_saved_volume );
660 p_intf->p_sys->b_mute = 0;
664 bool VlcWrapper::IsMuted()
666 return p_intf->p_sys->b_mute;
673 bool VlcWrapper::HasTitles()
679 return ( p_input->stream.i_area_nb > 1 );
682 BList * VlcWrapper::GetTitles()
686 vlc_mutex_lock( &p_input->stream.stream_lock );
688 BList *list = new BList( p_input->stream.i_area_nb );
692 for( unsigned int i = 1; i < p_input->stream.i_area_nb; i++ )
694 message = new BMessage( TOGGLE_TITLE );
695 message->AddInt32( "index", i );
696 BString helper( "" );
698 menuItem = new BMenuItem( helper.String(), message );
699 menuItem->SetMarked( p_input->stream.p_selected_area->i_id == i );
700 list->AddItem( menuItem );
703 vlc_mutex_unlock( &p_input->stream.stream_lock );
710 void VlcWrapper::PrevTitle()
713 i_id = p_input->stream.p_selected_area->i_id - 1;
720 void VlcWrapper::NextTitle()
723 i_id = p_input->stream.p_selected_area->i_id + 1;
724 if( i_id < p_input->stream.i_area_nb )
730 void VlcWrapper::ToggleTitle(int i_title)
732 if( p_input != NULL )
734 input_ChangeArea( p_input,
735 p_input->stream.pp_areas[i_title] );
737 vlc_mutex_lock( &p_input->stream.stream_lock );
739 vlc_mutex_unlock( &p_input->stream.stream_lock );
743 void VlcWrapper::TitleInfo( int32 ¤tIndex, int32 &maxIndex )
749 vlc_mutex_lock( &p_input->stream.stream_lock );
751 maxIndex = p_input->stream.i_area_nb - 1;
753 currentIndex = p_input->stream.p_selected_area->i_id;
757 vlc_mutex_unlock( &p_input->stream.stream_lock );
761 bool VlcWrapper::HasChapters()
767 return ( p_input->stream.p_selected_area->i_part_nb > 1 );
770 BList * VlcWrapper::GetChapters()
774 vlc_mutex_lock( &p_input->stream.stream_lock );
776 BList *list = new BList( p_input->stream.p_selected_area->i_part_nb );
780 for( unsigned int i = 1;
781 i < p_input->stream.p_selected_area->i_part_nb + 1; i++ )
783 message = new BMessage( TOGGLE_CHAPTER );
784 message->AddInt32( "index", i );
785 BString helper( "" );
787 menuItem = new BMenuItem( helper.String(), message );
788 menuItem->SetMarked( p_input->stream.p_selected_area->i_part == i );
789 list->AddItem( menuItem );
792 vlc_mutex_unlock( &p_input->stream.stream_lock );
799 void VlcWrapper::PrevChapter()
802 i_id = p_input->stream.p_selected_area->i_part - 1;
809 void VlcWrapper::NextChapter()
812 i_id = p_input->stream.p_selected_area->i_part + 1;
819 void VlcWrapper::ToggleChapter(int i_chapter)
821 if( p_input != NULL )
823 p_input->stream.p_selected_area->i_part = i_chapter;
824 input_ChangeArea( p_input,
825 p_input->stream.p_selected_area );
827 vlc_mutex_lock( &p_input->stream.stream_lock );
828 vlc_mutex_unlock( &p_input->stream.stream_lock );
832 void VlcWrapper::ChapterInfo( int32 ¤tIndex, int32 &maxIndex )
838 vlc_mutex_lock( &p_input->stream.stream_lock );
840 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
842 currentIndex = p_input->stream.p_selected_area->i_part;
846 vlc_mutex_unlock( &p_input->stream.stream_lock );
854 void VlcWrapper::LoadSubFile( char * psz_file )
856 config_PutPsz( p_intf, "sub-file", strdup( psz_file ) );