00001 #ifndef DECODERHANDLER_H_
00002 #define DECODERHANDLER_H_
00003
00004
00005 #include <iostream>
00006
00007
00008 #include <QObject>
00009 #include <QIODevice>
00010 #include <QFile>
00011 #include <QUrl>
00012 #include <QMutex>
00013
00014
00015 #include <mythobservable.h>
00016
00017
00018 #include "metadata.h"
00019 #include "pls.h"
00020
00021 class MusicBuffer;
00022 class RemoteFile;
00023
00024 class QUrl;
00025 class QNetworkAccessManager;
00026 class QNetworkReply;
00027
00028 class Decoder;
00029 class Metadata;
00030 class DecoderIOFactory;
00031 class DecoderHandler;
00032 class MusicBuffer;
00033 class MusicIODevice;
00034
00037 class DecoderHandlerEvent : public MythEvent
00038 {
00039 public:
00040 DecoderHandlerEvent(Type t)
00041 : MythEvent(t), m_msg(0), m_meta(0) {}
00042
00043 DecoderHandlerEvent(Type t, QString *e)
00044 : MythEvent(t), m_msg(e), m_meta(0) {}
00045
00046 DecoderHandlerEvent(Type t, const Metadata &m);
00047 ~DecoderHandlerEvent();
00048
00049 QString *getMessage(void) const { return m_msg; }
00050 Metadata *getMetadata(void) const { return m_meta; }
00051
00052 virtual MythEvent *clone(void) const;
00053
00054 static Type Ready;
00055 static Type Meta;
00056 static Type Info;
00057 static Type OperationStart;
00058 static Type OperationStop;
00059 static Type Error;
00060
00061 private:
00062 QString *m_msg;
00063 Metadata *m_meta;
00064 };
00065
00079 class DecoderHandler : public QObject, public MythObservable
00080 {
00081 Q_OBJECT
00082 friend class DecoderIOFactory;
00083 public:
00084 typedef enum
00085 {
00086 ACTIVE,
00087 LOADING,
00088 STOPPED
00089 } State;
00090
00091 DecoderHandler(void);
00092 virtual ~DecoderHandler(void);
00093
00094 Decoder *getDecoder(void) { return m_decoder; }
00095 void start(Metadata *mdata);
00096
00097 void stop(void);
00098 void customEvent(QEvent *e);
00099 bool done(void);
00100 bool next(void);
00101 void error(const QString &msg);
00102
00103 protected:
00104 void doOperationStart(const QString &name);
00105 void doOperationStop(void);
00106 void doConnectDecoder(const QUrl &url, const QString &format);
00107 void doFailed(const QUrl &url, const QString &message);
00108 void doInfo(const QString &message);
00109
00110 private:
00111 bool createPlaylist(const QUrl &url);
00112 bool createPlaylistForSingleFile(const QUrl &url);
00113 bool createPlaylistFromFile(const QUrl &url);
00114 bool createPlaylistFromRemoteUrl(const QUrl &url);
00115
00116 bool haveIOFactory(void) { return m_io_factory != NULL; }
00117 DecoderIOFactory *getIOFactory(void) { return m_io_factory; }
00118 void createIOFactory(const QUrl &url);
00119 void deleteIOFactory(void);
00120
00121 int m_state;
00122 int m_playlist_pos;
00123 PlayListFile m_playlist;
00124 DecoderIOFactory *m_io_factory;
00125 Decoder *m_decoder;
00126 Metadata *m_meta;
00127 bool m_op;
00128 uint m_redirects;
00129
00130 static const uint MaxRedirects = 3;
00131 };
00132
00138 class DecoderIOFactory : public QObject, public MythObservable
00139 {
00140 public:
00141 DecoderIOFactory(DecoderHandler *parent);
00142 virtual ~DecoderIOFactory();
00143
00144 virtual void start(void) = 0;
00145 virtual void stop(void) = 0;
00146 virtual QIODevice *takeInput(void) = 0;
00147
00148 void setUrl (const QUrl &url) { m_url = url; }
00149 void setMeta (Metadata *meta) { m_meta = *meta; }
00150
00151 static const uint DefaultPrebufferSize = 128 * 1024;
00152 static const uint DefaultBufferSize = 256 * 1024;
00153 static const uint MaxRedirects = 3;
00154
00155 protected:
00156 void doConnectDecoder(const QString &format);
00157 Decoder *getDecoder(void);
00158 void doFailed(const QString &message);
00159 void doInfo(const QString &message);
00160 void doOperationStart(const QString &name);
00161 void doOperationStop(void);
00162 Metadata& getMetadata() { return m_meta; }
00163 QUrl& getUrl() { return m_url; }
00164
00165 private:
00166 DecoderHandler *m_handler;
00167 Metadata m_meta;
00168 QUrl m_url;
00169 };
00170
00171 class DecoderIOFactoryFile : public DecoderIOFactory
00172 {
00173 Q_OBJECT
00174
00175 public:
00176 DecoderIOFactoryFile(DecoderHandler *parent);
00177 ~DecoderIOFactoryFile(void);
00178 void start(void);
00179 void stop() {}
00180 QIODevice *takeInput(void);
00181
00182 private:
00183 QIODevice *m_input;
00184 };
00185
00186 class DecoderIOFactorySG : public DecoderIOFactory
00187 {
00188 Q_OBJECT
00189
00190 public:
00191 DecoderIOFactorySG(DecoderHandler *parent);
00192 ~DecoderIOFactorySG(void);
00193 void start(void);
00194 void stop() {}
00195 QIODevice *takeInput(void);
00196
00197 private:
00198 QIODevice *m_input;
00199 };
00200
00201 class DecoderIOFactoryUrl : public DecoderIOFactory
00202 {
00203 Q_OBJECT
00204
00205 public:
00206 DecoderIOFactoryUrl(DecoderHandler *parent);
00207 ~DecoderIOFactoryUrl(void);
00208
00209 void start(void);
00210 void stop(void);
00211 QIODevice *takeInput(void);
00212
00213 protected slots:
00214 void replyFinished(QNetworkReply *reply);
00215 void readyRead(void);
00216
00217 private:
00218 void doStart(void);
00219 void doClose(void);
00220
00221 bool m_started;
00222 QNetworkAccessManager *m_accessManager;
00223 QNetworkReply *m_reply;
00224 MusicIODevice *m_input;
00225 QUrl m_redirectedURL;
00226 uint m_redirectCount;
00227 uint m_bytesWritten;
00228 };
00229
00230 class MusicBuffer
00231 {
00232 public:
00233 MusicBuffer(void) { }
00234 ~MusicBuffer(void) { }
00235
00236 qint64 read(char *data, qint64 max, bool doRemove = true);
00237 qint64 read(QByteArray &array, qint64 max, bool doRemove = true);
00238
00239 void write(const char *data, uint sz);
00240 void write(QByteArray &array);
00241
00242 void remove(int index, int len);
00243
00244 qint64 readBufAvail(void) const { return m_buffer.size(); }
00245
00246 private:
00247 QByteArray m_buffer;
00248 QMutex m_mutex;
00249 };
00250
00251 class MusicIODevice : public QIODevice
00252 {
00253 Q_OBJECT
00254
00255 public:
00256 MusicIODevice(void);
00257 ~MusicIODevice(void);
00258
00259 bool open(int);
00260 void close(void) { };
00261 bool flush(void);
00262
00263 qint64 size(void) const;
00264 qint64 pos(void) const { return 0; }
00265 qint64 bytesAvailable(void) const;
00266 bool isSequential(void) const { return true; }
00267
00268 qint64 readData(char *data, qint64 sz);
00269 qint64 writeData(const char *data, qint64 sz);
00270
00271 int getch(void);
00272 int putch(int c);
00273 int ungetch(int);
00274
00275 signals:
00276 void freeSpaceAvailable(void);
00277
00278 protected:
00279 MusicBuffer *m_buffer;
00280 };
00281
00282 class MusicSGIODevice : public QIODevice
00283 {
00284 Q_OBJECT
00285
00286 public:
00287 MusicSGIODevice(const QString &url);
00288 ~MusicSGIODevice(void);
00289
00290 bool open(int);
00291 void close(void) { };
00292 bool flush(void);
00293
00294 qint64 size(void) const;
00295 qint64 pos(void) const { return 0; }
00296 qint64 bytesAvailable(void) const;
00297 bool isSequential(void) const { return true; }
00298 bool seek(qint64 pos);
00299
00300 qint64 readData(char *data, qint64 sz);
00301 qint64 writeData(const char *data, qint64 sz);
00302
00303 int getch(void);
00304 int putch(int c);
00305 int ungetch(int);
00306
00307 protected:
00308 RemoteFile *m_remotefile;
00309 };
00310
00311 #endif