You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kplayer/kplayer/kplayerprocess.cpp

2099 lines
66 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/***************************************************************************
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èínám pøehrávat|Starte Wiedergabe|Påbegynder afspilning|Åêêßíçóç áíáðáñáãùãÞò|Empezando reproducción|Démarre la lecture|Lejátszás indítása|Inizio la riproduzione|ºÆÀ¸³«»Ï|재ìƒ<C3AC>ì<EFBFBD>„ 시작합니다|Почнува плејбекот|Start afspelen|Starter avspilling|Zaczynam odtwarzanie|Iníciando reprodução|Rulez|îÁÞÁÌÏ ×ÏcÐÒÏÉÚ×ÅÄÅÎÉÑ|Zaèínam prehráva»|Çalmaya baþlanýyor|ðÏÞÁÔÏË ÐÒÏÇÒÁ×ÁÎÎÑ|¿ªÊ¼²¥·Å|¶\\}©l¼½©ñ)\\.\\.\\.", false);
//static TQRegExp re_playing ("(?:^(?:Playing|Pøehrávám|Spiele|Afspiller|ÁíáðáñáãùãÞ ôïõ|Reproduciendo|Joue|In riproduzione|Пуштено|Bezig met het afspelen van|Spiller|Odtwarzam|Reproduzindo|Rulez|ðÒÏÉÇÒÙ×ÁÎÉÅ|Prehrávam|ðÒÏÇÒÁ×ÁÎÎÑ|²¥·Å|¥¿¦b¼½©ñ) | (?:lejátszása|¤òºÆÀ¸Ãæ|재ìƒ<C3AC> 중|Çalýnýyor)\\.*$)", false);
static TQRegExp re_exiting ("^(?:Exiting|Èçëèçàì|Konèím|Beende| ?Afslutter| ?¸îïäïò|Saliendo|Sortie|Kilépek|In uscita|½ªÎ»¤·¤Æ¤¤¤Þ¤¹|종료합니다.|ИзлегуÐ|Bezig met afsluiten|Avslutter|Wychodzê|Saindo|Ieºire|÷ÙÈÏÄÉÍ|Konèím|Çýkýlýyor|÷ÉÈÏÄÉÍÏ|ÕýÔÚÍ˳ö|¥¿¦b°h¥X)", false);
static TQRegExp re_quit ("^(?:Exiting|Èçëèçàì|Konèím|Beende| ?Afslutter| ?¸îïäïò|Saliendo|Sortie|Kilépek|In uscita|½ªÎ»¤·¤Æ¤¤¤Þ¤¹|종료합니다.|ИзлегуÐ|Bezig met afsluiten|Avslutter|Wychodzê|Saindo|Ieºire|÷ÙÈÏÄÉÍ|Konèím|Çýkýlýyor|÷ÉÈÏÄÉÍÏ|ÕýÔÚÍ˳ö|¥¿¦b°h¥X)\\.\\.\\. \\((?:Quit|Êðàé|Konec|Ende|Afslut|Êëåßóéìï|Salida\\.?|Fin|Kilépés|Uscita|½ªÎ»|ì¢ë£Œ|ОÑкаÐи|Stop|Avslutt|Wyjcie|Sair|Ieºire|÷ÙÈÏÄ|Koniec|Çýkýþ|÷ÉȦÄ|Í˳ö|Â÷\\})\\)", false);
static TQRegExp re_success ("^(?:Exiting|Èçëèçàì|Konèím|Beende| ?Afslutter| ?¸îïäïò|Saliendo|Sortie|Kilépek|In uscita|½ªÎ»¤·¤Æ¤¤¤Þ¤¹|Á¾·áÇÕ´Ï´Ù|ÐзлегÑва|Bezig met afsluiten|Avslutter|Wychodzê|Saindo|Ieºire|÷ÙÈÏÄÉÍ|Konèím|Çýkýlýyor|÷ÉÈÏÄÉÍÏ|ÕýÔÚÍ˳ö|¥¿¦b°h¥X)\\.\\.\\. \\((?:End of file|Êðàé íà ôàéëà|Konec souboru|Ende der Datei|Slut på filen|ÔÝëïò ôïõ áñ÷åßïõ|Fin del archivo\\.?|Fin du fichier|Vége a file-nak|Fine del file|¥Õ¥¡¥¤¥ë¤ÎËöü¤Ç¤¹|파ì<EFBFBD>¼ì<EFBFBD>˜ ë<EFBFBD><EFBFBD>|КÑај на даÑоÑекаÑа|Einde van bestand|Slutt på filen|Koniec pliku|Fim do arquivo|Sfârºit fiºier|ëÏÎÅà ÆÁÊÌÁ|Koniec súboru|Dosyanýn Sonu|ë¦ÎÅÃØ ÆÁÊÌÕ|Îļþ½áÊø|ÀÉ®×¥½ºÝ)\\)", 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;
}
}
}