/***************************************************************************
kplayerprocess . cpp
- - - - - - - - - - - - - - - - - -
begin : Sat Jan 11 2003
copyright : ( C ) 2002 - 2007 by kiriuja
email : http : //kplayer.sourceforge.net/email.html
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation , either version 3 of the License , or *
* ( at your option ) any later version . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
# include <fcntl.h>
# include <tdelocale.h>
# include <kprocctrl.h>
# include <kstandarddirs.h>
# include <tdetempfile.h>
# include <tqdir.h>
# include <tqfileinfo.h>
# include <tqregexp.h>
# include <tqsocketnotifier.h>
# include <tqtimer.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# ifdef DEBUG
# define DEBUG_KPLAYER_PROCESS
//#define DEBUG_KPLAYER_PROGRESS
# define DEBUG_KPLAYER_HELPER
//#define DEBUG_KPLAYER_LINEOUT
//#define DEBUG_KPLAYER_KIOSLAVE
//#define DEBUG_KPLAYER_DUMP
# endif
# include "kplayerprocess.h"
# include "kplayerprocess.moc"
# include "kplayerengine.h"
# include "kplayersettings.h"
# include "kplayerwidget.h"
# define MIN_VIDEO_LENGTH 5
# define NO_SEEK_ORIGIN -5
# ifdef DEBUG_KPLAYER_DUMP
static TQFile s_dump ( TQDir : : homeDirPath ( ) + " /tdeioslave.dump " ) ;
# endif
static TQRegExp re_ext ( " ^[A-Za-z0-9]+$ " ) ;
static TQRegExp re_a_or_v ( " ^[AV]: *([0-9,:.-]+) " ) ;
static TQRegExp re_a_and_v ( " ^A: *([0-9,:.-]+) + V : * ( [ 0 - 9 , : . - ] + ) " ) ;
static TQRegExp re_start ( " ^(?:Start playing|Starting playback|Za<5A> <61> n<EFBFBD> m p<> ehr<68> vat|Starte Wiedergabe|P<> begynder afspilning|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Empezando reproducci<63> n|D<> marre la lecture|Lej<65> tsz<73> s ind<6E> t<EFBFBD> sa|Inizio la riproduzione|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |재생을 시작합니다|Почнува плејбекот|Start afspelen|Starter avspilling|Zaczynam odtwarzanie|In<49> ciando reprodu<64> <75> o|Rulez|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Za<5A> <61> nam prehr<68> va<76> |<7C> almaya ba<62> lan<61> yor|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |<7C> <> ʼ <EFBFBD> <CABC> <EFBFBD> <EFBFBD> |<7C> \\ }<7D> l<EFBFBD> <6C> <EFBFBD> <EFBFBD> ) \ \ . \ \ . \ \ . " , false) ;
//static TQRegExp re_playing ("(?:^(?:Playing|P<> ehr<68> v<EFBFBD> m|Spiele|Afspiller|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> |Reproduciendo|Joue|In riproduzione|Пуштено|Bezig met het afspelen van|Spiller|Odtwarzam|Reproduzindo|Rulez|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Prehr<68> vam|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |<7C> <> <EFBFBD> <EFBFBD> |<7C> <> <EFBFBD> b<EFBFBD> <62> <EFBFBD> <EFBFBD> ) | (?:lej<65> tsz<73> sa|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |재생 중|<7C> al<61> n<EFBFBD> yor)\\.*$)", false);
static TQRegExp re_exiting ( " ^(?:Exiting|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Kon<6F> <6E> m|Beende| ?Afslutter| ?<3F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Saliendo|Sortie|Kil<69> pek|In uscita|<7C> <> λ<EFBFBD> <CEBB> <EFBFBD> Ƥ<EFBFBD> <C6A4> ޤ<EFBFBD> |종료합니다.|Изле г у <D0B3> |Bezig met afsluiten|Avslutter|Wychodz<64> |Saindo|Ie<49> ire|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Kon<6F> <6E> m|<7C> <> k<EFBFBD> l<EFBFBD> yor|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> |<7C> <> <EFBFBD> b<EFBFBD> h<EFBFBD> X) " , false) ;
static TQRegExp re_quit ( " ^(?:Exiting|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Kon<6F> <6E> m|Beende| ?Afslutter| ?<3F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Saliendo|Sortie|Kil<69> pek|In uscita|<7C> <> λ<EFBFBD> <CEBB> <EFBFBD> Ƥ<EFBFBD> <C6A4> ޤ<EFBFBD> |종료합니다.|Изле г у <D0B3> |Bezig met afsluiten|Avslutter|Wychodz<64> |Saindo|Ie<49> ire|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Kon<6F> <6E> m|<7C> <> k<EFBFBD> l<EFBFBD> yor|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> |<7C> <> <EFBFBD> b<EFBFBD> h<EFBFBD> X) \ \ . \ \ . \ \ . \ \ ( ( ? : Quit | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | Konec | Ende | Afslut | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | Salida \ \ . ? | Fin | Kil <EFBFBD> p <EFBFBD> s | Uscita | <EFBFBD> <EFBFBD> λ | 종 료 | О т к а ж и | Stop | Avslutt | Wyj <EFBFBD> cie | Sair | Ie <EFBFBD> ire | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | Koniec | <EFBFBD> <EFBFBD> k <EFBFBD> <EFBFBD> | <EFBFBD> <EFBFBD> Ȧ <EFBFBD> | <EFBFBD> ˳ <EFBFBD> | <EFBFBD> <EFBFBD> <EFBFBD> \ \ } ) \ \ ) " , false) ;
static TQRegExp re_success ( " ^(?:Exiting|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Kon<6F> <6E> m|Beende| ?Afslutter| ?<3F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Saliendo|Sortie|Kil<69> pek|In uscita|<7C> <> λ<EFBFBD> <CEBB> <EFBFBD> Ƥ<EFBFBD> <C6A4> ޤ<EFBFBD> |<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> |<7C> зле г <D0B5> ва |Bezig met afsluiten|Avslutter|Wychodz<64> |Saindo|Ie<49> ire|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |Kon<6F> <6E> m|<7C> <> k<EFBFBD> l<EFBFBD> yor|<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> |<7C> <> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> |<7C> <> <EFBFBD> b<EFBFBD> h<EFBFBD> X) \ \ . \ \ . \ \ . \ \ ( ( ? : End of file | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | Konec souboru | Ende der Datei | Slut p <EFBFBD> filen | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | Fin del archivo \ \ . ? | Fin du fichier | V <EFBFBD> ge a file - nak | Fine del file | <EFBFBD> ե <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ü <EFBFBD> Ǥ <EFBFBD> | 파 일 의 끝 | К р а ј н а д а т о т е к а т а | Einde van bestand | Slutt p <EFBFBD> filen | Koniec pliku | Fim do arquivo | Sf <EFBFBD> r <EFBFBD> it fi <EFBFBD> ier | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | Koniec s <EFBFBD> boru | Dosyan <EFBFBD> n Sonu | <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | <EFBFBD> ļ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | <EFBFBD> ɮ ץ <EFBFBD> <EFBFBD> <EFBFBD> ) \ \ ) " , false) ;
static TQRegExp re_cache_fill ( " ^Cache fill: *([0-9]+[.,]?[0-9]*) * % " , false) ;
static TQRegExp re_generating_index ( " ^Generating Index: *([0-9]+[.,]?[0-9]*) * % " , false) ;
static TQRegExp re_mpeg12 ( " mpeg[12] " , false ) ;
static TQRegExp re_version ( " ^MPlayer *0 \\ .9.* \\ (C \\ ) " ) ;
static TQRegExp re_crash ( " ^ID_SIGNAL=([0-9]+) $ " ) ;
static TQRegExp re_paused ( " ^ID_PAUSED$ " ) ;
static TQCString command_quit ( " quit \n " ) ;
static TQCString command_pause ( " pause \n " ) ;
static TQCString command_visibility ( " sub_visibility \n " ) ;
static TQCString command_seek_100 ( " seek 100 1 \n " ) ;
static TQCString command_seek_99 ( " seek 99 1 \n " ) ;
static TQCString command_seek_95 ( " seek 95 1 \n " ) ;
static TQCString command_seek_90 ( " seek 90 1 \n " ) ;
static TQCString command_seek_50 ( " seek 50 1 \n " ) ;
KPlayerLineOutputProcess : : KPlayerLineOutputProcess ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Creating MPlayer process \n " ;
# endif
m_stdout_line_length = m_stderr_line_length = 0 ;
m_stdout_buffer_length = m_stderr_buffer_length = 129 ;
m_stdout_buffer = new char [ m_stdout_buffer_length ] ;
m_stderr_buffer = new char [ m_stderr_buffer_length ] ;
#if 0
m_merge = false ;
# endif
connect ( this , TQ_SIGNAL ( receivedStdout ( TDEProcess * , char * , int ) ) , TQ_SLOT ( slotReceivedStdout ( TDEProcess * , char * , int ) ) ) ;
connect ( this , TQ_SIGNAL ( receivedStderr ( TDEProcess * , char * , int ) ) , TQ_SLOT ( slotReceivedStderr ( TDEProcess * , char * , int ) ) ) ;
}
KPlayerLineOutputProcess : : ~ KPlayerLineOutputProcess ( )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Destroying MPlayer process \n " ;
# endif
delete [ ] m_stdout_buffer ;
delete [ ] m_stderr_buffer ;
}
void KPlayerLineOutputProcess : : processHasExited ( int state )
{
status = state ;
runs = false ;
commClose ( ) ;
if ( m_stdout_line_length )
emit receivedStdoutLine ( this , m_stdout_buffer , m_stdout_line_length ) ; // , None
if ( m_stderr_line_length )
emit receivedStderrLine ( this , m_stderr_buffer , m_stderr_line_length ) ; // , None
if ( run_mode ! = DontCare )
emit processExited ( this ) ;
}
void KPlayerLineOutputProcess : : slotReceivedStdout ( TDEProcess * proc , char * str , int len )
{
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " StdOut: " < < len < < " ' " < < str < < " ' \n " ;
# endif
receivedOutput ( proc , str , len , m_stdout_buffer , m_stdout_buffer_length , m_stdout_line_length , true ) ;
}
void KPlayerLineOutputProcess : : slotReceivedStderr ( TDEProcess * proc , char * str , int len )
{
#if 0
if ( m_merge )
slotReceivedStdout ( proc , str , len ) ;
else
# endif
receivedOutput ( proc , str , len , m_stderr_buffer , m_stderr_buffer_length , m_stderr_line_length , false ) ;
}
void KPlayerLineOutputProcess : : receivedOutput ( TDEProcess * proc , char * str , int len , char * buf , int blen , int llen , bool bstdout )
{
static int avlen = 0 ;
static char * av = 0 ;
if ( proc ! = this )
return ;
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " stdout received length: " < < len < < " \n " ;
kdDebugTime ( ) < < llen < < " / " < < blen < < " : " < < buf < < " \n " ;
# endif
while ( len > 0 & & ! str [ len - 1 ] )
len - - ;
while ( len > 0 )
{
char * lf = ( char * ) memchr ( str , ' \n ' , len ) ;
if ( ! lf )
lf = str + len ;
char * eol = ( char * ) memchr ( str , ' \r ' , lf - str ) ;
if ( ! eol )
eol = lf ;
if ( eol - str + llen > = blen )
{
char * old_buffer = buf ;
blen = eol - str + llen + 10 ;
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " new buffer length: " < < blen < < " \n " ;
# endif
buf = new char [ blen ] ;
if ( bstdout )
{
m_stdout_buffer = buf ;
m_stdout_buffer_length = blen ;
}
else
{
m_stderr_buffer = buf ;
m_stderr_buffer_length = blen ;
}
if ( llen )
memcpy ( buf , old_buffer , llen ) ;
delete [ ] old_buffer ;
}
if ( eol > str )
{
memcpy ( buf + llen , str , eol - str ) ;
llen + = eol - str ;
if ( bstdout )
m_stdout_line_length = llen ;
else
m_stderr_line_length = llen ;
}
buf [ llen ] = 0 ;
if ( eol - str = = len )
break ;
if ( av & & * av & & re_paused . search ( buf ) > = 0 )
{
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " Sending AV Buffer On Pause: ' " < < av < < " ' \n " ;
# endif
if ( bstdout )
emit receivedStdoutLine ( this , av , strlen ( av ) - 1 ) ;
else
emit receivedStderrLine ( this , av , strlen ( av ) - 1 ) ;
* av = 0 ;
}
if ( re_a_or_v . search ( buf ) > = 0 | | re_cache_fill . search ( buf ) > = 0 | | re_generating_index . search ( buf ) > = 0 )
{
if ( avlen < = llen )
{
if ( av )
delete [ ] av ;
avlen = llen + 10 ;
av = new char [ avlen ] ;
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " new av buffer length: " < < avlen < < " \n " ;
# endif
}
memcpy ( av , buf , llen + 1 ) ;
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " AV Buffer: ' " < < av < < " ' \n " ;
# endif
}
else if ( bstdout )
emit receivedStdoutLine ( this , buf , llen ) ; // , *cr == '\r' ? CR : LF
else
emit receivedStderrLine ( this , buf , llen ) ; // , *cr == '\r' ? CR : LF
// if ( *buf ) // && eol == lf
// {
// write (STDOUT_FILENO, buf, llen);
// write (STDOUT_FILENO, "\n", 1);
// }
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " Buffer: ' " < < buf < < " ' \n " ;
# endif
llen = 0 ;
if ( bstdout )
m_stdout_line_length = llen ;
else
m_stderr_line_length = llen ;
len - = eol - str + 1 ;
str = eol + 1 ;
}
if ( av & & * av )
{
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " Sending AV Buffer: ' " < < av < < " ' \n " ;
# endif
if ( bstdout )
emit receivedStdoutLine ( this , av , strlen ( av ) - 1 ) ;
else
emit receivedStderrLine ( this , av , strlen ( av ) - 1 ) ;
* av = 0 ;
}
//kdDebugTime() << "normal return\n";
}
inline KPlayerSettings * KPlayerProcess : : settings ( void ) const
{
return KPlayerEngine : : engine ( ) - > settings ( ) ;
}
inline KPlayerTrackProperties * KPlayerProcess : : properties ( void ) const
{
return settings ( ) - > properties ( ) ;
}
inline KPlayerConfiguration * KPlayerProcess : : configuration ( void ) const
{
return KPlayerEngine : : engine ( ) - > configuration ( ) ;
}
KPlayerProcess : : KPlayerProcess ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Creating process \n " ;
# endif
m_player = m_helper = 0 ;
m_temporary_file = 0 ;
m_state = Idle ;
m_pausing = m_paused = m_quit = m_kill = m_seek = m_success = m_size_sent = m_info_available = false ;
m_delayed_player = m_delayed_helper = m_sent = m_send_seek = false ;
m_seekable = m_09_version = m_first_chunk = false ;
m_position = m_max_position = m_helper_position = 0 ;
m_seek_origin = NO_SEEK_ORIGIN ;
m_helper_seek = m_helper_seek_count = m_absolute_seek = m_seek_count = m_sent_count = m_cache_size = 0 ;
m_slave_job = m_temp_job = 0 ;
m_send_volume = m_send_contrast = m_send_brightness = m_send_hue = m_send_saturation = false ;
m_send_frame_drop = m_send_audio_id = m_send_subtitle_load = m_send_subtitle_visibility = false ;
m_send_audio_delay = m_send_subtitle_delay = m_send_subtitle_position = 0 ;
m_audio_delay = m_subtitle_delay = m_subtitle_position = 0 ;
m_audio_id = m_subtitle_index = - 1 ;
m_send_subtitle_index = - 2 ;
m_subtitle_visibility = true ;
m_fifo_handle = - 1 ;
m_fifo_offset = 0 ;
m_fifo_notifier = 0 ;
m_fifo_timer = 0 ;
TQString home ( TQDir : : homeDirPath ( ) ) ;
TQDir ( home ) . mkdir ( " .mplayer " ) ;
m_cache . setAutoDelete ( true ) ;
}
KPlayerProcess : : ~ KPlayerProcess ( )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Destroying process \n " ;
# endif
if ( m_player )
delete m_player ;
if ( m_helper )
delete m_helper ;
if ( m_slave_job )
m_slave_job - > kill ( true ) ;
if ( m_temp_job )
m_temp_job - > kill ( true ) ;
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
}
removeDataFifo ( ) ;
}
void KPlayerProcess : : transferTemporaryFile ( void )
{
if ( properties ( ) - > useKioslave ( ) & & properties ( ) - > useTemporaryFile ( ) & & ! m_temporary_file )
{
TQFileInfo fi ( properties ( ) - > url ( ) . fileName ( ) ) ;
TQString extension ( fi . extension ( false ) . lower ( ) ) ;
if ( ! extension . isEmpty ( ) )
extension = " . " + extension ;
m_temporary_file = new KTempFile ( locateLocal ( " tmp " , " kpl " ) , extension ) ;
# ifdef DEBUG_KPLAYER_PROCESS
if ( m_temporary_file )
{
kdDebugTime ( ) < < " Temporary file: " < < m_temporary_file - > name ( ) < < " \n " ;
kdDebugTime ( ) < < " Temporary file creation status: " < < m_temporary_file - > status ( ) < < " \n " ;
}
kdDebugTime ( ) < < " Process: Creating temp job \n " ;
# endif
m_temp_job = TDEIO : : get ( properties ( ) - > url ( ) , false , false ) ;
m_temp_job - > setWindow ( kPlayerWorkspace ( ) ) ;
m_temp_job - > addMetaData ( " PropagateHttpHeader " , " true " ) ;
connect ( m_temp_job , TQ_SIGNAL ( data ( TDEIO : : Job * , const TQByteArray & ) ) , TQ_SLOT ( transferTempData ( TDEIO : : Job * , const TQByteArray & ) ) ) ;
connect ( m_temp_job , TQ_SIGNAL ( result ( TDEIO : : Job * ) ) , TQ_SLOT ( transferTempDone ( TDEIO : : Job * ) ) ) ;
connect ( m_temp_job , TQ_SIGNAL ( percent ( TDEIO : : Job * , unsigned long ) ) , TQ_SLOT ( transferProgress ( TDEIO : : Job * , unsigned long ) ) ) ;
connect ( m_temp_job , TQ_SIGNAL ( infoMessage ( TDEIO : : Job * , const TQString & ) ) , TQ_SLOT ( transferInfoMessage ( TDEIO : : Job * , const TQString & ) ) ) ;
transferProgress ( m_temp_job , 0 ) ;
m_delayed_helper = true ;
}
}
void KPlayerProcess : : load ( KURL )
{
m_position = 0 ;
m_delayed_player = m_delayed_helper = false ;
m_size_sent = properties ( ) - > hasVideo ( ) | | properties ( ) - > hasNoVideo ( ) ;
m_info_available = properties ( ) - > hasLength ( ) ;
if ( m_temp_job )
m_temp_job - > kill ( false ) ;
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
m_temporary_file = 0 ;
}
transferTemporaryFile ( ) ;
}
void KPlayerProcess : : setState ( State state )
{
if ( m_state = = state & & state ! = Paused )
return ;
State previous = m_state ;
m_state = state ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: New state: " < < state < < " , previous state: " < < previous < < " , position: " < < m_position < < " \n " ;
# endif
if ( previous = = Running & & state = = Idle & & ! m_quit )
emit errorDetected ( ) ;
if ( ! m_quit | | state = = Idle )
emit stateChanged ( state , previous ) ;
}
TQString KPlayerProcess : : positionString ( void ) const
{
TQString l ( properties ( ) - > lengthString ( ) ) , p ( timeString ( position ( ) , true ) ) ;
return l . isEmpty ( ) ? p : p + " / " + l ;
}
void KPlayerProcess : : sendHelperCommand ( TQCString & command )
{
if ( ! m_helper )
return ;
m_helper - > writeStdin ( command , command . length ( ) ) ;
# ifdef DEBUG_KPLAYER_HELPER
kdDebugTime ( ) < < " helper << " < < command ;
# endif
}
void KPlayerProcess : : sendPlayerCommand ( TQCString & command )
{
if ( ! m_player )
return ;
m_player - > writeStdin ( command , command . length ( ) ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " process << " < < command ;
# endif
m_sent = true ;
m_sent_count = 0 ;
}
void KPlayerProcess : : get_info ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Get info \n " ;
kdDebugTime ( ) < < " Widget " < < kPlayerWorkspace ( ) - > hiddenWidget ( ) - > x ( )
< < " x " < < kPlayerWorkspace ( ) - > hiddenWidget ( ) - > y ( )
< < " " < < kPlayerWorkspace ( ) - > hiddenWidget ( ) - > width ( )
< < " x " < < kPlayerWorkspace ( ) - > hiddenWidget ( ) - > height ( ) < < " \n " ;
# endif
m_delayed_helper = m_kill = false ;
m_helper_seek = m_helper_seek_count = 0 ;
m_helper_position = 0 ;
if ( properties ( ) - > url ( ) . isEmpty ( ) | | ! properties ( ) - > deviceOption ( ) . isEmpty ( ) )
return ;
if ( properties ( ) - > useKioslave ( ) )
{
if ( ! properties ( ) - > useTemporaryFile ( ) )
return ;
if ( m_temporary_file & & m_temporary_file - > handle ( ) > = 0 )
{
m_delayed_helper = true ;
return ;
}
}
m_helper = new KPlayerLineOutputProcess ;
* m_helper < < properties ( ) - > executablePath ( ) < < " -slave " < < " -ao " < < " null " < < " -vo " < < " x11 "
< < " -wid " < < TQString : : number ( kPlayerWorkspace ( ) - > hiddenWidget ( ) - > winId ( ) ) ;
if ( properties ( ) - > cache ( ) = = 1 | | ! properties ( ) - > url ( ) . isLocalFile ( ) & & ! properties ( ) - > useKioslave ( ) )
* m_helper < < " -nocache " ;
else if ( properties ( ) - > cache ( ) = = 2 )
* m_helper < < " -cache " < < TQString : : number ( properties ( ) - > cacheSize ( ) ) ;
connect ( m_helper , TQ_SIGNAL ( receivedStdoutLine ( KPlayerLineOutputProcess * , char * , int ) ) ,
TQ_SLOT ( receivedHelperLine ( KPlayerLineOutputProcess * , char * , int ) ) ) ;
if ( ! run ( m_helper ) )
{
delete m_helper ;
m_helper = 0 ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Could not start helper \n " ;
# endif
return ;
}
}
void KPlayerProcess : : play ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Play \n " ;
# endif
if ( properties ( ) - > url ( ) . isEmpty ( ) )
return ;
m_position = 0 ;
emit progressChanged ( m_position , Position ) ;
start ( ) ;
}
TQString resourcePath ( const TQString & filename )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Looking for " < < filename < < " \n " ;
# endif
TQString path ( TDEGlobal : : dirs ( ) - > findResource ( " appdata " , filename ) ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " appdata ' " < < path < < " ' \n " ;
# endif
if ( path . isEmpty ( ) )
path = TDEGlobal : : dirs ( ) - > findResource ( " data " , " kplayer/ " + filename ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " found ' " < < path < < " ' \n " ;
# endif
return path ;
}
void KPlayerProcess : : start ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Start \n " ;
# endif
if ( m_slave_job )
m_slave_job - > kill ( false ) ;
m_position = m_max_position = 0 ;
m_seek_count = m_cache_size = m_sent_count = 0 ;
m_pausing = m_paused = m_quit = m_kill = m_09_version = m_delayed_player = m_first_chunk = false ;
m_seek = m_success = m_send_seek = m_sent = false ;
m_send_volume = m_send_contrast = m_send_brightness = m_send_hue = m_send_saturation = false ;
m_send_frame_drop = m_send_audio_id = m_send_subtitle_load = m_send_subtitle_visibility = false ;
m_send_audio_delay = m_send_subtitle_delay = m_send_subtitle_position = 0 ;
m_send_subtitle_index = - 2 ;
m_seekable = m_subtitle_visibility = true ;
m_cache . clear ( ) ;
setState ( Running ) ;
transferTemporaryFile ( ) ;
if ( properties ( ) - > useKioslave ( ) & & properties ( ) - > useTemporaryFile ( )
& & m_temporary_file & & m_temporary_file - > handle ( ) > = 0 )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Delaying play... \n " ;
# endif
m_delayed_player = true ;
return ;
}
/*if ( m_helper && re_dvd_vcd.search (settings() -> url().url()) >= 0 )
{
m_delayed_play = true ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Delaying play... \n " ;
# endif
return ;
} */
m_player = new KPlayerLineOutputProcess ;
* m_player < < properties ( ) - > executablePath ( ) < < " -zoom " < < " -noautosub " < < " -slave "
< < " -wid " < < TQString : : number ( kPlayerWidget ( ) - > winId ( ) ) < < " -stop-xscreensaver " ;
TQString driver ( properties ( ) - > videoDriverString ( ) ) ;
if ( ! driver . isEmpty ( ) )
{
if ( driver . startsWith ( " xvmc " ) )
driver = " xvmc:ck=set " + driver . mid ( 4 ) ;
else if ( driver . startsWith ( " xv, " ) | | driver . startsWith ( " xv: " ) )
driver = " xv:ck=set " + driver . mid ( 2 ) ;
* m_player < < " -vo " < < driver < < " -colorkey " < < " 0x020202 " ;
}
driver = properties ( ) - > audioDriverString ( ) ;
if ( ! driver . isEmpty ( ) )
* m_player < < " -ao " < < driver ;
if ( properties ( ) - > softwareVolume ( ) )
* m_player < < " -softvol " < < " -softvol-max " < < TQString : : number ( properties ( ) - > maximumSoftwareVolume ( ) ) ;
else if ( driver . startsWith ( " alsa " ) | | driver . startsWith ( " oss " ) )
{
driver = properties ( ) - > mixerDevice ( ) ;
if ( ! driver . isEmpty ( ) )
* m_player < < " -mixer " < < driver ;
driver = properties ( ) - > mixerChannel ( ) ;
if ( ! driver . isEmpty ( ) )
* m_player < < " -mixer-channel " < < driver ;
}
* m_player < < " -osdlevel " < < TQCString ( ) . setNum ( properties ( ) - > osdLevel ( ) ) ;
* m_player < < " -contrast " < < TQCString ( ) . setNum ( settings ( ) - > contrast ( ) ) ;
* m_player < < " -brightness " < < TQCString ( ) . setNum ( settings ( ) - > brightness ( ) ) ;
* m_player < < " -hue " < < TQCString ( ) . setNum ( settings ( ) - > hue ( ) ) ;
* m_player < < " -saturation " < < TQCString ( ) . setNum ( settings ( ) - > saturation ( ) ) ;
if ( settings ( ) - > frameDrop ( ) = = 0 )
* m_player < < " -noframedrop " ;
else if ( settings ( ) - > frameDrop ( ) = = 1 )
* m_player < < " -framedrop " ;
else if ( settings ( ) - > frameDrop ( ) = = 2 )
* m_player < < " -hardframedrop " ;
int cache = properties ( ) - > cache ( ) ;
if ( cache = = 0 & & properties ( ) - > useKioslave ( ) & & ( ! properties ( ) - > useTemporaryFile ( ) | | ! m_temporary_file ) )
* m_player < < " -cache " < < " 1024 " ;
else if ( cache = = 2 )
* m_player < < " -cache " < < TQString ( ) . setNum ( properties ( ) - > cacheSize ( ) ) ;
else if ( cache = = 1 )
* m_player < < " -nocache " ;
if ( properties ( ) - > videoScaler ( ) > 0 )
* m_player < < " -sws " < < TQCString ( ) . setNum ( properties ( ) - > videoScaler ( ) ) ;
m_audio_delay = settings ( ) - > audioDelay ( ) ;
if ( m_audio_delay ! = 0 )
* m_player < < " -delay " < < TQCString ( ) . setNum ( m_audio_delay ) ;
if ( properties ( ) - > hasVideoID ( ) )
* m_player < < " -vid " < < TQCString ( ) . setNum ( properties ( ) - > videoID ( ) ) ;
m_audio_id = properties ( ) - > audioID ( ) ;
if ( m_audio_id > - 1 )
* m_player < < " -aid " < < TQCString ( ) . setNum ( m_audio_id ) ;
m_subtitles . clear ( ) ;
m_vobsub = TQString : : null ;
m_subtitle_index = properties ( ) - > subtitleIndex ( ) ;
if ( settings ( ) - > hasSubtitles ( ) )
{
if ( settings ( ) - > showVobsubSubtitles ( ) | | settings ( ) - > hasVobsubSubtitles ( ) & & ! settings ( ) - > showSubtitles ( ) )
{
m_vobsub = settings ( ) - > vobsubSubtitles ( ) ;
* m_player < < " -vobsub " < < m_vobsub ;
if ( properties ( ) - > hasVobsubID ( ) )
* m_player < < " -vobsubid " < < TQString : : number ( properties ( ) - > vobsubID ( ) ) ;
else
m_send_subtitle_index = m_subtitle_index ;
}
else if ( settings ( ) - > showSubtitles ( ) )
{
if ( properties ( ) - > hasSubtitleID ( ) )
* m_player < < " -sid " < < TQString : : number ( properties ( ) - > subtitleID ( ) ) ;
else if ( settings ( ) - > hasExternalSubtitles ( ) )
{
TQString urls ( settings ( ) - > currentSubtitles ( ) ) ;
if ( urls . find ( ' , ' ) < 0 )
* m_player < < " -sub " < < urls ;
else
{
m_subtitle_index = - 1 ;
m_send_subtitle_load = true ;
}
}
}
}
m_subtitle_delay = settings ( ) - > subtitleDelay ( ) ;
if ( m_subtitle_delay ! = 0 )
* m_player < < " -subdelay " < < TQCString ( ) . setNum ( m_subtitle_delay ) ;
m_subtitle_position = settings ( ) - > subtitlePosition ( ) ;
if ( m_subtitle_position ! = 100 )
* m_player < < " -subpos " < < TQCString ( ) . setNum ( m_subtitle_position ) ;
TQString font ( configuration ( ) - > subtitleFontName ( ) ) ;
if ( configuration ( ) - > subtitleFontBold ( ) )
font + = " :bold " ;
if ( configuration ( ) - > subtitleFontItalic ( ) )
font + = " :italic " ;
* m_player < < " -fontconfig " < < " -font " < < font ;
* m_player < < " -subfont-autoscale " < < ( configuration ( ) - > subtitleAutoscale ( ) ? " 3 " : " 0 " ) ;
if ( configuration ( ) - > subtitleTextSize ( ) )
* m_player < < " -subfont-text-scale " < < TQString : : number ( configuration ( ) - > subtitleTextSize ( ) ) ;
if ( configuration ( ) - > hasSubtitleFontOutline ( ) )
* m_player < < " -ffactor " < < configuration ( ) - > subtitleFontOutlineString ( ) ;
if ( configuration ( ) - > hasSubtitleTextWidth ( ) )
* m_player < < " -subwidth " < < configuration ( ) - > subtitleTextWidthString ( ) ;
const TQString & encoding ( properties ( ) - > subtitleEncoding ( ) ) ;
if ( encoding = = " UTF-8 " )
* m_player < < " -utf8 " ;
else if ( ! encoding . isEmpty ( ) )
* m_player < < " -subcp " < < encoding ;
if ( properties ( ) - > hasSubtitleFramerate ( ) )
* m_player < < " -subfps " < < properties ( ) - > subtitleFramerateString ( ) ;
* m_player < < ( configuration ( ) - > subtitleEmbeddedFonts ( ) ? " -embeddedfonts " : " -noembeddedfonts " ) ;
if ( properties ( ) - > subtitleClosedCaption ( ) )
* m_player < < " -subcc " ;
if ( properties ( ) - > videoDoubleBuffering ( ) )
* m_player < < " -double " ;
if ( properties ( ) - > videoDirectRendering ( ) & & ! settings ( ) - > showSubtitles ( ) )
* m_player < < " -dr " ;
if ( ! properties ( ) - > videoDriverString ( ) . startsWith ( " sdl " )
& & ! properties ( ) - > videoDriverString ( ) . startsWith ( " svga " ) )
{
TQString path = resourcePath ( " input.conf " ) ;
if ( ! path . isEmpty ( ) )
* m_player < < " -input " < < " conf= " + path ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Input.conf: ' " < < path < < " ' \n " ;
# endif
}
if ( properties ( ) - > useKioslave ( ) & & ( ! properties ( ) - > useTemporaryFile ( ) | | ! m_temporary_file ) )
{
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
m_temporary_file = 0 ;
}
TQString ext ( properties ( ) - > extension ( ) ) ;
if ( re_ext . search ( ext ) > = 0 )
ext . prepend ( ' . ' ) ;
else
ext = " " ;
m_fifo_name = TQFile : : encodeName ( TQDir : : homeDirPath ( ) + " /.mplayer/kpstream " + ext ) ;
removeDataFifo ( ) ;
# ifdef HAVE_MKFIFO
# ifdef DEBUG_KPLAYER_PROCESS
int rv =
# endif
: : mkfifo ( m_fifo_name , S_IRUSR | S_IWUSR ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: mkfifo " < < m_fifo_name < < " returned " < < rv < < " \n " ;
# endif
# else
# ifdef DEBUG_KPLAYER_PROCESS
int rv =
# endif
: : mknod ( m_fifo_name , S_IFIFO | S_IRUSR | S_IWUSR , 0 ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: mknod " < < m_fifo_name < < " returned " < < rv < < " \n " ;
# endif
# endif
}
else
m_fifo_name = TQCString ( ) ;
connect ( m_player , TQ_SIGNAL ( receivedStdoutLine ( KPlayerLineOutputProcess * , char * , int ) ) ,
TQ_SLOT ( receivedOutputLine ( KPlayerLineOutputProcess * , char * , int ) ) ) ;
connect ( m_player , TQ_SIGNAL ( receivedStderrLine ( KPlayerLineOutputProcess * , char * , int ) ) ,
TQ_SLOT ( receivedOutputLine ( KPlayerLineOutputProcess * , char * , int ) ) ) ;
if ( ! run ( m_player ) )
{
delete m_player ;
m_player = 0 ;
emit messageReceived ( i18n ( " Could not start MPlayer " ) ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Could not start MPlayer \n " ;
# endif
setState ( Idle ) ;
return ;
}
if ( properties ( ) - > useKioslave ( ) & & ( ! properties ( ) - > useTemporaryFile ( ) | | ! m_temporary_file ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Will send get_time_length for ' " < < properties ( ) - > url ( ) . url ( ) < < " ' \n " ;
kdDebugTime ( ) < < " Process: Creating slave job \n " ;
# endif
m_slave_job = TDEIO : : get ( properties ( ) - > url ( ) , false , false ) ;
m_slave_job - > setWindow ( kPlayerWorkspace ( ) ) ;
m_slave_job - > addMetaData ( " PropagateHttpHeader " , " true " ) ;
connect ( m_slave_job , TQ_SIGNAL ( data ( TDEIO : : Job * , const TQByteArray & ) ) , TQ_SLOT ( transferData ( TDEIO : : Job * , const TQByteArray & ) ) ) ;
connect ( m_slave_job , TQ_SIGNAL ( result ( TDEIO : : Job * ) ) , TQ_SLOT ( transferDone ( TDEIO : : Job * ) ) ) ;
connect ( m_slave_job , TQ_SIGNAL ( infoMessage ( TDEIO : : Job * , const TQString & ) ) , TQ_SLOT ( transferInfoMessage ( TDEIO : : Job * , const TQString & ) ) ) ;
m_cache_size = properties ( ) - > cache ( ) = = 2 ? properties ( ) - > cacheSize ( ) * 1024 : 1048576 ;
m_first_chunk = true ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Cache size: " < < m_cache_size < < " \n " ;
# endif
m_seekable = properties ( ) - > playlist ( ) ;
}
properties ( ) - > resetVobsubIDs ( ) ;
}
void KPlayerProcess : : restart ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Restart \n " ;
# endif
if ( m_temp_job | | ! m_player | | properties ( ) - > url ( ) . isEmpty ( ) | | state ( ) = = Idle )
return ;
m_quit = true ;
m_cache . clear ( ) ;
if ( m_slave_job )
m_slave_job - > kill ( false ) ;
m_absolute_seek = int ( m_position ) ;
sendPlayerCommand ( command_quit ) ;
stop ( & m_player , & m_quit , m_state ! = Paused ) ;
start ( ) ;
m_send_seek = true ;
}
bool KPlayerProcess : : run ( KPlayerLineOutputProcess * player )
{
static TQRegExp re_space ( " + " ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Run \n " ;
# endif
TQString codec ( properties ( ) - > videoCodecString ( ) ) ;
if ( ! codec . isEmpty ( ) )
* player < < " -vc " < < codec ;
codec = properties ( ) - > audioCodecString ( ) ;
if ( ! codec . isEmpty ( ) )
* player < < " -ac " < < codec ;
codec = properties ( ) - > demuxerString ( ) ;
if ( ! codec . isEmpty ( ) )
* player < < " -demuxer " < < codec ;
if ( properties ( ) - > buildNewIndex ( ) = = 0 )
* player < < " -idx " ;
else if ( properties ( ) - > buildNewIndex ( ) = = 2 )
* player < < " -forceidx " ;
* player < < " -noquiet " < < " -msglevel " < < " identify=4 " ;
TQString commandline = properties ( ) - > commandLine ( ) ;
if ( ! commandline . isEmpty ( ) )
* player < < TQStringList : : split ( re_space , commandline ) ;
codec = properties ( ) - > deviceSetting ( ) ;
if ( ! codec . isEmpty ( ) )
* player < < properties ( ) - > deviceOption ( ) < < codec ;
if ( properties ( ) - > playlist ( ) )
* player < < " -playlist " ;
else
* player < < " -- " ;
if ( properties ( ) - > useKioslave ( ) )
* player < < ( properties ( ) - > useTemporaryFile ( ) & & m_temporary_file ? TQFile : : encodeName ( m_temporary_file - > name ( ) ) : m_fifo_name ) ;
else
* player < < properties ( ) - > urlString ( ) ;
connect ( player , TQ_SIGNAL ( processExited ( TDEProcess * ) ) , TQ_SLOT ( playerProcessExited ( TDEProcess * ) ) ) ;
#if 0
player - > setMerge ( true ) ;
# endif
return player - > start ( TDEProcess : : NotifyOnExit , TDEProcess : : All ) ;
}
void KPlayerProcess : : pause ( void )
{
if ( ! m_player | | m_quit )
return ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process::Pause: state " < < m_state < < " sent " < < m_sent < < " count " < < m_sent_count < < " pausing " < < m_pausing < < " paused " < < m_paused < < " \n " ;
# endif
if ( m_sent | | m_pausing | | state ( ) = = Running )
{
m_pausing = ! m_pausing ;
return ;
}
sendPlayerCommand ( command_pause ) ;
setState ( m_state = = Paused ? Playing : Paused ) ;
m_pausing = m_paused = false ;
}
void KPlayerProcess : : stop ( KPlayerLineOutputProcess * * player , bool * quit , bool send_quit )
{
if ( * player )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Stopping MPlayer process \n " ;
# endif
* quit = true ;
if ( send_quit )
{
if ( ( * player ) - > isRunning ( ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: MPlayer is running. Waiting... \n " ;
# endif
TDEProcessController : : theTDEProcessController - > waitForProcessExit ( 1 ) ;
}
//if ( *player && (*player) -> isRunning() )
// TDEProcessController::theTDEProcessController -> waitForProcessExit (1);
//if ( *player && (*player) -> isRunning() )
// TDEProcessController::theTDEProcessController -> waitForProcessExit (1);
}
if ( * quit & & * player & & ( * player ) - > isRunning ( ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Closing MPlayer... \n " ;
# endif
( * player ) - > kill ( ) ;
TDEProcessController : : theTDEProcessController - > waitForProcessExit ( 1 ) ;
if ( * quit & & * player & & ( * player ) - > isRunning ( ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Killing MPlayer... \n " ;
# endif
( * player ) - > kill ( SIGKILL ) ;
TDEProcessController : : theTDEProcessController - > waitForProcessExit ( 1 ) ;
if ( * quit & & * player & & ( * player ) - > isRunning ( ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Could not shut down MPlayer \n " ;
# endif
( * player ) - > detach ( ) ;
}
}
}
if ( * quit & & * player )
{
delete * player ;
* player = 0 ;
}
}
}
void KPlayerProcess : : stop ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Stop \n " ;
# endif
m_delayed_helper = m_delayed_player = false ;
m_quit = true ;
if ( m_temp_job )
{
m_temp_job - > kill ( false ) ;
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
m_temporary_file = 0 ;
}
}
m_cache . clear ( ) ;
if ( m_slave_job )
m_slave_job - > kill ( false ) ;
if ( m_player )
sendPlayerCommand ( command_quit ) ;
stop ( & m_player , & m_quit , m_state ! = Paused ) ;
setState ( Idle ) ;
}
void KPlayerProcess : : kill ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Kill \n " ;
# endif
m_delayed_helper = m_delayed_player = false ;
m_quit = m_kill = true ;
if ( m_temp_job )
{
m_temp_job - > kill ( false ) ;
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
m_temporary_file = 0 ;
}
}
m_cache . clear ( ) ;
if ( m_slave_job )
m_slave_job - > kill ( false ) ;
if ( m_player )
sendPlayerCommand ( command_quit ) ;
if ( m_helper )
sendHelperCommand ( command_quit ) ;
stop ( & m_player , & m_quit , m_state ! = Paused ) ;
stop ( & m_helper , & m_kill ) ;
//setState (Idle);
}
void KPlayerProcess : : progressSliderReleased ( void )
{
m_seek_count = 1 ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Slider released. Position " < < position ( ) < < " origin " < < m_seek_origin < < " sent " < < m_sent < < " count " < < m_seek_count < < " \n " ;
# endif
}
void KPlayerProcess : : absoluteSeek ( int seconds )
{
if ( ! m_player | | m_quit )
return ;
if ( seconds < 0 )
seconds = 0 ;
if ( m_sent | | m_position - m_seek_origin < 0.65 & & m_seek_origin - m_position < 0.25 )
{
m_send_seek = true ;
m_absolute_seek = seconds ;
return ;
}
if ( m_position - float ( seconds ) < 0.95 & & float ( seconds ) - m_position < 0.45 )
{
if ( float ( seconds ) > m_position )
seconds + + ;
else
seconds - - ;
}
TQCString s ( " seek " ) ;
// broken codec workaround
if ( properties ( ) - > length ( ) > = MIN_VIDEO_LENGTH
& & re_mpeg12 . search ( properties ( ) - > videoCodecString ( ) ) > = 0
& & properties ( ) - > deviceOption ( ) . isEmpty ( ) )
{
seconds = limit ( int ( float ( seconds ) / properties ( ) - > length ( ) * 100 + 0.5 ) , 0 , 100 ) ;
s + = TQCString ( ) . setNum ( seconds ) + " 1 \n " ;
}
else
s + = TQCString ( ) . setNum ( seconds ) + " 2 \n " ;
sendPlayerCommand ( s ) ;
m_seek = true ;
m_seek_origin = position ( ) ;
m_send_seek = false ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sent seek. Position " < < position ( ) < < " origin " < < m_seek_origin < < " sent " < < m_sent < < " count " < < m_seek_count < < " \n " ;
# endif
}
void KPlayerProcess : : relativeSeek ( int seconds )
{
if ( ! m_player | | m_quit | | seconds = = 0 )
return ;
TQCString s ( " seek " ) ;
// broken codec workaround
if ( ( seconds > 4 | | seconds < - 4 ) & & properties ( ) - > length ( ) > = MIN_VIDEO_LENGTH
& & re_mpeg12 . search ( properties ( ) - > videoCodecString ( ) ) > = 0
& & properties ( ) - > deviceOption ( ) . isEmpty ( ) )
{
//seconds = limit (int ((m_position + seconds) / properties() -> length() * 100 + 0.5), 0, 100);
//s += TQCString().setNum (seconds) + " 1\n";
//if ( m_send_seek )
// m_absolute_seek += seconds;
//else
absoluteSeek ( int ( m_position + seconds + 0.5 ) ) ;
return ;
}
else
s + = TQCString ( ) . setNum ( seconds ) + " \n " ;
sendPlayerCommand ( s ) ;
m_seek = true ;
}
void KPlayerProcess : : volume ( int volume )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing )
return ;
if ( m_sent )
{
m_send_volume = true ;
return ;
}
volume = limit ( volume , 0 , 100 ) ;
TQCString s ( " volume " ) ;
s + = TQCString ( ) . setNum ( volume ) + " 1 \n " ;
sendPlayerCommand ( s ) ;
m_send_volume = false ;
}
void KPlayerProcess : : frameDrop ( int frame_drop )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( m_sent | | state ( ) = = Running )
{
m_send_frame_drop = true ;
return ;
}
TQCString s ( " frame_drop " ) ;
s + = TQCString ( ) . setNum ( frame_drop ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_frame_drop = false ;
}
void KPlayerProcess : : contrast ( int contrast )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing )
return ;
if ( m_sent )
{
m_send_contrast = true ;
return ;
}
contrast = limit ( contrast , - 100 , 100 ) ;
TQCString s ( " contrast " ) ;
s + = TQCString ( ) . setNum ( contrast ) + " 1 \n " ;
sendPlayerCommand ( s ) ;
m_send_contrast = false ;
}
void KPlayerProcess : : brightness ( int brightness )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing )
return ;
if ( m_sent )
{
m_send_brightness = true ;
return ;
}
brightness = limit ( brightness , - 100 , 100 ) ;
TQCString s ( " brightness " ) ;
s + = TQCString ( ) . setNum ( brightness ) + " 1 \n " ;
sendPlayerCommand ( s ) ;
m_send_brightness = false ;
}
void KPlayerProcess : : hue ( int hue )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing )
return ;
if ( m_sent )
{
m_send_hue = true ;
return ;
}
hue = limit ( hue , - 100 , 100 ) ;
TQCString s ( " hue " ) ;
s + = TQCString ( ) . setNum ( hue ) + " 1 \n " ;
sendPlayerCommand ( s ) ;
m_send_hue = false ;
}
void KPlayerProcess : : saturation ( int saturation )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing )
return ;
if ( m_sent )
{
m_send_saturation = true ;
return ;
}
saturation = limit ( saturation , - 100 , 100 ) ;
TQCString s ( " saturation " ) ;
s + = TQCString ( ) . setNum ( saturation ) + " 1 \n " ;
sendPlayerCommand ( s ) ;
m_send_saturation = false ;
}
void KPlayerProcess : : subtitleMove ( int position , bool absolute )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( absolute )
position - = m_subtitle_position ;
if ( position = = 0 )
return ;
m_subtitle_position + = position ;
if ( m_sent | | state ( ) = = Running )
{
m_send_subtitle_position + = position ;
return ;
}
position + = m_send_subtitle_position ;
if ( position = = 0 )
return ;
TQCString s ( " sub_pos " ) ;
s + = TQCString ( ) . setNum ( position ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_subtitle_position = 0 ;
}
void KPlayerProcess : : subtitleDelay ( float delay , bool absolute )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( absolute )
delay - = m_subtitle_delay ;
if ( delay < 0.001 & & delay > - 0.001 )
return ;
m_subtitle_delay + = delay ;
if ( m_sent | | state ( ) = = Running )
{
m_send_subtitle_delay + = delay ;
return ;
}
delay + = m_send_subtitle_delay ;
if ( delay < 0.001 & & delay > - 0.001 )
return ;
TQCString s ( " sub_delay " ) ;
s + = TQCString ( ) . setNum ( - delay ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_subtitle_delay = 0 ;
}
void KPlayerProcess : : subtitleIndex ( int index )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( m_sent | | state ( ) = = Running )
{
m_send_subtitle_index = index ;
return ;
}
TQCString s ( " sub_select " ) ;
s + = TQCString ( ) . setNum ( index ) + " \n " ;
sendPlayerCommand ( s ) ;
m_subtitle_index = index ;
m_send_subtitle_index = - 2 ;
if ( index = = - 1 = = m_subtitle_visibility )
subtitleVisibility ( ) ;
else
m_send_subtitle_visibility = false ;
}
void KPlayerProcess : : subtitleVisibility ( void )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( m_sent | | state ( ) = = Running )
{
m_send_subtitle_visibility = true ;
return ;
}
sendPlayerCommand ( command_visibility ) ;
m_subtitle_visibility = ! m_subtitle_visibility ;
m_send_subtitle_visibility = false ;
}
void KPlayerProcess : : subtitles ( void )
{
if ( ! m_player | | m_quit | | state ( ) = = Idle )
return ;
if ( m_vobsub ! = settings ( ) - > vobsubSubtitles ( ) & & settings ( ) - > showVobsubSubtitles ( ) )
{
restart ( ) ;
return ;
}
int index = properties ( ) - > subtitleIndex ( ) ;
int count = properties ( ) - > subtitleIDs ( ) . count ( ) + properties ( ) - > vobsubIDs ( ) . count ( ) ;
if ( index < count )
{
subtitleIndex ( index ) ;
m_send_subtitle_load = false ;
return ;
}
TQString subtitle ( settings ( ) - > currentSubtitles ( ) ) ;
index = m_subtitles . findIndex ( subtitle ) ;
if ( index > = 0 )
{
subtitleIndex ( index + count ) ;
m_send_subtitle_load = false ;
return ;
}
if ( m_sent | | state ( ) = = Running )
{
m_send_subtitle_load = true ;
return ;
}
TQCString s ( " sub_load " ) ;
s + = ' " ' + subtitle . utf8 ( ) + " \" \n " ;
sendPlayerCommand ( s ) ;
m_send_subtitle_load = false ;
}
void KPlayerProcess : : audioDelay ( float delay , bool absolute )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( absolute )
delay - = m_audio_delay ;
if ( delay < 0.001 & & delay > - 0.001 )
return ;
m_audio_delay + = delay ;
if ( m_sent | | state ( ) = = Running )
{
m_send_audio_delay + = delay ;
return ;
}
delay + = m_send_audio_delay ;
if ( delay < 0.001 & & delay > - 0.001 )
return ;
TQCString s ( " audio_delay " ) ;
s + = TQCString ( ) . setNum ( - delay ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_audio_delay = 0 ;
}
void KPlayerProcess : : audioID ( int id )
{
if ( ! m_player | | m_quit | | state ( ) ! = Playing & & state ( ) ! = Running )
return ;
if ( m_sent | | state ( ) = = Running )
{
m_send_audio_id = true ;
return ;
}
if ( id ! = m_audio_id )
{
TQRegExp demuxers ( configuration ( ) - > switchAudioDemuxers ( ) ) ;
if ( demuxers . search ( properties ( ) - > demuxerString ( ) ) > = 0 )
{
TQCString s ( " switch_audio " ) ;
s + = TQCString ( ) . setNum ( id ) + " \n " ;
sendPlayerCommand ( s ) ;
m_audio_id = id ;
}
else
restart ( ) ;
}
m_send_audio_id = false ;
}
void KPlayerProcess : : transferData ( TDEIO : : Job * job , const TQByteArray & data )
{
if ( job & & job = = m_slave_job & & m_player )
{
if ( data . size ( ) = = 0 )
return ;
if ( m_cache . count ( ) = = 0 | | m_cache . count ( ) = = 1 & & ! m_first_chunk )
{
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process: Cache: Creating new chunk, size " < < data . size ( ) < < " \n " ;
# endif
m_cache . append ( new TQByteArray ( data . copy ( ) ) ) ;
}
else
{
TQByteArray * array = m_cache . last ( ) ;
int size = array - > size ( ) ;
array - > resize ( size + data . size ( ) , TQGArray : : SpeedOptim ) ;
# ifdef DEBUG_KPLAYER_KIOSLAVE
if ( array - > size ( ) ! = size + data . size ( ) )
kdDebugTime ( ) < < " Process: Cache: Size mismatch: " < < size < < " + " < < data . size ( ) < < " = " < < array - > size ( ) < < " \n " ;
else
kdDebugTime ( ) < < " Process: Cache: Appended to chunk " < < m_cache . count ( ) < < " size " < < size < < " + " < < data . size ( ) < < " = " < < array - > size ( ) < < " \n " ;
# endif
memcpy ( array - > data ( ) + size , data . data ( ) , data . size ( ) ) ;
}
if ( m_cache . count ( ) > 1 & & ! m_slave_job - > isSuspended ( ) & & m_cache . last ( ) - > size ( ) > = m_cache_size )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Suspending transfer job \n " ;
# endif
m_slave_job - > suspend ( ) ;
}
if ( m_cache . count ( ) = = 1 & & ( ! m_first_chunk | | m_cache . first ( ) - > size ( ) > = m_cache_size ) )
{
if ( m_first_chunk & & ! m_quit )
emit progressChanged ( 100 , CacheFill ) ;
sendFifoData ( ) ;
}
else if ( m_first_chunk & & ! m_quit )
emit progressChanged ( limit ( int ( ( m_cache . first ( ) - > size ( ) * 100 + m_cache_size / 2 ) / m_cache_size ) , 0 , 100 ) , CacheFill ) ;
}
else
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Stray transfer job \n " ;
# endif
m_cache . clear ( ) ;
if ( job )
job - > kill ( true ) ;
}
}
void KPlayerProcess : : transferTempData ( TDEIO : : Job * job , const TQByteArray & data )
{
if ( job & & job = = m_temp_job & & m_temporary_file )
{
# ifdef DEBUG_KPLAYER_KIOSLAVE
int rv =
# endif
m_temporary_file - > file ( ) - > writeBlock ( data ) ;
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process: Write call returned " < < rv < < " \n " ;
# endif
}
else
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Stray temporary file TransferJob \n " ;
# endif
if ( job )
job - > kill ( true ) ;
}
}
void KPlayerProcess : : transferProgress ( TDEIO : : Job * job , unsigned long progress )
{
if ( job & & job = = m_temp_job )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Temporary file transfer progress received: " < < progress < < " \n " ;
# endif
emit progressChanged ( progress , FileTransfer ) ;
}
# ifdef DEBUG_KPLAYER_PROCESS
else
kdDebugTime ( ) < < " Process: Stray temporary file progress received: " < < progress < < " \n " ;
# endif
}
void KPlayerProcess : : transferInfoMessage ( TDEIO : : Job * job , const TQString & message )
{
if ( job & & ( job = = m_slave_job | | job = = m_temp_job ) )
emit messageReceived ( message ) ;
}
void KPlayerProcess : : transferDone ( TDEIO : : Job * job )
{
if ( job & & job = = m_slave_job )
{
bool error_page = m_slave_job - > isErrorPage ( ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Transfer job ended, result code: " < < job - > error ( )
< < " error page " < < error_page < < " \n " ;
# endif
if ( job - > error ( ) ! = 0 & & ( job - > error ( ) ! = 20 | | ! m_quit ) | | error_page )
{
TQString errorString ;
if ( job - > error ( ) ! = 0 )
{
errorString = job - > errorString ( ) ;
if ( errorString . isEmpty ( ) )
{
KURL url ( properties ( ) - > url ( ) ) ;
errorString = job - > detailedErrorStrings ( & url ) . first ( ) ;
}
}
else if ( error_page )
{
m_cache . clear ( ) ;
/*#ifdef DEBUG_KPLAYER_PROCESS
TDEIO : : MetaData metadata ( job - > metaData ( ) ) ;
for ( TDEIO : : MetaData : : Iterator it = metadata . begin ( ) ; it ! = metadata . end ( ) ; + + it )
kdDebugTime ( ) < < " Process: Error page metadata: key ' " < < it . key ( ) < < " ' data ' " < < it . data ( ) < < " ' \n " ;
# endif* /
errorString = job - > queryMetaData ( " HTTP-Headers " ) ;
}
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Error string: ' " < < errorString < < " ' \n " ;
# endif
if ( ! errorString . isEmpty ( ) )
emit messageReceived ( errorString ) ;
emit errorDetected ( ) ;
error_page = ( error_page | | m_first_chunk ) & & ! m_quit ;
}
else if ( m_cache . count ( ) = = 1 & & m_first_chunk & & m_cache . first ( ) - > size ( ) < m_cache_size & & ! m_quit )
sendFifoData ( ) ;
m_cache_size = 0 ;
m_first_chunk = false ;
m_slave_job = 0 ;
if ( m_player & & m_cache . isEmpty ( ) )
{
removeDataFifo ( ) ;
if ( error_page & & m_player )
{
stop ( & m_player , & m_quit ) ;
setState ( Idle ) ;
}
}
}
# ifdef DEBUG_KPLAYER_PROCESS
else
kdDebugTime ( ) < < " Process: Stray transfer job ended \n " ;
# endif
}
void KPlayerProcess : : transferTempDone ( TDEIO : : Job * job )
{
if ( job & & job = = m_temp_job )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Temporary file transfer job ended, result code: " < < job - > error ( )
< < " error page " < < m_temp_job - > isErrorPage ( ) < < " \n " ;
# endif
if ( job - > error ( ) ! = 0 & & ( job - > error ( ) ! = 20 | | ! m_quit ) | | m_temp_job - > isErrorPage ( ) )
{
TQString errorString ;
if ( job - > error ( ) ! = 0 )
errorString = job - > errorString ( ) ;
else if ( m_temp_job - > isErrorPage ( ) )
errorString = job - > queryMetaData ( " HTTP-Headers " ) ;
/* {
# ifdef DEBUG_KPLAYER_PROCESS
TDEIO : : MetaData metadata ( job - > metaData ( ) ) ;
for ( TDEIO : : MetaData : : Iterator it = metadata . begin ( ) ; it ! = metadata . end ( ) ; + + it )
kdDebugTime ( ) < < " Process: Error page metadata: key ' " < < it . key ( ) < < " ' data ' " < < it . data ( ) < < " ' \n " ;
# endif
} */
if ( ! errorString . isEmpty ( ) )
{
emit messageReceived ( errorString ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Error string: " < < errorString < < " \n " ;
# endif
}
/*if ( m_temp_job -> isErrorPage() )
emit messageReceived ( " HTTP request returned an error " ) ;
TQString errorString ( job - > errorString ( ) ) ;
if ( ! errorString . isEmpty ( ) )
emit messageReceived ( errorString ) ;
KURL url ( settings ( ) - > url ( ) ) ;
TQStringList errors ( job - > detailedErrorStrings ( & url ) ) ;
for ( TQStringList : : Iterator it = errors . begin ( ) ; it ! = errors . end ( ) ; + + it )
if ( ! ( * it ) . isEmpty ( ) )
emit messageReceived ( * it ) ; */
emit errorDetected ( ) ;
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
m_temporary_file = 0 ;
}
m_temp_job = 0 ;
m_delayed_player = m_delayed_helper = false ;
setState ( Idle ) ;
}
else if ( m_quit )
{
if ( m_temporary_file )
{
m_temporary_file - > close ( ) ;
m_temporary_file - > unlink ( ) ;
delete m_temporary_file ;
m_temporary_file = 0 ;
}
m_temp_job = 0 ;
m_delayed_player = m_delayed_helper = false ;
}
else
{
emit progressChanged ( 100 , FileTransfer ) ;
m_temp_job = 0 ;
if ( m_temporary_file )
m_temporary_file - > close ( ) ;
if ( m_delayed_helper )
get_info ( ) ;
if ( m_delayed_player )
play ( ) ;
}
}
# ifdef DEBUG_KPLAYER_PROCESS
else
kdDebugTime ( ) < < " Process: Stray temporary file TransferJob ended \n " ;
# endif
}
void KPlayerProcess : : removeDataFifo ( void )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process::removeDataFifo \n " ;
# endif
if ( m_fifo_notifier )
{
delete m_fifo_notifier ;
m_fifo_notifier = 0 ;
}
if ( m_fifo_handle > = 0 )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: closing fifo " < < m_fifo_handle < < " ... \n " ;
# endif
m_fifo_handle = : : close ( m_fifo_handle ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: fifo close returned " < < m_fifo_handle < < " \n " ;
# endif
m_fifo_handle = - 1 ;
m_fifo_offset = 0 ;
}
if ( ! m_fifo_name . isEmpty ( ) )
: : unlink ( m_fifo_name ) ;
# ifdef DEBUG_KPLAYER_DUMP
if ( s_dump . isOpen ( ) )
s_dump . close ( ) ;
# endif
}
void KPlayerProcess : : sendFifoData ( void )
{
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process::sendFifoData \n " ;
# endif
if ( m_fifo_handle < 0 )
{
m_fifo_handle = : : open ( m_fifo_name , O_WRONLY | O_NONBLOCK , S_IRUSR | S_IWUSR ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: fifo open returned " < < m_fifo_handle < < " \n " ;
# endif
if ( m_fifo_handle > = 0 )
{
if ( m_fifo_timer )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: fifo open successful, deleting timer \n " ;
# endif
delete m_fifo_timer ;
m_fifo_timer = 0 ;
}
m_fifo_notifier = new TQSocketNotifier ( m_fifo_handle , TQSocketNotifier : : Write ) ;
m_fifo_notifier - > setEnabled ( false ) ;
connect ( m_fifo_notifier , TQ_SIGNAL ( activated ( int ) ) , TQ_SLOT ( playerDataWritten ( int ) ) ) ;
}
else if ( ! m_fifo_timer )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: fifo open failed, creating timer \n " ;
# endif
m_fifo_timer = new TQTimer ( this ) ;
connect ( m_fifo_timer , TQ_SIGNAL ( timeout ( ) ) , TQ_SLOT ( sendFifoData ( ) ) ) ;
m_fifo_timer - > start ( 100 ) ;
}
}
if ( m_fifo_handle > = 0 )
{
TQByteArray * array = m_cache . first ( ) ;
if ( array & & array - > size ( ) > m_fifo_offset )
{
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process: Cache: Writing " < < array - > size ( ) < < " - " < < m_fifo_offset < < " bytes to fifo \n " ;
# endif
int rv = : : write ( m_fifo_handle , array - > data ( ) + m_fifo_offset , array - > size ( ) - m_fifo_offset ) ;
if ( rv > 0 )
{
# ifdef DEBUG_KPLAYER_DUMP
if ( ! s_dump . isOpen ( ) )
s_dump . open ( IO_WriteOnly ) ;
s_dump . writeBlock ( array - > data ( ) + m_fifo_offset , rv ) ;
# endif
m_fifo_offset + = rv ;
}
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process: Cache: Write call returned " < < rv < < " \n " ;
# endif
m_fifo_notifier - > setEnabled ( true ) ;
m_first_chunk = false ;
}
}
}
void KPlayerProcess : : playerDataWritten ( int fd )
{
if ( fd = = m_fifo_handle )
{
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process: Cache: Data written \n " ;
# endif
TQByteArray * array = m_cache . first ( ) ;
if ( array & & array - > size ( ) < = m_fifo_offset )
{
# ifdef DEBUG_KPLAYER_KIOSLAVE
kdDebugTime ( ) < < " Process: Cache: Wrote " < < array - > size ( ) < < " byte chunk, offset " < < m_fifo_offset < < " \n " ;
# endif
m_cache . remove ( ) ;
m_fifo_offset = 0 ;
m_fifo_notifier - > setEnabled ( false ) ;
if ( m_slave_job & & m_slave_job - > isSuspended ( ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Resuming transfer job \n " ;
# endif
m_slave_job - > resume ( ) ;
}
}
if ( ! m_cache . isEmpty ( ) )
sendFifoData ( ) ;
else if ( ! m_slave_job )
removeDataFifo ( ) ;
}
# ifdef DEBUG_KPLAYER_PROCESS
else
kdDebugTime ( ) < < " Process: Stray socket notifier signal \n " ;
# endif
}
void KPlayerProcess : : playerProcessExited ( TDEProcess * proc )
{
if ( proc = = m_player )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: MPlayer process exited \n " ;
# endif
delete m_player ;
m_player = 0 ;
if ( m_success & & ! m_seek & & m_position > 0 & & m_position > properties ( ) - > length ( ) / 40 )
{
properties ( ) - > setLength ( m_max_position ) ;
m_info_available = true ;
emit infoAvailable ( ) ;
properties ( ) - > commit ( ) ;
}
m_cache . clear ( ) ;
if ( m_slave_job )
m_slave_job - > kill ( false ) ;
removeDataFifo ( ) ;
m_fifo_name = TQCString ( ) ;
if ( ! m_quit )
setState ( Idle ) ;
}
else if ( proc = = m_helper )
{
# ifdef DEBUG_KPLAYER_HELPER
kdDebugTime ( ) < < " MPlayer helper process exited \n " ;
# endif
delete m_helper ;
m_helper = 0 ;
if ( m_helper_seek < 500 & & m_helper_position > = MIN_VIDEO_LENGTH
& & m_helper_position > properties ( ) - > length ( ) / 40 )
properties ( ) - > setLength ( m_helper_position ) ;
m_info_available = true ;
if ( ! m_kill )
emit infoAvailable ( ) ;
if ( ! m_size_sent & & ! m_kill & & m_helper_seek > 0 )
{
emit sizeAvailable ( ) ;
m_size_sent = true ;
}
if ( ! m_kill & & properties ( ) - > url ( ) . isValid ( ) )
properties ( ) - > commit ( ) ;
/*if ( m_delayed_play && ! m_player )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Delayed play... \n " ;
# endif
play ( ) ;
} */
}
else
{
delete proc ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Stray MPlayer process exited \n " ;
# endif
}
}
void KPlayerProcess : : receivedOutputLine ( KPlayerLineOutputProcess * proc , char * str , int len )
{
if ( proc ! = m_player )
{
char buf [ 1025 ] ;
if ( len > 1024 )
len = 1024 ;
memcpy ( buf , str , len ) ;
buf [ len ] = 0 ;
if ( re_exiting . search ( buf ) < 0 )
proc - > writeStdin ( command_quit , command_quit . length ( ) ) ;
return ;
}
static float prev_position = - 1 ;
float ftime ;
if ( state ( ) = = Running )
kPlayerWidget ( ) - > sendConfigureEvent ( ) ;
if ( re_version . search ( str ) > = 0 )
{
m_09_version = true ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: MPlayer 0.9x detected \n " ;
# endif
}
if ( re_paused . search ( str ) > = 0 )
{
m_paused = true ;
m_pausing = false ;
m_sent = false ;
setState ( Paused ) ;
}
if ( strncmp ( str , " ID_FILE_SUB_FILENAME= " , 21 ) = = 0 & & str [ 21 ] )
{
m_subtitles . append ( str + 21 ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Subtitle file " < < m_subtitles . last ( ) < < " \n " ;
# endif
if ( settings ( ) - > currentSubtitles ( ) = = m_subtitles . last ( ) )
subtitleIndex ( properties ( ) - > subtitleIDs ( ) . count ( ) + properties ( ) - > vobsubIDs ( ) . count ( ) + m_subtitles . count ( ) - 1 ) ;
}
else if ( m_state < Playing | | strncmp ( str , " ID_ " , 3 ) = = 0
| | strncmp ( str , " Name " , 4 ) = = 0 | | strncmp ( str , " ICY Info: " , 9 ) = = 0 )
{
TQSize size ( properties ( ) - > originalSize ( ) ) ;
bool hadVideo = properties ( ) - > hasVideo ( ) ;
bool hadLength = properties ( ) - > hasLength ( ) ;
properties ( ) - > extractMeta ( str , true ) ;
if ( ! hadLength & & properties ( ) - > hasLength ( ) )
{
m_info_available = true ;
if ( ! m_quit )
emit infoAvailable ( ) ;
}
if ( properties ( ) - > hasVideo ( ) & & ( ! hadVideo | | size ! = properties ( ) - > originalSize ( ) ) )
m_size_sent = false ;
if ( ! m_quit & & ! m_size_sent & & properties ( ) - > heightAdjusted ( ) )
{
emit sizeAvailable ( ) ;
m_size_sent = true ;
}
}
if ( m_state = = Running & & ( m_pausing | | m_send_seek ) & & ! m_sent & & ! m_quit & & re_start . search ( str ) > = 0 )
{
if ( m_send_seek )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Initial seek to " < < m_absolute_seek < < " . Position " < < position ( ) < < " origin " < < m_seek_origin < < " sent " < < m_sent < < " count " < < m_seek_count < < " \n " ;
# endif
absoluteSeek ( m_absolute_seek ) ;
}
else
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Pausing: ' " < < str < < " ' \n " ;
# endif
sendPlayerCommand ( command_pause ) ;
setState ( m_state = = Paused ? Playing : Paused ) ;
m_pausing = m_paused = false ;
}
}
if ( re_success . search ( str ) > = 0 & & ! m_quit )
m_success = true ;
if ( re_exiting . search ( str ) > = 0 & & re_quit . search ( str ) < 0 & & re_success . search ( str ) < 0 & & ! m_quit )
emit errorDetected ( ) ;
if ( re_crash . search ( str ) > = 0 )
{
int sig = re_crash . cap ( 1 ) . toInt ( ) ;
if ( sig < = 15 & & ! m_quit | | sig < 9 | | sig > 9 & & sig < 15 )
emit errorDetected ( ) ;
}
//kdDebugTime() << "matching a_or_v regex\n";
if ( re_a_or_v . search ( str ) > = 0 )
{
# ifdef DEBUG_KPLAYER_LINEOUT
kdDebugTime ( ) < < " Received AV Buffer: ' " < < str < < " ' \n " ;
# endif
if ( m_state < Playing )
{
if ( ! m_size_sent & & ! m_quit )
{
emit sizeAvailable ( ) ;
m_size_sent = true ;
}
if ( ! m_quit )
properties ( ) - > commit ( ) ;
setState ( Playing ) ;
m_send_volume = m_send_contrast = m_send_brightness = m_send_hue = m_send_saturation = true ;
}
if ( m_sent & & + + m_sent_count > = 5 )
m_sent = false ;
if ( m_quit & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Resending quit command \n " ;
# endif
sendPlayerCommand ( command_quit ) ;
}
if ( m_send_subtitle_load & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending subtitles \n " ;
# endif
subtitles ( ) ;
}
if ( m_send_subtitle_index > - 2 & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending subtitle index \n " ;
# endif
subtitleIndex ( m_send_subtitle_index ) ;
}
if ( m_send_subtitle_visibility & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending subtitle visibility \n " ;
# endif
subtitleVisibility ( ) ;
}
if ( m_send_audio_id & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending audio ID \n " ;
# endif
audioID ( properties ( ) - > audioID ( ) ) ;
}
if ( ( m_send_audio_delay > = 0.001 | | m_send_audio_delay < = - 0.001 ) & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending audio delay \n " ;
# endif
TQCString s ( " audio_delay " ) ;
s + = TQCString ( ) . setNum ( - m_send_audio_delay ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_audio_delay = 0 ;
}
if ( ( m_send_subtitle_delay > = 0.001 | | m_send_subtitle_delay < = - 0.001 ) & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending subtitle delay \n " ;
# endif
TQCString s ( " sub_delay " ) ;
s + = TQCString ( ) . setNum ( - m_send_subtitle_delay ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_subtitle_delay = 0 ;
}
if ( m_send_subtitle_position & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending subtitle position \n " ;
# endif
TQCString s ( " sub_pos " ) ;
s + = TQCString ( ) . setNum ( m_send_subtitle_position ) + " \n " ;
sendPlayerCommand ( s ) ;
m_send_subtitle_position = 0 ;
}
if ( m_send_volume & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending volume \n " ;
# endif
volume ( settings ( ) - > actualVolume ( ) ) ;
}
if ( m_send_frame_drop & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending frame drop \n " ;
# endif
frameDrop ( settings ( ) - > frameDrop ( ) ) ;
}
if ( m_send_contrast & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending contrast \n " ;
# endif
contrast ( settings ( ) - > contrast ( ) ) ;
}
if ( m_send_brightness & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending brightness \n " ;
# endif
brightness ( settings ( ) - > brightness ( ) ) ;
}
if ( m_send_hue & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending hue \n " ;
# endif
hue ( settings ( ) - > hue ( ) ) ;
}
if ( m_send_saturation & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending saturation \n " ;
# endif
saturation ( settings ( ) - > saturation ( ) ) ;
}
// kdDebugTime() << "regex matched\n";
if ( re_a_and_v . search ( str ) > = 0 )
{
ftime = stringToFloat ( re_a_and_v . cap ( 1 ) ) ;
float ftime2 = stringToFloat ( re_a_and_v . cap ( 2 ) ) ;
if ( ftime2 > ftime )
ftime = ftime2 ;
}
else
{
ftime = stringToFloat ( re_a_or_v . cap ( 1 ) ) ;
// kdDebugTime() << "match: " << re_a_or_v.cap (1) << "ftime: " << ftime << "\n";
}
if ( ftime > properties ( ) - > length ( ) & & properties ( ) - > length ( ) > = MIN_VIDEO_LENGTH )
properties ( ) - > setLength ( ftime ) ;
if ( ftime ! = m_position )
{
m_position = ftime ;
if ( m_position > m_max_position )
m_max_position = m_position ;
float diff = m_position - prev_position ;
prev_position = m_position ;
if ( ! m_quit & & ( diff > 0 | | diff < - 0.15 | | m_position = = 0 )
& & ( m_position - m_seek_origin > 0.65 | | m_seek_origin - m_position > 0.25 )
& & ! m_send_seek & & ( m_seek_count = = 0 | | + + m_seek_count > 5 ) )
{
# ifdef DEBUG_KPLAYER_PROCESS
if ( m_seek_origin > = 0 )
kdDebugTime ( ) < < " Process: Reset seek origin. Position " < < position ( ) < < " origin " < < m_seek_origin < < " sent " < < m_sent < < " count " < < m_seek_count < < " \n " ;
# endif
m_seek_origin = NO_SEEK_ORIGIN ;
emit progressChanged ( m_position , Position ) ;
m_seek_count = 0 ;
}
// kdDebugTime() << "position: " << m_position << " length: " << properties() -> length() << "\n";
}
if ( m_pausing & & ! m_quit & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Pausing: ' " < < str < < " ' \n " ;
# endif
m_pausing = m_paused = false ;
pause ( ) ;
}
if ( m_paused & & ! m_quit & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Paused: ' " < < str < < " ' \n " ;
# endif
m_pausing = m_paused = false ;
sendPlayerCommand ( command_pause ) ;
}
if ( m_send_seek & & ! m_sent )
{
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " Process: Sending seek to " < < m_absolute_seek < < " . Position " < < position ( ) < < " origin " < < m_seek_origin < < " sent " < < m_sent < < " count " < < m_seek_count < < " \n " ;
# endif
absoluteSeek ( m_absolute_seek ) ;
}
}
else if ( re_cache_fill . search ( str ) > = 0 )
{
ftime = stringToFloat ( re_cache_fill . cap ( 1 ) ) ;
# ifdef DEBUG_KPLAYER_PROGRESS
kdDebugTime ( ) < < " Received cache progress: ' " < < str < < " ' -> " < < ftime < < " \n " ;
# endif
if ( ! m_quit & & ! m_first_chunk )
emit progressChanged ( ftime , CacheFill ) ;
}
else if ( re_generating_index . search ( str ) > = 0 )
{
ftime = stringToFloat ( re_generating_index . cap ( 1 ) ) ;
# ifdef DEBUG_KPLAYER_PROGRESS
kdDebugTime ( ) < < " Received indexing progress: ' " < < str < < " ' -> " < < ftime < < " \n " ;
# endif
if ( ! m_quit )
emit progressChanged ( ftime , IndexGeneration ) ;
}
else if ( ! m_quit )
{
emit messageReceived ( TQString : : fromLocal8Bit ( str ) ) ;
# ifdef DEBUG_KPLAYER_PROCESS
kdDebugTime ( ) < < " process >> " < < str < < " \n " ;
# endif
}
}
void KPlayerProcess : : receivedHelperLine ( KPlayerLineOutputProcess * proc , char * str , int len )
{
if ( proc ! = m_helper )
{
char buf [ 1025 ] ;
if ( len > 1024 )
len = 1024 ;
memcpy ( buf , str , len ) ;
buf [ len ] = 0 ;
if ( re_exiting . search ( buf ) < 0 )
proc - > writeStdin ( command_quit , command_quit . length ( ) ) ;
return ;
}
bool sent = false ;
float ftime ;
# ifdef DEBUG_KPLAYER_HELPER
kdDebugTime ( ) < < " helper >> " < < str < < " \n " ;
# endif
bool hadVideo = properties ( ) - > hasVideo ( ) ;
bool hadLength = properties ( ) - > hasLength ( ) ;
properties ( ) - > extractMeta ( str , false ) ;
if ( ! hadLength & & properties ( ) - > hasLength ( ) )
{
m_info_available = true ;
if ( ! m_kill )
emit infoAvailable ( ) ;
}
if ( m_helper_seek = = 1 & & properties ( ) - > hasLength ( ) )
m_helper_seek_count = 9 ;
if ( ! hadVideo & & properties ( ) - > hasVideo ( ) )
m_size_sent = false ;
if ( ! m_kill & & ! m_size_sent & & properties ( ) - > heightAdjusted ( ) )
{
emit sizeAvailable ( ) ;
m_size_sent = true ;
}
//kdDebugTime() << "matching a_or_v regex\n";
if ( re_a_or_v . search ( str ) > = 0 )
{
// kdDebugTime() << "regex matched\n";
if ( re_a_and_v . search ( str ) > = 0 )
{
ftime = stringToFloat ( re_a_and_v . cap ( 1 ) ) ;
float ftime2 = stringToFloat ( re_a_and_v . cap ( 2 ) ) ;
if ( ftime2 > ftime )
ftime = ftime2 ;
}
else
{
ftime = stringToFloat ( re_a_or_v . cap ( 1 ) ) ;
// kdDebugTime() << "match: " << re_a_or_v.cap (1) << "ftime: " << ftime << "\n";
}
if ( m_helper_seek > 0 & & ! sent )
{
if ( + + m_helper_seek_count < 10 )
sent = true ;
else
m_helper_seek_count = 0 ;
# ifdef DEBUG_KPLAYER_HELPER
kdDebugTime ( ) < < " Helper: Seek count: " < < m_helper_seek_count < < " \n " ;
# endif
}
if ( m_helper_seek = = 0 & & ftime > = MIN_VIDEO_LENGTH )
m_helper_seek = 100 ;
else
{
if ( m_helper_seek > 0 & & m_helper_seek < 500 & & ftime > = MIN_VIDEO_LENGTH
& & properties ( ) - > hasLength ( ) & & ftime > properties ( ) - > length ( ) )
properties ( ) - > setLength ( ftime ) ;
if ( ftime ! = m_helper_position )
{
m_helper_position = ftime ;
# ifdef DEBUG_KPLAYER_HELPER
kdDebugTime ( ) < < " helper position: " < < m_helper_position < < " length: " < < properties ( ) - > length ( ) < < " \n " ;
# endif
}
if ( m_helper_seek > 0 & & m_helper_seek < 500 & & ftime > = MIN_VIDEO_LENGTH )
{
float estlength = ftime * 100 / m_helper_seek ;
if ( properties ( ) - > length ( ) < estlength )
{
properties ( ) - > setLength ( estlength ) ;
m_info_available = true ;
if ( ! m_kill )
emit infoAvailable ( ) ;
}
# ifdef DEBUG_KPLAYER_HELPER
kdDebugTime ( ) < < " estimated length: " < < properties ( ) - > length ( ) < < " \n " ;
# endif
}
}
if ( m_helper_seek = = 0 & & ! sent )
{
sendHelperCommand ( command_seek_99 ) ;
m_helper_seek = 99 ;
m_helper_seek_count = 0 ;
sent = true ;
}
if ( m_helper_seek = = 99 & & ! sent & & properties ( ) - > length ( ) < MIN_VIDEO_LENGTH )
{
sendHelperCommand ( command_seek_95 ) ;
m_helper_seek = 95 ;
m_helper_seek_count = 0 ;
sent = true ;
}
if ( m_helper_seek = = 95 & & ! sent & & properties ( ) - > length ( ) < MIN_VIDEO_LENGTH )
{
sendHelperCommand ( command_seek_90 ) ;
m_helper_seek = 90 ;
m_helper_seek_count = 0 ;
sent = true ;
}
if ( m_helper_seek = = 90 & & ! sent & & properties ( ) - > length ( ) < MIN_VIDEO_LENGTH )
{
sendHelperCommand ( command_seek_50 ) ;
m_helper_seek = 50 ;
m_helper_seek_count = 0 ;
sent = true ;
}
if ( m_helper_seek < 100 & & properties ( ) - > length ( ) > = MIN_VIDEO_LENGTH )
{
sendHelperCommand ( command_seek_100 ) ;
m_helper_seek = 100 ;
m_helper_seek_count = 0 ;
sent = true ;
}
if ( ( m_helper_seek = = 50 | | m_helper_seek = = 100 ) & & ! sent )
{
sendHelperCommand ( command_quit ) ;
m_helper_seek = 500 ;
sent = true ;
}
}
}