Exemple #1
0
 foreach (QObject *object, objects) {
     MediaNode *sourceNode = qobject_cast<MediaNode *>(object);
     MediaObject *media = sourceNode->root();
     if (media) {
         media->saveState();
         return true;
     }
 }
Exemple #2
0
void MMF::MediaNode::updateMediaObject()
{
    QList<MediaNode *> nodes;
    MediaObject *mediaObject = 0;

    // Traverse the graph, collecting a list of nodes, and locating
    // the MediaObject node, if present
    visit(nodes, mediaObject);

    MediaNode *node = 0;
    foreach(node, nodes)
        node->setMediaObject(mediaObject);
}
/**
 * Propagates an event down the graph
 * sender is responsible for deleting the event
 */
void MediaNode::notify(const MediaNodeEvent *event)
{
    Q_ASSERT(event);
    mediaNodeEvent(event);
    for (int i=0; i<m_audioSinkList.size(); ++i) {
        MediaNode *node = qobject_cast<MediaNode*>(m_audioSinkList[i]);
        node->notify(event);
    }

    for (int i=0; i<m_videoSinkList.size(); ++i) {
        MediaNode *node = qobject_cast<MediaNode*>(m_videoSinkList[i]);
        node->notify(event);
    }
}
Exemple #4
0
void MMF::MediaNode::visit(QList<MediaNode *>& visited, MediaObject*& mediaObject)
{
    if (isMediaObject()) {
        // There can never be more than one MediaObject per graph, due to the
        // mediaObjectMisMatch test in connectOutput().
        Q_ASSERT_X(!mediaObject, Q_FUNC_INFO, "MediaObject already found");
        mediaObject = static_cast<MediaObject *>(this);
    }

    visited += this;

    if (m_input && !visited.contains(m_input))
        m_input->visit(visited, mediaObject);

    MediaNode *output = 0;
    foreach (output, m_outputs)
        if (!visited.contains(output))
            output->visit(visited, mediaObject);
}
bool MediaNode::connectNode(QObject *obj)
{
    MediaNode *sink = qobject_cast<MediaNode*>(obj);

    bool success = false;

    if (sink) {

        if (!sink->isValid()) {
            m_backend->logMessage(QString("Trying to link to an invalid node (%0)").arg(sink->name()), Backend::Warning);
            return false;
        }

        if (sink->root()) {
            m_backend->logMessage("Trying to link a node that is already linked to a different mediasource ", Backend::Warning);
            return false;
        }

        if ((m_description & AudioSource) && (sink->m_description & AudioSink)) {
            m_audioSinkList << obj;
            MediaNodeEvent event(MediaNodeEvent::AudioSinkAdded, sink);
            root()->mediaNodeEvent(&event);
            success = true;
        }

        if ((m_description & VideoSource) && (sink->m_description & VideoSink)) {
            m_videoSinkList << obj;
            MediaNodeEvent event(MediaNodeEvent::VideoSinkAdded, sink);
            root()->mediaNodeEvent(&event);
            success = true;
        }

        // If we have a root source, and we are connected
        // try to link the gstreamer elements
        if (success && root()) {
            MediaNodeEvent mediaObjectConnected(MediaNodeEvent::MediaObjectConnected, root());
            notify(&mediaObjectConnected);
            root()->buildGraph();
        }
    }
    return success;
}
/**
 *  Disconnects children recursively
 */
bool MediaNode::breakGraph()
{
    for (int i=0; i<m_audioSinkList.size(); ++i) {
        MediaNode *node = qobject_cast<MediaNode*>(m_audioSinkList[i]);
        if (!node || !node->breakGraph())
            return false;
        node->setRoot(0);
    }

    for (int i=0; i <m_videoSinkList.size(); ++i) {
        MediaNode *node = qobject_cast<MediaNode*>(m_videoSinkList[i]);
        if (!node || !node->breakGraph())
            return false;
        node->setRoot(0);
    }
    unlink();
    return true;
}
bool MediaNode::disconnectNode(QObject *obj)
{
    MediaNode *sink = qobject_cast<MediaNode*>(obj);
    if (root()) {
        // Disconnecting elements while playing or paused seems to cause
        // potential deadlock. Hence we force the pipeline into ready state
        // before any nodes are disconnected.
        gst_element_set_state(root()->pipeline(), GST_STATE_READY);    

        Q_ASSERT(sink->root()); //sink has to have a root since it is onnected

        if (sink->description() & (AudioSink)) {
            GstPad *sinkPad = gst_element_get_pad(sink->audioElement(), "sink");
            // Release requested src pad from tee
            GstPad *requestedPad = gst_pad_get_peer(sinkPad);
            if (requestedPad) {
                gst_element_release_request_pad(m_audioTee, requestedPad);
                gst_object_unref(requestedPad);
            }
            if (GST_ELEMENT_PARENT(sink->audioElement()))
                gst_bin_remove(GST_BIN(root()->audioGraph()), sink->audioElement());
            gst_object_unref(sinkPad);
        }

        if (sink->description() & (VideoSink)) {
            GstPad *sinkPad = gst_element_get_pad(sink->videoElement(), "sink");
            // Release requested src pad from tee
            GstPad *requestedPad = gst_pad_get_peer(sinkPad);
            if (requestedPad) {
                gst_element_release_request_pad(m_videoTee, requestedPad);
                gst_object_unref(requestedPad);
            }
            if (GST_ELEMENT_PARENT(sink->videoElement()))
                gst_bin_remove(GST_BIN(root()->videoGraph()), sink->videoElement());
            gst_object_unref(sinkPad);
        }

        sink->breakGraph();
        sink->setRoot(0);
    }

    m_videoSinkList.removeAll(obj);
    m_audioSinkList.removeAll(obj);

    if (sink->m_description & AudioSink) {
        // Remove sink from graph
        MediaNodeEvent event(MediaNodeEvent::AudioSinkRemoved, sink);
        mediaNodeEvent(&event);
        return true;
    }

    if ((m_description & VideoSource) && (sink->m_description & VideoSink)) {
        // Remove sink from graph
        MediaNodeEvent event(MediaNodeEvent::VideoSinkRemoved, sink);
        mediaNodeEvent(&event);
        return true;
    }

    return false;
}