Festlegen der Wiedergabestoppzeit

In diesem Thema wird beschrieben, wie Sie bei Verwendung der Mediensitzung eine Stoppzeit für die Wiedergabe festlegen.

Festlegen der Stoppzeit vor Beginn der Wiedergabe

Bevor Sie eine Topologie für die Wiedergabe in die Warteschlange stellen, können Sie mithilfe des Attributs MF_TOPONODE_MEDIASTOP die Stoppzeit angeben. Legen Sie für jeden Ausgabeknoten in der Topologie den Wert von MF_TOPONODE_MEDIASTOP in Schritten von 100 Nanosekunden auf die Stoppzeit fest.

Wenn Sie dieses Attributs erst nach dem Start der Wiedergabe festlegen, hat es keine Auswirkung auf die Wiedergabe. Legen Sie daher das Attribut vor dem Aufrufen von IMFMediaSession::Start fest.

Der folgende Code zeigt, wie Sie die Stoppzeit für eine bestehende Topologie festlegen.

template <class Q>
HRESULT GetCollectionObject(IMFCollection *pCollection, DWORD dwIndex, Q **ppObject)
{
    *ppObject = NULL;   // zero output

    IUnknown *pUnk = NULL;
    HRESULT hr = pCollection->GetElement(dwIndex, &pUnk);
    if (SUCCEEDED(hr))
    {
        hr = pUnk->QueryInterface(IID_PPV_ARGS(ppObject));
        pUnk->Release();
    }
    return hr;
}

HRESULT SetMediaStop(IMFTopology *pTopology, const LONGLONG& stop)
{
    IMFCollection *pCol = NULL;
    DWORD cNodes;

    HRESULT hr = pTopology->GetSourceNodeCollection(&pCol);
    if (SUCCEEDED(hr))
    {
        hr = pCol->GetElementCount(&cNodes);
    }
    if (SUCCEEDED(hr))
    {
        for (DWORD i = 0; i < cNodes; i++)
        {
            IMFTopologyNode *pNode;
            hr = GetCollectionObject(pCol, i, &pNode);
            if (SUCCEEDED(hr))
            {
                pNode->SetUINT64(MF_TOPONODE_MEDIASTOP, stop);
            }
            pNode->Release();
        }
    }
    SafeRelease(&pCol);
    return hr;
}

Festlegen der Stoppzeit nach dem Start der Wiedergabe

Es gibt eine Möglichkeit, die Stoppzeit nach dem Starten der Wiedergabe der Mediensitzung festzulegen. Verwenden Sie hierfür die Benutzeroberfläche IMFTopologyNodeAttributeEditor.

Wichtig

Diese Benutzeroberfläche hat eine gravierende Einschränkung, denn die Stoppzeit wird als 32-Bit-Wert angegeben. Das bedeutet, dass die maximale Stoppzeit, die Sie über diese Benutzeroberfläche einstellen können, 0xFFFFFFFF ist, also etwas mehr als 7 Minuten. Diese Einschränkung resultiert aus einer falschen Strukturdefinition.

 

Führen Sie die folgenden Schritte aus, um die Stoppzeit mithilfe der Benutzeroberfläche IMFTopologyNodeAttributeEditor festzulegen.

  1. Rufen Sie MFGetService auf, um die Benutzeroberfläche IMFTopologyNodeAttributeEditor aus der Mediensitzung zu öffnen.

  2. Rufen Sie IMFTopology::GetTopologyID auf, um die ID der Wiedergabetopologie abzurufen.

  3. Rufen Sie für jeden Ausgabeknoten in der Topologie IMFTopologyNodeAttributeEditor::UpdateNodeAttributes auf. Diese Methode verwendet die Topologie-ID und einen Zeiger auf eine MFTOPONODE_ATTRIBUTE_UPDATE-Struktur. Initialisieren Sie die Struktur wie folgt.

    Member Wert
    NodeId Die Knoten-ID. Rufen Sie zum Abrufen der Knoten-ID IMFTopologyNode::GetTopoNodeID auf.
    guidAttributeKey MF_TOPONODE_MEDIASTOP
    attrType MF_ATTRIBUTE_UINT64
    u64 Die Stoppzeit, in Schritten von 100 Nanosekunden.

     

Achten Sie darauf, den Wert von attrType richtig festzulegen. Obwohl u64 ein 32-Bit-Typ ist, erfordert die Methode, dass attrType auf MF_ATTRIBUTE_UINT64 festgelegt wird.

Diese Schritte sind im folgenden Code dargestellt:

HRESULT SetMediaStopDynamic(IMFMediaSession *pSession, IMFTopology *pTopology, const LONGLONG& stop)
{
    if (stop > MAXUINT32)
    {
        return E_INVALIDARG;
    }

    IMFTopologyNodeAttributeEditor *pAttr = NULL;
    IMFCollection *pCol = NULL;
    IMFTopologyNode *pNode = NULL;

    HRESULT hr = MFGetService(pSession, MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE, IID_PPV_ARGS(&pAttr));
    if (FAILED(hr))
    {
        goto done;
    }

    TOPOID id;
    hr = pTopology->GetTopologyID(&id);
    if (FAILED(hr))
    {
        goto done;
    }

    DWORD cNodes;
    hr = pTopology->GetSourceNodeCollection(&pCol);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pCol->GetElementCount(&cNodes);
    if (FAILED(hr))
    {
        goto done;
    }

    for (DWORD i = 0; i < cNodes; i++)
    {
        IMFTopologyNode *pNode;
        hr = GetCollectionObject(pCol, i, &pNode);
        if (FAILED(hr))
        {
            goto done;
        }

        TOPOID nodeID;
        hr = pNode->GetTopoNodeID(&nodeID);
        if (FAILED(hr))
        {
            goto done;
        }

        MFTOPONODE_ATTRIBUTE_UPDATE update;
        update.NodeId = nodeID;
        update.guidAttributeKey = MF_TOPONODE_MEDIASTOP;
        update.attrType = MF_ATTRIBUTE_UINT64;
        update.u64 = (UINT32)stop;

        hr = pAttr->UpdateNodeAttributes(id, 1, &update);
        if (FAILED(hr))
        {
            goto done;
        }
        SafeRelease(&pNode);
    }

done:
    SafeRelease(&pNode);
    SafeRelease(&pCol);
    SafeRelease(&pAttr);
    return hr;
}

Audio-/Videowiedergabe