再生停止時間を設定する方法
このトピックでは、メディア セッションを使用するときに再生の停止時間を設定する方法について説明します。
再生開始前の停止時間の設定
再生のためにトポロジをキューに登録する前に、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 インターフェイスを取得してください。
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;
}
関連トピック