File indexing completed on 2024-04-28 12:40:02

0001 /*
0002     This file belong to the KMPlayer project, a movie player plugin for Konqueror
0003     SPDX-FileCopyrightText: 2007 Koos Vriezen <koos.vriezen@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef _KMPLAYER__MEDIA_OBJECT_H_
0009 #define _KMPLAYER__MEDIA_OBJECT_H_
0010 
0011 #include <config-kmplayer.h>
0012 
0013 #include <QObject>
0014 #include <QPair>
0015 #include <QMap>
0016 #include <QString>
0017 #include <QMovie>
0018 #include <QList>
0019 
0020 #include "kmplayercommon_export.h"
0021 #include "kmplayerplaylist.h"
0022 
0023 class QMovie;
0024 class QImage;
0025 class QSvgRenderer;
0026 class QBuffer;
0027 class QByteArray;
0028 class KJob;
0029 namespace KIO {
0030     class Job;
0031     class TransferJob;
0032 }
0033 
0034 namespace KMPlayer {
0035 
0036 class IViewer;
0037 class PartBase;
0038 class ProcessUser;
0039 class ProcessInfo;
0040 class MediaManager;
0041 class AudioVideoMedia;
0042 class PreferencesPage;
0043 class MediaObject;
0044 class CalculatedSizer;
0045 class Surface;
0046 
0047 
0048 class KMPLAYERCOMMON_EXPORT IProcess
0049 {
0050 public:
0051     enum State { NotRunning = 0, Ready, Buffering, Playing, Paused };
0052 
0053     virtual ~IProcess () {}
0054 
0055     virtual bool ready () = 0;
0056     virtual bool play () = 0;
0057     virtual void pause () = 0;
0058     virtual void unpause () = 0;
0059     virtual bool grabPicture (const QString &file, int frame) = 0;
0060     virtual void stop () = 0;
0061     virtual void quit () = 0;
0062     /* seek (pos, abs) seek position in deci-seconds */
0063     virtual bool seek (int pos, bool absolute) = 0;
0064     /* volume from 0 to 100 */
0065     virtual void volume (int pos, bool absolute) = 0;
0066     virtual bool saturation (int pos, bool absolute) = 0;
0067     virtual bool hue (int pos, bool absolute) = 0;
0068     virtual bool contrast (int pos, bool absolute) = 0;
0069     virtual bool brightness (int pos, bool absolute) = 0;
0070     virtual void setAudioLang (int id) = 0;
0071     virtual void setSubtitle (int id) = 0;
0072     virtual bool running () const = 0;
0073 
0074     State state () const { return m_state; }
0075     ProcessUser *user;
0076     ProcessInfo *process_info;
0077 
0078 protected:
0079     IProcess (ProcessInfo *pinfo);
0080 
0081     State m_state;
0082 
0083 private:
0084     IProcess (const IViewer &);
0085 };
0086 
0087 class KMPLAYERCOMMON_EXPORT ProcessUser
0088 {
0089 public:
0090     virtual ~ProcessUser () {}
0091 
0092     virtual void starting (IProcess *) = 0;
0093     virtual void stateChange (IProcess *, IProcess::State, IProcess::State) = 0;
0094     virtual void processDestroyed (IProcess*) = 0;
0095     virtual IViewer *viewer () = 0;
0096     virtual Mrl *getMrl () = 0;
0097 };
0098 
0099 class KMPLAYERCOMMON_EXPORT ProcessInfo
0100 {
0101 public:
0102     ProcessInfo (const char *nm, const QString &lbl, const char **supported,
0103             MediaManager *, PreferencesPage *);
0104     virtual ~ProcessInfo ();
0105 
0106     bool supports (const char *source) const;
0107     virtual IProcess *create (PartBase*, ProcessUser*) = 0;
0108     virtual void quitProcesses () {};
0109 
0110     const char *name;
0111     QString label;
0112     const char **supported_sources;
0113     MediaManager *manager;
0114     PreferencesPage *config_page;
0115 };
0116 
0117 /*
0118  * Class that creates MediaObject and keeps track objects
0119  */
0120 class KMPLAYERCOMMON_EXPORT MediaManager
0121 {
0122 public:
0123     enum MediaType { Any, Audio, AudioVideo, Image, Text, Data };
0124     typedef QMap <QString, ProcessInfo *> ProcessInfoMap;
0125     typedef QList <IProcess *> ProcessList;
0126     typedef QList <MediaObject *> MediaList;
0127 
0128     MediaManager (PartBase *player);
0129     ~MediaManager ();
0130 
0131     MediaObject *createAVMedia (Node *node, const QByteArray &b);
0132 
0133     // backend process state changed
0134     void stateChange (AudioVideoMedia *m, IProcess::State o, IProcess::State n);
0135     void playAudioVideo (AudioVideoMedia *m);
0136     void grabPicture (AudioVideoMedia *m);
0137 
0138     void processDestroyed (IProcess *process);
0139     ProcessInfoMap &processInfos () { return m_process_infos; }
0140     ProcessList &processes () { return m_processes; }
0141     ProcessInfoMap &recorderInfos () { return m_record_infos; }
0142     ProcessList &recorders () { return m_recorders; }
0143     MediaList &medias () { return m_media_objects; }
0144     PartBase *player () const { return m_player; }
0145 
0146 private:
0147     MediaList m_media_objects;
0148     ProcessInfoMap m_process_infos;
0149     ProcessList m_processes;
0150     ProcessInfoMap m_record_infos;
0151     ProcessList m_recorders;
0152     PartBase *m_player;
0153 };
0154 
0155 
0156 //------------------------%<----------------------------------------------------
0157 
0158 /*
0159  * Abstract base of MediaObject types, handles downloading
0160  */
0161 
0162 class DataCache : public QObject
0163 {
0164     Q_OBJECT
0165     typedef QMap <QString, QPair <QString, QByteArray> > DataMap;
0166     typedef QMap <QString, bool> PreserveMap;
0167     DataMap cache_map;
0168     PreserveMap preserve_map;
0169 public:
0170     DataCache () {}
0171     ~DataCache () override {}
0172     void add (const QString &, const QString &, const QByteArray &);
0173     bool get (const QString &, QString &, QByteArray &);
0174     bool preserve (const QString &);
0175     bool unpreserve (const QString &);
0176     bool isPreserved (const QString &);
0177 Q_SIGNALS:
0178     void preserveRemoved (const QString &); // ready or canceled
0179 };
0180 
0181 class KMPLAYERCOMMON_EXPORT MediaObject : public QObject
0182 {
0183     Q_OBJECT
0184     friend class MediaManager;
0185 public:
0186     virtual MediaManager::MediaType type () const = 0;
0187 
0188     virtual bool play () = 0;
0189     virtual void pause () {}
0190     virtual void unpause () {}
0191     virtual void stop () {}
0192     virtual void destroy() KMPLAYERCOMMON_NO_EXPORT;
0193 
0194     Mrl *mrl ();
0195 
0196 protected:
0197     MediaObject (MediaManager *manager, Node *node);
0198     ~MediaObject () override;
0199 
0200     MediaManager *m_manager;
0201     NodePtrW m_node;
0202 };
0203 
0204 //------------------------%<----------------------------------------------------
0205 
0206 class KMPLAYERCOMMON_EXPORT MediaInfo : public QObject
0207 {
0208     Q_OBJECT
0209 public:
0210     MediaInfo (Node *node, MediaManager::MediaType type);
0211     ~MediaInfo () override;
0212 
0213     bool wget(const QString& url, const QString& from_domain=QString());
0214     void killWGet() KMPLAYERCOMMON_NO_EXPORT;
0215     void clearData() KMPLAYERCOMMON_NO_EXPORT;
0216     QString mimetype() KMPLAYERCOMMON_NO_EXPORT;
0217     bool downloading() const KMPLAYERCOMMON_NO_EXPORT;
0218     void create ();
0219 
0220     QByteArray &rawData () { return data; }
0221     MediaObject *media;
0222     QString url;
0223     QByteArray data;
0224     QString mime;
0225     MediaManager::MediaType type;
0226 
0227 private Q_SLOTS:
0228     void slotResult(KJob*) KMPLAYERCOMMON_NO_EXPORT;
0229     void slotData(KIO::Job*, const QByteArray& qb) KMPLAYERCOMMON_NO_EXPORT;
0230     void slotMimetype (KIO::Job* job, const QString& mimestr) KMPLAYERCOMMON_NO_EXPORT;
0231     void cachePreserveRemoved(const QString&) KMPLAYERCOMMON_NO_EXPORT;
0232 
0233 private:
0234     void ready() KMPLAYERCOMMON_NO_EXPORT;
0235     bool readChildDoc() KMPLAYERCOMMON_NO_EXPORT;
0236     void setMimetype(const QString&) KMPLAYERCOMMON_NO_EXPORT;
0237 
0238     Node *node;
0239     KIO::TransferJob *job;
0240     QString cross_domain;
0241     QString access_from;
0242     bool preserve_wait;
0243     bool check_access;
0244 };
0245 
0246 //------------------------%<----------------------------------------------------
0247 
0248 /*
0249  * MediaObject for audio/video, groups Mrl, Process and Viewer
0250  */
0251 
0252 typedef unsigned long WindowId;
0253 
0254 class AudioVideoMedia;
0255 
0256 class IViewer
0257 {
0258 public:
0259     enum Monitor {
0260         MonitorNothing = 0, MonitorMouse = 1, MonitorKey = 2 , MonitorAll = 3
0261     };
0262     IViewer () {}
0263     virtual ~IViewer () {}
0264 
0265     virtual WindowId windowHandle () = 0;
0266     virtual WindowId clientHandle () = 0;
0267     virtual WindowId ownHandle() = 0;
0268     virtual void setGeometry (const IRect &rect) = 0;
0269     virtual void setAspect (float a) = 0;
0270     virtual float aspect () = 0;
0271     virtual void useIndirectWidget (bool) = 0;
0272     virtual void setMonitoring (Monitor) = 0;
0273     virtual void map () = 0;
0274     virtual void unmap () = 0;
0275     virtual void embedded(WindowId handle) = 0;
0276 private:
0277     IViewer (const IViewer &);
0278 };
0279 
0280 class AudioVideoMedia : public MediaObject, ProcessUser
0281 {
0282     friend class MediaManager;
0283 public:
0284     enum Request {
0285         ask_nothing, ask_play, ask_pause, ask_grab, ask_stop, ask_delete
0286     };
0287 
0288     AudioVideoMedia (MediaManager *manager, Node *node);
0289 
0290     MediaManager::MediaType type () const override { return MediaManager::AudioVideo; }
0291 
0292     bool play () override;
0293     virtual bool grabPicture (const QString &file, int frame);
0294     void stop () override;
0295     void pause () override;
0296     void unpause () override;
0297     void destroy () override;
0298 
0299     void starting (IProcess *) override;
0300     void stateChange (IProcess *, IProcess::State, IProcess::State) override;
0301     void processDestroyed (IProcess *p) override;
0302     IViewer *viewer () override;
0303     Mrl *getMrl () override;
0304 
0305     void setViewer (IViewer *v) { m_viewer = v; }
0306 
0307     IProcess *process;
0308     IViewer *m_viewer;
0309     QString m_grab_file;
0310     int m_frame;
0311     Request request;
0312 
0313 protected:
0314     ~AudioVideoMedia () override;
0315 };
0316 
0317 
0318 //------------------------%<----------------------------------------------------
0319 
0320 /*
0321  * MediaObject for (animated)images
0322  */
0323 
0324 struct ImageData
0325 {
0326     enum ImageFlags {
0327         ImageAny=0, ImagePixmap=0x1, ImageAnimated=0x2, ImageScalable=0x4
0328     };
0329     ImageData( const QString & img);
0330     ~ImageData();
0331     void setImage (QImage *img);
0332 #ifdef KMPLAYER_WITH_CAIRO
0333     void copyImage (Surface *s, const SSize &sz, cairo_surface_t *similar, CalculatedSizer *zoom=nullptr);
0334 #endif
0335     bool isEmpty () const {
0336         return !image
0337 #ifdef KMPLAYER_WITH_CAIRO
0338             && !surface
0339 #endif
0340             ;
0341     }
0342 
0343     unsigned short width;
0344     unsigned short height;
0345     short flags;
0346     bool has_alpha;
0347 private:
0348     QImage *image;
0349 #ifdef KMPLAYER_WITH_CAIRO
0350     cairo_surface_t *surface;
0351 #endif
0352     QString url;
0353 };
0354 
0355 typedef SharedPtr <ImageData> ImageDataPtr;
0356 typedef WeakPtr <ImageData> ImageDataPtrW;
0357 
0358 class ImageMedia : public MediaObject
0359 {
0360     Q_OBJECT
0361 public:
0362     ImageMedia (MediaManager *manager, Node *node,
0363             const QString &url, const QByteArray &data);
0364     ImageMedia (Node *node, ImageDataPtr id = nullptr);
0365 
0366     MediaManager::MediaType type () const override { return MediaManager::Image; }
0367 
0368     bool play () override;
0369     void stop () override;
0370     void pause () override;
0371     void unpause () override;
0372 
0373     bool wget (const QString &url);
0374     bool isEmpty () const;
0375     void render (const ISize &size);
0376     void sizes (SSize &size);
0377     void updateRender ();
0378 
0379     ImageDataPtr cached_img;
0380 
0381 private Q_SLOTS:
0382     void svgUpdated();
0383     void movieUpdated (const QRect &);
0384     void movieStatus (QMovie::MovieState);
0385     void movieResize (const QSize &);
0386 
0387 protected:
0388     ~ImageMedia () override;
0389 
0390 private:
0391     void setupImage (const QString &url);
0392 
0393     QByteArray data;
0394     QBuffer *buffer;
0395     QMovie *img_movie;
0396     QSvgRenderer *svg_renderer;
0397     int frame_nr;
0398     bool update_render;
0399     bool paused;
0400 };
0401 
0402 //------------------------%<----------------------------------------------------
0403 
0404 /*
0405  * MediaObject for text
0406  */
0407 class TextMedia : public MediaObject
0408 {
0409 public:
0410     TextMedia (MediaManager *manager, Node *node, const QByteArray &ba);
0411 
0412     MediaManager::MediaType type () const override { return MediaManager::Text; }
0413 
0414     bool play () override;
0415 
0416     QString text;
0417     static int defaultFontSize ();
0418 
0419 protected:
0420     ~TextMedia () override;
0421 };
0422 
0423 } // namespace
0424 
0425 #endif