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 die Stoppzeit mithilfe des MF _ TOPONODE _ MEDIASTOP-Attributs angeben. Legen Sie für jeden Ausgabeknoten in der Topologie den Wert von MF TOPONODE MEDIASTOP auf die Stoppzeit in Einheiten von _ _ 100 Nanosekunden fest.

Beachten Sie, dass das Festlegen dieses Attributs nach dem Start der Wiedergabe keine Auswirkungen hat. Legen Sie daher das -Attribut fest, bevor SIE DIEMEDIASession::Start aufrufen.

Der folgende Code zeigt, wie die Stoppzeit für eine vorhandene Topologie festgelegt wird.

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 Starten der Wiedergabe

Es gibt eine Möglichkeit, die Stoppzeit nach dem Start der Wiedergabe der Mediensitzung mithilfe der BENUTZEROBERFLÄCHENodeAttributeEditor-Schnittstelle festzuhalten.

Wichtig

Diese Schnittstelle hat eine schwerwiegende Einschränkung, da die Stoppzeit als 32-Bit-Wert angegeben wird. Das bedeutet, dass die maximale Stoppzeit, die Sie mit dieser Schnittstelle festlegen können, 0xFFFFFFFF oder etwas mehr als 7 Minuten beträgt. Diese Einschränkung ist auf eine falsche Strukturdefinition zurück.

Führen Sie die folgenden Schritte aus, um die Stoppzeit mithilfe der SCHNITTSTELLETOPOLOGYNodeAttributeEditor festzuhalten.

  1. Rufen Sie MFGetService auf, um die SCHNITTSTELLETOPOLOGYNodeAttributeEditor aus der Mediensitzung zu erhalten.

  2. Rufen Sie DIE TOPOLOGIE::GetTopologyID auf, um die ID der Wiedergabetopologie zu erhalten.

  3. Rufen Sie für jeden Ausgabeknoten in der Topologie DEN TYPTOPOLOGYNodeAttributeEditor::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. Um die Knoten-ID zu erhalten, rufen Sie DIE TOPOLOGIENode::GetTopoNodeID auf.
    guidAttributeKey MF _ TOPONODE _ MEDIASTOP
    attrType _MF-ATTRIBUT _ UINT64
    u64 Die Stoppzeit in Einheiten von 100 Nanosekunden.

Achten Sie darauf, dass Sie den Wert von attrType richtig festlegen. Obwohl u64 ein 32-Bit-Typ ist, erfordert die -Methode, dass attrType auf MF ATTRIBUTE _ _ UINT64 festgelegt ist.

Der folgende Code zeigt diese Schritte.

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