Come impostare l'ora di arresto della riproduzione

In questo argomento viene descritto come impostare un tempo di arresto per la riproduzione quando si usa la sessione multimediale.

Impostazione dell'ora di arresto prima dell'inizio della riproduzione

Prima di accodare una topologia per la riproduzione, è possibile specificare l'ora di arresto usando l'attributo MF_TOPONODE_MEDIASTOP . Per ogni nodo di output nella topologia, impostare il valore del MF_TOPONODE_MEDIASTOP sull'ora di arresto in unità di 100 nanosecondi.

Tieni presente che l'impostazione di questo attributo dopo l'avvio della riproduzione non ha alcun effetto. Impostare quindi l'attributo prima di chiamare IMFMediaSession::Start.

Il codice seguente illustra come impostare l'ora di arresto in una topologia esistente.

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;
}

Impostazione dell'ora di arresto dopo l'avvio della riproduzione

È possibile impostare l'ora di arresto dopo l'avvio della riproduzione della sessione multimediale usando l'interfaccia IMFTopologyNodeAttributeEditor.

Importante

Questa interfaccia presenta una limitazione grave, perché il tempo di arresto viene specificato come valore a 32 bit. Ciò significa che il tempo massimo di arresto che è possibile impostare usando questa interfaccia è 0xFFFFFFFF o più di 7 minuti. Questa limitazione è dovuta a una definizione di struttura non corretta.

 

Per impostare l'ora di arresto usando l'interfaccia IMFTopologyNodeAttributeEditor , seguire questa procedura.

  1. Chiamare MFGetService per ottenere l'interfaccia IMFTopologyNodeAttributeEditor dalla sessione multimediale.

  2. Chiamare IMFTopology::GetTopologyID per ottenere l'ID della topologia di riproduzione.

  3. Per ogni nodo di output nella topologia, chiamare IMFTopologyNodeAttributeEditor::UpdateNodeAttributes. Questo metodo accetta l'ID topologia e un puntatore a una struttura MFTOPONODE_ATTRIBUTE_UPDATE. Inizializzare la struttura come indicato di seguito.

    Membro valore
    NodeId ID del nodo. Per ottenere l'ID del nodo, chiamare IMFTopologyNode::GetTopoNodeID.
    guidAttributeKey MF_TOPONODE_MEDIASTOP
    attrType MF_ATTRIBUTE_UINT64
    u64 Tempo di arresto, in unità di 100 nanosecondi.

     

Prestare attenzione a impostare correttamente il valore di attrType . Anche se u64 è un tipo a 32 bit, il metodo richiede che attrType sia impostato su MF_ATTRIBUTE_UINT64.

Il codice seguente illustra questi passaggi.

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;
}

Riproduzione audio/video