void QGstreamerMetaDataProvider::updateTags()
{
    QVariantMap oldTags = m_tags;
    m_tags.clear();
    bool changed = false;

    QMapIterator<QByteArray ,QVariant> i(m_session->tags());
    while (i.hasNext()) {
         i.next();
         //use gstreamer native keys for elements not in our key map
         QString key = qt_gstreamerMetaDataKeys()->value(i.key(), i.key());
         m_tags.insert(key, i.value());
         if (i.value() != oldTags.value(key)) {
             changed = true;
             emit metaDataChanged(key, i.value());
         }
    }

    if (oldTags.isEmpty() != m_tags.isEmpty()) {
        emit metaDataAvailableChanged(isMetaDataAvailable());
        changed = true;
    }

    if (changed)
        emit metaDataChanged();
}
void DirectShowMetaDataControl::setMetadataAvailable(bool available)
{
    if (m_available == available)
        return;

    m_available = available;
    emit metaDataAvailableChanged(m_available);
}
void MmRendererMetaDataReaderControl::setMetaData(const MmRendererMetaData &data)
{
    const MmRendererMetaData oldMetaData = m_metaData;
    const bool oldMetaDataAvailable = isMetaDataAvailable();

    m_metaData = data;

    bool changed = false;
    if (m_metaData.title() != oldMetaData.title()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Title, m_metaData.title());
    } else if (m_metaData.artist() != oldMetaData.artist()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Author, m_metaData.artist());
    } else if (m_metaData.comment() != oldMetaData.comment()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Comment, m_metaData.comment());
    } else if (m_metaData.genre() != oldMetaData.genre()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Genre, m_metaData.genre());
    } else if (m_metaData.year() != oldMetaData.year()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Year, m_metaData.year());
    } else if (m_metaData.mediaType() != oldMetaData.mediaType()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::MediaType, m_metaData.mediaType());
    } else if (m_metaData.duration() != oldMetaData.duration()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Duration, m_metaData.duration());
    } else if (m_metaData.audioBitRate() != oldMetaData.audioBitRate()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::AudioBitRate, m_metaData.audioBitRate());
    } else if (m_metaData.sampleRate() != oldMetaData.sampleRate()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::SampleRate, m_metaData.sampleRate());
    } else if (m_metaData.album() != oldMetaData.album()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::AlbumTitle, m_metaData.album());
    } else if (m_metaData.track() != oldMetaData.track()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::TrackNumber, m_metaData.track());
    } else if (m_metaData.resolution() != oldMetaData.resolution()) {
        changed = true;
        emit metaDataChanged(QMediaMetaData::Resolution, m_metaData.resolution());
    }

    if (changed)
        emit metaDataChanged();

    const bool metaDataAvailable = isMetaDataAvailable();
    if (metaDataAvailable != oldMetaDataAvailable)
        emit metaDataAvailableChanged(metaDataAvailable);
}
void QAndroidMetaDataReaderControl::updateData(const QVariantMap &metadata, const QUrl &url)
{
    const QMutexLocker l(&m_mtx);

    if (m_mediaContent.canonicalUrl() != url)
        return;

    const bool oldAvailable = m_available;
    m_metadata = metadata;
    m_available = !m_metadata.isEmpty();

    if (m_available != oldAvailable)
        Q_EMIT metaDataAvailableChanged(m_available);

    Q_EMIT metaDataChanged();
}
QVariant DirectShowMetaDataControl::metaData(const QString &key) const
{
    QVariant value;

#ifndef QT_NO_WMSDK
    if (m_headerInfo) {
        static const int  count = sizeof(qt_wmMetaDataKeys) / sizeof(QWMMetaDataKeyLookup);
        for (int i = 0; i < count; ++i) {
            if (qt_wmMetaDataKeys[i].key == key) {
                value = getValue(m_headerInfo, qt_wmMetaDataKeys[i].token);
                break;
            }
        }
    }  else if (m_content) {
#else
    if (m_content) {
#endif
        BSTR string = 0;

        if (key == QMediaMetaData::Author)
            m_content->get_AuthorName(&string);
        else if (key == QMediaMetaData::Title)
            m_content->get_Title(&string);
        else if (key == QMediaMetaData::ParentalRating)
            m_content->get_Rating(&string);
        else if (key == QMediaMetaData::Description)
            m_content->get_Description(&string);
        else if (key == QMediaMetaData::Copyright)
            m_content->get_Copyright(&string);

        if (string) {
            value = QString::fromUtf16(reinterpret_cast<ushort *>(string), ::SysStringLen(string));

            ::SysFreeString(string);
        }
    }
    return value;
}

QStringList DirectShowMetaDataControl::availableMetaData() const
{
    return QStringList();
}

void DirectShowMetaDataControl::updateGraph(IFilterGraph2 *graph, IBaseFilter *source)
{
    if (m_content)
        m_content->Release();

    if (!graph || graph->QueryInterface(
            IID_IAMMediaContent, reinterpret_cast<void **>(&m_content)) != S_OK) {
        m_content = 0;
    }

#ifdef QT_NO_WMSDK
    Q_UNUSED(source);
#else
    if (m_headerInfo)
        m_headerInfo->Release();

    m_headerInfo = com_cast<IWMHeaderInfo>(source, IID_IWMHeaderInfo);
#endif
    // DirectShowMediaPlayerService holds a lock at this point so defer emitting signals to a later
    // time.
    QCoreApplication::postEvent(this, new QEvent(QEvent::Type(MetaDataChanged)));
}

void DirectShowMetaDataControl::customEvent(QEvent *event)
{
    if (event->type() == QEvent::Type(MetaDataChanged)) {
        event->accept();

        emit metaDataChanged();
#ifndef QT_NO_WMSDK
        emit metaDataAvailableChanged(m_content || m_headerInfo);
#else
        emit metaDataAvailableChanged(m_content);
#endif
    } else {
        QMetaDataReaderControl::customEvent(event);
    }
}