다음을 통해 공유


재생 중지 시간을 설정하는 방법

이 항목에서는 미디어 세션을 사용할 때 재생 중지 시간을 설정하는 방법을 설명합니다.

재생이 시작되기 전에 중지 시간 설정

재생을 위해 토폴로지 큐에 대기하기 전에 MF_TOPONODE_MEDIASTOP 특성을 사용하여 중지 시간을 지정할 수 있습니다. 토폴로지의 각 출력 노드에 대해 MF_TOPONODE_MEDIASTOP 값을 100나노초 단위의 중지 시간으로 설정합니다.

재생이 시작된 후 이 특성을 설정해도 효과가 없습니다. 따라서 IMFMediaSession::Start를 호출하기 전에 특성을 설정합니다.

다음 코드는 기존 토폴로지에서 중지 시간을 설정하는 방법을 보여줍니다.

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

재생이 시작된 후 중지 시간 설정

미디어 세션이 재생을 시작한 후 IMFTopologyNodeAttributeEditor 인터페이스를 사용하여 중지 시간을 설정하는 방법이 있습니다.

Important

중지 시간은 32비트 값으로 지정되므로 이 인터페이스에는 심각한 제한이 있습니다. 즉, 이 인터페이스를 사용하여 설정할 수 있는 최대 중지 시간은 0xFFFFFFFF 또는 7분 이상입니다. 이 제한은 잘못된 구조 정의 때문입니다.

 

IMFTopologyNodeAttributeEditor 인터페이스를 사용하여 중지 시간을 설정하려면 다음 단계를 수행합니다.

  1. MFGetService를 호출하여 미디어 세션에서 IMFTopologyNodeAttributeEditor 인터페이스를 가져옵니다.

  2. IMFTopology::GetTopologyID를 호출하여 재생 토폴로지의 ID를 가져옵니다.

  3. 토폴로지의 각 출력 노드에 대해 IMFTopologyNodeAttributeEditor::UpdateNodeAttributes를 호출 합니다. 이 메서드는 토폴로지 ID와 포인터를 MFTOPONODE_ATTRIBUTE_UPDATE 구조체에 사용합니다. 다음과 같이 구조를 초기화합니다.

    멤버
    NodeId 노드 ID입니다. 노드 ID를 가져오려면 IMFTopologyNode::GetTopoNodeID를 호출합니다.
    guidAttributeKey MF_TOPONODE_MEDIASTOP
    attrType MF_ATTRIBUTE_UINT64
    u64 정지 시간(100나노초 단위)입니다.

     

attrType값을 올바르게 설정해야 합니다. u64는 32비트 형식이지만 이 메서드를 사용하려면 attrType을 MF_ATTRIBUTE_UINT64 설정해야 합니다.

다음 코드는 이러한 단계를 보여줍니다.

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

오디오/비디오 재생