Tutorial: Simple Media Engine
Files:
The Ffmpeg Media Engine tutorial shows how to use the Qt Extended Media API to create a simple Media Engine.
The engine requires ffmpeg installed into your system or toolchain. This engine is for demonstration purposes only.
Firstly ffmpeg requires initialization, this is added to ffmpegengine.cpp
av_register_all();
Everything else goes into ffmpegplaybinsession.cpp In constructor open audio output
d->output = new QAudioOutput(this);
Create video output, wrapper class for QVideoFrame, see ffmpegdirectpainterwidget.cpp
d->sinkWidget = new DirectPainterWidget;
Ffmpeg's open and codec functions
av_open_input_file();
av_find_stream_info();
avcodec_find_decoder();
avcodec_open();
avcodec_alloc_frame();
Once we have all the information about the file to play we can register if it has video to play.
d->videoControlServer = new QMediaVideoControlServer(d->id);
d->videoControlServer->setVideoDelegate(d->sinkWidget->videoSurface());
d->videoControlServer->setRenderTarget(d->sinkWidget->windowId());
d->interfaces << "Video";
emit interfaceAvailable("Video");
d->haveStreamInfo = true;
When the system is ready to start playback void PlaybinSession::start() is called to begin, readFrame() is called to decode and output the audio and video data.
av_read_frame();
d->output->write((const char*)audio_buf,(qint64)data_size);
d->sinkWidget->paint(*f);
Engine Class Definition
class QMediaEngineInformation;
class QMediaSessionRequest;
class QMediaServerSession;
namespace ffmpeg
{
class EnginePrivate;
class Engine : public QMediaEngine
{
Q_OBJECT
public:
Engine();
~Engine();
void initialize();
void start();
void stop();
void suspend();
void resume();
QMediaEngineInformation const* engineInformation();
void registerSession(QMediaServerSession* session);
void unregisterSession(QMediaServerSession* session);
private:
PlaybinSession* s;
EnginePrivate* d;
};
PlaybinSession Class Definition
class PlaybinSessionPrivate;
class PlaybinSession : public QMediaServerSession
{
Q_OBJECT
public:
PlaybinSession(Engine* engine, QUuid const& id, QUrl const& url,
QMediaDevice* sink);
~PlaybinSession();
bool isValid() const;
void start();
void pause();
void stop();
void suspend();
void resume();
void seek(quint32 ms);
quint32 length();
void setVolume(int volume);
int volume() const;
void setMuted(bool mute);
bool isMuted() const;
QtopiaMedia::State playerState() const;
QString errorString();
void setDomain(QString const& domain);
QString domain() const;
QStringList interfaces();
QString id() const;
QString reportData() const;
private slots:
void readFrame();
private:
void getStreamsInfo();
void readySession();
PlaybinSessionPrivate* d;
};
Building the Simple Media Engine
To install and run the demonstration, carry out the following steps.
- Create a new directory (e.g. $HOME/src/ffmpeg) and copy all the example files to that directory.
mkdir $HOME/src/ffmpeg
cd $HOME/src/ffmpeg
cp -r <qt-extended-source-directory>/examples/ffmpeg/* .
chmod +w *
- Build the new engine.
Add CONFIG+=enable_ffmpeg to the pro file or add it to your device profiles custom.pri file
export QPEDIR=<qt-extended-build-directory>
$QPEDIR/bin/qbuild
$QPEDIR/bin/qbuild image
- Run Qt Extended.
$QPEDIR/bin/runqtopia
- Restart Qt Extended.