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.12 2002/11/27 05:36:41 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 *****************************************************************************/
27 #include <SupportKit.h>
31 #include <audio_output.h>
32 #include <aout_internal.h>
34 #include "VlcWrapper.h"
37 VlcWrapper::VlcWrapper( intf_thread_t *p_interface )
42 p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
47 VlcWrapper::~VlcWrapper()
51 vlc_object_release( p_input );
55 vlc_object_release( p_playlist );
59 vlc_object_release( p_aout );
63 /* UpdateInputAndAOut: updates p_input and p_aout, returns true if the
64 interface needs to be updated */
65 bool VlcWrapper::UpdateInputAndAOut()
69 p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
74 p_aout = (aout_instance_t*)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
82 vlc_object_release( p_input );
87 vlc_object_release( p_aout );
97 /***************************
98 * input infos and control *
99 ***************************/
101 /* status (UNDEF_S, PLAYING_S, PAUSE_S, FORWARD_S, BACKWARD_S,
102 REWIND_S, NOT_STARTED_S, START_S) */
103 int VlcWrapper::InputStatus()
109 return p_input->stream.control.i_status;
112 int VlcWrapper::InputRate()
118 return p_input->stream.control.i_rate;
121 /* tell: location in the current stream (in arbitrary units) */
122 int VlcWrapper::InputTell()
128 return p_input->stream.p_selected_area->i_tell;
131 /* size: total size of the current stream (in arbitrary units) */
132 int VlcWrapper::InputSize()
138 return p_input->stream.p_selected_area->i_size;
141 void VlcWrapper::InputSlower()
143 if( p_input != NULL )
145 input_SetStatus( p_input, INPUT_STATUS_SLOWER );
147 if( p_input->stream.control.i_rate == DEFAULT_RATE)
157 void VlcWrapper::InputFaster()
159 if( p_input != NULL )
161 input_SetStatus( p_input, INPUT_STATUS_FASTER );
163 if( p_input->stream.control.i_rate == DEFAULT_RATE)
173 void VlcWrapper::openFiles( BList* o_files, bool replace )
177 while( ( o_file = (BString *)o_files->LastItem() ) )
179 o_files->RemoveItem(o_files->CountItems() - 1);
180 playlist_Add( p_playlist, o_file->String(),
181 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
186 void VlcWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
188 BString o_source("");
189 o_source << o_type << ":" << o_device ;
191 playlist_Add( p_playlist, o_source.String(),
192 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
197 void VlcWrapper::toggleLanguage(int i_language)
201 int i_cat = AUDIO_ES;
203 vlc_mutex_lock( &p_input->stream.stream_lock );
204 for( int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
206 if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
212 vlc_mutex_unlock( &p_input->stream.stream_lock );
214 msg_Info( p_intf, "Old: %d, New: %d", i_old, i_language);
215 if( i_language != -1 )
217 input_ToggleES( p_input,
218 p_input->stream.pp_selected_es[i_language],
222 if( (i_old != -1) && (i_old != i_language) )
224 input_ToggleES( p_input,
225 p_input->stream.pp_selected_es[i_old],
230 void VlcWrapper::toggleSubtitle(int i_subtitle)
235 vlc_mutex_lock( &p_input->stream.stream_lock );
236 for( int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
238 if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
244 vlc_mutex_unlock( &p_input->stream.stream_lock );
246 msg_Info( p_intf, "Old: %d, New: %d", i_old, i_subtitle);
247 if( i_subtitle != -1 )
249 input_ToggleES( p_input,
250 p_input->stream.pp_selected_es[i_subtitle],
254 if( (i_old != -1) && (i_old != i_subtitle) )
256 input_ToggleES( p_input,
257 p_input->stream.pp_selected_es[i_old],
262 const char* VlcWrapper::getTimeAsString()
264 static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
266 if( p_input == NULL )
271 input_OffsetToTime( p_input,
273 p_input->stream.p_selected_area->i_tell );
275 return(psz_currenttime);
278 float VlcWrapper::getTimeAsFloat()
282 if( p_input != NULL )
284 f_time = (float)p_input->stream.p_selected_area->i_tell /
285 (float)p_input->stream.p_selected_area->i_size;
294 void VlcWrapper::setTimeAsFloat(float f_position)
296 if( p_input != NULL )
299 (long long int)(p_input->stream.p_selected_area->i_size
300 * f_position / SEEKSLIDER_RANGE ),
306 /******************************
307 * playlist infos and control *
308 ******************************/
309 int VlcWrapper::PlaylistSize()
311 vlc_mutex_lock( &p_playlist->object_lock );
312 int i_size = p_playlist->i_size;
313 vlc_mutex_unlock( &p_playlist->object_lock );
317 char *VlcWrapper::PlaylistItemName( int i )
319 return p_playlist->pp_items[i]->psz_name;
322 int VlcWrapper::PlaylistCurrent()
324 return p_playlist->i_index;
327 int VlcWrapper::PlaylistStatus()
329 return p_playlist->i_status;
332 bool VlcWrapper::PlaylistPlay()
336 playlist_Play( p_playlist );
341 void VlcWrapper::PlaylistPause()
346 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
350 void VlcWrapper::PlaylistStop()
353 playlist_Stop( p_playlist );
356 void VlcWrapper::PlaylistNext()
358 playlist_Next( p_playlist );
361 void VlcWrapper::PlaylistPrev()
363 playlist_Prev( p_playlist );
366 void VlcWrapper::PlaylistSkip( int i )
368 playlist_Skip( p_playlist, i );
371 void VlcWrapper::PlaylistGoto( int i )
373 playlist_Goto( p_playlist, i );
376 void VlcWrapper::PlaylistLoop()
378 if ( p_intf->p_sys->b_loop )
380 playlist_Delete( p_playlist, p_playlist->i_size - 1 );
384 playlist_Add( p_playlist, "vlc:loop",
385 PLAYLIST_APPEND | PLAYLIST_GO,
388 p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
391 BList * VlcWrapper::PlaylistAsArray()
394 BList* p_list = new BList(p_playlist->i_size);
396 vlc_mutex_lock( &p_playlist->object_lock );
398 for( i = 0; i < p_playlist->i_size; i++ )
400 p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
403 vlc_mutex_unlock( &p_playlist->object_lock );
407 void VlcWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
413 maxIndex = p_playlist->i_size;
415 currentIndex = p_playlist->i_index + 1;
422 void VlcWrapper::PlaylistJumpTo( int pos )
428 int size = playlistSize();
432 if( p_input_bank->pp_input[0] != NULL )
434 // stop current stream
436 // modify current position in playlist
438 p_main->p_playlist->i_index = pos;
445 void VlcWrapper::getNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
447 if ( canSkipPrev && canSkipNext )
449 // init the parameters
450 *canSkipPrev = false;
451 *canSkipNext = false;
453 int pos = PlaylistCurrent();
454 int size = PlaylistSize();
456 // see if we have got a stream going
459 vlc_mutex_lock( &p_input->stream.stream_lock );
461 bool hasTitles = p_input->stream.i_area_nb > 1;
462 int numChapters = p_input->stream.p_selected_area->i_part_nb;
463 bool hasChapters = numChapters > 1;
464 // first, look for chapters
467 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
468 *canSkipNext = p_input->stream.p_selected_area->i_part <
469 p_input->stream.p_selected_area->i_part_nb - 1;
471 // if one of the skip capabilities is false,
472 // make it depend on titles instead
473 if ( !*canSkipPrev && hasTitles )
474 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
475 if ( !*canSkipNext && hasTitles )
476 *canSkipNext = p_input->stream.p_selected_area->i_id <
477 p_input->stream.i_area_nb - 1;
479 vlc_mutex_unlock( &p_input->stream.stream_lock );
481 // last but not least, make capabilities depend on playlist
483 *canSkipPrev = pos > 0;
485 *canSkipNext = pos < size - 1;
489 void VlcWrapper::navigatePrev()
491 bool hasSkiped = false;
493 // see if we have got a stream going
496 // get information from stream (lock it while looking at it)
497 vlc_mutex_lock( &p_input->stream.stream_lock );
499 int currentTitle = p_input->stream.p_selected_area->i_id;
500 int currentChapter = p_input->stream.p_selected_area->i_part;
501 int numTitles = p_input->stream.i_area_nb;
502 bool hasTitles = numTitles > 1;
503 int numChapters = p_input->stream.p_selected_area->i_part_nb;
504 bool hasChapters = numChapters > 1;
506 vlc_mutex_unlock( &p_input->stream.stream_lock );
508 // first, look for chapters
511 // skip to the previous chapter
514 if ( currentChapter >= 0 )
516 toggleChapter( currentChapter );
520 // if we couldn't skip chapters, try titles instead
521 if ( !hasSkiped && hasTitles )
523 // skip to the previous title
525 // disallow area 0 since it is used for video_ts.vob
526 if( currentTitle > 0 )
528 toggleTitle(currentTitle);
534 // last but not least, skip to previous file
539 void VlcWrapper::navigateNext()
541 bool hasSkiped = false;
543 // see if we have got a stream going
546 // get information from stream (lock it while looking at it)
547 vlc_mutex_lock( &p_input->stream.stream_lock );
549 int currentTitle = p_input->stream.p_selected_area->i_id;
550 int currentChapter = p_input->stream.p_selected_area->i_part;
551 int numTitles = p_input->stream.i_area_nb;
552 bool hasTitles = numTitles > 1;
553 int numChapters = p_input->stream.p_selected_area->i_part_nb;
554 bool hasChapters = numChapters > 1;
556 vlc_mutex_unlock( &p_input->stream.stream_lock );
558 // first, look for chapters
561 // skip to the next chapter
563 if ( currentChapter < numChapters )
565 toggleChapter( currentChapter );
569 // if we couldn't skip chapters, try titles instead
570 if ( !hasSkiped && hasTitles )
572 // skip to the next title
574 // disallow area 0 since it is used for video_ts.vob
575 if ( currentTitle < numTitles - 1 )
577 toggleTitle(currentTitle);
583 // last but not least, skip to next file
589 /***************************
590 * audio infos and control *
591 ***************************/
593 void VlcWrapper::volume_mute()
597 if( !p_intf->p_sys->b_mute )
599 p_intf->p_sys->i_saved_volume = p_aout->output.i_volume;
600 p_aout->output.i_volume = 0;
601 p_intf->p_sys->b_mute = 1;
607 void VlcWrapper::volume_restore()
611 p_aout->output.i_volume = p_intf->p_sys->i_saved_volume;
612 p_intf->p_sys->i_saved_volume = 0;
613 p_intf->p_sys->b_mute = 0;
618 void VlcWrapper::set_volume(int value)
622 // make sure value is within bounds
625 if (value > AOUT_VOLUME_MAX)
626 value = AOUT_VOLUME_MAX;
627 vlc_mutex_lock( &p_aout->mixer_lock );
628 // unmute volume if muted
629 if ( p_intf->p_sys->b_mute )
631 p_intf->p_sys->b_mute = 0;
632 p_aout->output.i_volume = value;
634 vlc_mutex_unlock( &p_aout->mixer_lock );
638 void VlcWrapper::toggle_mute()
642 if ( p_intf->p_sys->b_mute )
653 bool VlcWrapper::is_muted()
659 vlc_mutex_lock( &p_aout->mixer_lock );
660 if( p_aout->output.i_volume > 0 )
664 vlc_mutex_unlock( &p_aout->mixer_lock );
665 // unfortunately, this is not reliable!
666 // return p_main->p_intf->p_sys->b_mute;
671 bool VlcWrapper::is_playing()
674 bool playing = false;
677 switch ( p_input->stream.control.i_status )
696 void VlcWrapper::maxvolume()
700 if( p_intf->p_sys->b_mute )
702 p_intf->p_sys->i_saved_volume = AOUT_VOLUME_MAX;
706 p_aout->output.i_volume = AOUT_VOLUME_MAX;
711 bool VlcWrapper::has_audio()
713 return( p_aout != NULL );
719 bool VlcWrapper::HasTitles()
725 return ( p_input->stream.i_area_nb > 1 );
728 void VlcWrapper::PrevTitle()
731 i_id = p_input->stream.p_selected_area->i_id - 1;
738 void VlcWrapper::NextTitle()
741 i_id = p_input->stream.p_selected_area->i_id + 1;
742 if( i_id < p_input->stream.i_area_nb )
748 bool VlcWrapper::HasChapters()
754 return ( p_input->stream.p_selected_area->i_part_nb > 1 );
757 void VlcWrapper::PrevChapter()
760 i_id = p_input->stream.p_selected_area->i_part - 1;
767 void VlcWrapper::NextChapter()
770 i_id = p_input->stream.p_selected_area->i_part + 1;
777 void VlcWrapper::TitleInfo( int32 ¤tIndex, int32 &maxIndex )
783 vlc_mutex_lock( &p_input->stream.stream_lock );
785 maxIndex = p_input->stream.i_area_nb - 1;
787 currentIndex = p_input->stream.p_selected_area->i_id;
791 vlc_mutex_unlock( &p_input->stream.stream_lock );
795 void VlcWrapper::ChapterInfo( int32 ¤tIndex, int32 &maxIndex )
801 vlc_mutex_lock( &p_input->stream.stream_lock );
803 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
805 currentIndex = p_input->stream.p_selected_area->i_part;
809 vlc_mutex_unlock( &p_input->stream.stream_lock );
813 void VlcWrapper::toggleTitle(int i_title)
815 if( p_input != NULL )
817 input_ChangeArea( p_input,
818 p_input->stream.pp_areas[i_title] );
820 vlc_mutex_lock( &p_input->stream.stream_lock );
822 vlc_mutex_unlock( &p_input->stream.stream_lock );
826 void VlcWrapper::toggleChapter(int i_chapter)
828 if( p_input != NULL )
830 p_input->stream.p_selected_area->i_part = i_chapter;
831 input_ChangeArea( p_input,
832 p_input->stream.p_selected_area );
834 vlc_mutex_lock( &p_input->stream.stream_lock );
835 vlc_mutex_unlock( &p_input->stream.stream_lock );