Comment définir l’heure d’arrêt de lecture
Cette rubrique explique comment définir une heure d’arrêt pour la lecture lors de l’utilisation de la session multimédia.
Définition de l’heure d’arrêt avant le début de la lecture
Avant de mettre en file d’attente une topologie pour la lecture, vous pouvez spécifier l’heure d’arrêt à l’aide de l’attribut MF_TOPONODE_MEDIASTOP. Pour chaque nœud de sortie de la topologie, définissez la valeur de l’attribut MF_TOPONODE_MEDIASTOP sur l’heure d’arrêt en unités de 100 nanosecondes.
Notez que la définition de cet attribut après le démarrage de la lecture n’a aucun effet. Par conséquent, définissez l’attribut avant d’appeler IMFMediaSession::Start.
Le code suivant montre comment définir l’heure d’arrêt sur une topologie existante.
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;
}
Définition de l’heure d’arrêt après le démarrage de la lecture
Il existe un moyen de définir l’heure d’arrêt après le démarrage de la lecture de la session multimédia, à l’aide de l’interface IMFTopologyNodeAttributeEditor.
Important
Cette interface est sujette à des limites, car le temps d’arrêt est spécifié sous la forme d’une valeur 32 bits. Cela signifie que la durée maximale d’arrêt que vous pouvez définir à l’aide de cette interface est 0xFFFFFFFF, ou juste plus de 7 minutes. Cette limitation est due à une définition de structure incorrecte.
Pour définir l’heure d’arrêt à l’aide de l’interface IMFTopologyNodeAttributeEditor, procédez comme suit.
Appelez MFGetService pour obtenir l’interface IMFTopologyNodeAttributeEditor à partir de la session multimédia.
Appelez IMFTopology::GetTopologyID pour obtenir l’ID de la topologie de lecture.
Pour chaque nœud de sortie de la topologie, appelez IMFTopologyNodeAttributeEditor::UpdateNodeAttributes. Cette méthode prend l’ID de topologie et un pointeur vers une structure MFTOPONODE_ATTRIBUTE_UPDATE. Initialisez la structure comme suit.
Membre Valeur NodeId ID du nœud. Pour obtenir l’ID du nœud, appelez IMFTopologyNode::GetTopoNodeID. guidAttributeKey MF_TOPONODE_MEDIASTOP attrType MF_ATTRIBUTE_UINT64 u64 Temps d’arrêt, en unités de 100 nanosecondes.
Veillez à définir correctement la valeur de l’attribut attrType. Même si u64 est un type 32 bits, la méthode exige que attrType soit défini sur MF_ATTRIBUTE_UINT64.
Cette procédure est illustrée par le code suivant :
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;
}
Rubriques connexes