File indexing completed on 2024-04-14 04:49:05

0001 /*
0002     SPDX-FileCopyrightText: 2003 Koos Vriezen <koos.vriezen@xs4all.nl>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef _KMPLAYERPROCESS_H_
0008 #define _KMPLAYERPROCESS_H_
0009 
0010 #include <QObject>
0011 #include <QString>
0012 #include <QList>
0013 #include <QByteArray>
0014 #include <QStringList>
0015 #include <QRegExp>
0016 #include <QProcess>
0017 
0018 #include <KIO/Global>
0019 
0020 #include "kmplayerplaylist.h"
0021 #include "kmplayerpartbase.h"
0022 #include "mediaobject.h"
0023 #include "kmplayercommon_export.h"
0024 
0025 class QWidget;
0026 class KJob;
0027 
0028 namespace KIO {
0029     class Job;
0030     class TransferJob;
0031 }
0032 
0033 namespace KMPlayer {
0034 
0035 class Settings;
0036 class View;
0037 class MediaManager;
0038 class Source;
0039 class Callback;
0040 class Backend_stub;
0041 class NpPlayer;
0042 class MPlayerPreferencesPage;
0043 class MPlayerPreferencesFrame;
0044 class XMLPreferencesPage;
0045 class XMLPreferencesFrame;
0046 
0047 
0048 /*
0049  * Base class for all backend processes
0050  */
0051 class KMPLAYERCOMMON_EXPORT Process : public QObject, public IProcess
0052 {
0053     Q_OBJECT
0054 public:
0055     Process (QObject *parent, ProcessInfo *, Settings *settings);
0056     ~Process () override;
0057 
0058     virtual void init ();
0059     virtual void initProcess ();
0060     void setAudioLang (int id) override;
0061     void setSubtitle (int id) override;
0062     bool running () const override;
0063     KMPLAYERCOMMON_NO_EXPORT QProcess * process () const { return m_process; }
0064     KMPLAYERCOMMON_NO_EXPORT Source * source () const { return m_source; }
0065     View *view () const;
0066     WId widget ();
0067     void setSource (Source * src) { m_source = src; }
0068     void setState (IProcess::State newstate);
0069     bool grabPicture (const QString &file, int frame) override KMPLAYERCOMMON_NO_EXPORT;
0070     Mrl *mrl () const;
0071 
0072     bool ready () override;
0073     bool play () override;
0074     void stop () override;
0075     void quit () override;
0076     void pause () override;
0077     void unpause () override;
0078     /* seek (pos, abs) seek position in deci-seconds */
0079     bool seek (int pos, bool absolute) override;
0080     /* volume from 0 to 100 */
0081     void volume (int pos, bool absolute) override;
0082     /* saturation/hue/contrast/brightness from -100 to 100 */
0083     bool saturation (int pos, bool absolute) override;
0084     bool hue (int pos, bool absolute) override;
0085     bool contrast (int pos, bool absolute) override;
0086     bool brightness (int pos, bool absolute) override;
0087 Q_SIGNALS:
0088     void grabReady (const QString & path);
0089 protected Q_SLOTS:
0090     void rescheduledStateChanged () KMPLAYERCOMMON_NO_EXPORT;
0091     void result (KJob *);
0092     void processStateChanged (QProcess::ProcessState);
0093 protected:
0094     virtual bool deMediafiedPlay ();
0095     virtual void terminateJobs ();
0096     void startProcess (const QString &program, const QStringList &args);
0097 
0098     Source * m_source;
0099     Settings * m_settings;
0100     State m_old_state;
0101     QProcess * m_process;
0102     KIO::Job * m_job;
0103     QString m_url;
0104     int m_request_seek;
0105     QProcess::ProcessState m_process_state;
0106 };
0107 
0108 
0109 /*
0110  * Base class for all MPlayer based processes
0111  */
0112 class MPlayerBase : public Process {
0113     Q_OBJECT
0114 public:
0115     MPlayerBase (QObject *parent, ProcessInfo *, Settings *);
0116     ~MPlayerBase () override;
0117     void initProcess () override;
0118     void stop () override;
0119     void quit () override;
0120 protected:
0121     bool sendCommand (const QString &);
0122     bool removeQueued (const char *cmd);
0123     QList<QByteArray> commands;
0124     bool m_needs_restarted;
0125 protected Q_SLOTS:
0126     virtual void processStopped ();
0127 private Q_SLOTS:
0128     void dataWritten (qint64);
0129     void processStopped (int, QProcess::ExitStatus);
0130 };
0131 
0132 /*
0133  * MPlayer process
0134  */
0135 class MPlayerProcessInfo : public ProcessInfo
0136 {
0137 public:
0138     MPlayerProcessInfo (MediaManager *);
0139     IProcess *create (PartBase*, ProcessUser*) override;
0140 };
0141 
0142 class KMPLAYERCOMMON_EXPORT MPlayer : public MPlayerBase
0143 {
0144     Q_OBJECT
0145 public:
0146     MPlayer (QObject *parent, ProcessInfo *pinfo, Settings *settings);
0147     ~MPlayer () override;
0148 
0149     void init () override KMPLAYERCOMMON_NO_EXPORT;
0150     bool grabPicture (const QString &file, int pos) override KMPLAYERCOMMON_NO_EXPORT;
0151     void setAudioLang (int id) override;
0152     void setSubtitle (int id) override;
0153     bool deMediafiedPlay () override KMPLAYERCOMMON_NO_EXPORT;
0154     void stop () override KMPLAYERCOMMON_NO_EXPORT;
0155     void pause () override KMPLAYERCOMMON_NO_EXPORT;
0156     void unpause () override KMPLAYERCOMMON_NO_EXPORT;
0157     bool seek (int pos, bool absolute) override KMPLAYERCOMMON_NO_EXPORT;
0158     void volume (int pos, bool absolute) override KMPLAYERCOMMON_NO_EXPORT;
0159     bool saturation (int pos, bool absolute) override KMPLAYERCOMMON_NO_EXPORT;
0160     bool hue (int pos, bool absolute) override KMPLAYERCOMMON_NO_EXPORT;
0161     bool contrast (int pos, bool absolute) override KMPLAYERCOMMON_NO_EXPORT;
0162     bool brightness (int pos, bool absolute) override KMPLAYERCOMMON_NO_EXPORT;
0163     bool ready () override KMPLAYERCOMMON_NO_EXPORT;
0164 protected:
0165     void processStopped () override KMPLAYERCOMMON_NO_EXPORT;
0166 private Q_SLOTS:
0167     void processOutput () KMPLAYERCOMMON_NO_EXPORT;
0168 private:
0169     QString m_process_output;
0170     QString m_grab_file;
0171     QString m_grab_dir;
0172     QWidget * m_widget;
0173     QString m_tmpURL;
0174     Source::LangInfoPtr alanglist;
0175     WeakPtr <Source::LangInfo> alanglist_end;
0176     Source::LangInfoPtr slanglist;
0177     WeakPtr <Source::LangInfo> slanglist_end;
0178     State m_transition_state;
0179     int aid, sid;
0180     int old_volume;
0181 };
0182 
0183 #ifdef _KMPLAYERCONFIG_H_
0184 /*
0185  * MPlayer preferences page
0186  */
0187 class MPlayerPreferencesPage : public PreferencesPage
0188 {
0189 public:
0190     enum Pattern {
0191         pat_size = 0, pat_cache, pat_pos, pat_index,
0192         pat_refurl, pat_ref, pat_start,
0193         pat_vcdtrack, pat_cdromtracks,
0194         pat_last
0195     };
0196     MPlayerPreferencesPage ();
0197     ~MPlayerPreferencesPage () override {}
0198     void write (KSharedConfigPtr) override;
0199     void read (KSharedConfigPtr) override;
0200     void sync (bool fromUI) override;
0201     void prefLocation (QString & item, QString & icon, QString & tab) override;
0202     QFrame * prefPage (QWidget * parent) override;
0203     QRegExp m_patterns[pat_last];
0204     int cachesize;
0205     QString mplayer_path;
0206     QString additionalarguments;
0207     bool alwaysbuildindex;
0208 private:
0209     MPlayer * m_process;
0210     MPlayerPreferencesFrame *m_configframe;
0211 };
0212 
0213 #endif
0214 /*
0215  * Base class for all recorders
0216  */
0217 class RecordDocument : public SourceDocument
0218 {
0219 public:
0220     RecordDocument (const QString &url, const QString &rurl, const QString &rec,
0221                     Source *source);
0222 
0223     void begin () override;
0224     void message (MessageType msg, void *) override;
0225     void deactivate () override;
0226 
0227     QString record_file;
0228     QString recorder;
0229 };
0230 
0231 /*
0232  * MEncoder recorder
0233  */
0234 class MEncoderProcessInfo : public ProcessInfo
0235 {
0236 public:
0237     MEncoderProcessInfo (MediaManager *);
0238     IProcess *create (PartBase*, ProcessUser*) override;
0239 };
0240 
0241 class MEncoder : public MPlayerBase {
0242     Q_OBJECT
0243 public:
0244     MEncoder (QObject *parent, ProcessInfo *pinfo, Settings *settings);
0245     ~MEncoder () override;
0246     void init () override;
0247     bool deMediafiedPlay () override;
0248     void stop () override;
0249 };
0250 
0251 /*
0252  * MPlayer recorder, runs 'mplayer -dumpstream'
0253  */
0254 class MPlayerDumpProcessInfo : public ProcessInfo
0255 {
0256 public:
0257     MPlayerDumpProcessInfo (MediaManager *);
0258     IProcess *create (PartBase*, ProcessUser*) override;
0259 };
0260 
0261 class MPlayerDumpstream : public MPlayerBase
0262 {
0263     Q_OBJECT
0264 public:
0265     MPlayerDumpstream (QObject *parent, ProcessInfo *pinfo, Settings *settings);
0266     ~MPlayerDumpstream () override;
0267     void init () override;
0268     bool deMediafiedPlay () override;
0269     void stop () override;
0270 };
0271 
0272 class MasterProcessInfo : public QObject, public ProcessInfo
0273 {
0274     Q_OBJECT
0275 public:
0276     MasterProcessInfo (const char *nm, const QString &lbl,
0277             const char **supported,MediaManager *, PreferencesPage *);
0278     ~MasterProcessInfo () override;
0279 
0280     void quitProcesses () override;
0281 
0282     void running (const QString &srv);
0283 
0284     QString m_service;
0285     QString m_path;
0286     QString m_agent_service;
0287     QProcess *m_agent;
0288 
0289 private Q_SLOTS:
0290     void agentStopped (int, QProcess::ExitStatus);
0291     void agentOutput ();
0292 
0293 protected:
0294     virtual void initAgent ();
0295     virtual bool startAgent () = 0;
0296     virtual void stopAgent ();
0297 };
0298 
0299 class MasterProcess : public Process
0300 {
0301     Q_OBJECT
0302 public:
0303     MasterProcess (QObject *p, ProcessInfo *pi, Settings *s);
0304     ~MasterProcess () override;
0305 
0306     void init () override;
0307     bool deMediafiedPlay () override;
0308     bool running () const override;
0309 
0310     void streamInfo (uint64_t length, double aspect);
0311     void streamMetaInfo (QString info);
0312     void loading (int p);
0313     void playing ();
0314     void progress (uint64_t pos);
0315     void pause () override;
0316     void unpause () override;
0317     bool seek (int pos, bool absolute) override;
0318     void volume (int pos, bool absolute) override;
0319     void eof ();
0320     void stop () override;
0321 
0322 private:
0323     QString m_agent_path;
0324 };
0325 
0326 class PhononProcessInfo : public MasterProcessInfo
0327 {
0328 public:
0329     PhononProcessInfo (MediaManager *);
0330 
0331     IProcess *create (PartBase*, ProcessUser*) override;
0332 
0333     bool startAgent () override;
0334 };
0335 
0336 class Phonon : public MasterProcess
0337 {
0338     Q_OBJECT
0339 public:
0340     Phonon (QObject *parent, ProcessInfo*, Settings *settings);
0341 
0342     bool ready () override;
0343 };
0344 
0345 /*
0346  * Config document as used by kxineplayer backend
0347  */
0348 struct ConfigDocument : public Document
0349 {
0350     ConfigDocument ();
0351     ~ConfigDocument () override;
0352     Node *childFromTag (const QString & tag) override;
0353 };
0354 
0355 /*
0356  * Element for ConfigDocument
0357  */
0358 struct ConfigNode : public DarkNode
0359 {
0360     ConfigNode (NodePtr & d, const QString & tag);
0361     ~ConfigNode () override {}
0362     Node *childFromTag (const QString & tag) override;
0363     QWidget * w;
0364 };
0365 
0366 /*
0367  * Element for ConfigDocument, defining type of config item
0368  */
0369 struct TypeNode : public ConfigNode
0370 {
0371     TypeNode (NodePtr & d, const QString & t);
0372     ~TypeNode () override {}
0373     Node *childFromTag (const QString & tag) override;
0374     void changedXML (QTextStream & out);
0375     QWidget * createWidget (QWidget * parent);
0376     const char * nodeName () const override { return tag.toLatin1().constData(); }
0377     QString tag;
0378 };
0379 
0380 /*
0381  * ffmpeg backend recorder
0382  */
0383 class FFMpegProcessInfo : public ProcessInfo
0384 {
0385 public:
0386     FFMpegProcessInfo (MediaManager *);
0387     IProcess *create (PartBase*, ProcessUser*) override;
0388 };
0389 
0390 class KMPLAYERCOMMON_EXPORT FFMpeg : public Process
0391 {
0392     Q_OBJECT
0393 public:
0394     FFMpeg (QObject *parent, ProcessInfo *pinfo, Settings *settings);
0395     ~FFMpeg () override;
0396     void init () override KMPLAYERCOMMON_NO_EXPORT;
0397     bool deMediafiedPlay () override;
0398     void stop () override KMPLAYERCOMMON_NO_EXPORT;
0399     void quit () override KMPLAYERCOMMON_NO_EXPORT;
0400 private Q_SLOTS:
0401     void processStopped (int, QProcess::ExitStatus) KMPLAYERCOMMON_NO_EXPORT;
0402 };
0403 
0404 /*
0405  * npplayer backend
0406  */
0407 
0408 class NpStream : public QObject
0409 {
0410     Q_OBJECT
0411 public:
0412     enum Reason {
0413         NoReason = -1,
0414         BecauseDone = 0, BecauseError = 1, BecauseStopped = 2
0415     };
0416 
0417     NpStream (NpPlayer *parent, uint32_t stream_id, const QString &url, const QByteArray &post);
0418     ~NpStream () override;
0419 
0420     void open ();
0421     void close ();
0422 
0423     void destroy ();
0424 
0425     QString url;
0426     QByteArray post;
0427     QByteArray pending_buf;
0428     KIO::TransferJob *job;
0429     timeval data_arrival;
0430     uint32_t bytes;
0431     uint32_t stream_id;
0432     uint32_t content_length;
0433     Reason finish_reason;
0434     QString mimetype;
0435     QString http_headers;
0436     bool received_data;
0437 Q_SIGNALS:
0438     void stateChanged ();
0439     void redirected(uint32_t, const QUrl&);
0440 private Q_SLOTS:
0441     void slotResult (KJob*);
0442     void slotData (KIO::Job*, const QByteArray& qb);
0443     void redirection(KIO::Job*, const QUrl& url);
0444     void slotMimetype (KIO::Job *, const QString &mime);
0445     void slotTotalSize (KJob *, qulonglong sz);
0446 };
0447 
0448 class NppProcessInfo : public ProcessInfo
0449 {
0450 public:
0451     NppProcessInfo (MediaManager *);
0452     IProcess *create (PartBase*, ProcessUser*) override;
0453 };
0454 
0455 class KMPLAYERCOMMON_EXPORT NpPlayer : public Process
0456 {
0457     Q_OBJECT
0458 public:
0459     NpPlayer (QObject *, KMPlayer::ProcessInfo*, Settings *);
0460     ~NpPlayer () override;
0461 
0462     static const char *name;
0463     static const char *supports [];
0464     static IProcess *create (PartBase *, ProcessUser *);
0465 
0466     void init () override;
0467     bool deMediafiedPlay () override;
0468     void initProcess () override;
0469 
0470     using Process::running;
0471     void running (const QString &srv);
0472     void plugged ();
0473     void request_stream (const QString &path, const QString &url, const QString &target, const QByteArray &post);
0474     QString evaluate (const QString &script, bool store);
0475     QString cookie (const QString &url);
0476     void dimension (int w, int h);
0477 
0478     void destroyStream (uint32_t sid);
0479 
0480     const QString & destination () const { return service; }
0481     const QString & interface () const { return iface; }
0482     QString objectPath () const { return path; }
0483     void stop () override;
0484     void quit () override;
0485     bool ready () override;
0486 Q_SIGNALS:
0487     void evaluateRequested(const QString & scr, bool store, QString & result);
0488     void loaded ();
0489 public Q_SLOTS:
0490     void requestGet (const uint32_t, const QString &, QString *);
0491     void requestCall (const uint32_t, const QString &, const QStringList &, QString *);
0492 private Q_SLOTS:
0493     void processOutput ();
0494     void processStopped (int, QProcess::ExitStatus);
0495     void wroteStdin (qint64);
0496     void streamStateChanged ();
0497     void streamRedirected(uint32_t, const QUrl&);
0498 protected:
0499     void terminateJobs () override;
0500 private:
0501     void sendFinish (uint32_t sid, uint32_t total, NpStream::Reason because);
0502     void processStreams ();
0503     QString service;
0504     QString iface;
0505     QString path;
0506     QString filter;
0507     typedef QMap <uint32_t, NpStream *> StreamMap;
0508     StreamMap streams;
0509     QString remote_service;
0510     QString m_base_url;
0511     QByteArray send_buf;
0512     bool write_in_progress;
0513     bool in_process_stream;
0514 };
0515 
0516 } // namespace
0517 
0518 #endif //_KMPLAYERPROCESS_H_