/****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg Copyright (C) 2012-2016 Wang Bin * This file is part of QtAV (from 2014) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ******************************************************************************/ #ifndef QTAV_MediaIO_H #define QTAV_MediaIO_H #include //SEEK_SET #include "_fav_constants.h" #include #include namespace FAV { /*! * \brief MediaIO * Built-in io (use MediaIO::create(name), example: MediaIO *qio = MediaIO::create("QIODevice")) * "QIODevice": * properties: * device - read/write. parameter: QIODevice*. example: io->setDevice(mydev) * "QFile" * properties: * device - read only. example: io->device() * protocols: "", "qrc" */ typedef int MediaIOId; class MediaIOPrivate; class Q_AV_EXPORT MediaIO : public QObject { Q_OBJECT DPTR_DECLARE_PRIVATE(MediaIO) Q_DISABLE_COPY(MediaIO) Q_ENUMS(AccessMode) public: enum AccessMode { Read, // default Write }; /// Registered MediaIO::name(): "QIODevice", "QFile" static QStringList builtInNames(); /*! * \brief createForProtocol * If an MediaIO subclass SomeInput.protocols() contains the protocol, return it's instance. * "QFile" input has protocols "qrc"(and empty "" means "qrc") * \return Null if none of registered MediaIO supports the protocol */ static MediaIO* createForProtocol(const QString& protocol); /*! * \brief createForUrl * Create a MediaIO and setUrl(url) if protocol of url is supported. * Example: MediaIO *qrc = MediaIO::createForUrl("qrc:/icon/test.mkv"); * \return MediaIO instance with url set. Null if protocol is not supported. */ static MediaIO* createForUrl(const QString& url); virtual ~MediaIO(); virtual QString name() const = 0; /*! * \brief setUrl * onUrlChange() will be called if url is different. onUrlChange() will close the old url and open the new url if it's not empty * \param url */ void setUrl(const QString& url = QString()); QString url() const; /*! * \brief setAccessMode * A MediaIO instance can be 1 mode, Read (default) or Write. If !isWritable(), then set to Write will fail and mode does not change * Call it before any function! * \return false if set failed */ bool setAccessMode(AccessMode value); AccessMode accessMode() const; /// supported protocols. default is empty virtual const QStringList& protocols() const; virtual bool isSeekable() const = 0; virtual bool isWritable() const { return false;} /*! * \brief read * read at most maxSize bytes to data, and return the bytes were actually read */ virtual qint64 read(char *data, qint64 maxSize) = 0; /*! * \brief write * write at most maxSize bytes from data, and return the bytes were actually written */ virtual qint64 write(const char* data, qint64 maxSize) { Q_UNUSED(data); Q_UNUSED(maxSize); return 0; } /*! * \brief seek * \param from SEEK_SET, SEEK_CUR and SEEK_END from stdio.h * \return true if success */ virtual bool seek(qint64 offset, int from = SEEK_SET) = 0; /*! * \brief position * MUST implement this. Used in seek * TODO: implement internally by default */ virtual qint64 position() const = 0; /*! * \brief size * \return <=0 if not support */ virtual qint64 size() const = 0; /*! * \brief isVariableSize * Experiment: A hack for size() changes during playback. * If true, containers that estimate duration from pts(or bit rate) will get an invalid duration. Thus no eof get * when the size of playback start reaches. So playback will not stop. * Demuxer seeking should work for this case. */ virtual bool isVariableSize() const { return false;} /*! * \brief setBufferSize * \param value <0: use default value */ void setBufferSize(int value = -1); int bufferSize() const; // The followings are for internal use. used by AVDemuxer, AVMuxer //struct AVIOContext; //anonymous struct in FFmpeg1.0.x void* avioContext(); //const? void release(); //TODO: how to remove it? public: static void registerAll(); template static bool Register(MediaIOId id, const char* name) { return Register(id, create, name);} static MediaIO* create(MediaIOId id); static MediaIO* create(const char* name); /*! * \brief next * \param id NULL to get the first id address * \return address of id or NULL if not found/end */ static MediaIOId* next(MediaIOId* id = 0); static const char* name(MediaIOId id); static MediaIOId id(const char* name); private: template static MediaIO* create() { return new C();} typedef MediaIO* (*MediaIOCreator)(); static bool Register(MediaIOId id, MediaIOCreator, const char *name); protected: MediaIO(MediaIOPrivate& d, QObject* parent = 0); /*! * \brief onUrlChanged * Here you can close old url, parse new url() and open it */ virtual void onUrlChanged(); DPTR_DECLARE(MediaIO) //private: // must add QT+=av-private if default ctor is private // base class, not direct create. only final class has public ctor is enough // FIXME: it's required by Q_DECLARE_METATYPE (also copy ctor) MediaIO(QObject* parent = 0); }; Q_DECL_DEPRECATED typedef MediaIO AVInput; // for source compatibility } //namespace FAV #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #include Q_DECLARE_METATYPE(FAV::MediaIO*) Q_DECLARE_METATYPE(QIODevice*) #endif #endif // QTAV_MediaIO_H