Traitement des données dans l’encodeur
Une fois que vous avez négocié le type d’entrée et le type de sortie pour l’encodeur MFT, comme décrit dans Négociation du type de média sur l’encodeur, vous pouvez commencer à traiter des exemples de données multimédias. Les données sont transmises sous forme d’échantillons multimédias (interface IMFSample ) et également reçues de la sortie sous forme d’échantillons multimédias.
Avant d’envoyer des données à l’encodeur pour traitement, vous devez allouer un exemple de média et ajouter l’un des autres tampons multimédias contenant des données multimédias qui doivent être encodées. Appelez IMFTransform::P rocessInput et passez un pointeur vers l’exemple multimédia alloué. En plus de l’exemple multimédia, ProcessInput a également besoin de l’identificateur de flux d’entrée. Pour obtenir l’identificateur de flux, appelez IMFTransform::GetStreamIDs. Étant donné qu’un encodeur est conçu pour n’avoir qu’une seule sortie, ces identificateurs de flux ont toujours la valeur 0.
Pour obtenir des données à partir de l’encodeur, appelez IMFTransform::P rocessOutput. Avant d’appeler ProcessOutput, vous devez savoir si l’encodeur alloue les exemples de média de sortie ou si vous devez le faire explicitement. Pour ce faire, appelez IMFTransform::GetOutputStreamInfo. Cela retourne des informations d’exemple de média de sortie dans la structure MFT_OUTPUT_STREAM_INFO . Si l’encodeur alloue des exemples multimédias, il retourne l’indicateur MFT_OUTPUT_STREAM_PROVIDES_SAMPLES dans le membre dwFlags et le membre cbSize contient zéro. Si l’encodeur s’attend à ce que vous allouiez la mémoire tampon de sortie, créez l’exemple de média de sortie et la mémoire tampon multimédia associée en fonction de la taille retournée dans cbSize. Lorsque vous appelez ProcessSample, passez un pointeur vers l’exemple multimédia nouvellement créé. Pendant la session d’encodage, l’encodeur remplit les mémoires tampons multimédias, pointées par l’exemple de média de sortie, avec les données encodées.
Pour démarrer la session d’encodage, passez l’exemple de média d’entrée à l’encodeur en appelant ProcessInput. L’encodeur démarre le traitement et les données et produit un ou plusieurs exemples de supports de sortie qui doivent être récupérés par ProcessOutput tant qu’il retourne MF_E_TRANSFORM_NEED_MORE_INPUT. Si vous appelez ProcessInput pour passer plus d’entrée tant qu’il y a des données de sortie à récupérer, ProcessInput échoue avec MF_E_NOTACCEPTING. L’encodeur n’accepte plus d’entrée tant que le client n’appelle pas ProcessOutput au moins une fois.
Vous devez définir des horodatages et des durées précis pour tous les exemples d’entrée passés. Les horodatages ne sont pas strictement requis, mais permettent de maintenir la synchronisation audio/vidéo. Si vous n’avez pas les horodatages de vos échantillons, il est préférable de les laisser de côté plutôt que d’utiliser des valeurs incertaines.
Exemple de traitement de l’encodeur
L’exemple de code suivant montre comment appeler IMFTransform::P rocessOutput pour obtenir un exemple encodé. Pour obtenir le contexte complet de cet exemple, consultez Exemple de code d’encodeur.
HRESULT CWmaEncoder::ProcessOutput(IMFSample **ppSample)
{
if (m_pMFT == NULL)
{
return MF_E_NOT_INITIALIZED;
}
*ppSample = NULL;
IMFMediaBuffer* pBufferOut = NULL;
IMFSample* pSampleOut = NULL;
DWORD dwStatus;
MFT_OUTPUT_STREAM_INFO mftStreamInfo = { 0 };
MFT_OUTPUT_DATA_BUFFER mftOutputData = { 0 };
HRESULT hr = m_pMFT->GetOutputStreamInfo(m_dwOutputID, &mftStreamInfo);
if (FAILED(hr))
{
goto done;
}
//create a buffer for the output sample
hr = MFCreateMemoryBuffer(mftStreamInfo.cbSize, &pBufferOut);
if (FAILED(hr))
{
goto done;
}
//Create the output sample
hr = MFCreateSample(&pSampleOut);
if (FAILED(hr))
{
goto done;
}
//Add the output buffer
hr = pSampleOut->AddBuffer(pBufferOut);
if (FAILED(hr))
{
goto done;
}
//Set the output sample
mftOutputData.pSample = pSampleOut;
//Set the output id
mftOutputData.dwStreamID = m_dwOutputID;
//Generate the output sample
hr = m_pMFT->ProcessOutput(0, 1, &mftOutputData, &dwStatus);
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
{
hr = S_OK;
goto done;
}
// TODO: Handle MF_E_TRANSFORM_STREAM_CHANGE
if (FAILED(hr))
{
goto done;
}
*ppSample = pSampleOut;
(*ppSample)->AddRef();
done:
SafeRelease(&pBufferOut);
SafeRelease(&pSampleOut);
return hr;
};
Rubriques connexes