재생 중지 시간을 설정하는 방법
이 항목에서는 미디어 세션을 사용할 때 재생 중지 시간을 설정하는 방법을 설명합니다.
재생이 시작되기 전에 중지 시간 설정
재생을 위해 토폴로지 큐에 대기하기 전에 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 인터페이스를 사용하여 중지 시간을 설정하려면 다음 단계를 수행합니다.
MFGetService를 호출하여 미디어 세션에서 IMFTopologyNodeAttributeEditor 인터페이스를 가져옵니다.
IMFTopology::GetTopologyID를 호출하여 재생 토폴로지의 ID를 가져옵니다.
토폴로지의 각 출력 노드에 대해 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;
}
관련 항목