Настройка времени остановки воспроизведения
В этом разделе описывается, как задать время остановки воспроизведения при использовании сеанса мультимедиа.
Установка времени остановки перед началом воспроизведения
Перед очередью топологии для воспроизведения можно указать время остановки с помощью атрибута 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.
Важно!
Этот интерфейс имеет серьезное ограничение, так как время остановки указывается как 32-разрядное значение. Это означает, что максимальное время остановки, которое можно задать с помощью этого интерфейса, 0xFFFFFFFF или чуть более 7 минут. Это ограничение связано с неправильным определением структуры.
Чтобы задать время остановки с помощью интерфейса IMFTopologyNodeAttributeEditor , выполните следующие действия.
Вызовите MFGetService, чтобы получить интерфейс IMFTopologyNodeAttributeEditor из сеанса мультимедиа.
Вызовите МВФTopology::GetTopologyID , чтобы получить идентификатор топологии воспроизведения.
Для каждого выходного узла в топологии вызовите МВФTopologyNodeAttributeEditor::UpdateNodeAttributes. Этот метод принимает идентификатор топологии и указатель на структуру MFTOPONODE_ATTRIBUTE_UPDATE . Инициализировать структуру следующим образом.
Элемент Значение NodeId Идентификатор узла. Чтобы получить идентификатор узла, вызовите 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;
}
См. также