Share via


Verwenden der Sequencer-Quelle

In diesem Thema wird die Verwendung der Sequencer-Quelle beschrieben. Es enthält die folgenden Abschnitte:

Eine allgemeine Übersicht über die Sequencer-Quelle finden Sie unter Informationen zur Sequencer-Quelle.

Überblick

Die Sequencer-Quelle macht die folgenden Schnittstellen verfügbar.

Schnittstelle Beschreibung
IMFMediaSource Macht generische Medienquellenfunktionen verfügbar.
IMFSequencerSource Ermöglicht der Anwendung das Hinzufügen oder Entfernen von Topologien.
IMFMediaSourceTopologyProvider Ruft die nächste Topologie ab, die in der Mediensitzung in die Warteschlange gestellt wird.
IMFMediaSourcePresentationProvider Wird von der Mediensitzung zum Beenden von Segmenten verwendet. Anwendungen verwenden diese Schnittstelle nicht.
IMFGetService Fragt die Sequencer-Quelle nach Dienstschnittstellen ab.

 

Führen Sie die folgenden Schritte aus, um eine Abfolge von Medienquellen wiederzugeben:

  1. Rufen Sie zum Erstellen der Sequencer-Quelle die MFCreateSequencerSource-Funktion auf.
  2. Erstellen Sie für jedes Segment eine Wiedergabetopologie, wie in Erstellen von Wiedergabetopologien beschrieben. Rufen Sie IMFSequencerSource::AppendTopology auf, um der Präsentation die Topologie hinzuzufügen.
  3. Rufen Sie vor dem Starten der Wiedergabe IMFMediaSource::CreatePresentationDescriptor für die Sequencer-Quelle auf. Diese Methode gibt einen Zeiger auf einen Präsentationsdeskriptor für das erste Segment zurück. Rufen Sie QueryInterface auf der Sequencer-Quelle für die IMFMediaSourceTopologyProvider-Schnittstelle auf, um die diesem Segment zugeordnete Topologie abzurufen. Übergeben Sie den Präsentationsdeskriptor an die IMFMediaSourceTopologyProvider::GetMediaSourceTopology-Methode. Diese Methode gibt einen Zeiger auf die Topologie zurück.
  4. Übergeben Sie die Topologie für das erste Segment an die Mediensitzung, indem Sie die IMFMediaSession::SetTopology-Methode der Mediensitzung aufrufen.
  5. Starten Sie die Wiedergabe, indem Sie IMFMediaSession::Start aufrufen.
  6. Wenn die Sequencer-Quelle bereit ist, das nächste Segment vorlaufen zu lassen, sendet sie ein MENewPresentation-Ereignis, dessen Ereignisdaten ein IMFPresentationDescriptor-Schnittstellenzeiger sind. Rufen Sie die Topologie für das Segment erneut ab, indem Sie GetMediaSourceTopology für die Sequencer-Quelle aufrufen und die Topologie für die Mediensitzung durch Aufrufen von SetTopology festlegen. Es ist nicht erforderlich, die Medienquelle erneut zu starten; die Wiedergabe erfolgt automatisch bis zum nächsten Segment.
  7. Bevor die Anwendung beendet wird, beenden Sie die Sequencer-Quelle durch Aufrufen von IMFMediaSource::Shutdown.

Der folgende Code zeigt, wie die Topologie abgerufen und in der Mediensitzung festgelegt wird:

// Queues the next topology on the session.

HRESULT CPlaylist::QueueNextSegment(IMFPresentationDescriptor *pPD)
{
    IMFMediaSourceTopologyProvider *pTopoProvider = NULL;
    IMFTopology *pTopology = NULL;

    //Get the topology for the presentation descriptor
    HRESULT hr = m_pSequencerSource->QueryInterface(IID_PPV_ARGS(&pTopoProvider));
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pTopoProvider->GetMediaSourceTopology(pPD, &pTopology);
    if (FAILED(hr))
    {
        goto done;
    }

    //Set the topology on the media session
    m_pSession->SetTopology(NULL, pTopology);

done:
    SafeRelease(&pTopoProvider);
    SafeRelease(&pTopology);
    return hr;
}

Ein vollständiges Codebeispiel finden Sie unter Codebeispiel für Sequencer-Quelle.

Hinzufügen von Topologien

Die Sequencer-Quelle enthält zwei Topologielisten: die Eingabeliste und die Vorlaufliste.

Die Eingabeliste ist eine Sammlung von Topologien, die Wiedergabelistensegmenten entsprechen, in der Reihenfolge, in der sie von der Anwendung durch Aufrufen von IMFSequencerSource::AppendTopology hinzugefügt wurden. Diese Methode weist jeder Topologie einen eindeutigen Segmentbezeichner des Typs MFSequencerElementId zu. Der Segmentbezeichner wird als Attribut für alle Quelltopologieknoten festgelegt. Eine Anwendung kann den Segmentbezeichner über einen Quellknoten mithilfe des Attributs MF_TOPONODE_SEQUENCE_ELEMENTID abrufen. Die Eingabeliste kann doppelte Topologien aufweisen, wenn die Anwendung AppendTopology in derselben Topologie mehrmals aufgerufen wird. Sie werden jedoch durch ihre eindeutigen Segmentbezeichner identifiziert.

Die Vorlaufliste ist eine Sammlung von Eingabelistentopologien, die zur Vorbereitung auf die Wiedergabe initialisiert wurden. Dadurch kann die Mediensitzung nahtlos zur nächsten Topologie wechseln, wenn die aktive Topologie endet. Die Anwendung kann Topologien nicht direkt aus der Vorlaufliste hinzufügen oder entfernen. Sie wird von der Sequencer-Quelle generiert, wenn eine Topologie aus der Eingabeliste für die Wiedergabe ausgewählt wird. Dies bewirkt, dass die Sequenecr-Quelle die nächste Topologie aus der Eingabeliste zur Vorlaufliste hinzufügt. Anschließend löst die Sequencer-Qquelle asynchron das MENewPresentation-Ereignis aus und übergibt den Präsentationsdeskriptor für die Vorlauftopologie als Ereignisdaten. Die Anwendung muss auf dieses Ereignis mithilfe der IMFMediaEventGenerator-Schnittstelle der Mediensitzung lauschen und die Vorlauftopologie in der Mediensitzung in die Warteschlange stellen, indem IMFMediaSession::SetTopology aufgerufen wird. Dies muss erfolgen, bevor die Mediensitzung die Wiedergabe der aktiven Topologie abgeschlossen hat. SetTopology informiert die Mediensitzung über die nächste Topologie, dass sie wiedergegeben werden muss, nachdem die Wiedergabe der aktiven Topologie beendet wurde. Um einen nahtlosen Übergang sicherzustellen, muss die Anwendung SetTopology aufrufen, bevor die Mediensitzung die Wiedergabe der vorherigen Topologie abgeschlossen hat. Andernfalls gibt es eine Lücke zwischen den Segmenten.

Das MENewPresentation-Ereignis wird ausgelöst, solange nach der aktiven Topologie eine Topologie vorhanden ist. Wenn die Eingabeliste also nur eine Topologie enthält oder die aktive Topologie die letzte in der Eingabeliste ist, wird dieses Ereignis nicht ausgelöst.

Die Vorlaufliste wird mit der Eingabeliste synchronisiert und jedes Mal aktualisiert, wenn eine Topologie der Eingabeliste hinzugefügt oder daraus gelöscht wird.

Löschen von Topologien

Um eine Topologie aus der Sequencer-Quelle zu entfernen, muss eine Anwendung die IMFSequencerSource::D eleteTopology-Methode aufrufen und den Segmentbezeichner angeben.

Vor dem Aufrufen von DeleteTopology muss die Anwendung sicherstellen, dass die Mediensitzung nicht die Topologie verwendet, die die Anwendung löschen möchte. Dazu müssen beide der folgenden Aktionen ausgeführt werden, bevor die Anwendung DeleteTopology aufruft:

  • Das MESessionTopologyStatus-Ereignis mit MF_TOPOSTATUS_ENDED wird für die Topologie empfangen, um sicherzustellen, dass die Mediensitzung die Wiedergabe abgeschlossen hat.

  • MESessionTopologyStatus mit MF_TOPOSTATUS_STARTED_SOURCE wird für die nächste Topologie empfangen, um sicherzustellen, dass die Mediensitzung mit der Wiedergabe der nächsten Topologie begonnen hat. Das MESessionEnded-Ereignis wird empfangen, um sicherzustellen, dass die Mediensitzung mit der letzten Topologie in der Sequencer-Quelle erfolgt.

Wenn das gelöschte Segment die aktive Topologie ist, wird die Wiedergabe beendet, und die Sequencer-Quelle löst das MEEndOfPresentationSegment-Ereignis aus. Wenn die aktive Topologie auch die letzte Topologie ist, wird das MEEndOfPresentation-Ereignis ausgelöst.

Springen zu einem Segment

Eine Anwendung kann zu einem bestimmten Segment in der Sequenz springen, indem die Mediensitzung mit einem Segmentversatz wie folgt gestartet wird:

  1. Rufen Sie die MFCreateSequencerSegmentOffset-Funktion auf, um den Segmentoffset zu erstellen. Geben Sie den Bezeichner des Segments im dwId-Parameter an. (Der Bezeichner wurde von der IMFSequencerSource::AppendTopology-Methode zurückgegeben, wenn die Topologie zum ersten Mal zur Sequencer-Quelle hinzugefügt wurde.) Der hnsOffset-Parameter gibt einen Zeitversatz relativ zum Anfang des Abschnitts an. Die Wiedergabe startet zu diesem Zeitpunkt. Übergeben Sie für den pvarSegmentOffset-Parameter die Adresse eines leeren PROPVARIANT. Wenn die Funktion zurückgegeben wird, enthält dieser PROPVARIANT den Segmentoffset.

  2. Rufen Sie die IMFMediaSession::Start-Methode für die Mediensitzung auf. Verwenden Sie für den pguidTimeFormat-Parameter den GUID-Wert MF_TIME_FORMAT_SEGMENT_OFFSET. Dieser Wert gibt die Suche nach Segmentversatz an. Übergeben Sie für den pvarStartPosition-Parameter die Adresse des im vorherigen Schritt erstellten PROPVARIANT.

Das folgende Codebeispiel zeigt, wie Sie zum Anfang eines angegebenen Abschnitts in einer Sequenz springen.

// Skips to the specified segment in the sequencer source

HRESULT CPlaylist::SkipTo(DWORD index)
{
    if (index >= m_count)
    {
        return E_INVALIDARG;
    }

    MFSequencerElementId ID = m_segments[index].SegmentID;

    PROPVARIANT var;

    HRESULT hr = MFCreateSequencerSegmentOffset(ID, NULL, &var);
    
    if (SUCCEEDED(hr))
    {
        hr = m_pSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
        PropVariantClear(&var);
    }
    return hr;
}

Wenn die Anwendung segmentübergreifend sucht, empfängt die Anwendung mehrere Ereignisse, da die Sequencer-Quelle das aktuelle Segment beendet und sich darauf vorbereitet, das neue Segment wiederzugeben. Da diese Ereignisse asynchron empfangen werden, ist es schwierig, die genaue Abfolge von Ereignissen vorherzusagen. Die Ereignisse sind wie folgt:

Weitere Details zu den Ereignissen, die von der Sequencer-Quelle gesendet werden, finden Sie im Thema Ereignisse der Sequencer-Quelle.

Erstellen einer Wiedergabeliste

Sequencer-Quelle