1 /* This file is part of the KDE project
2 *
3 * Copyright (C) 2003 Koos Vriezen <koos.vriezen@xs4all.nl>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20 #include <math.h>
21 #include "config-kmplayer.h"
22 #include <unistd.h>
23 #include <qstring.h>
24 #include <qfile.h>
25 #include <qfileinfo.h>
26 #include <qtimer.h>
27 #include <qlayout.h>
28 #include <qtablewidget.h>
29 #include <qlineedit.h>
30 #include <qslider.h>
31 #include <qcombobox.h>
32 #include <qcheckbox.h>
33 #include <qspinbox.h>
34 #include <qlabel.h>
35 #include <qfontmetrics.h>
36 #include <qwhatsthis.h>
37 #include <QList>
38 #include <QtDBus/QtDBus>
39 #include <QtCore/QDir>
40 #include <QtCore/QUrl>
41 #include <QHeaderView>
42 #include <QNetworkCookie>
43
44 #include <kdebug.h>
45 #include <kprotocolmanager.h>
46 #include <kfiledialog.h>
47 #include <kmessagebox.h>
48 #include <klocale.h>
49 #include <kstandarddirs.h>
50 #include <kshell.h>
51 #include <kio/job.h>
52 #include <kio/accessmanager.h>
53
54 #include "kmplayer_def.h"
55 #include "kmplayerconfig.h"
56 #include "kmplayerview.h"
57 #include "kmplayercontrolpanel.h"
58 #include "kmplayerprocess.h"
59 #include "kmplayerpartbase.h"
60 #include "masteradaptor.h"
61 #include "streammasteradaptor.h"
62 #ifdef KMPLAYER_WITH_NPP
63 # include "callbackadaptor.h"
64 # include "streamadaptor.h"
65 #endif
66
67 using namespace KMPlayer;
68
ProcessInfo(const char * nm,const QString & lbl,const char ** supported,MediaManager * mgr,PreferencesPage * prefs)69 ProcessInfo::ProcessInfo (const char *nm, const QString &lbl,
70 const char **supported, MediaManager* mgr, PreferencesPage *prefs)
71 : name (nm),
72 label (lbl),
73 supported_sources (supported),
74 manager (mgr),
75 config_page (prefs) {
76 if (config_page)
77 manager->player ()->settings ()->addPage (config_page);
78 }
79
~ProcessInfo()80 ProcessInfo::~ProcessInfo () {
81 delete config_page;
82 }
83
supports(const char * source) const84 bool ProcessInfo::supports (const char *source) const {
85 for (const char ** s = supported_sources; s[0]; ++s) {
86 if (!strcmp (s[0], source))
87 return true;
88 }
89 return false;
90 }
91
92 //------------------------%<----------------------------------------------------
93
getPath(const KUrl & url)94 static QString getPath (const KUrl & url) {
95 QString p = QUrl::fromPercentEncoding (url.url ().toAscii ());
96 if (p.startsWith (QString ("file:/"))) {
97 int i = 0;
98 p = p.mid (5);
99 for (; i < p.size () && p[i] == QChar ('/'); ++i)
100 ;
101 //kDebug () << "getPath " << p.mid (i-1);
102 if (i > 0)
103 return p.mid (i-1);
104 return QString (QChar ('/') + p);
105 }
106 return p;
107 }
108
encodeFileOrUrl(const KUrl & url)109 static QString encodeFileOrUrl (const KUrl &url)
110 {
111 return url.isEmpty ()
112 ? QString ()
113 : QString::fromLocal8Bit (QFile::encodeName (
114 url.isLocalFile ()
115 ? url.toLocalFile ()
116 : QUrl::fromPercentEncoding (url.url ().toLocal8Bit ())));
117 }
118
encodeFileOrUrl(const QString & str)119 static QString encodeFileOrUrl (const QString &str)
120 {
121 if (!str.startsWith (QString ("dvd:")) &&
122 !str.startsWith (QString ("vcd:")) &&
123 !str.startsWith (QString ("tv:")) &&
124 !str.startsWith (QString ("cdda:")))
125 return encodeFileOrUrl (KUrl (str));
126 return str;
127 }
128
setupProcess(QProcess ** process)129 static void setupProcess (QProcess **process)
130 {
131 delete *process;
132 *process = new QProcess;
133 QStringList env = (*process)->systemEnvironment ();
134 const QStringList::iterator e = env.end ();
135 for (QStringList::iterator i = env.begin (); i != e; ++i)
136 if ((*i).startsWith ("SESSION_MANAGER")) {
137 env.erase (i);
138 break;
139 }
140 (*process)->setEnvironment (env);
141 }
142
killProcess(QProcess * process,QWidget * widget)143 static void killProcess (QProcess *process, QWidget *widget) {
144 if (!process || !process->pid ())
145 return;
146 process->terminate ();
147 if (!process->waitForFinished (1000)) {
148 process->kill ();
149 if (!process->waitForFinished (1000) && widget)
150 KMessageBox::error (widget,
151 i18n ("Failed to end player process."), i18n ("Error"));
152 }
153 }
154
outputToView(View * view,const QByteArray & ba)155 static void outputToView (View *view, const QByteArray &ba)
156 {
157 if (view && ba.size ())
158 view->addText (QString::fromLocal8Bit (ba.constData ()));
159 }
160
Process(QObject * parent,ProcessInfo * pinfo,Settings * settings)161 Process::Process (QObject *parent, ProcessInfo *pinfo, Settings *settings)
162 : QObject (parent),
163 IProcess (pinfo),
164 m_source (0L),
165 m_settings (settings),
166 m_old_state (IProcess::NotRunning),
167 m_process (0L),
168 m_job(0L),
169 m_process_state (QProcess::NotRunning)
170 {}
171
~Process()172 Process::~Process () {
173 quit ();
174 delete m_process;
175 if (user)
176 user->processDestroyed (this);
177 }
178
init()179 void Process::init () {
180 }
181
initProcess()182 void Process::initProcess () {
183 setupProcess (&m_process);
184 m_process_state = QProcess::NotRunning;
185 connect (m_process, SIGNAL (stateChanged (QProcess::ProcessState)),
186 this, SLOT (processStateChanged (QProcess::ProcessState)));
187 if (m_source) m_source->setPosition (0);
188 }
189
widget()190 WId Process::widget () {
191 return view () && user && user->viewer ()
192 ? user->viewer ()->windowHandle ()
193 : 0;
194 }
195
mrl() const196 Mrl *Process::mrl () const {
197 if (user)
198 return user->getMrl ();
199 return NULL;
200 }
201
processRunning(QProcess * process)202 static bool processRunning (QProcess *process) {
203 return process && process->state () > QProcess::NotRunning;
204 }
205
running() const206 bool Process::running () const {
207 return processRunning (m_process);
208 }
209
setAudioLang(int)210 void Process::setAudioLang (int) {}
211
setSubtitle(int)212 void Process::setSubtitle (int) {}
213
pause()214 void Process::pause () {
215 }
216
unpause()217 void Process::unpause () {
218 }
219
seek(int,bool)220 bool Process::seek (int /*pos*/, bool /*absolute*/) {
221 return false;
222 }
223
volume(int,bool)224 void Process::volume (int /*pos*/, bool /*absolute*/) {
225 }
226
saturation(int,bool)227 bool Process::saturation (int /*pos*/, bool /*absolute*/) {
228 return false;
229 }
230
hue(int,bool)231 bool Process::hue (int /*pos*/, bool /*absolute*/) {
232 return false;
233 }
234
contrast(int,bool)235 bool Process::contrast (int /*pos*/, bool /*absolute*/) {
236 return false;
237 }
238
brightness(int,bool)239 bool Process::brightness (int /*pos*/, bool /*absolute*/) {
240 return false;
241 }
242
grabPicture(const QString &,int)243 bool Process::grabPicture (const QString &/*file*/, int /*pos*/) {
244 m_old_state = m_state = Buffering;
245 setState (Ready);
246 return false;
247 }
248
stop()249 void Process::stop () {
250 }
251
quit()252 void Process::quit () {
253 killProcess (m_process, view ());
254 setState (IProcess::NotRunning);
255 }
256
setState(IProcess::State newstate)257 void Process::setState (IProcess::State newstate) {
258 if (m_state != newstate) {
259 bool need_timer = m_old_state == m_state;
260 m_old_state = m_state;
261 m_state = newstate;
262 if (need_timer)
263 QTimer::singleShot (0, this, SLOT (rescheduledStateChanged ()));
264 }
265 }
266
rescheduledStateChanged()267 KDE_NO_EXPORT void Process::rescheduledStateChanged () {
268 IProcess::State old_state = m_old_state;
269 m_old_state = m_state;
270 if (user) {
271 user->stateChange (this, old_state, m_state);
272 } else {
273 if (m_state > IProcess::Ready)
274 kError() << "Process running, mrl disappeared" << endl;
275 delete this;
276 }
277 }
278
play()279 bool Process::play () {
280 Mrl *m = mrl ();
281 if (!m)
282 return false;
283 bool nonstdurl = m->src.startsWith ("tv:/") ||
284 m->src.startsWith ("dvd:") ||
285 m->src.startsWith ("cdda:") ||
286 m->src.startsWith ("vcd:");
287 QString url = nonstdurl ? m->src : m->absolutePath ();
288 bool changed = m_url != url;
289 m_url = url;
290 if (user) // FIXME: remove check
291 user->starting (this);
292 if (!changed ||
293 KUrl (m_url).isLocalFile () ||
294 nonstdurl ||
295 (m_source && m_source->avoidRedirects ()))
296 return deMediafiedPlay ();
297 m_job = KIO::stat (m_url, KIO::HideProgressInfo);
298 connect (m_job, SIGNAL (result (KJob *)), this, SLOT (result (KJob *)));
299 return true;
300 }
301
deMediafiedPlay()302 bool Process::deMediafiedPlay () {
303 return false;
304 }
305
result(KJob * job)306 void Process::result (KJob * job) {
307 KIO::UDSEntry entry = static_cast <KIO::StatJob *> (job)->statResult ();
308 QString url = entry.stringValue (KIO::UDSEntry::UDS_LOCAL_PATH);
309 if (!url.isEmpty ())
310 m_url = url;
311 m_job = 0L;
312 deMediafiedPlay ();
313 }
314
terminateJobs()315 void Process::terminateJobs () {
316 if (m_job) {
317 m_job->kill ();
318 m_job = 0L;
319 }
320 }
321
ready()322 bool Process::ready () {
323 setState (IProcess::Ready);
324 return true;
325 }
326
processStateChanged(QProcess::ProcessState nstate)327 void Process::processStateChanged (QProcess::ProcessState nstate)
328 {
329 if (QProcess::Starting == m_process_state) {
330 if (QProcess::NotRunning == nstate)
331 setState (IProcess::NotRunning);
332 else if (state () == IProcess::Ready)
333 setState (IProcess::Buffering);
334 m_process_state = nstate;
335 }
336 }
337
startProcess(const QString & program,const QStringList & args)338 void Process::startProcess (const QString &program, const QStringList &args)
339 {
340 m_process_state = QProcess::Starting;
341 m_process->start (program, args);
342 }
343
view() const344 View *Process::view () const {
345 return m_source ? m_source->player ()->viewWidget () : NULL;
346 }
347
348 //-----------------------------------------------------------------------------
349
RecordDocument(const QString & url,const QString & rurl,const QString & rec,Source * src)350 RecordDocument::RecordDocument (const QString &url, const QString &rurl,
351 const QString &rec, Source *src)
352 : SourceDocument (src, url),
353 record_file (rurl),
354 recorder (rec) {
355 id = id_node_record_document;
356 }
357
begin()358 void RecordDocument::begin () {
359 if (!media_info) {
360 media_info = new MediaInfo (this, MediaManager::AudioVideo);
361 media_info->create ();
362 }
363 media_info->media->play ();
364 }
365
message(MessageType msg,void * content)366 void RecordDocument::message (MessageType msg, void *content) {
367 switch (msg) {
368 case MsgMediaFinished:
369 deactivate ();
370 break;
371 default:
372 SourceDocument::message (msg, content);
373 }
374 }
375
deactivate()376 void RecordDocument::deactivate () {
377 state = state_deactivated;
378 ((MediaManager *) role (RoleMediaManager))->player ()->recorderStopped ();
379 Document::deactivate ();
380 }
381
recordDocument(ProcessUser * user)382 static RecordDocument *recordDocument (ProcessUser *user) {
383 Mrl *mrl = user ? user->getMrl () : NULL;
384 return mrl && id_node_record_document == mrl->id
385 ? static_cast <RecordDocument *> (mrl) : NULL;
386 }
387
388 //-----------------------------------------------------------------------------
389
proxyForURL(const KUrl & url,QString & proxy)390 static bool proxyForURL (const KUrl &url, QString &proxy) {
391 KProtocolManager::slaveProtocol (url, proxy);
392 return !proxy.isNull ();
393 }
394
395 //-----------------------------------------------------------------------------
396
MPlayerBase(QObject * parent,ProcessInfo * pinfo,Settings * settings)397 KDE_NO_CDTOR_EXPORT MPlayerBase::MPlayerBase (QObject *parent, ProcessInfo *pinfo, Settings * settings)
398 : Process (parent, pinfo, settings),
399 m_needs_restarted (false) {
400 m_process = new QProcess;
401 }
402
~MPlayerBase()403 KDE_NO_CDTOR_EXPORT MPlayerBase::~MPlayerBase () {
404 }
405
initProcess()406 KDE_NO_EXPORT void MPlayerBase::initProcess () {
407 Process::initProcess ();
408 const KUrl &url (m_source->url ());
409 if (!url.isEmpty ()) {
410 QString proxy_url;
411 if (KProtocolManager::useProxy () && proxyForURL (url, proxy_url)) {
412 QStringList env = m_process->environment ();
413 env << (QString ("http_proxy=") + proxy_url);
414 m_process->setEnvironment (env);
415 }
416 }
417 connect (m_process, SIGNAL (bytesWritten (qint64)),
418 this, SLOT (dataWritten (qint64)));
419 connect (m_process, SIGNAL (finished (int, QProcess::ExitStatus)),
420 this, SLOT (processStopped (int, QProcess::ExitStatus)));
421 }
422
removeQueued(const char * cmd)423 bool MPlayerBase::removeQueued (const char *cmd) {
424 for (QList<QByteArray>::iterator i = commands.begin ();
425 i != commands.end ();
426 ++i)
427 if (!strncmp ((*i).data (), cmd, strlen (cmd))) {
428 commands.erase (i);
429 return true;
430 }
431 return false;
432 }
433
sendCommand(const QString & cmd)434 KDE_NO_EXPORT bool MPlayerBase::sendCommand (const QString & cmd) {
435 if (running ()) {
436 commands.push_front (QString (cmd + '\n').toAscii ());
437 fprintf (stderr, "eval %s", commands.last ().constData ());
438 if (commands.size () < 2)
439 m_process->write (commands.last ());
440 return true;
441 }
442 return false;
443 }
444
stop()445 KDE_NO_EXPORT void MPlayerBase::stop () {
446 terminateJobs ();
447 }
448
quit()449 KDE_NO_EXPORT void MPlayerBase::quit () {
450 if (running ()) {
451 kDebug() << "MPlayerBase::quit";
452 stop ();
453 disconnect (m_process, SIGNAL (finished (int, QProcess::ExitStatus)),
454 this, SLOT (processStopped (int, QProcess::ExitStatus)));
455 m_process->waitForFinished (2000);
456 if (running ())
457 Process::quit ();
458 commands.clear ();
459 m_needs_restarted = false;
460 processStopped ();
461 }
462 Process::quit ();
463 }
464
dataWritten(qint64)465 KDE_NO_EXPORT void MPlayerBase::dataWritten (qint64) {
466 if (!commands.size ()) return;
467 kDebug() << "eval done " << commands.last ().data ();
468 commands.pop_back ();
469 if (commands.size ())
470 m_process->write (commands.last ());
471 }
472
processStopped()473 KDE_NO_EXPORT void MPlayerBase::processStopped () {
474 setState (IProcess::Ready);
475 }
476
processStopped(int,QProcess::ExitStatus)477 KDE_NO_EXPORT void MPlayerBase::processStopped (int, QProcess::ExitStatus) {
478 kDebug() << "process stopped" << endl;
479 commands.clear ();
480 processStopped ();
481 }
482
483 //-----------------------------------------------------------------------------
484
485 static const char *mplayer_supports [] = {
486 "dvdsource", "exitsource", "introsource", "pipesource", "tvscanner", "tvsource", "urlsource", "vcdsource", "audiocdsource", 0L
487 };
488
MPlayerProcessInfo(MediaManager * mgr)489 MPlayerProcessInfo::MPlayerProcessInfo (MediaManager *mgr)
490 : ProcessInfo ("mplayer", i18n ("&MPlayer"), mplayer_supports,
491 mgr, new MPlayerPreferencesPage ()) {}
492
create(PartBase * part,ProcessUser * usr)493 IProcess *MPlayerProcessInfo::create (PartBase *part, ProcessUser *usr) {
494 MPlayer *m = new MPlayer (part, this, part->settings ());
495 m->setSource (part->source ());
496 m->user = usr;
497 part->processCreated (m);
498 return m;
499 }
500
501 KDE_NO_CDTOR_EXPORT
MPlayer(QObject * parent,ProcessInfo * pinfo,Settings * settings)502 MPlayer::MPlayer (QObject *parent, ProcessInfo *pinfo, Settings *settings)
503 : MPlayerBase (parent, pinfo, settings),
504 m_widget (0L),
505 m_transition_state (NotRunning),
506 aid (-1), sid (-1)
507 {}
508
~MPlayer()509 KDE_NO_CDTOR_EXPORT MPlayer::~MPlayer () {
510 if (m_widget && !m_widget->parent ())
511 delete m_widget;
512 }
513
init()514 KDE_NO_EXPORT void MPlayer::init () {
515 }
516
ready()517 KDE_NO_EXPORT bool MPlayer::ready () {
518 Process::ready ();
519 if (user && user->viewer ())
520 user->viewer ()->useIndirectWidget (true);
521 return false;
522 }
523
deMediafiedPlay()524 KDE_NO_EXPORT bool MPlayer::deMediafiedPlay () {
525 if (running ())
526 return sendCommand (QString ("gui_play"));
527
528 m_transition_state = NotRunning;
529 if (!m_needs_restarted && running ())
530 quit (); // rescheduling of setState will reset state just-in-time
531
532 initProcess ();
533 connect (m_process, SIGNAL (readyReadStandardOutput ()),
534 this, SLOT (processOutput ()));
535 connect (m_process, SIGNAL (readyReadStandardError ()),
536 this, SLOT (processOutput ()));
537
538 m_process_output = QString ();
539 m_source->setPosition (0);
540 if (!m_needs_restarted) {
541 if (m_source->identified ()) {
542 aid = m_source->audioLangId ();
543 sid = m_source->subTitleId ();
544 } else {
545 aid = sid = -1;
546 }
547 } else {
548 m_needs_restarted = false;
549 }
550 alanglist = NULL;
551 slanglist = NULL;
552 slanglist_end = NULL;
553 alanglist_end = NULL;
554 m_request_seek = -1;
555 m_tmpURL.truncate (0);
556
557 QStringList args;
558 //m_view->consoleOutput ()->clear ();
559 MPlayerPreferencesPage *cfg_page = static_cast <MPlayerPreferencesPage *>(process_info->config_page);
560 QString exe = cfg_page->mplayer_path;
561 if (exe.isEmpty ())
562 exe = "mplayer";
563
564 args << "-wid" << QString::number (widget ());
565 args << "-slave";
566
567 QString strVideoDriver = QString (m_settings->videodrivers[m_settings->videodriver].driver);
568 if (!strVideoDriver.isEmpty ()) {
569 args << "-vo" << strVideoDriver.toLower();
570 if (view () && view ()->keepSizeRatio () &&
571 strVideoDriver.toLower() == QString::fromLatin1 ("x11"))
572 args << "-zoom";
573 }
574
575 QString strAudioDriver = QString (m_settings->audiodrivers[m_settings->audiodriver].driver);
576 if (!strAudioDriver.isEmpty ())
577 args << "-ao" << strAudioDriver.toLower();
578
579 if (m_settings->framedrop)
580 args << "-framedrop";
581
582 if (cfg_page->additionalarguments.length () > 0)
583 args << KShell::splitArgs (cfg_page->additionalarguments);
584
585 // postproc thingies
586 args << KShell::splitArgs (m_source->filterOptions ());
587
588 if (m_settings->autoadjustcolors) {
589 args << "-contrast" << QString::number (m_settings->contrast);
590 args << "-brightness" <<QString::number(m_settings->brightness);
591 args << "-hue" << QString::number (m_settings->hue);
592 args << "-saturation" <<QString::number(m_settings->saturation);
593 }
594
595 if (aid > -1)
596 args << "-aid" << QString::number (aid);
597
598 if (sid > -1)
599 args << "-sid" << QString::number (sid);
600
601 for (Node *n = mrl (); n; n = n->parentNode ()) {
602 if (n->id != id_node_group_node && n->id != id_node_playlist_item)
603 break;
604 QString plops = static_cast<Element *>(n)->getAttribute ("mplayeropts");
605 if (!plops.isNull ()) {
606 QStringList sl = plops.split (QChar (' '));
607 for (int i = 0; i < sl.size (); ++i)
608 args << sl[i];
609 break;
610 }
611 }
612
613 args << KShell::splitArgs (m_source->options ());
614
615 KUrl url (m_url);
616 if (!url.isEmpty ()) {
617 if (m_source->url ().isLocalFile ())
618 m_process->setWorkingDirectory
619 (QFileInfo (m_source->url ().path ()).absolutePath ());
620 if (url.isLocalFile ()) {
621 m_url = url.toLocalFile ();
622 if (cfg_page->alwaysbuildindex &&
623 (m_url.toLower ().endsWith (".avi") ||
624 m_url.toLower ().endsWith (".divx")))
625 args << "-idx";
626 } else {
627 int cache = cfg_page->cachesize;
628 if (cache > 3 && !url.url ().startsWith (QString ("dvd")) &&
629 !url.url ().startsWith (QString ("vcd")) &&
630 !m_url.startsWith (QString ("tv://")))
631 args << "-cache" << QString::number (cache);
632 if (m_url.startsWith (QString ("cdda:/")) &&
633 !m_url.startsWith (QString ("cdda://")))
634 m_url = QString ("cdda://") + m_url.mid (6);
635 }
636 if (url.protocol () != QString ("stdin"))
637 args << encodeFileOrUrl (m_url);
638 }
639 Mrl *m = mrl ();
640 if (m && m->repeat > 0)
641 args << "-loop" << QString::number (m->repeat);
642 else if (m_settings->loop)
643 args << "-loop" << 0;
644 args << "-identify";
645 const QString surl = encodeFileOrUrl (m_source->subUrl ());
646 if (!surl.isEmpty ())
647 args << "-sub" << surl;
648 qDebug ("mplayer %s\n", args.join (" ").toLocal8Bit ().constData ());
649
650 startProcess (exe, args);
651
652 old_volume = view () ? view ()->controlPanel ()->volumeBar ()->value () : 0;
653
654 return true;
655 }
656
stop()657 KDE_NO_EXPORT void MPlayer::stop () {
658 terminateJobs ();
659 if (!m_source || !running ())
660 return;
661 sendCommand (QString ("quit"));
662 MPlayerBase::stop ();
663 }
664
pause()665 KDE_NO_EXPORT void MPlayer::pause () {
666 if (Paused != m_transition_state) {
667 m_transition_state = Paused;
668 if (!removeQueued ("pause"))
669 sendCommand (QString ("pause"));
670 }
671 }
672
unpause()673 KDE_NO_EXPORT void MPlayer::unpause () {
674 if (m_transition_state == Paused
675 || (Paused == m_state
676 && m_transition_state != Playing)) {
677 m_transition_state = Playing;
678 if (!removeQueued ("pause"))
679 sendCommand (QString ("pause"));
680 }
681 }
682
seek(int pos,bool absolute)683 KDE_NO_EXPORT bool MPlayer::seek (int pos, bool absolute) {
684 if (!m_source || !m_source->hasLength () ||
685 (absolute && m_source->position () == pos))
686 return false;
687 if (m_request_seek >= 0 && commands.size () > 1) {
688 QList<QByteArray>::iterator i = commands.begin ();
689 for (++i; i != commands.end (); ++i)
690 if (!strncmp ((*i).data (), "seek", 4)) {
691 i = commands.erase (i);
692 m_request_seek = -1;
693 break;
694 }
695 }
696 if (m_request_seek >= 0) {
697 //m_request_seek = pos;
698 return false;
699 }
700 m_request_seek = pos;
701 QString cmd;
702 cmd.sprintf ("seek %d %d", pos/10, absolute ? 2 : 0);
703 if (!absolute)
704 pos = m_source->position () + pos;
705 m_source->setPosition (pos);
706 return sendCommand (cmd);
707 }
708
volume(int incdec,bool absolute)709 KDE_NO_EXPORT void MPlayer::volume (int incdec, bool absolute) {
710 if (absolute)
711 incdec -= old_volume;
712 if (incdec == 0)
713 return;
714 old_volume += incdec;
715 sendCommand (QString ("volume ") + QString::number (incdec));
716 }
717
saturation(int val,bool absolute)718 KDE_NO_EXPORT bool MPlayer::saturation (int val, bool absolute) {
719 QString cmd;
720 cmd.sprintf ("saturation %d %d", val, absolute ? 1 : 0);
721 return sendCommand (cmd);
722 }
723
hue(int val,bool absolute)724 KDE_NO_EXPORT bool MPlayer::hue (int val, bool absolute) {
725 QString cmd;
726 cmd.sprintf ("hue %d %d", val, absolute ? 1 : 0);
727 return sendCommand (cmd);
728 }
729
contrast(int val,bool)730 KDE_NO_EXPORT bool MPlayer::contrast (int val, bool /*absolute*/) {
731 QString cmd;
732 cmd.sprintf ("contrast %d 1", val);
733 return sendCommand (cmd);
734 }
735
brightness(int val,bool)736 KDE_NO_EXPORT bool MPlayer::brightness (int val, bool /*absolute*/) {
737 QString cmd;
738 cmd.sprintf ("brightness %d 1", val);
739 return sendCommand (cmd);
740 }
741
grabPicture(const QString & file,int pos)742 KDE_NO_EXPORT bool MPlayer::grabPicture (const QString &file, int pos) {
743 Mrl *m = mrl ();
744 if (m_state > Ready || !m || m->src.isEmpty ())
745 return false; //FIXME
746 initProcess ();
747 m_old_state = m_state = Buffering;
748 unlink (file.toAscii ().constData ());
749 QByteArray ba = file.toLocal8Bit ();
750 ba.append ("XXXXXX");
751 if (mkdtemp ((char *) ba.constData ())) {
752 m_grab_dir = QString::fromLocal8Bit (ba.constData ());
753 QString exe ("mplayer");
754 QStringList args;
755 QString jpgopts ("jpeg:outdir=");
756 jpgopts += KShell::quoteArg (m_grab_dir);
757 args << "-vo" << jpgopts;
758 args << "-frames" << "1" << "-nosound" << "-quiet";
759 if (pos > 0)
760 args << "-ss" << QString::number (pos);
761 args << encodeFileOrUrl (m->src);
762 kDebug () << args.join (" ");
763 m_process->start (exe, args);
764 if (m_process->waitForStarted ()) {
765 m_grab_file = file;
766 setState (Playing);
767 return true;
768 } else {
769 rmdir (ba.constData ());
770 m_grab_dir.truncate (0);
771 }
772 } else {
773 kError () << "mkdtemp failure";
774 }
775 setState (Ready);
776 return false;
777 }
778
processOutput()779 KDE_NO_EXPORT void MPlayer::processOutput () {
780 const QByteArray ba = m_process->readAllStandardOutput ();
781 const char *str = ba.constData ();
782 int slen = ba.size ();
783 if (!mrl () || slen <= 0) return;
784 View *v = view ();
785
786 bool ok;
787 QRegExp *patterns = static_cast<MPlayerPreferencesPage *>(process_info->config_page)->m_patterns;
788 QRegExp & m_refURLRegExp = patterns[MPlayerPreferencesPage::pat_refurl];
789 QRegExp & m_refRegExp = patterns[MPlayerPreferencesPage::pat_ref];
790 do {
791 int len = strcspn (str, "\r\n");
792 QString out = m_process_output + QString::fromLocal8Bit (str, len);
793 m_process_output = QString ();
794 str += len;
795 slen -= len;
796 if (slen <= 0) {
797 m_process_output = out;
798 break;
799 }
800 bool process_stats = false;
801 if (str[0] == '\r') {
802 if (slen > 1 && str[1] == '\n') {
803 str++;
804 slen--;
805 } else
806 process_stats = true;
807 }
808 str++;
809 slen--;
810
811 if (process_stats) {
812 QRegExp & m_posRegExp = patterns[MPlayerPreferencesPage::pat_pos];
813 QRegExp & m_cacheRegExp = patterns[MPlayerPreferencesPage::pat_cache];
814 if (m_posRegExp.indexIn (out) > -1) {
815 if (m_source->hasLength ()) {
816 int pos = int (10.0 * m_posRegExp.cap (1).toFloat ());
817 m_source->setPosition (pos);
818 m_request_seek = -1;
819 }
820 if (Playing == m_transition_state) {
821 m_transition_state = NotRunning;
822 setState (Playing);
823 }
824 } else if (m_cacheRegExp.indexIn (out) > -1) {
825 m_source->setLoading (int (m_cacheRegExp.cap(1).toDouble()));
826 }
827 } else if (out.startsWith ("ID_LENGTH")) {
828 int pos = out.indexOf ('=');
829 if (pos > 0) {
830 int l = (int) out.mid (pos + 1).toDouble (&ok);
831 if (ok && l >= 0) {
832 m_source->setLength (mrl (), 10 * l);
833 }
834 }
835 } else if (out.startsWith ("ID_PAUSED")) {
836 if (Paused == m_transition_state) {
837 m_transition_state = NotRunning;
838 setState (Paused);
839 }
840 } else if (m_refURLRegExp.indexIn(out) > -1) {
841 kDebug () << "Reference mrl " << m_refURLRegExp.cap (1);
842 if (!m_tmpURL.isEmpty () &&
843 (m_url.endsWith (m_tmpURL) || m_tmpURL.endsWith (m_url)))
844 m_source->insertURL (mrl (), m_tmpURL);;
845 KUrl tmp (m_refURLRegExp.cap (1));
846 m_tmpURL = tmp.isLocalFile () ? tmp.toLocalFile () : tmp.url ();
847 if (m_source->url () == m_tmpURL ||
848 m_url.endsWith (m_tmpURL) || m_tmpURL.endsWith (m_url))
849 m_tmpURL.truncate (0);
850 } else if (m_refRegExp.indexIn (out) > -1) {
851 kDebug () << "Reference File ";
852 m_tmpURL.truncate (0);
853 } else if (out.startsWith ("ID_VIDEO_WIDTH")) {
854 int pos = out.indexOf ('=');
855 if (pos > 0) {
856 int w = out.mid (pos + 1).toInt ();
857 m_source->setDimensions (mrl (), w, m_source->height ());
858 }
859 } else if (out.startsWith ("ID_VIDEO_HEIGHT")) {
860 int pos = out.indexOf ('=');
861 if (pos > 0) {
862 int h = out.mid (pos + 1).toInt ();
863 m_source->setDimensions (mrl (), m_source->width (), h);
864 }
865 } else if (out.startsWith ("ID_VIDEO_ASPECT")) {
866 int pos = out.indexOf ('=');
867 if (pos > 0) {
868 bool ok;
869 QString val = out.mid (pos + 1);
870 float a = val.toFloat (&ok);
871 if (!ok) {
872 val.replace (',', '.');
873 a = val.toFloat (&ok);
874 }
875 if (ok && a > 0.001)
876 m_source->setAspect (mrl (), a);
877 }
878 } else if (out.startsWith ("ID_AID_")) {
879 int pos = out.indexOf ('_', 7);
880 if (pos > 0) {
881 int id = out.mid (7, pos - 7).toInt ();
882 pos = out.indexOf ('=', pos);
883 if (pos > 0) {
884 if (!alanglist_end) {
885 alanglist = new Source::LangInfo (id, out.mid (pos + 1));
886 alanglist_end = alanglist;
887 } else {
888 alanglist_end->next = new Source::LangInfo (id, out.mid(pos+1));
889 alanglist_end = alanglist_end->next;
890 }
891 kDebug () << "lang " << id << " " << alanglist_end->name;
892 }
893 }
894 } else if (out.startsWith ("ID_SID_")) {
895 int pos = out.indexOf ('_', 7);
896 if (pos > 0) {
897 int id = out.mid (7, pos - 7).toInt ();
898 pos = out.indexOf ('=', pos);
899 if (pos > 0) {
900 if (!slanglist_end) {
901 slanglist = new Source::LangInfo (id, out.mid (pos + 1));
902 slanglist_end = slanglist;
903 } else {
904 slanglist_end->next = new Source::LangInfo (id, out.mid(pos+1));
905 slanglist_end = slanglist_end->next;
906 }
907 kDebug () << "sid " << id << " " << slanglist_end->name;
908 }
909 }
910 } else if (out.startsWith ("ICY Info")) {
911 int p = out.indexOf ("StreamTitle=", 8);
912 if (p > -1) {
913 p += 12;
914 int e = out.indexOf (';', p);
915 if (e > -1)
916 e -= p;
917 QString inf = out.mid (p, e);
918 mrl ()->document ()->message (MsgInfoString, &inf);
919 }
920 } else if (v) {
921 QRegExp & m_startRegExp = patterns[MPlayerPreferencesPage::pat_start];
922 QRegExp & m_sizeRegExp = patterns[MPlayerPreferencesPage::pat_size];
923 v->addText (out, true);
924 if (!m_source->processOutput (out)) {
925 // int movie_width = m_source->width ();
926 if (/*movie_width <= 0 &&*/ m_sizeRegExp.indexIn (out) > -1) {
927 int movie_width = m_sizeRegExp.cap (1).toInt (&ok);
928 int movie_height = ok ? m_sizeRegExp.cap (2).toInt (&ok) : 0;
929 if (ok && movie_width > 0 && movie_height > 0) {
930 m_source->setDimensions(mrl(),movie_width,movie_height);
931 m_source->setAspect (mrl(), 1.0*movie_width/movie_height);
932 }
933 } else if (m_startRegExp.indexIn (out) > -1) {
934 if (!m_tmpURL.isEmpty () && m_url != m_tmpURL) {
935 m_source->insertURL (mrl (), m_tmpURL);;
936 m_tmpURL.truncate (0);
937 }
938 m_source->setIdentified ();
939 m_source->setLanguages (alanglist, slanglist);
940 m_source->setLoading (100);
941 setState (IProcess::Playing);
942 m_source->setPosition (0);
943 }
944 }
945 }
946 } while (slen > 0);
947 }
948
processStopped()949 KDE_NO_EXPORT void MPlayer::processStopped () {
950 if (mrl ()) {
951 QString url;
952 if (!m_grab_dir.isEmpty ()) {
953 QDir dir (m_grab_dir);
954 QStringList files = dir.entryList ();
955 bool renamed = false;
956 for (int i = 0; i < files.size (); ++i) {
957 kDebug() << files[i];
958 if (files[i] == "." || files[i] == "..")
959 continue;
960 if (!renamed) {
961 kDebug() << "rename " << dir.filePath (files[i]) << "->" << m_grab_file;
962 renamed = true;
963 ::rename (dir.filePath (files[i]).toLocal8Bit().constData(),
964 m_grab_file.toLocal8Bit ().constData ());
965 } else {
966 kDebug() << "rm " << files[i];
967 dir.remove (files[i]);
968 }
969 }
970 QString dirname = dir.dirName ();
971 dir.cdUp ();
972 kDebug() << m_grab_dir << " " << files.size () << " rmdir " << dirname;
973 dir.rmdir (dirname);
974 }
975 if (m_source && m_needs_restarted) {
976 commands.clear ();
977 int pos = m_source->position ();
978 play ();
979 seek (pos, true);
980 return;
981 }
982 }
983 setState (IProcess::Ready);
984 }
985
setAudioLang(int id)986 void MPlayer::setAudioLang (int id) {
987 aid = id;
988 m_needs_restarted = true;
989 sendCommand (QString ("quit"));
990 }
991
setSubtitle(int id)992 void MPlayer::setSubtitle (int id) {
993 sid = id;
994 m_needs_restarted = true;
995 sendCommand (QString ("quit"));
996 }
997
998 //-----------------------------------------------------------------------------
999
1000 extern const char * strMPlayerGroup;
1001 static const char * strMPlayerPatternGroup = "MPlayer Output Matching";
1002 static const char * strMPlayerPath = "MPlayer Path";
1003 static const char * strAddArgs = "Additional Arguments";
1004 static const char * strCacheSize = "Cache Size for Streaming";
1005 static const char * strAlwaysBuildIndex = "Always build index";
1006 static const int non_patterns = 4;
1007
1008 static struct MPlayerPattern {
1009 QString caption;
1010 const char * name;
1011 const char * pattern;
1012 } _mplayer_patterns [] = {
1013 { i18n ("Size pattern"), "Movie Size", "VO:.*[^0-9]([0-9]+)x([0-9]+)" },
1014 { i18n ("Cache pattern"), "Cache Fill", "Cache fill:[^0-9]*([0-9\\.]+)%" },
1015 { i18n ("Position pattern"), "Movie Position", "[AV]:\\s*([0-9\\.]+)" },
1016 { i18n ("Index pattern"), "Index Pattern", "Generating Index: +([0-9]+)%" },
1017 { i18n ("Reference URL pattern"), "Reference URL Pattern", "Playing\\s+(.*[^\\.])\\.?\\s*$" },
1018 { i18n ("Reference pattern"), "Reference Pattern", "Reference Media file" },
1019 { i18n ("Start pattern"), "Start Playing", "Start[^ ]* play" },
1020 { i18n ("VCD track pattern"), "VCD Tracks", "track ([0-9]+):" },
1021 { i18n ("Audio CD tracks pattern"), "CDROM Tracks", "[Aa]udio CD[^0-9]+([0-9]+)[^0-9]tracks" }
1022 };
1023
1024 namespace KMPlayer {
1025
1026 class KMPLAYER_NO_EXPORT MPlayerPreferencesFrame : public QFrame {
1027 public:
1028 MPlayerPreferencesFrame (QWidget * parent);
1029 QTableWidget * table;
1030 };
1031
1032 } // namespace
1033
MPlayerPreferencesFrame(QWidget * parent)1034 KDE_NO_CDTOR_EXPORT MPlayerPreferencesFrame::MPlayerPreferencesFrame (QWidget * parent)
1035 : QFrame (parent) {
1036 QVBoxLayout * layout = new QVBoxLayout (this);
1037 table = new QTableWidget (int (MPlayerPreferencesPage::pat_last)+non_patterns, 2, this);
1038 table->verticalHeader ()->setVisible (false);
1039 table->horizontalHeader ()->setVisible (false);
1040 table->setContentsMargins (0, 0, 0, 0);
1041 table->setItem (0, 0, new QTableWidgetItem (i18n ("MPlayer command:")));
1042 table->setItem (0, 1, new QTableWidgetItem ());
1043 table->setItem (1, 0, new QTableWidgetItem (i18n ("Additional command line arguments:")));
1044 table->setItem (1, 1, new QTableWidgetItem ());
1045 table->setItem (2, 0, new QTableWidgetItem (QString("%1 (%2)").arg (i18n ("Cache size:")).arg (i18n ("kB")))); // FIXME for new translations
1046 QSpinBox* spin = new QSpinBox(table->viewport());
1047 spin->setMaximum(32767);
1048 spin->setSingleStep(32);
1049 table->setCellWidget (2, 1, spin);
1050 table->setItem (3, 0, new QTableWidgetItem (i18n ("Build new index when possible")));
1051 table->setCellWidget (3, 1, new QCheckBox (table->viewport()));
1052 table->cellWidget (3, 1)->setWhatsThis(i18n ("Allows seeking in indexed files (AVIs)"));
1053 for (int i = 0; i < int (MPlayerPreferencesPage::pat_last); i++) {
1054 table->setItem (i+non_patterns, 0, new QTableWidgetItem (_mplayer_patterns[i].caption));
1055 table->setItem (i+non_patterns, 1, new QTableWidgetItem ());
1056 }
1057 for (int i = 0; i < non_patterns + int (MPlayerPreferencesPage::pat_last); i++) {
1058 QTableWidgetItem *item = table->itemAt (i, 0);
1059 item->setFlags (item->flags () ^ Qt::ItemIsEditable);
1060 }
1061 table->horizontalHeader ()->setResizeMode (QHeaderView::ResizeToContents);
1062 table->horizontalHeader ()->setStretchLastSection (true);
1063 table->resizeRowsToContents ();
1064 layout->addWidget (table);
1065 }
1066
MPlayerPreferencesPage()1067 KDE_NO_CDTOR_EXPORT MPlayerPreferencesPage::MPlayerPreferencesPage ()
1068 : m_configframe (0L) {
1069 }
1070
write(KSharedConfigPtr config)1071 KDE_NO_EXPORT void MPlayerPreferencesPage::write (KSharedConfigPtr config) {
1072 KConfigGroup patterns_cfg (config, strMPlayerPatternGroup);
1073 for (int i = 0; i < int (pat_last); i++)
1074 patterns_cfg.writeEntry
1075 (_mplayer_patterns[i].name, m_patterns[i].pattern ());
1076 KConfigGroup mplayer_cfg (config, strMPlayerGroup);
1077 mplayer_cfg.writeEntry (strMPlayerPath, mplayer_path);
1078 mplayer_cfg.writeEntry (strAddArgs, additionalarguments);
1079 mplayer_cfg.writeEntry (strCacheSize, cachesize);
1080 mplayer_cfg.writeEntry (strAlwaysBuildIndex, alwaysbuildindex);
1081 }
1082
read(KSharedConfigPtr config)1083 KDE_NO_EXPORT void MPlayerPreferencesPage::read (KSharedConfigPtr config) {
1084 KConfigGroup patterns_cfg (config, strMPlayerPatternGroup);
1085 for (int i = 0; i < int (pat_last); i++)
1086 m_patterns[i].setPattern (patterns_cfg.readEntry
1087 (_mplayer_patterns[i].name, _mplayer_patterns[i].pattern));
1088 KConfigGroup mplayer_cfg (config, strMPlayerGroup);
1089 mplayer_path = mplayer_cfg.readEntry (strMPlayerPath, QString ("mplayer"));
1090 additionalarguments = mplayer_cfg.readEntry (strAddArgs, QString ());
1091 cachesize = mplayer_cfg.readEntry (strCacheSize, 384);
1092 alwaysbuildindex = mplayer_cfg.readEntry (strAlwaysBuildIndex, false);
1093 }
1094
sync(bool fromUI)1095 KDE_NO_EXPORT void MPlayerPreferencesPage::sync (bool fromUI) {
1096 QTableWidget * table = m_configframe->table;
1097 QSpinBox * cacheSize = static_cast<QSpinBox *>(table->cellWidget (2, 1));
1098 QCheckBox * buildIndex = static_cast<QCheckBox *>(table->cellWidget (3, 1));
1099 if (fromUI) {
1100 mplayer_path = table->item (0, 1)->text ();
1101 additionalarguments = table->item (1, 1)->text ();
1102 for (int i = 0; i < int (pat_last); i++)
1103 m_patterns[i].setPattern (table->item (i+non_patterns, 1)->text ());
1104 cachesize = cacheSize->value();
1105 alwaysbuildindex = buildIndex->isChecked ();
1106 } else {
1107 table->item (0, 1)->setText (mplayer_path);
1108 table->item (1, 1)->setText (additionalarguments);
1109 for (int i = 0; i < int (pat_last); i++)
1110 table->item (i+non_patterns, 1)->setText (m_patterns[i].pattern ());
1111 if (cachesize > 0)
1112 cacheSize->setValue(cachesize);
1113 buildIndex->setChecked (alwaysbuildindex);
1114 }
1115 }
1116
prefLocation(QString & item,QString & icon,QString & tab)1117 KDE_NO_EXPORT void MPlayerPreferencesPage::prefLocation (QString & item, QString & icon, QString & tab) {
1118 item = i18n ("General Options");
1119 icon = QString ("kmplayer");
1120 tab = i18n ("MPlayer");
1121 }
1122
prefPage(QWidget * parent)1123 KDE_NO_EXPORT QFrame * MPlayerPreferencesPage::prefPage (QWidget * parent) {
1124 m_configframe = new MPlayerPreferencesFrame (parent);
1125 return m_configframe;
1126 }
1127
1128 //-----------------------------------------------------------------------------
1129
1130 static const char * mencoder_supports [] = {
1131 "dvdsource", "pipesource", "tvscanner", "tvsource", "urlsource",
1132 "vcdsource", "audiocdsource", NULL
1133 };
1134
MEncoderProcessInfo(MediaManager * mgr)1135 MEncoderProcessInfo::MEncoderProcessInfo (MediaManager *mgr)
1136 : ProcessInfo ("mencoder", i18n ("M&Encoder"), mencoder_supports,
1137 mgr, NULL) {}
1138
create(PartBase * part,ProcessUser * usr)1139 IProcess *MEncoderProcessInfo::create (PartBase *part, ProcessUser *usr) {
1140 MEncoder *m = new MEncoder (part, this, part->settings ());
1141 m->setSource (part->source ());
1142 m->user = usr;
1143 part->processCreated (m);
1144 return m;
1145 }
1146
1147 KDE_NO_CDTOR_EXPORT
MEncoder(QObject * parent,ProcessInfo * pinfo,Settings * settings)1148 MEncoder::MEncoder (QObject * parent, ProcessInfo *pinfo, Settings * settings)
1149 : MPlayerBase (parent, pinfo, settings) {}
1150
~MEncoder()1151 KDE_NO_CDTOR_EXPORT MEncoder::~MEncoder () {
1152 }
1153
init()1154 KDE_NO_EXPORT void MEncoder::init () {
1155 }
1156
deMediafiedPlay()1157 bool MEncoder::deMediafiedPlay () {
1158 stop ();
1159 RecordDocument *rd = recordDocument (user);
1160 if (!rd)
1161 return false;
1162 initProcess ();
1163 QString exe ("mencoder");
1164 QString margs = m_settings->mencoderarguments;
1165 if (m_settings->recordcopy)
1166 margs = QString ("-oac copy -ovc copy");
1167 QStringList args = KShell::splitArgs (margs);
1168 if (m_source)
1169 args << KShell::splitArgs (m_source->recordCmd ());
1170 // FIXME if (m_player->source () == source) // ugly
1171 // m_player->stop ();
1172 QString myurl = encodeFileOrUrl (m_url);
1173 if (!myurl.isEmpty ())
1174 args << myurl;
1175 args << "-o" << encodeFileOrUrl (rd->record_file);
1176 startProcess (exe, args);
1177 qDebug ("mencoder %s\n", args.join (" ").toLocal8Bit ().constData ());
1178 if (m_process->waitForStarted ()) {
1179 setState (Playing);
1180 return true;
1181 }
1182 stop ();
1183 return false;
1184 }
1185
stop()1186 KDE_NO_EXPORT void MEncoder::stop () {
1187 terminateJobs ();
1188 if (running ()) {
1189 kDebug () << "MEncoder::stop ()";
1190 Process::quit ();
1191 MPlayerBase::stop ();
1192 }
1193 }
1194
1195 //-----------------------------------------------------------------------------
1196
1197 static const char * mplayerdump_supports [] = {
1198 "dvdsource", "pipesource", "tvscanner", "tvsource", "urlsource", "vcdsource", "audiocdsource", 0L
1199 };
1200
MPlayerDumpProcessInfo(MediaManager * mgr)1201 MPlayerDumpProcessInfo::MPlayerDumpProcessInfo (MediaManager *mgr)
1202 : ProcessInfo ("mplayerdumpstream", i18n ("&MPlayerDumpstream"),
1203 mplayerdump_supports, mgr, NULL) {}
1204
create(PartBase * p,ProcessUser * usr)1205 IProcess *MPlayerDumpProcessInfo::create (PartBase *p, ProcessUser *usr) {
1206 MPlayerDumpstream *m = new MPlayerDumpstream (p, this, p->settings ());
1207 m->setSource (p->source ());
1208 m->user = usr;
1209 p->processCreated (m);
1210 return m;
1211 }
1212
1213 KDE_NO_CDTOR_EXPORT
MPlayerDumpstream(QObject * p,ProcessInfo * pi,Settings * s)1214 MPlayerDumpstream::MPlayerDumpstream (QObject *p, ProcessInfo *pi, Settings *s)
1215 : MPlayerBase (p, pi, s) {}
1216
~MPlayerDumpstream()1217 KDE_NO_CDTOR_EXPORT MPlayerDumpstream::~MPlayerDumpstream () {
1218 }
1219
init()1220 KDE_NO_EXPORT void MPlayerDumpstream::init () {
1221 }
1222
deMediafiedPlay()1223 bool MPlayerDumpstream::deMediafiedPlay () {
1224 stop ();
1225 RecordDocument *rd = recordDocument (user);
1226 if (!rd)
1227 return false;
1228 initProcess ();
1229 QString exe ("mplayer");
1230 QStringList args;
1231 args << KShell::splitArgs (m_source->recordCmd ());
1232 // FIXME if (m_player->source () == source) // ugly
1233 // m_player->stop ();
1234 QString myurl = encodeFileOrUrl (m_url);
1235 if (!myurl.isEmpty ())
1236 args << myurl;
1237 args << "-dumpstream" << "-dumpfile" << encodeFileOrUrl (rd->record_file);
1238 qDebug ("mplayer %s\n", args.join (" ").toLocal8Bit ().constData ());
1239 startProcess (exe, args);
1240 if (m_process->waitForStarted ()) {
1241 setState (Playing);
1242 return true;
1243 }
1244 stop ();
1245 return false;
1246 }
1247
stop()1248 KDE_NO_EXPORT void MPlayerDumpstream::stop () {
1249 terminateJobs ();
1250 if (!m_source || !running ())
1251 return;
1252 kDebug () << "MPlayerDumpstream::stop";
1253 if (running ())
1254 Process::quit ();
1255 MPlayerBase::stop ();
1256 }
1257
1258 //-----------------------------------------------------------------------------
1259
MasterProcessInfo(const char * nm,const QString & lbl,const char ** supported,MediaManager * mgr,PreferencesPage * pp)1260 MasterProcessInfo::MasterProcessInfo (const char *nm, const QString &lbl,
1261 const char **supported, MediaManager *mgr, PreferencesPage *pp)
1262 : ProcessInfo (nm, lbl, supported, mgr, pp),
1263 m_slave (NULL) {}
1264
~MasterProcessInfo()1265 MasterProcessInfo::~MasterProcessInfo () {
1266 stopSlave ();
1267 }
1268
initSlave()1269 void MasterProcessInfo::initSlave () {
1270 if (m_path.isEmpty ()) {
1271 static int count = 0;
1272 m_path = QString ("/master_%1").arg (count++);
1273 (void) new MasterAdaptor (this);
1274 QDBusConnection::sessionBus().registerObject (m_path, this);
1275 m_service = QDBusConnection::sessionBus().baseService ();
1276 }
1277 setupProcess (&m_slave);
1278 connect (m_slave, SIGNAL (finished (int, QProcess::ExitStatus)),
1279 this, SLOT (slaveStopped (int, QProcess::ExitStatus)));
1280 connect (m_slave, SIGNAL (readyReadStandardOutput ()),
1281 this, SLOT (slaveOutput ()));
1282 connect (m_slave, SIGNAL (readyReadStandardError ()),
1283 this, SLOT (slaveOutput ()));
1284 }
1285
quitProcesses()1286 void MasterProcessInfo::quitProcesses () {
1287 stopSlave ();
1288 }
1289
stopSlave()1290 void MasterProcessInfo::stopSlave () {
1291 if (!m_slave_service.isEmpty ()) {
1292 QDBusMessage msg = QDBusMessage::createMethodCall (
1293 m_slave_service, QString ("/%1").arg (ProcessInfo::name),
1294 "org.kde.kmplayer.Slave", "quit");
1295 //msg << m_url << mime << plugin << param_len;
1296 msg.setDelayedReply (false);
1297 QDBusConnection::sessionBus().send (msg);
1298 }
1299 if (processRunning (m_slave)) {
1300 m_slave->waitForFinished (1000);
1301 killProcess (m_slave, manager->player ()->view ());
1302 }
1303 }
1304
running(const QString & srv)1305 void MasterProcessInfo::running (const QString &srv) {
1306 kDebug() << "MasterProcessInfo::running " << srv;
1307 m_slave_service = srv;
1308 MediaManager::ProcessList &pl = manager->processes ();
1309 const MediaManager::ProcessList::iterator e = pl.end ();
1310 for (MediaManager::ProcessList::iterator i = pl.begin (); i != e; ++i)
1311 if (this == (*i)->process_info)
1312 static_cast <Process *> (*i)->setState (IProcess::Ready);
1313 }
1314
slaveStopped(int,QProcess::ExitStatus)1315 void MasterProcessInfo::slaveStopped (int, QProcess::ExitStatus) {
1316 m_slave_service.truncate (0);
1317 MediaManager::ProcessList &pl = manager->processes ();
1318 const MediaManager::ProcessList::iterator e = pl.end ();
1319 for (MediaManager::ProcessList::iterator i = pl.begin (); i != e; ++i)
1320 if (this == (*i)->process_info)
1321 static_cast <Process *> (*i)->setState (IProcess::NotRunning);
1322 }
1323
slaveOutput()1324 void MasterProcessInfo::slaveOutput () {
1325 outputToView(manager->player()->viewWidget(), m_slave->readAllStandardOutput());
1326 outputToView(manager->player()->viewWidget(), m_slave->readAllStandardError ());
1327 }
1328
MasterProcess(QObject * parent,ProcessInfo * pinfo,Settings * settings)1329 MasterProcess::MasterProcess (QObject *parent, ProcessInfo *pinfo, Settings *settings)
1330 : Process (parent, pinfo, settings) {}
1331
~MasterProcess()1332 MasterProcess::~MasterProcess () {
1333 }
1334
init()1335 void MasterProcess::init () {
1336 }
1337
deMediafiedPlay()1338 bool MasterProcess::deMediafiedPlay () {
1339 WindowId wid = user->viewer ()->windowHandle ();
1340 m_slave_path = QString ("/stream_%1").arg (wid);
1341 MasterProcessInfo *mpi = static_cast <MasterProcessInfo *>(process_info);
1342 kDebug() << "MasterProcess::deMediafiedPlay " << m_url << " " << wid;
1343
1344 (void) new StreamMasterAdaptor (this);
1345 QDBusConnection::sessionBus().registerObject (
1346 QString ("%1/stream_%2").arg (mpi->m_path).arg (wid), this);
1347
1348 QDBusMessage msg = QDBusMessage::createMethodCall (
1349 mpi->m_slave_service, QString ("/%1").arg (process_info->name),
1350 "org.kde.kmplayer.Slave", "newStream");
1351 if (!m_url.startsWith ("dvd:") ||
1352 !m_url.startsWith ("vcd:") ||
1353 !m_url.startsWith ("cdda:")) {
1354 KUrl url (m_url);
1355 if (url.isLocalFile ())
1356 m_url = getPath (url);
1357 }
1358 msg << m_url << (qulonglong)wid;
1359 msg.setDelayedReply (false);
1360 QDBusConnection::sessionBus().send (msg);
1361 setState (IProcess::Buffering);
1362 return true;
1363 }
1364
running() const1365 bool MasterProcess::running () const {
1366 MasterProcessInfo *mpi = static_cast <MasterProcessInfo *>(process_info);
1367 return processRunning (mpi->m_slave);
1368 }
1369
loading(int perc)1370 void MasterProcess::loading (int perc) {
1371 process_info->manager->player ()->setLoaded (perc);
1372 }
1373
streamInfo(uint64_t length,double aspect)1374 void MasterProcess::streamInfo (uint64_t length, double aspect) {
1375 kDebug() << length;
1376 m_source->setLength (mrl (), length);
1377 m_source->setAspect (mrl (), aspect);
1378 }
1379
streamMetaInfo(QString info)1380 void MasterProcess::streamMetaInfo (QString info) {
1381 m_source->document ()->message (MsgInfoString, &info);
1382 }
1383
playing()1384 void MasterProcess::playing () {
1385 process_info->manager->player ()->setLoaded (100);
1386 setState (IProcess::Playing);
1387 }
1388
progress(uint64_t pos)1389 void MasterProcess::progress (uint64_t pos) {
1390 m_source->setPosition (pos);
1391 }
1392
pause()1393 void MasterProcess::pause () {
1394 if (IProcess::Playing == m_state) {
1395 MasterProcessInfo *mpi = static_cast<MasterProcessInfo *>(process_info);
1396 QDBusMessage msg = QDBusMessage::createMethodCall (
1397 mpi->m_slave_service,
1398 m_slave_path,
1399 "org.kde.kmplayer.StreamSlave",
1400 "pause");
1401 msg.setDelayedReply (false);
1402 QDBusConnection::sessionBus().send (msg);
1403 }
1404 }
1405
unpause()1406 void MasterProcess::unpause () {
1407 pause ();
1408 }
1409
seek(int pos,bool)1410 bool MasterProcess::seek (int pos, bool) {
1411 if (IProcess::Playing == m_state) {
1412 MasterProcessInfo *mpi = static_cast<MasterProcessInfo *>(process_info);
1413 QDBusMessage msg = QDBusMessage::createMethodCall (
1414 mpi->m_slave_service,
1415 m_slave_path,
1416 "org.kde.kmplayer.StreamSlave",
1417 "seek");
1418 msg << (qulonglong) pos << true;
1419 msg.setDelayedReply (false);
1420 QDBusConnection::sessionBus().send (msg);
1421 return true;
1422 }
1423 return false;
1424 }
1425
volume(int incdec,bool)1426 KDE_NO_EXPORT void MasterProcess::volume (int incdec, bool) {
1427 if (IProcess::Playing == m_state) {
1428 MasterProcessInfo *mpi = static_cast<MasterProcessInfo *>(process_info);
1429 QDBusMessage msg = QDBusMessage::createMethodCall (
1430 mpi->m_slave_service,
1431 m_slave_path,
1432 "org.kde.kmplayer.StreamSlave",
1433 "volume");
1434 msg << incdec;
1435 msg.setDelayedReply (false);
1436 QDBusConnection::sessionBus().send (msg);
1437 }
1438 }
1439
eof()1440 void MasterProcess::eof () {
1441 setState (IProcess::Ready);
1442 }
1443
stop()1444 void MasterProcess::stop () {
1445 if (m_state > IProcess::Ready) {
1446 MasterProcessInfo *mpi = static_cast<MasterProcessInfo *>(process_info);
1447 QDBusMessage msg = QDBusMessage::createMethodCall (
1448 mpi->m_slave_service,
1449 m_slave_path,
1450 "org.kde.kmplayer.StreamSlave",
1451 "stop");
1452 msg.setDelayedReply (false);
1453 QDBusConnection::sessionBus().send (msg);
1454 }
1455 }
1456
1457 //-------------------------%<--------------------------------------------------
1458
1459 static const char *phonon_supports [] = {
1460 "urlsource", "dvdsource", "vcdsource", "audiocdsource", 0L
1461 };
1462
PhononProcessInfo(MediaManager * mgr)1463 PhononProcessInfo::PhononProcessInfo (MediaManager *mgr)
1464 : MasterProcessInfo ("phonon", i18n ("&Phonon"), phonon_supports, mgr, NULL)
1465 {}
1466
create(PartBase * part,ProcessUser * usr)1467 IProcess *PhononProcessInfo::create (PartBase *part, ProcessUser *usr) {
1468 if (!processRunning (m_slave))
1469 startSlave ();
1470 Phonon *p = new Phonon (part, this, part->settings ());
1471 p->setSource (part->source ());
1472 p->user = usr;
1473 part->processCreated (p);
1474 return p;
1475 }
1476
startSlave()1477 bool PhononProcessInfo::startSlave () {
1478 initSlave ();
1479 QString exe ("kphononplayer");
1480 QStringList args;
1481 args << "-cb" << (m_service + m_path);
1482 qDebug ("kphononplayer %s", args.join (" ").toLocal8Bit ().constData ());
1483 m_slave->start (exe, args);
1484 return true;
1485 }
1486
Phonon(QObject * parent,ProcessInfo * pinfo,Settings * settings)1487 Phonon::Phonon (QObject *parent, ProcessInfo *pinfo, Settings *settings)
1488 : MasterProcess (parent, pinfo, settings) {}
1489
ready()1490 bool Phonon::ready () {
1491 if (user && user->viewer ())
1492 user->viewer ()->useIndirectWidget (false);
1493 kDebug() << "Phonon::ready " << state () << endl;
1494 PhononProcessInfo *ppi = static_cast <PhononProcessInfo *>(process_info);
1495 if (running ()) {
1496 if (!ppi->m_slave_service.isEmpty ())
1497 setState (IProcess::Ready);
1498 return true;
1499 } else {
1500 return ppi->startSlave ();
1501 }
1502 }
1503
1504 //-----------------------------------------------------------------------------
1505
ConfigDocument()1506 KDE_NO_CDTOR_EXPORT ConfigDocument::ConfigDocument ()
1507 : Document (QString ()) {}
1508
~ConfigDocument()1509 KDE_NO_CDTOR_EXPORT ConfigDocument::~ConfigDocument () {
1510 kDebug () << "~ConfigDocument";
1511 }
1512
1513 namespace KMPlayer {
1514 /*
1515 * Element for ConfigDocument
1516 */
1517 struct KMPLAYER_NO_EXPORT SomeNode : public ConfigNode {
SomeNodeKMPlayer::SomeNode1518 KDE_NO_CDTOR_EXPORT SomeNode (NodePtr & d, const QString & t)
1519 : ConfigNode (d, t) {}
~SomeNodeKMPlayer::SomeNode1520 KDE_NO_CDTOR_EXPORT ~SomeNode () {}
1521 Node *childFromTag (const QString & t);
1522 };
1523 } // namespace
1524
ConfigNode(NodePtr & d,const QString & t)1525 KDE_NO_CDTOR_EXPORT ConfigNode::ConfigNode (NodePtr & d, const QString & t)
1526 : DarkNode (d, t.toUtf8 ()), w (0L) {}
1527
childFromTag(const QString & tag)1528 Node *ConfigDocument::childFromTag (const QString & tag) {
1529 if (tag.toLower () == QString ("document"))
1530 return new ConfigNode (m_doc, tag);
1531 return 0L;
1532 }
1533
childFromTag(const QString & t)1534 Node *ConfigNode::childFromTag (const QString & t) {
1535 return new TypeNode (m_doc, t);
1536 }
1537
TypeNode(NodePtr & d,const QString & t)1538 KDE_NO_CDTOR_EXPORT TypeNode::TypeNode (NodePtr & d, const QString & t)
1539 : ConfigNode (d, t), tag (t) {}
1540
childFromTag(const QString & tag)1541 Node *TypeNode::childFromTag (const QString & tag) {
1542 return new SomeNode (m_doc, tag);
1543 }
1544
childFromTag(const QString & t)1545 Node *SomeNode::childFromTag (const QString & t) {
1546 return new SomeNode (m_doc, t);
1547 }
1548
createWidget(QWidget * parent)1549 QWidget * TypeNode::createWidget (QWidget * parent) {
1550 QByteArray ba = getAttribute (Ids::attr_type).toAscii ();
1551 const char *ctype = ba.constData ();
1552 QString value = getAttribute (Ids::attr_value);
1553 if (!strcmp (ctype, "range")) {
1554 QSlider* slider = new QSlider (parent);
1555 slider->setMinimum(getAttribute (QString ("START")).toInt ());
1556 slider->setMaximum(getAttribute (Ids::attr_end).toInt ());
1557 slider->setPageStep(1);
1558 slider->setOrientation(Qt::Horizontal);
1559 slider->setValue(value.toInt ());
1560 w = slider;
1561 } else if (!strcmp (ctype, "num") || !strcmp (ctype, "string")) {
1562 w = new QLineEdit (value, parent);
1563 } else if (!strcmp (ctype, "bool")) {
1564 QCheckBox * checkbox = new QCheckBox (parent);
1565 checkbox->setChecked (value.toInt ());
1566 w = checkbox;
1567 } else if (!strcmp (ctype, "enum")) {
1568 QComboBox * combo = new QComboBox (parent);
1569 for (Node *e = firstChild (); e; e = e->nextSibling ())
1570 if (e->isElementNode () && !strcmp (e->nodeName (), "item"))
1571 combo->addItem (static_cast <Element *> (e)->getAttribute (Ids::attr_value));
1572 combo->setCurrentIndex (value.toInt ());
1573 w = combo;
1574 } else if (!strcmp (ctype, "tree")) {
1575 } else
1576 kDebug() << "Unknown type:" << ctype;
1577 return w;
1578 }
1579
changedXML(QTextStream & out)1580 void TypeNode::changedXML (QTextStream & out) {
1581 if (!w) return;
1582 QByteArray ba = getAttribute (Ids::attr_type).toAscii ();
1583 const char *ctype = ba.constData ();
1584 QString value = getAttribute (Ids::attr_value);
1585 QString newvalue;
1586 if (!strcmp (ctype, "range")) {
1587 newvalue = QString::number (static_cast <QSlider *> (w)->value ());
1588 } else if (!strcmp (ctype, "num") || !strcmp (ctype, "string")) {
1589 newvalue = static_cast <QLineEdit *> (w)->text ();
1590 } else if (!strcmp (ctype, "bool")) {
1591 newvalue = QString::number (static_cast <QCheckBox *> (w)->isChecked());
1592 } else if (!strcmp (ctype, "enum")) {
1593 newvalue = QString::number (static_cast<QComboBox *>(w)->currentIndex());
1594 } else if (!strcmp (ctype, "tree")) {
1595 } else
1596 kDebug() << "Unknown type:" << ctype;
1597 if (value != newvalue) {
1598 value = newvalue;
1599 setAttribute (Ids::attr_value, newvalue);
1600 out << outerXML ();
1601 }
1602 }
1603
1604 //-----------------------------------------------------------------------------
1605
1606 static const char * ffmpeg_supports [] = {
1607 "tvsource", "urlsource", 0L
1608 };
1609
FFMpegProcessInfo(MediaManager * mgr)1610 FFMpegProcessInfo::FFMpegProcessInfo (MediaManager *mgr)
1611 : ProcessInfo ("ffmpeg", i18n ("&FFMpeg"), ffmpeg_supports, mgr, NULL) {}
1612
create(PartBase * p,ProcessUser * usr)1613 IProcess *FFMpegProcessInfo::create (PartBase *p, ProcessUser *usr) {
1614 FFMpeg *m = new FFMpeg (p, this, p->settings ());
1615 m->setSource (p->source ());
1616 m->user = usr;
1617 p->processCreated (m);
1618 return m;
1619 }
1620
FFMpeg(QObject * parent,ProcessInfo * pinfo,Settings * settings)1621 FFMpeg::FFMpeg (QObject *parent, ProcessInfo *pinfo, Settings * settings)
1622 : Process (parent, pinfo, settings) {
1623 }
1624
~FFMpeg()1625 KDE_NO_CDTOR_EXPORT FFMpeg::~FFMpeg () {
1626 }
1627
init()1628 KDE_NO_EXPORT void FFMpeg::init () {
1629 }
1630
deMediafiedPlay()1631 bool FFMpeg::deMediafiedPlay () {
1632 RecordDocument *rd = recordDocument (user);
1633 if (!rd)
1634 return false;
1635 initProcess ();
1636 connect (m_process, SIGNAL (finished (int, QProcess::ExitStatus)),
1637 this, SLOT (processStopped (int, QProcess::ExitStatus)));
1638 QString outurl = encodeFileOrUrl (rd->record_file);
1639 if (outurl.startsWith (QChar ('/')))
1640 QFile (outurl).remove ();
1641 QString exe ("ffmpeg ");
1642 QStringList args;
1643 if (!m_source->videoDevice ().isEmpty () ||
1644 !m_source->audioDevice ().isEmpty ()) {
1645 if (!m_source->videoDevice ().isEmpty ())
1646 args << "-vd" << m_source->videoDevice ();
1647 else
1648 args << "-vn";
1649 if (!m_source->audioDevice ().isEmpty ())
1650 args << "-ad" << m_source->audioDevice ();
1651 else
1652 args << "-an";
1653 QProcess process;
1654 QString ctl_exe ("v4lctl");
1655 QStringList ctl_args;
1656 if (!m_source->videoNorm ().isEmpty ()) {
1657 ctl_args << "-c" << m_source->videoDevice () << "setnorm" << m_source->videoNorm ();
1658 process.start (ctl_exe, ctl_args);
1659 process.waitForFinished (5000);
1660 args << "-tvstd" << m_source->videoNorm ();
1661 }
1662 if (m_source->frequency () > 0) {
1663 ctl_args.clear ();
1664 ctl_args << "-c" << m_source->videoDevice () << "setfreq" << QString::number (m_source->frequency ());
1665 process.start (ctl_exe, ctl_args);
1666 process.waitForFinished (5000);
1667 }
1668 } else {
1669 args << "-i" << encodeFileOrUrl (m_url);
1670 }
1671 args << KShell::splitArgs (m_settings->ffmpegarguments);
1672 args << outurl;
1673 qDebug ("ffmpeg %s\n", args.join (" ").toLocal8Bit().constData ());
1674 // FIXME if (m_player->source () == source) // ugly
1675 // m_player->stop ();
1676 m_process->start (exe, args);
1677 if (m_process->waitForStarted ()) {
1678 setState (Playing);
1679 return true;
1680 }
1681 stop ();
1682 return false;
1683 }
1684
stop()1685 KDE_NO_EXPORT void FFMpeg::stop () {
1686 terminateJobs ();
1687 if (!running ())
1688 return;
1689 kDebug () << "FFMpeg::stop";
1690 m_process->write ("q");
1691 }
1692
quit()1693 KDE_NO_EXPORT void FFMpeg::quit () {
1694 stop ();
1695 if (!running ())
1696 return;
1697 if (m_process->waitForFinished (2000))
1698 Process::quit ();
1699 }
1700
processStopped(int,QProcess::ExitStatus)1701 KDE_NO_EXPORT void FFMpeg::processStopped (int, QProcess::ExitStatus) {
1702 setState (IProcess::NotRunning);
1703 }
1704
1705 //-----------------------------------------------------------------------------
1706
1707 static const char *npp_supports [] = { "urlsource", 0L };
1708
NppProcessInfo(MediaManager * mgr)1709 NppProcessInfo::NppProcessInfo (MediaManager *mgr)
1710 : ProcessInfo ("npp", i18n ("&Ice Ape"), npp_supports, mgr, NULL) {}
1711
create(PartBase * p,ProcessUser * usr)1712 IProcess *NppProcessInfo::create (PartBase *p, ProcessUser *usr) {
1713 NpPlayer *n = new NpPlayer (p, this, p->settings());
1714 n->setSource (p->source ());
1715 n->user = usr;
1716 p->processCreated (n);
1717 return n;
1718 }
1719
1720 #ifdef KMPLAYER_WITH_NPP
1721
NpStream(NpPlayer * p,uint32_t sid,const QString & u,const QByteArray & ps)1722 KDE_NO_CDTOR_EXPORT NpStream::NpStream (NpPlayer *p, uint32_t sid, const QString &u, const QByteArray &ps)
1723 : QObject (p),
1724 url (u),
1725 post (ps),
1726 job (0L), bytes (0),
1727 stream_id (sid),
1728 content_length (0),
1729 finish_reason (NoReason),
1730 received_data (false) {
1731 data_arrival.tv_sec = 0;
1732 (void) new StreamAdaptor (this);
1733 QString objpath = QString ("%1/stream_%2").arg (p->objectPath ()).arg (sid);
1734 QDBusConnection::sessionBus().registerObject (objpath, this);
1735 }
1736
~NpStream()1737 KDE_NO_CDTOR_EXPORT NpStream::~NpStream () {
1738 close ();
1739 }
1740
open()1741 KDE_NO_EXPORT void NpStream::open () {
1742 kDebug () << "NpStream " << stream_id << " open " << url;
1743 if (url.startsWith ("javascript:")) {
1744 NpPlayer *npp = static_cast <NpPlayer *> (parent ());
1745 QString result = npp->evaluate (url.mid (11), false);
1746 if (!result.isEmpty ()) {
1747 QByteArray cr = result.toLocal8Bit ();
1748 int len = strlen (cr.constData ());
1749 pending_buf.resize (len + 1);
1750 memcpy (pending_buf.data (), cr.constData (), len);
1751 pending_buf.data ()[len] = 0;
1752 gettimeofday (&data_arrival, 0L);
1753 }
1754 kDebug () << "result is " << pending_buf.constData ();
1755 finish_reason = BecauseDone;
1756 emit stateChanged ();
1757 } else {
1758 if (!post.size ()) {
1759 job = KIO::get (KUrl (url), KIO::NoReload, KIO::HideProgressInfo);
1760 job->addMetaData ("PropagateHttpHeader", "true");
1761 } else {
1762 QStringList name;
1763 QStringList value;
1764 QString buf;
1765 int data_pos = -1;
1766 for (int i = 0; i < post.size () && data_pos < 0; ++i) {
1767 char c = post.at (i);
1768 switch (c) {
1769 case ':':
1770 if (name.size () == value.size ()) {
1771 name << buf;
1772 buf.truncate (0);
1773 } else
1774 buf += QChar (':');
1775 break;
1776 case '\r':
1777 break;
1778 case '\n':
1779 if (name.size () == value.size ()) {
1780 if (buf.isEmpty ()) {
1781 data_pos = i + 1;
1782 } else {
1783 name << buf;
1784 value << QString ("");
1785 }
1786 } else {
1787 value << buf;
1788 }
1789 buf.truncate (0);
1790 break;
1791 default:
1792 buf += QChar (c);
1793 }
1794 }
1795 job = KIO::http_post (KUrl (url), post.mid (data_pos), KIO::HideProgressInfo);
1796 for (int i = 0; i < name.size (); ++i)
1797 job->addMetaData (name[i].trimmed (), value[i].trimmed ());
1798 }
1799 job->addMetaData ("errorPage", "false");
1800 connect (job, SIGNAL (data (KIO::Job *, const QByteArray &)),
1801 this, SLOT (slotData (KIO::Job *, const QByteArray &)));
1802 connect (job, SIGNAL (result (KJob *)),
1803 this, SLOT (slotResult (KJob *)));
1804 connect (job, SIGNAL(redirection(KIO::Job*, const QUrl&)),
1805 this, SLOT (redirection (KIO::Job *, const QUrl &)));
1806 connect (job, SIGNAL (mimetype (KIO::Job *, const QString &)),
1807 SLOT (slotMimetype (KIO::Job *, const QString &)));
1808 connect (job, SIGNAL (totalSize (KJob *, qulonglong)),
1809 SLOT (slotTotalSize (KJob *, qulonglong)));
1810 }
1811 }
1812
close()1813 KDE_NO_EXPORT void NpStream::close () {
1814 if (job) {
1815 job->kill (); // quiet, no result signal
1816 job = 0L;
1817 finish_reason = BecauseStopped;
1818 // don't emit stateChanged(), because always triggered from NpPlayer
1819 }
1820 }
1821
destroy()1822 KDE_NO_EXPORT void NpStream::destroy () {
1823 pending_buf.clear ();
1824 static_cast <NpPlayer *> (parent ())->destroyStream (stream_id);
1825 }
1826
slotResult(KJob * jb)1827 KDE_NO_EXPORT void NpStream::slotResult (KJob *jb) {
1828 kDebug() << "slotResult " << stream_id << " " << bytes << " err:" << jb->error ();
1829 finish_reason = jb->error () ? BecauseError : BecauseDone;
1830 job = 0L; // signal KIO::Job::result deletes itself
1831 emit stateChanged ();
1832 }
1833
slotData(KIO::Job *,const QByteArray & qb)1834 KDE_NO_EXPORT void NpStream::slotData (KIO::Job*, const QByteArray& qb) {
1835 if (job) {
1836 int sz = pending_buf.size ();
1837 if (sz) {
1838 pending_buf.resize (sz + qb.size ());
1839 memcpy (pending_buf.data () + sz, qb.constData (), qb.size ());
1840 } else {
1841 pending_buf = qb;
1842 }
1843 if (sz + qb.size () > 64000 &&
1844 !job->isSuspended () && !job->suspend ())
1845 kError () << "suspend not supported" << endl;
1846 if (!sz)
1847 gettimeofday (&data_arrival, 0L);
1848 if (!received_data) {
1849 received_data = true;
1850 http_headers = job->queryMetaData ("HTTP-Headers");
1851 if (!http_headers.isEmpty() && !http_headers.endsWith (QChar ('\n')))
1852 http_headers += QChar ('\n');
1853 }
1854 if (sz + qb.size ())
1855 emit stateChanged ();
1856 }
1857 }
1858
redirection(KIO::Job *,const QUrl & kurl)1859 KDE_NO_EXPORT void NpStream::redirection (KIO::Job*, const QUrl& kurl) {
1860 url = kurl.url ();
1861 emit redirected (stream_id, kurl);
1862 }
1863
slotMimetype(KIO::Job *,const QString & mime)1864 void NpStream::slotMimetype (KIO::Job *, const QString &mime) {
1865 mimetype = mime.indexOf("adobe.flash") > -1 ? "application/x-shockwave-flash" : mime;
1866 }
1867
slotTotalSize(KJob *,qulonglong sz)1868 void NpStream::slotTotalSize (KJob *, qulonglong sz) {
1869 content_length = sz;
1870 }
1871
1872 KDE_NO_CDTOR_EXPORT
NpPlayer(QObject * parent,ProcessInfo * pinfo,Settings * settings)1873 NpPlayer::NpPlayer (QObject *parent, ProcessInfo *pinfo, Settings *settings)
1874 : Process (parent, pinfo, settings),
1875 write_in_progress (false),
1876 in_process_stream (false) {
1877 }
1878
~NpPlayer()1879 KDE_NO_CDTOR_EXPORT NpPlayer::~NpPlayer () {
1880 }
1881
init()1882 KDE_NO_EXPORT void NpPlayer::init () {
1883 }
1884
initProcess()1885 KDE_NO_EXPORT void NpPlayer::initProcess () {
1886 setupProcess (&m_process);
1887 m_process_state = QProcess::NotRunning;
1888 connect (m_process, SIGNAL (finished (int, QProcess::ExitStatus)),
1889 this, SLOT (processStopped (int, QProcess::ExitStatus)));
1890 connect (m_process, SIGNAL (readyReadStandardError ()),
1891 this, SLOT (processOutput ()));
1892 connect (m_process, SIGNAL (bytesWritten (qint64)),
1893 this, SLOT (wroteStdin (qint64)));
1894 if (iface.isEmpty ()) {
1895 iface = QString ("org.kde.kmplayer.callback");
1896 static int count = 0;
1897 path = QString ("/npplayer%1").arg (count++);
1898 (void) new CallbackAdaptor (this);
1899 QDBusConnection::sessionBus().registerObject (path, this);
1900 filter = QString ("type='method_call',interface='org.kde.kmplayer.callback'");
1901 service = QDBusConnection::sessionBus().baseService ();
1902 //service = QString (dbus_bus_get_unique_name (conn));
1903 kDebug() << "using service " << service << " interface " << iface << " filter:" << filter;
1904 }
1905 }
1906
deMediafiedPlay()1907 KDE_NO_EXPORT bool NpPlayer::deMediafiedPlay () {
1908 kDebug() << "NpPlayer::play '" << m_url << "' state " << m_state;
1909 // if we change from XPLAIN to XEMBED, the DestroyNotify may come later
1910 if (!view ())
1911 return false;
1912 if (!m_url.isEmpty () && m_url != "about:empty") {
1913 QDBusMessage msg = QDBusMessage::createMethodCall (
1914 remote_service, "/plugin", "org.kde.kmplayer.backend", "play");
1915 msg << m_url;
1916 msg.setDelayedReply (false);
1917 QDBusConnection::sessionBus().send (msg);
1918 setState (IProcess::Buffering);
1919 }
1920 return true;
1921 }
1922
ready()1923 KDE_NO_EXPORT bool NpPlayer::ready () {
1924 Mrl *node = mrl ();
1925 if (!node || !user || !user->viewer ())
1926 return false;
1927
1928 user->viewer ()->useIndirectWidget (false);
1929 user->viewer ()->setMonitoring (IViewer::MonitorNothing);
1930
1931 if (state () == IProcess::Ready)
1932 return true;
1933
1934 initProcess ();
1935 QString exe ("knpplayer");
1936 QStringList args;
1937 args << "-cb" << (service + path);
1938 args << "-wid" << QString::number (user->viewer ()->windowHandle ());
1939 startProcess (exe, args);
1940 if (m_process->waitForStarted (5000)) {
1941 QString s;
1942 for (int i = 0; i < 2 && remote_service.isEmpty (); ++i) {
1943 if (!m_process->waitForReadyRead (5000))
1944 return false;
1945 const QByteArray ba = m_process->readAllStandardOutput ();
1946 s += QString::fromAscii (ba.data (), ba.size ());
1947 int nl = s.indexOf (QChar ('\n'));
1948 if (nl > 0) {
1949 int p = s.indexOf ("NPP_DBUS_SRV=");
1950 if (p > -1)
1951 remote_service = s.mid (p + 13, nl - p - 13);
1952 }
1953 }
1954 }
1955 connect (m_process, SIGNAL (readyReadStandardOutput ()),
1956 this, SLOT (processOutput ()));
1957 if (!remote_service.isEmpty ()) {
1958 QString mime = "text/plain";
1959 QString plugin;
1960 Element *elm = node;
1961 if (elm->id == id_node_html_object) {
1962 // this sucks to have to do this here ..
1963 for (Node *n = elm->firstChild (); n; n = n->nextSibling ())
1964 if (n->id == KMPlayer::id_node_html_embed) {
1965 elm = static_cast <Element *> (n);
1966 break;
1967 }
1968 }
1969 for (Node *n = mrl (); n; n = n->parentNode ()) {
1970 Mrl *mrl = n->mrl ();
1971 if (mrl && !mrl->mimetype.isEmpty ()) {
1972 plugin = m_source->plugin (mrl->mimetype);
1973 kDebug() << "search plugin " << mrl->mimetype << "->" << plugin;
1974 if (!plugin.isEmpty ()) {
1975 mime = mrl->mimetype;
1976 if ( mime.indexOf("adobe.flash") > -1 )
1977 mime = "application/x-shockwave-flash";
1978 break;
1979 }
1980 }
1981 }
1982 if (!plugin.isEmpty ()) {
1983 QDBusMessage msg = QDBusMessage::createMethodCall (
1984 remote_service, "/plugin", "org.kde.kmplayer.backend", "setup");
1985 msg << mime << plugin;
1986 QMap <QString, QVariant> urlargs;
1987 for (AttributePtr a = elm->attributes ().first (); a; a = a->nextSibling ())
1988 urlargs.insert (a->name ().toString (), a->value ());
1989 msg << urlargs;
1990 msg.setDelayedReply (false);
1991 QDBusConnection::sessionBus().call (msg, QDBus::BlockWithGui);
1992 setState (IProcess::Ready);
1993 return true;
1994 }
1995 }
1996 m_old_state = m_state = Ready;
1997 stop ();
1998
1999 return false;
2000 }
2001
running(const QString & srv)2002 KDE_NO_EXPORT void NpPlayer::running (const QString &srv) {
2003 remote_service = srv;
2004 kDebug () << "NpPlayer::running " << srv;
2005 setState (Ready);
2006 }
2007
plugged()2008 void NpPlayer::plugged () {
2009 view ()->videoStart ();
2010 }
2011
getStreamId(const QString & path)2012 static int getStreamId (const QString &path) {
2013 int p = path.lastIndexOf (QChar ('_'));
2014 if (p < 0) {
2015 kError() << "wrong object path " << path << endl;
2016 return -1;
2017 }
2018 bool ok;
2019 qint32 sid = path.mid (p+1).toInt (&ok);
2020 if (!ok) {
2021 kError() << "wrong object path suffix " << path.mid (p+1) << endl;
2022 return -1;
2023 }
2024 return sid;
2025 }
2026
request_stream(const QString & path,const QString & url,const QString & target,const QByteArray & post)2027 KDE_NO_EXPORT void NpPlayer::request_stream (const QString &path, const QString &url, const QString &target, const QByteArray &post) {
2028 QString uri (url);
2029 kDebug () << "NpPlayer::request " << path << " '" << url << "' " << " tg:" << target << "post" << post.size ();
2030 bool js = url.startsWith ("javascript:");
2031 if (!js) {
2032 QString base = process_info->manager->player ()->docBase ().url ();
2033 uri = KUrl (base.isEmpty () ? m_url : base, url).url ();
2034 }
2035 kDebug () << "NpPlayer::request " << path << " '" << uri << "'" << m_url << "->" << url;
2036 qint32 sid = getStreamId (path);
2037 if ((int)sid >= 0) {
2038 if (!target.isEmpty ()) {
2039 kDebug () << "new page request " << target;
2040 if (js) {
2041 QString result = evaluate (url.mid (11), false);
2042 kDebug() << "result is " << result;
2043 if (result == "undefined")
2044 uri = QString ();
2045 else
2046 uri = KUrl (m_url, result).url (); // probably wrong ..
2047 }
2048 KUrl kurl(uri);
2049 if (kurl.isValid ())
2050 process_info->manager->player ()->openUrl (kurl, target, QString ());
2051 sendFinish (sid, 0, NpStream::BecauseDone);
2052 } else {
2053 NpStream * ns = new NpStream (this, sid, uri, post);
2054 connect (ns, SIGNAL (stateChanged ()), this, SLOT (streamStateChanged ()));
2055 streams[sid] = ns;
2056 if (url != uri)
2057 streamRedirected (sid, uri);
2058 if (!write_in_progress)
2059 processStreams ();
2060 }
2061 }
2062 }
2063
evaluate(const QString & script,bool store)2064 KDE_NO_EXPORT QString NpPlayer::evaluate (const QString &script, bool store) {
2065 QString result ("undefined");
2066 emit evaluate (script, store, result);
2067 //kDebug () << "evaluate " << script << " => " << result;
2068 return result;
2069 }
2070
dimension(int w,int h)2071 KDE_NO_EXPORT void NpPlayer::dimension (int w, int h) {
2072 source ()->setAspect (mrl (), 1.0 * w/ h);
2073 }
2074
destroyStream(uint32_t sid)2075 KDE_NO_EXPORT void NpPlayer::destroyStream (uint32_t sid) {
2076 if (streams.contains (sid)) {
2077 NpStream *ns = streams[sid];
2078 ns->close ();
2079 if (!write_in_progress)
2080 processStreams ();
2081 } else {
2082 kWarning () << "Object " << sid << " not found";
2083 }
2084 if (!sid)
2085 emit loaded ();
2086 }
2087
2088 KDE_NO_EXPORT
sendFinish(quint32 sid,quint32 bytes,NpStream::Reason because)2089 void NpPlayer::sendFinish (quint32 sid, quint32 bytes, NpStream::Reason because) {
2090 kDebug() << "NpPlayer::sendFinish " << sid << " bytes:" << bytes;
2091 if (running ()) {
2092 uint32_t reason = (int) because;
2093 QString objpath = QString ("/stream_%1").arg (sid);
2094 QDBusMessage msg = QDBusMessage::createMethodCall (
2095 remote_service, objpath, "org.kde.kmplayer.backend", "eof");
2096 msg << bytes << reason;
2097 msg.setDelayedReply (false);
2098 QDBusConnection::sessionBus().send (msg);
2099 }
2100 if (!sid)
2101 emit loaded ();
2102 }
2103
terminateJobs()2104 KDE_NO_EXPORT void NpPlayer::terminateJobs () {
2105 Process::terminateJobs ();
2106 const StreamMap::iterator e = streams.end ();
2107 for (StreamMap::iterator i = streams.begin (); i != e; ++i)
2108 delete i.value ();
2109 streams.clear ();
2110 }
2111
stop()2112 KDE_NO_EXPORT void NpPlayer::stop () {
2113 terminateJobs ();
2114 if (!running ())
2115 return;
2116 kDebug () << "NpPlayer::stop ";
2117 QDBusMessage msg = QDBusMessage::createMethodCall (
2118 remote_service, "/plugin", "org.kde.kmplayer.backend", "quit");
2119 msg.setDelayedReply (false);
2120 QDBusConnection::sessionBus().send (msg);
2121 }
2122
quit()2123 KDE_NO_EXPORT void NpPlayer::quit () {
2124 if (running () && !m_process->waitForFinished (2000))
2125 Process::quit ();
2126 }
2127
processOutput()2128 KDE_NO_EXPORT void NpPlayer::processOutput () {
2129 if (!remote_service.isEmpty ())
2130 outputToView (view (), m_process->readAllStandardOutput ());
2131 outputToView (view (), m_process->readAllStandardError ());
2132 }
2133
processStopped(int,QProcess::ExitStatus)2134 KDE_NO_EXPORT void NpPlayer::processStopped (int, QProcess::ExitStatus) {
2135 terminateJobs ();
2136 if (m_source)
2137 m_source->document ()->message (MsgInfoString, NULL);
2138 setState (IProcess::NotRunning);
2139 }
2140
streamStateChanged()2141 KDE_NO_EXPORT void NpPlayer::streamStateChanged () {
2142 setState (IProcess::Playing); // hmm, this doesn't really fit in current states
2143 if (!write_in_progress)
2144 processStreams ();
2145 }
2146
streamRedirected(uint32_t sid,const QUrl & u)2147 KDE_NO_EXPORT void NpPlayer::streamRedirected(uint32_t sid, const QUrl& u) {
2148 if (running ()) {
2149 kDebug() << "redirected " << sid << " to " << u.url();
2150 QString objpath = QString ("/stream_%1").arg (sid);
2151 QDBusMessage msg = QDBusMessage::createMethodCall (
2152 remote_service, objpath, "org.kde.kmplayer.backend", "redirected");
2153 msg << u.url ();
2154 msg.setDelayedReply (false);
2155 QDBusConnection::sessionBus().send (msg);
2156 }
2157 }
2158
2159 KDE_NO_EXPORT
requestGet(const uint32_t id,const QString & prop,QString * res)2160 void NpPlayer::requestGet (const uint32_t id, const QString &prop, QString *res) {
2161 if (!remote_service.isEmpty ()) {
2162 QDBusMessage msg = QDBusMessage::createMethodCall (
2163 remote_service, "/plugin", "org.kde.kmplayer.backend", "get");
2164 msg << id << prop;
2165 QDBusMessage rmsg = QDBusConnection::sessionBus().call (msg, QDBus::BlockWithGui);
2166 if (rmsg.type () == QDBusMessage::ReplyMessage) {
2167 //kDebug() << "get " << prop << rmsg.arguments ().size ();
2168 if (rmsg.arguments ().size ()) {
2169 QString s = rmsg.arguments ().first ().toString ();
2170 if (s != "error")
2171 *res = s;
2172 }
2173 } else {
2174 kError() << "get" << prop << rmsg.type () << rmsg.errorMessage ();
2175 }
2176 }
2177 }
2178
requestCall(const uint32_t id,const QString & func,const QStringList & args,QString * res)2179 KDE_NO_EXPORT void NpPlayer::requestCall (const uint32_t id, const QString &func,
2180 const QStringList &args, QString *res) {
2181 QDBusMessage msg = QDBusMessage::createMethodCall (
2182 remote_service, "/plugin", "org.kde.kmplayer.backend", "call");
2183 msg << id << func << args;
2184 QDBusMessage rmsg = QDBusConnection::sessionBus().call (msg, QDBus::BlockWithGui);
2185 //kDebug() << "call " << func << rmsg.arguments ().size ();
2186 if (rmsg.arguments ().size ()) {
2187 QString s = rmsg.arguments ().first ().toString ();
2188 if (s != "error")
2189 *res = s;
2190 }
2191 }
2192
processStreams()2193 KDE_NO_EXPORT void NpPlayer::processStreams () {
2194 NpStream *stream = 0L;
2195 qint32 stream_id;
2196 timeval tv = { 0x7fffffff, 0 };
2197 const StreamMap::iterator e = streams.end ();
2198 int active_count = 0;
2199
2200 if (in_process_stream || write_in_progress) {
2201 kDebug() << "wrong call" << kBacktrace();
2202 return;
2203 }
2204 in_process_stream = true;
2205
2206 //kDebug() << "NpPlayer::processStreams " << streams.size ();
2207 for (StreamMap::iterator i = streams.begin (); i != e;) {
2208 NpStream *ns = i.value ();
2209 if (ns->job) {
2210 active_count++;
2211 } else if (active_count < 5 &&
2212 ns->finish_reason == NpStream::NoReason) {
2213 write_in_progress = true; // javascript: urls emit stateChange
2214 ns->open ();
2215 write_in_progress = false;
2216 if (ns->job) {
2217 connect(ns, SIGNAL(redirected(uint32_t, const QUrl&)),
2218 this, SLOT(streamRedirected(uint32_t, const QUrl&)));
2219 active_count++;
2220 }
2221 }
2222 if (ns->finish_reason == NpStream::BecauseStopped ||
2223 ns->finish_reason == NpStream::BecauseError ||
2224 (ns->finish_reason == NpStream::BecauseDone &&
2225 ns->pending_buf.size () == 0)) {
2226 sendFinish (i.key(), ns->bytes, ns->finish_reason);
2227 i = streams.erase (i);
2228 delete ns;
2229 } else {
2230 if (ns->pending_buf.size () > 0 &&
2231 (ns->data_arrival.tv_sec < tv.tv_sec ||
2232 (ns->data_arrival.tv_sec == tv.tv_sec &&
2233 ns->data_arrival.tv_usec < tv.tv_usec))) {
2234 tv = ns->data_arrival;
2235 stream = ns;
2236 stream_id = i.key();
2237 }
2238 ++i;
2239 }
2240 }
2241 //kDebug() << "NpPlayer::processStreams " << stream;
2242 if (stream) {
2243 if (stream->finish_reason != NpStream::BecauseStopped &&
2244 stream->finish_reason != NpStream::BecauseError &&
2245 !stream->bytes &&
2246 (!stream->mimetype.isEmpty() || stream->content_length)) {
2247 QString objpath = QString ("/stream_%1").arg (stream->stream_id);
2248 QDBusMessage msg = QDBusMessage::createMethodCall (
2249 remote_service, objpath, "org.kde.kmplayer.backend", "streamInfo");
2250 msg << stream->mimetype
2251 << stream->content_length
2252 << stream->http_headers;
2253 msg.setDelayedReply (false);
2254 QDBusConnection::sessionBus().send (msg);
2255 }
2256 const int header_len = 2 * sizeof (qint32);
2257 qint32 chunk = stream->pending_buf.size ();
2258 send_buf.resize (chunk + header_len);
2259 memcpy (send_buf.data (), &stream_id, sizeof (qint32));
2260 memcpy (send_buf.data() + sizeof (qint32), &chunk, sizeof (qint32));
2261 memcpy (send_buf.data ()+header_len,
2262 stream->pending_buf.constData (), chunk);
2263 stream->pending_buf = QByteArray ();
2264 /*fprintf (stderr, " => %d %d\n", (long)stream_id, chunk);*/
2265 stream->bytes += chunk;
2266 write_in_progress = true;
2267 m_process->write (send_buf);
2268 if (stream->finish_reason == NpStream::NoReason)
2269 stream->job->resume ();
2270 }
2271 in_process_stream = false;
2272 }
2273
wroteStdin(qint64)2274 KDE_NO_EXPORT void NpPlayer::wroteStdin (qint64) {
2275 if (!m_process->bytesToWrite ()) {
2276 write_in_progress = false;
2277 if (running ())
2278 processStreams ();
2279 }
2280 }
2281
cookie(const QString & url)2282 QString NpPlayer::cookie (const QString &url)
2283 {
2284 QString s;
2285 View *v = view ();
2286 if (v) {
2287 KIO::Integration::CookieJar jar (v);
2288 jar.setWindowId (v->topLevelWidget()->winId ());
2289 QList<QNetworkCookie> c = jar.cookiesForUrl (url);
2290 QList<QNetworkCookie>::const_iterator e = c.end ();
2291 for (QList<QNetworkCookie>::const_iterator i = c.begin (); i != e; ++i)
2292 s += (s.isEmpty() ? "" : ";") + QString::fromUtf8 ((*i).toRawForm());
2293 }
2294 return s;
2295 }
2296
2297 #else
2298
NpStream(NpPlayer * p,uint32_t sid,const QString & u,const QByteArray &)2299 KDE_NO_CDTOR_EXPORT NpStream::NpStream (NpPlayer *p, uint32_t sid, const QString &u, const QByteArray &/*ps*/)
2300 : QObject (p) {}
2301
~NpStream()2302 KDE_NO_CDTOR_EXPORT NpStream::~NpStream () {}
slotResult(KJob *)2303 void NpStream::slotResult (KJob*) {}
slotData(KIO::Job *,const QByteArray &)2304 void NpStream::slotData (KIO::Job*, const QByteArray&) {}
redirection(KIO::Job *,const QUrl &)2305 void NpStream::redirection(KIO::Job*, const QUrl&) {}
slotMimetype(KIO::Job *,const QString &)2306 void NpStream::slotMimetype (KIO::Job *, const QString &) {}
slotTotalSize(KJob *,KIO::filesize_t)2307 void NpStream::slotTotalSize (KJob *, KIO::filesize_t) {}
2308
2309 KDE_NO_CDTOR_EXPORT
NpPlayer(QObject * parent,ProcessInfo * pinfo,Settings * settings)2310 NpPlayer::NpPlayer (QObject *parent, ProcessInfo *pinfo, Settings *settings)
2311 : Process (parent, pinfo, settings) {}
~NpPlayer()2312 KDE_NO_CDTOR_EXPORT NpPlayer::~NpPlayer () {}
init()2313 KDE_NO_EXPORT void NpPlayer::init () {}
deMediafiedPlay()2314 KDE_NO_EXPORT bool NpPlayer::deMediafiedPlay () { return false; }
initProcess()2315 KDE_NO_EXPORT void NpPlayer::initProcess () {}
stop()2316 KDE_NO_EXPORT void NpPlayer::stop () {}
quit()2317 KDE_NO_EXPORT void NpPlayer::quit () { }
ready()2318 KDE_NO_EXPORT bool NpPlayer::ready () { return false; }
requestGet(const uint32_t,const QString &,QString *)2319 KDE_NO_EXPORT void NpPlayer::requestGet (const uint32_t, const QString &, QString *) {}
requestCall(const uint32_t,const QString &,const QStringList &,QString *)2320 KDE_NO_EXPORT void NpPlayer::requestCall (const uint32_t, const QString &, const QStringList &, QString *) {}
processOutput()2321 KDE_NO_EXPORT void NpPlayer::processOutput () {}
processStopped(int,QProcess::ExitStatus)2322 KDE_NO_EXPORT void NpPlayer::processStopped (int, QProcess::ExitStatus) {}
wroteStdin(qint64)2323 KDE_NO_EXPORT void NpPlayer::wroteStdin (qint64) {}
streamStateChanged()2324 KDE_NO_EXPORT void NpPlayer::streamStateChanged () {}
streamRedirected(uint32_t,const QUrl &)2325 KDE_NO_EXPORT void NpPlayer::streamRedirected(uint32_t, const QUrl&) {}
terminateJobs()2326 KDE_NO_EXPORT void NpPlayer::terminateJobs () {}
2327
2328 #endif
2329
2330 #include "kmplayerprocess.moc"
2331