[Merge] lp:~jhodapp/qtubuntu-media/metadata into lp:qtubuntu-media

Ricardo Salveti rsalveti at rsalveti.net
Tue Feb 24 15:53:50 UTC 2015


Review: Needs Fixing

Minor comments.

Diff comments:

> === modified file 'debian/control'
> --- debian/control	2014-08-28 07:17:02 +0000
> +++ debian/control	2015-02-19 16:31:49 +0000
> @@ -20,6 +20,7 @@
>                 qtbase5-dev,
>                 qtdeclarative5-dev,
>                 qtmultimedia5-dev,
> +               libmediascanner-2.0-dev,
>  Standards-Version: 3.9.4
>  # If you don't have commit rights to lp:qtubuntu-media but need to upload
>  # packaging changes, just go ahead.  The developers will notice and sync
> @@ -36,6 +37,8 @@
>  Depends: ${misc:Depends},
>           ${shlibs:Depends},
>           qtvideonode-plugin,
> +         libmediascanner-2.0-3,
> +         mediascanner2.0,

Please remove the dependency on the service here (mediascanner2.0), as the image should be the one providing the service (this will also not be required once we're able to retrieve the metadata directly from the library calls.

>  Description: QtMultimedia plugin for AAL+
>   Video and audio playback plugin that interfaces Qt with
>   the hybris media backend on Android.
> 
> === modified file 'src/aal/aal.pro'
> --- src/aal/aal.pro	2014-03-26 16:08:35 +0000
> +++ src/aal/aal.pro	2015-02-19 16:31:49 +0000
> @@ -9,10 +9,12 @@
>  target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
>  INSTALLS = target
>  
> -INCLUDEPATH += /usr/include/hybris /usr/include/libqtubuntu-media-signals
> +INCLUDEPATH += /usr/include/hybris /usr/include/libqtubuntu-media-signals \
> +               /usr/include/mediascanner-2.0
>  LIBS += \
>      -lhybris-common -lubuntu_application_api -lmedia -lqtubuntu-media-signals \
> -    -lmedia-hub-client
> +    -lmedia-hub-client \
> +    -lmediascanner-2.0
>  
>  OTHER_FILES += aalmediaplayer.json
>  
> @@ -20,10 +22,12 @@
>      aalmediaplayercontrol.h \
>      aalmediaplayerservice.h \
>      aalmediaplayerserviceplugin.h \
> +    aalmetadatareadercontrol.h \
>      aalvideorenderercontrol.h
>  
>  SOURCES += \
>      aalmediaplayercontrol.cpp \
> +    aalmetadatareadercontrol.cpp \
>      aalmediaplayerservice.cpp \
>      aalmediaplayerserviceplugin.cpp \
>      aalvideorenderercontrol.cpp
> 
> === modified file 'src/aal/aalmediaplayerservice.cpp'
> --- src/aal/aalmediaplayerservice.cpp	2015-01-19 21:50:52 +0000
> +++ src/aal/aalmediaplayerservice.cpp	2015-02-19 16:31:49 +0000
> @@ -16,6 +16,7 @@
>  
>  #include "aalmediaplayercontrol.h"
>  #include "aalmediaplayerservice.h"
> +#include "aalmetadatareadercontrol.h"
>  
>  #include <core/media/service.h>
>  #include <core/media/track_list.h>
> @@ -65,6 +66,7 @@
>      m_errorConnection(the_void.connect([](){})),
>      m_mediaPlayerControl(nullptr),
>      m_videoOutput(nullptr),
> +    m_metaDataReaderControl(nullptr),
>      m_videoOutputReady(false),
>      m_cachedDuration(0),
>      m_mediaPlaylist(NULL)
> @@ -81,10 +83,50 @@
>          qWarning() << "Failed to create a new media player backend. Video playback will not function." << endl;
>  
>      if (m_hubPlayerSession == NULL)
> -        return;
> -
> -    createMediaPlayerControl();
> -    createVideoRendererControl();
> +    {
> +        qWarning() << "Could not finish contructing new AalMediaPlayerService instance since m_hubPlayerSession is NULL";
> +        return;
> +    }
> +
> +    createMediaPlayerControl();
> +    createVideoRendererControl();
> +    createMetaDataReaderControl();
> +
> +    m_playbackStatusChangedConnection = m_hubPlayerSession->playback_status_changed().connect(
> +            std::bind(&AalMediaPlayerService::onPlaybackStatusChanged, this, _1));
> +    m_errorConnection = m_hubPlayerSession->error().connect(
> +            std::bind(&AalMediaPlayerService::onError, this, _1));
> +}
> +
> +AalMediaPlayerService::AalMediaPlayerService(const std::shared_ptr<core::ubuntu::media::Service> &service,
> +                                             const std::shared_ptr<core::ubuntu::media::Player> &player, QObject *parent)
> +   : QMediaService(parent),
> +    m_hubService(service),
> +    m_hubPlayerSession(player),
> +    m_playbackStatusChangedConnection(the_void.connect([](){})),
> +    m_errorConnection(the_void.connect([](){})),
> +    m_mediaPlayerControl(nullptr),
> +    m_videoOutput(nullptr),
> +    m_metaDataReaderControl(nullptr),
> +    m_videoOutputReady(false),
> +    m_cachedDuration(0),
> +    m_mediaPlaylist(NULL)
> +#ifdef MEASURE_PERFORMANCE
> +     , m_lastFrameDecodeStart(0)
> +     , m_currentFrameDecodeStart(0)
> +     , m_avgCount(0)
> +     , m_frameDecodeAvg(0)
> +#endif
> +{
> +    if (m_hubPlayerSession == NULL)
> +    {
> +        qWarning() << "Could not finish contructing new AalMediaPlayerService instance since m_hubPlayerSession is NULL";
> +        return;
> +    }
> +
> +    createMediaPlayerControl();
> +    createVideoRendererControl();
> +    createMetaDataReaderControl();
>  
>      m_playbackStatusChangedConnection = m_hubPlayerSession->playback_status_changed().connect(
>              std::bind(&AalMediaPlayerService::onPlaybackStatusChanged, this, _1));
> @@ -99,6 +141,7 @@
>  
>      deleteMediaPlayerControl();
>      deleteVideoRendererControl();
> +    deleteMetaDataReaderControl();
>  }
>  
>  QMediaControl *AalMediaPlayerService::requestControl(const char *name)
> @@ -111,7 +154,7 @@
>          return m_mediaPlayerControl;
>      }
>  
> -    if (qstrcmp(name, QVideoRendererControl_iid) == 0)    
> +    if (qstrcmp(name, QVideoRendererControl_iid) == 0)
>      {
>          if (not m_videoOutput)
>              createVideoRendererControl();
> @@ -119,6 +162,14 @@
>          return m_videoOutput;
>      }
>  
> +    if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
> +    {
> +        if (not m_metaDataReaderControl)
> +            createMetaDataReaderControl();
> +
> +        return m_metaDataReaderControl;
> +    }
> +
>      return NULL;
>  }
>  
> @@ -128,6 +179,8 @@
>          deleteMediaPlayerControl();
>      else if (control == m_videoOutput)
>          deleteVideoRendererControl();
> +    else if (control == m_metaDataReaderControl)
> +        deleteMetaDataReaderControl();
>      else
>          delete control;
>  }
> @@ -469,6 +522,19 @@
>      m_videoOutput = new AalVideoRendererControl(this);
>  }
>  
> +void AalMediaPlayerService::createMetaDataReaderControl()
> +{
> +    qDebug() << Q_FUNC_INFO;
> +
> +    m_metaDataReaderControl = new AalMetaDataReaderControl(this);
> +
> +    if (m_mediaPlayerControl == nullptr)
> +        qDebug() << "m_mediaPlayerControl is NULL, can't connect mediaChanged signal";
> +
> +    connect(m_mediaPlayerControl, SIGNAL(mediaChanged(QMediaContent)),
> +            m_metaDataReaderControl, SLOT(onMediaChanged(QMediaContent)));
> +}
> +
>  void AalMediaPlayerService::deleteMediaPlayerControl()
>  {
>      if (m_hubPlayerSession == NULL)
> @@ -484,7 +550,7 @@
>  
>  void AalMediaPlayerService::deleteVideoRendererControl()
>  {
> -    if (m_hubPlayerSession == NULL)
> +    if (m_hubPlayerSession == nullptr)
>          return;
>  
>      m_hubPlayerSession->set_frame_available_callback(
> @@ -492,7 +558,16 @@
>                  nullptr);
>  
>      delete m_videoOutput;
> -    m_videoOutput = NULL;
> +    m_videoOutput = nullptr;
> +}
> +
> +void AalMediaPlayerService::deleteMetaDataReaderControl()
> +{
> +    if (m_hubPlayerSession == nullptr)
> +        return;
> +
> +    delete m_metaDataReaderControl;
> +    m_metaDataReaderControl = nullptr;
>  }
>  
>  void AalMediaPlayerService::signalQMediaPlayerError(const media::Player::Error &error)
> @@ -587,6 +662,7 @@
>  
>      createMediaPlayerControl();
>      createVideoRendererControl();
> +    createMetaDataReaderControl();
>  
>      m_hubPlayerSession->playback_status_changed().connect(
>              std::bind(&AalMediaPlayerService::onPlaybackStatusChanged, this, _1));
> 
> === modified file 'src/aal/aalmediaplayerservice.h'
> --- src/aal/aalmediaplayerservice.h	2015-01-19 21:50:52 +0000
> +++ src/aal/aalmediaplayerservice.h	2015-02-19 16:31:49 +0000
> @@ -29,8 +29,9 @@
>  
>  class AalMediaPlayerControl;
>  class QMediaPlayerControl;
> +class QMetaDataReaderControl;
>  class AalVideoRendererControl;
> -class txt_MediaPlayerPlugin;
> +class tst_MediaPlayerPlugin;
>  class QTimerEvent;
>  
>  namespace core { namespace ubuntu { namespace media {
> @@ -50,6 +51,8 @@
>      typedef void *GLConsumerWrapperHybris;
>  
>      AalMediaPlayerService(QObject *parent = 0);
> +    AalMediaPlayerService(const std::shared_ptr<core::ubuntu::media::Service> &service,
> +            const std::shared_ptr<core::ubuntu::media::Player> &player, QObject *parent = 0);
>      ~AalMediaPlayerService();
>  
>      QMediaControl* requestControl(const char *name);
> @@ -103,9 +106,11 @@
>  private:
>      void createMediaPlayerControl();
>      void createVideoRendererControl();
> +    void createMetaDataReaderControl();
>  
>      void deleteMediaPlayerControl();
>      void deleteVideoRendererControl();
> +    void deleteMetaDataReaderControl();
>  
>      // Signals the proper QMediaPlayer::Error from a core::ubuntu::media::Error
>      void signalQMediaPlayerError(const core::ubuntu::media::Player::Error &error);
> @@ -120,6 +125,7 @@
>  
>      AalMediaPlayerControl *m_mediaPlayerControl;
>      AalVideoRendererControl *m_videoOutput;
> +    QMetaDataReaderControl *m_metaDataReaderControl;
>      bool m_videoOutputReady;
>  
>      int64_t m_cachedDuration;
> 
> === modified file 'src/aal/aalmediaplayerserviceplugin.cpp'
> --- src/aal/aalmediaplayerserviceplugin.cpp	2014-11-04 14:45:10 +0000
> +++ src/aal/aalmediaplayerserviceplugin.cpp	2015-02-19 16:31:49 +0000
> @@ -16,6 +16,7 @@
>  
>  #include "aalmediaplayerserviceplugin.h"
>  #include "aalmediaplayerservice.h"
> +#include "aalmetadatareadercontrol.h"
>  
>  #include <QDebug>
>  
> 
> === added file 'src/aal/aalmetadatareadercontrol.cpp'
> --- src/aal/aalmetadatareadercontrol.cpp	1970-01-01 00:00:00 +0000
> +++ src/aal/aalmetadatareadercontrol.cpp	2015-02-19 16:31:49 +0000
> @@ -0,0 +1,148 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * This program 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; version 3.
> + *
> + * This program 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "aalmetadatareadercontrol.h"
> +
> +#include <mediascanner/MediaFile.hh>
> +#include <mediascanner/MediaStore.hh>
> +
> +#include <QDate>
> +#include <QDateTime>
> +#include <QDebug>
> +#include <QMediaMetaData>
> +#include <QSize>
> +
> +using namespace mediascanner;
> +
> +AalMetaDataReaderControl::AalMetaDataReaderControl(QObject *parent)
> +    : QMetaDataReaderControl(parent),
> +      m_available(false)
> +{
> +}
> +
> +bool AalMetaDataReaderControl::isMetaDataAvailable() const
> +{
> +    return m_available;
> +}
> +
> +QVariant AalMetaDataReaderControl::metaData(const QString &key) const
> +{
> +    qDebug() << Q_FUNC_INFO;
> +    return m_metadata.value(key);
> +}
> +
> +QStringList AalMetaDataReaderControl::availableMetaData() const
> +{
> +    return m_metadata.keys();
> +}
> +
> +void AalMetaDataReaderControl::onMediaChanged(const QMediaContent &media)
> +{
> +    qDebug() << Q_FUNC_INFO;
> +    m_mediaContent = media;
> +    updateMetaData();
> +}
> +
> +void AalMetaDataReaderControl::onUpdateMetaData()
> +{
> +    qDebug() << Q_FUNC_INFO;
> +    if (m_mediaContent.isNull())
> +        return;
> +
> +    updateMetaData();
> +}
> +
> +void AalMetaDataReaderControl::updateMetaData()
> +{
> +    qDebug() << Q_FUNC_INFO;
> +    if (m_mediaContent.isNull())
> +    {
> +        qWarning() << "Not updating metadata since the source has not been set.";
> +        return;
> +    }
> +
> +    m_metadata.clear();
> +
> +    bool isVideo = false, isAudio = false, isImage = false;
> +    try {
> +        MediaStore store(MS_READ_ONLY);
> +        qDebug() << "Doing a mediascanner lookup of file: " << m_mediaContent.canonicalUrl().toString(QUrl::RemoveScheme);
> +        MediaFile mf = store.lookup(m_mediaContent.canonicalUrl().toString(QUrl::RemoveScheme).toStdString());
> +
> +        isVideo = (mf.getType() == VideoMedia);
> +        isAudio = (mf.getType() == AudioMedia);
> +        isImage = (mf.getType() == ImageMedia);
> +
> +        m_metadata.insert(QMediaMetaData::Title, QString(mf.getTitle().c_str()));
> +        m_metadata.insert(QMediaMetaData::Author, QStringList(QString(mf.getAuthor().c_str())));
> +        {
> +            QString format = "yyyy-MM-ddThh:mm:ss";
> +            QDateTime datetime = QDateTime::fromString(QString(mf.getDate().c_str()), format);
> +            m_metadata.insert(QMediaMetaData::Date, datetime.date());
> +        }
> +        m_metadata.insert(QMediaMetaData::Genre, QStringList(QString(mf.getGenre().c_str())));
> +        m_metadata.insert(QMediaMetaData::Duration, static_cast<qint64>(mf.getDuration()));
> +
> +        // Metadata specific to video goes here:
> +        if (isVideo)
> +        {
> +            m_metadata.insert(QMediaMetaData::Resolution, QSize(mf.getWidth(), mf.getHeight()));
> +        }
> +
> +        // Metadata specific to audio/music goes here:
> +        if (isAudio)
> +        {
> +            m_metadata.insert(QMediaMetaData::AlbumTitle, QString(mf.getAlbum().c_str()));
> +            m_metadata.insert(QMediaMetaData::AlbumArtist, QString(mf.getAlbumArtist().c_str()));
> +            m_metadata.insert(QMediaMetaData::CoverArtUrlSmall, QUrl(mf.getArtUri().c_str()));
> +            m_metadata.insert(QMediaMetaData::CoverArtUrlLarge, QUrl(mf.getArtUri().c_str()));
> +            m_metadata.insert(QMediaMetaData::TrackNumber, mf.getTrackNumber());
> +        }
> +
> +        // Metadata specific to images goes here:
> +        if (isImage)
> +        {
> +            if (m_metadata.value(QMediaMetaData::Resolution).value<QSize>().isEmpty())
> +                m_metadata.insert(QMediaMetaData::Resolution, QSize(mf.getWidth(), mf.getHeight()));
> +
> +            m_metadata.insert(QMediaMetaData::GPSLatitude, mf.getLatitude());
> +            m_metadata.insert(QMediaMetaData::GPSLongitude, mf.getLongitude());
> +        }
> +
> +        qDebug() << "-----------------------------------------------------";
> +        qDebug() << "Media type: " << ((isVideo) ? "video" : "audio");
> +        qDebug() << "Media title: " << mf.getTitle().c_str();
> +        qDebug() << "Media author: " << mf.getAuthor().c_str();
> +        qDebug() << "Media date: " << mf.getDate().c_str();
> +        qDebug() << "Media genre: " << mf.getGenre().c_str();
> +        qDebug() << "Media duration: " << mf.getDuration();
> +        qDebug() << "Media height: " << mf.getHeight();
> +        qDebug() << "Media width: " << mf.getWidth();
> +        qDebug() << "Latitude: " << mf.getLatitude();
> +        qDebug() << "Longitude: " << mf.getLongitude();
> +        qDebug() << "-----------------------------------------------------";
> +    } catch (std::runtime_error &e) {
> +        qWarning() << "Caught runtime exception from mediascanner: " << e.what();
> +    }
> +
> +    bool previousAvailable = m_available;
> +    m_available = !m_metadata.isEmpty();
> +
> +    if (m_available != previousAvailable)
> +        Q_EMIT metaDataAvailableChanged(m_available);
> +
> +    Q_EMIT metaDataChanged();
> +}
> 
> === added file 'src/aal/aalmetadatareadercontrol.h'
> --- src/aal/aalmetadatareadercontrol.h	1970-01-01 00:00:00 +0000
> +++ src/aal/aalmetadatareadercontrol.h	2015-02-19 16:31:49 +0000
> @@ -0,0 +1,70 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * This program 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; version 3.
> + *
> + * This program 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef AALMETADATAREADERCONTROL_H
> +#define AALMETADATAREADERCONTROL_H
> +
> +#include <QMetaDataReaderControl>
> +#include <qmediacontent.h>
> +
> +class tst_MetaDataReaderControl;
> +
> +QT_BEGIN_NAMESPACE
> +
> +class AalMetaDataReaderControl : public QMetaDataReaderControl
> +{
> +    Q_OBJECT
> +
> +    // For unit testing purposes
> +    friend class tst_MetaDataReaderControl;
> +
> +public:
> +    explicit AalMetaDataReaderControl(QObject *parent = 0);
> +
> +    /**
> +     * @brief Returns whether there is any metadata available to read for the given media source.
> +     */
> +    bool isMetaDataAvailable() const Q_DECL_OVERRIDE;
> +
> +    /**
> +     * @brief Returns a metadata value given a metadata key name. See QMediaMetaData for a list of keys.
> +     * @return Returns a QVariant with the metadata value.
> +     */
> +    QVariant metaData(const QString &key) const Q_DECL_OVERRIDE;
> +    /**
> +     * @brief Returns a list of key names for which metadata values are available.
> +     * @return Returns a QStringList of key names.
> +     */
> +    QStringList availableMetaData() const Q_DECL_OVERRIDE;
> +
> +public Q_SLOTS:
> +    void onMediaChanged(const QMediaContent &media);
> +    /**
> +     * @brief Updates the internal metadata metadata store from the mediascanner for the given media source.
> +     **/
> +    void onUpdateMetaData();
> +
> +private:
> +    void updateMetaData();
> +
> +    QMediaContent m_mediaContent;
> +    bool m_available;
> +    QVariantMap m_metadata;
> +};
> +
> +QT_END_NAMESPACE
> +
> +#endif // AALMETADATAREADERCONTROL_H
> 
> === added directory 'unittests/audio'
> === added file 'unittests/audio/testfile.ogg'
> Binary files unittests/audio/testfile.ogg	1970-01-01 00:00:00 +0000 and unittests/audio/testfile.ogg	2015-02-19 16:31:49 +0000 differ
> === added directory 'unittests/images'
> === added file 'unittests/images/testfile.jpg'
> Binary files unittests/images/testfile.jpg	1970-01-01 00:00:00 +0000 and unittests/images/testfile.jpg	2015-02-19 16:31:49 +0000 differ
> === modified file 'unittests/service.cpp'
> --- unittests/service.cpp	2014-10-08 07:57:42 +0000
> +++ unittests/service.cpp	2015-02-19 16:31:49 +0000
> @@ -20,6 +20,11 @@
>  namespace ubuntu {
>  namespace media {
>  
> +const std::shared_ptr<media::Service> TestService::Client::instance()
> +{
> +    return NULL;
> +}
> +
>  std::shared_ptr<Player> TestService::create_session(const Player::Configuration&)
>  {
>      return NULL;
> @@ -27,12 +32,13 @@
>  
>  std::shared_ptr<Player> TestService::create_fixed_session(const std::string& name, const Player::Configuration&)
>  {
> -  return 0;
> +    (void) name;
> +    return 0;
>  }
>  
>  std::shared_ptr<Player> TestService::resume_session(Player::PlayerKey)
>  {
> -  return 0;
> +    return 0;
>  }
>  
>  void TestService::pause_other_sessions(Player::PlayerKey)
> 
> === added file 'unittests/setup_mediascanner.sh'
> --- unittests/setup_mediascanner.sh	1970-01-01 00:00:00 +0000
> +++ unittests/setup_mediascanner.sh	2015-02-19 16:31:49 +0000
> @@ -0,0 +1,46 @@
> +#!/bin/sh
> +# Setup the mediascanner and copy test media into place
> +
> +set -e
> +
> +TESTFILE="testfile"
> +DEST_PREFIX="/home/phablet"

Please try to get the home dir from the current user instead, as this also needs to run on desktop.

> +
> +if [ ! -d "$DEST_PREFIX/Videos" ]; then
> +    echo "Creating directory $DEST_PREFIX/Videos"
> +    mkdir -p $DEST_PREFIX/Videos
> +fi
> +
> +if [ ! -d "$DEST_PREFIX/Music" ]; then
> +    echo "Creating directory $DEST_PREFIX/Music"
> +    mkdir -p $DEST_PREFIX/Music
> +fi
> +
> +if [ ! -d "$DEST_PREFIX/Pictures" ]; then
> +    echo "Creating directory $DEST_PREFIX/Pictures"
> +    mkdir -p $DEST_PREFIX/Pictures
> +fi
> +
> +if [ ! -f "$DEST_PREFIX/Videos/$TESTFILE.mp4" ]; then
> +    echo "Copying video/$TESTFILE.mp4 to $DEST_PREFIX/Videos/$TESTFILE.mp4"
> +    cp videos/$TESTFILE.mp4 $DEST_PREFIX/Videos/$TESTFILE.mp4
> +fi
> +
> +if [ ! -f "$DEST_PREFIX/Music/$TESTFILE.ogg" ]; then
> +    echo "Copying audio/$TESTFILE.ogg to $DEST_PREFIX/Music/$TESTFILE.ogg"
> +    cp audio/$TESTFILE.ogg $DEST_PREFIX/Music/$TESTFILE.ogg
> +fi
> +
> +if [ ! -f "$DEST_PREFIX/Pictures/$TESTFILE.jpg" ]; then
> +    echo "Copying images/$TESTFILE.jpg to $DEST_PREFIX/Pictures/$TESTFILE.jpg"
> +    cp images/$TESTFILE.jpg $DEST_PREFIX/Pictures/$TESTFILE.jpg
> +fi
> +
> +status mediascanner-2.0
> +if [ $? -ne 0 ]; then
> +    echo "mediascanner-2.0 not running, starting"
> +    start mediascanner-2.0
> +else
> +    echo "restarting mediascanner-2.0"
> +    restart mediascanner-2.0
> +fi
> 
> === modified file 'unittests/tst_mediaplayerplugin.cpp'
> --- unittests/tst_mediaplayerplugin.cpp	2014-11-05 10:06:47 +0000
> +++ unittests/tst_mediaplayerplugin.cpp	2015-02-19 16:31:49 +0000
> @@ -17,58 +17,25 @@
>  #include "player.h"
>  #include "service.h"
>  #include "aalmediaplayerservice.h"
> -
> -#include <core/media/player.h>
> +#include "tst_mediaplayerplugin.h"
> +#include "tst_metadatareadercontrol.h"
>  
>  #include <memory>
>  
> -#include <QObject>
> -#include <QMediaPlayerControl>
>  #include <QVideoRendererControl>
>  #include <QtTest/QtTest>
>  
>  #define private public
> -
>  #include "aalmediaplayercontrol.h"
>  
>  using namespace std;
>  using namespace core::ubuntu::media;
>  
> -class tst_MediaPlayerPlugin : public QObject
> -{
> -    Q_OBJECT
> -
> -    AalMediaPlayerService *m_service;
> -    AalMediaPlayerControl *m_mediaPlayerControl;
> -    QMediaControl *m_playerControl;
> -    QMediaControl *m_rendererControl;
> -    shared_ptr<Player> m_player;
> -    shared_ptr<Service> m_hubService;
> -
> -private Q_SLOTS:
> -    // We want the setup to be run prior to every test case to
> -    // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
> -    void init();
> -
> -    void tst_requestRelease();
> -    void tst_newMediaPlayer();
> -    void tst_setMedia();
> -    void tst_unescape();
> -    void tst_play();
> -    void tst_pause();
> -    void tst_stop();
> -    void tst_position();
> -    void tst_duration();
> -    void tst_isAudioSource();
> -    void tst_isVideoSource();
> -    void tst_volume();
> -};
> -
>  void tst_MediaPlayerPlugin::init()
>  {
>      m_hubService.reset(new TestService());
>      m_service = new AalMediaPlayerService(this);
> -    m_service->setService(m_hubService);    
> +    m_service->setService(m_hubService);
>      m_player.reset(new TestPlayer());
>      m_service->setPlayer(m_player);
>      m_playerControl = m_service->requestControl(QMediaPlayerControl_iid);
> @@ -169,6 +136,15 @@
>      QVERIFY(m_mediaPlayerControl->volume() == 1);
>  }
>  
> -QTEST_GUILESS_MAIN(tst_MediaPlayerPlugin)
> -
> -#include "tst_mediaplayerplugin.moc"
> +int main(int argc, char **argv)
> +{
> +    // Create a GUI-less unit test standalone app
> +    QCoreApplication app(argc, argv);
> +    tst_MediaPlayerPlugin mpp;
> +    // FIXME: Disabled for now until we can get metadata from mediascanner without a file
> +    // first needing to be indexed. This is required so that the metadata tests will work
> +    // in the CI infrastructure.
> +    //tst_MetaDataReaderControl mdrc;
> +    //return (QTest::qExec(&mpp, argc, argv) && QTest::qExec(&mdrc, argc, argv));
> +    return QTest::qExec(&mpp, argc, argv);
> +}
> 
> === added file 'unittests/tst_mediaplayerplugin.h'
> --- unittests/tst_mediaplayerplugin.h	1970-01-01 00:00:00 +0000
> +++ unittests/tst_mediaplayerplugin.h	2015-02-19 16:31:49 +0000
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * This program 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; version 3.
> + *
> + * This program 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <core/media/player.h>
> +
> +#include <memory>
> +
> +#include <QObject>
> +#include <QMediaPlayerControl>
> +
> +class AalMediaPlayerService;
> +class AalMediaPlayerControl;
> +
> +class tst_MediaPlayerPlugin : public QObject
> +{
> +    Q_OBJECT
> +
> +    AalMediaPlayerService *m_service;
> +    AalMediaPlayerControl *m_mediaPlayerControl;
> +    QMediaControl *m_playerControl;
> +    QMediaControl *m_rendererControl;
> +    std::shared_ptr<core::ubuntu::media::Player> m_player;
> +    std::shared_ptr<core::ubuntu::media::Service> m_hubService;
> +
> +private Q_SLOTS:
> +    // We want the setup to be run prior to every test case to
> +    // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
> +    void init();
> +
> +    void tst_requestRelease();
> +    void tst_newMediaPlayer();
> +    void tst_setMedia();
> +    void tst_unescape();
> +    void tst_play();
> +    void tst_pause();
> +    void tst_stop();
> +    void tst_position();
> +    void tst_duration();
> +    void tst_isAudioSource();
> +    void tst_isVideoSource();
> +    void tst_volume();
> +};
> 
> === added file 'unittests/tst_metadatareadercontrol.cpp'
> --- unittests/tst_metadatareadercontrol.cpp	1970-01-01 00:00:00 +0000
> +++ unittests/tst_metadatareadercontrol.cpp	2015-02-19 16:31:49 +0000
> @@ -0,0 +1,168 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * This program 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; version 3.
> + *
> + * This program 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "tst_metadatareadercontrol.h"
> +#include "aalmetadatareadercontrol.h"
> +
> +#include <QMediaMetaData>
> +#include <QObject>
> +#include <QtTest/QtTest>
> +
> +using namespace core::ubuntu::media;
> +
> +void tst_MetaDataReaderControl::initTestCase()
> +{
> +    m_mdControlVideo = new AalMetaDataReaderControl(this);
> +    m_mdControlAudio = new AalMetaDataReaderControl(this);
> +    m_mdControlImage = new AalMetaDataReaderControl(this);
> +
> +    QVERIFY(m_mdControlVideo != nullptr);
> +    QVERIFY(m_mdControlAudio != nullptr);
> +    QVERIFY(m_mdControlImage != nullptr);
> +
> +    connect(this, SIGNAL(onMediaChanged(const QMediaContent&)), m_mdControlVideo, SLOT(onMediaChanged(const QMediaContent&)));
> +    connect(this, SIGNAL(onMediaChanged(const QMediaContent&)), m_mdControlAudio, SLOT(onMediaChanged(const QMediaContent&)));
> +    connect(this, SIGNAL(onMediaChanged(const QMediaContent&)), m_mdControlImage, SLOT(onMediaChanged(const QMediaContent&)));
> +}
> +
> +void tst_MetaDataReaderControl::cleanupTestCase()
> +{
> +    delete m_mdControlImage;
> +    delete m_mdControlAudio;
> +    delete m_mdControlVideo;
> +}
> +
> +// Adapted to have custom delta from qFuzzyCompare
> +static inline bool fuzzyCompare(double p1, double p2)
> +{
> +    return (qAbs(p1 - p2) <= 0.00001 * qMin(qAbs(p1), qAbs(p2)));
> +}
> +
> +void tst_MetaDataReaderControl::setVideoMediaResource()
> +{
> +    m_mediaResource = QMediaResource(QUrl("/home/phablet/Videos/testfile.mp4"));
> +    m_media = QMediaContent(m_mediaResource);
> +    // Signal to the AalMetaDataReaderControl instance that we are setting example media to extract metadata from
> +    Q_EMIT onMediaChanged(m_media);
> +}
> +
> +void tst_MetaDataReaderControl::setAudioMediaResource()
> +{
> +    m_mediaResource = QMediaResource(QUrl("/home/phablet/Music/testfile.ogg"));
> +    m_media = QMediaContent(m_mediaResource);
> +    // Signal to the AalMetaDataReaderControl instance that we are setting example media to extract metadata from
> +    Q_EMIT onMediaChanged(m_media);
> +}
> +
> +void tst_MetaDataReaderControl::setImageMediaResource()
> +{
> +    m_mediaResource = QMediaResource(QUrl("/home/phablet/Pictures/testfile.jpg"));
> +    m_media = QMediaContent(m_mediaResource);
> +    // Signal to the AalMetaDataReaderControl instance that we are setting example media to extract metadata from
> +    Q_EMIT onMediaChanged(m_media);
> +}
> +
> +void tst_MetaDataReaderControl::verifyResolution()
> +{
> +    setVideoMediaResource();
> +    QSize resolutionSize = m_mdControlVideo->metaData(QMediaMetaData::Resolution).value<QSize>();
> +    QCOMPARE(resolutionSize, QSize(320, 240));
> +
> +    setImageMediaResource();
> +    resolutionSize = m_mdControlVideo->metaData(QMediaMetaData::Resolution).value<QSize>();
> +    QCOMPARE(resolutionSize, QSize(2448, 3264));
> +}
> +
> +void tst_MetaDataReaderControl::verifyDuration()
> +{
> +    setVideoMediaResource();
> +    qint64 duration = m_mdControlVideo->metaData(QMediaMetaData::Duration).value<qint64>();
> +    QCOMPARE(duration, 34);
> +
> +    setAudioMediaResource();
> +    duration = m_mdControlVideo->metaData(QMediaMetaData::Duration).value<qint64>();
> +    QCOMPARE(duration, 5);
> +}
> +
> +void tst_MetaDataReaderControl::verifyTitle()
> +{
> +    setVideoMediaResource();
> +    QString title = m_mdControlVideo->metaData(QMediaMetaData::Title).value<QString>();
> +    QCOMPARE(title, QString("h264 title"));
> +
> +    setAudioMediaResource();
> +    title = m_mdControlVideo->metaData(QMediaMetaData::Title).value<QString>();
> +    QCOMPARE(title, QString("track1"));
> +}
> +
> +void tst_MetaDataReaderControl::verifyAuthor()
> +{
> +    setVideoMediaResource();
> +    QString author = m_mdControlVideo->metaData(QMediaMetaData::Author).value<QString>();
> +    QCOMPARE(author, QString("Canonical"));
> +}
> +
> +void tst_MetaDataReaderControl::verifyGenre()
> +{
> +    setVideoMediaResource();
> +    QString genre = m_mdControlVideo->metaData(QMediaMetaData::Genre).value<QString>();
> +    QCOMPARE(genre, QString("Trailer"));
> +
> +    setAudioMediaResource();
> +    genre = m_mdControlAudio->metaData(QMediaMetaData::Genre).value<QString>();
> +    QCOMPARE(genre, QString("Progressive Rock"));
> +}
> +
> +void tst_MetaDataReaderControl::verifyDate()
> +{
> +    setAudioMediaResource();
> +    QDate date = m_mdControlAudio->metaData(QMediaMetaData::Date).value<QDate>();
> +    QCOMPARE(date, QDate(2013, 0, 0));
> +
> +    setImageMediaResource();
> +    date = m_mdControlAudio->metaData(QMediaMetaData::Date).value<QDate>();
> +    QCOMPARE(date, QDate(2015, 2, 10));
> +}
> +
> +void tst_MetaDataReaderControl::verifyAlbumTitle()
> +{
> +    setAudioMediaResource();
> +    QString title = m_mdControlAudio->metaData(QMediaMetaData::AlbumTitle).value<QString>();
> +    QCOMPARE(title, QString("album1"));
> +}
> +
> +void tst_MetaDataReaderControl::verifyAlbumArtist()
> +{
> +    setAudioMediaResource();
> +    QString artist = m_mdControlAudio->metaData(QMediaMetaData::AlbumArtist).value<QString>();
> +    QCOMPARE(artist, QString("artist1"));
> +}
> +
> +void tst_MetaDataReaderControl::verifyLatitude()
> +{
> +    setImageMediaResource();
> +    double latitude = m_mdControlImage->metaData(QMediaMetaData::GPSLatitude).value<double>();
> +    qDebug() << "latitude: " << latitude;
> +    QVERIFY(fuzzyCompare(latitude, 39.8566));
> +}
> +
> +void tst_MetaDataReaderControl::verifyLongitude()
> +{
> +    setImageMediaResource();
> +    double longitude = m_mdControlImage->metaData(QMediaMetaData::GPSLongitude).value<double>();
> +    qDebug() << "longitude: " << longitude;
> +    QVERIFY(fuzzyCompare(longitude, -86.1242));
> +}
> 
> === added file 'unittests/tst_metadatareadercontrol.h'
> --- unittests/tst_metadatareadercontrol.h	1970-01-01 00:00:00 +0000
> +++ unittests/tst_metadatareadercontrol.h	2015-02-19 16:31:49 +0000
> @@ -0,0 +1,72 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * This program 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; version 3.
> + *
> + * This program 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef TST_METADATAREADERCONTROL_H
> +#define TST_METADATAREADERCONTROL_H
> +
> +#include <core/media/player.h>
> +
> +#include <memory>
> +
> +#include <QMediaContent>
> +#include <QMediaResource>
> +#include <QObject>
> +
> +class AalMetaDataReaderControl;
> +class AalMediaPlayerService;
> +class AalMediaPlayerControl;
> +class QMediaControl;
> +class QMediaPlayer;
> +
> +class tst_MetaDataReaderControl : public QObject
> +{
> +    Q_OBJECT
> +
> +    AalMetaDataReaderControl *m_mdControlVideo;
> +    AalMetaDataReaderControl *m_mdControlAudio;
> +    AalMetaDataReaderControl *m_mdControlImage;
> +    QMediaResource m_mediaResource;
> +    QMediaContent m_media;
> +
> +Q_SIGNALS:
> +    void onMediaChanged(const QMediaContent &media);
> +
> +private Q_SLOTS:
> +    // We want the setup to be run prior to every test case to
> +    // ensure correct test isolation, see http://qt-project.org/doc/qt-5/qtest-overview.html.
> +    void initTestCase();
> +    void cleanupTestCase();
> +
> +    void verifyResolution();
> +    void verifyDuration();
> +    void verifyTitle();
> +    void verifyAuthor();
> +    void verifyGenre();
> +
> +    void verifyDate();
> +    void verifyAlbumTitle();
> +    void verifyAlbumArtist();
> +
> +    void verifyLatitude();
> +    void verifyLongitude();
> +
> +private:
> +    void setVideoMediaResource();
> +    void setAudioMediaResource();
> +    void setImageMediaResource();
> +};
> +
> +#endif // TST_METADATAREADERCONTROL_H
> 
> === modified file 'unittests/unittests.pro'
> --- unittests/unittests.pro	2014-04-25 21:12:56 +0000
> +++ unittests/unittests.pro	2015-02-19 16:31:49 +0000
> @@ -10,23 +10,33 @@
>  INCLUDEPATH += ../src/aal \
>      /usr/include/qt5/QtMultimedia \
>      /usr/include/hybris \
> -    /usr/include/libqtubuntu-media-signals
> +    /usr/include/libqtubuntu-media-signals \
> +    /usr/include/mediascanner-2.0
>  LIBS += \
> -    -lqtubuntu-media-signals
> +    -lqtubuntu-media-signals \
> +    -lmediascanner-2.0
>  
>  HEADERS += \
>      ../src/aal/aalmediaplayercontrol.h \
>      ../src/aal/aalmediaplayerservice.h \
>      ../src/aal/aalmediaplayerserviceplugin.h \
>      ../src/aal/aalvideorenderercontrol.h \
> +    ../src/aal/aalmetadatareadercontrol.h \
> +    tst_mediaplayerplugin.h \
> +    tst_metadatareadercontrol.h \
>      player.h \
>      service.h
>  
>  SOURCES += \
>      tst_mediaplayerplugin.cpp \
> +    tst_metadatareadercontrol.cpp \
>      player.cpp \
>      service.cpp \
>      ../src/aal/aalmediaplayercontrol.cpp \
> +    ../src/aal/aalmetadatareadercontrol.cpp \
>      ../src/aal/aalmediaplayerservice.cpp \
>      ../src/aal/aalmediaplayerserviceplugin.cpp \
>      ../src/aal/aalvideorenderercontrol.cpp
> +
> +# Installs required test media into place where the mediascanner will scan them
> +system(cd $$PWD; echo $$PWD; ./setup_mediascanner.sh)

If you want to run/start mediascanner when building the package (running the tests), please also build-depend on mediascanner2.0.

> 
> === added directory 'unittests/videos'
> === added file 'unittests/videos/testfile.mp4'
> Binary files unittests/videos/testfile.mp4	1970-01-01 00:00:00 +0000 and unittests/videos/testfile.mp4	2015-02-19 16:31:49 +0000 differ


-- 
https://code.launchpad.net/~jhodapp/qtubuntu-media/metadata/+merge/250154
Your team Ubuntu Phablet Team is subscribed to branch lp:qtubuntu-media.



More information about the Ubuntu-reviews mailing list