Поделиться через


Обработка данных в кодировщике

После согласования типа ввода и выходного типа для кодировщика MFT, как описано в разделе Согласование типов мультимедиа в кодировщике, можно начать обработку примеров данных мультимедиа. Данные передаются в форме медиа-образцов (IMF образец интерфейс) и также принимаются на выходе в качестве медиа-образцов.

Перед отправкой данных кодировщику для обработки необходимо выделить образец носителя и добавить один из нескольких буферов мультимедиа, содержащих данные мультимедиа, которые необходимо закодировать. Вызовите IMFTransform::ProcessInput и передайте указатель на выделенный медиасемпл. Помимо примера носителя, для ProcessInput также требуется идентификатор входного потока. Чтобы получить идентификатор потока, вызовите IMFTransform::GetStreamIDs. Так как кодировщик предназначен только для одного и одного выходных данных, эти идентификаторы потока всегда имеют значение 0.

Чтобы получить данные из кодировщика, вызовите IMFTransform::ProcessOutput. Перед вызовом ProcessOutputнужно выяснить, выделяет ли кодировщик выходные медиа-выборки или вы должны сделать это явно. Для этого вызовите IMFTransform::GetOutputStreamInfo. Возвращает выходные сведения о носителе в структуре MFT_OUTPUT_STREAM_INFO. Если кодировщик выделяет мультимедийные образцы, он возвращает флаг MFT_OUTPUT_STREAM_PROVIDES_SAMPLES в элементе dwFlags, а элемент cbSize содержит ноль. Если кодировщик ожидает, что вы выделите выходной буфер, создайте выходной медиапример и связанный медиабуфер на основе размера, возвращаемого в cbSize. При вызове ProcessSampleпередайте указатель на новосозданный образец носителя. Во время сеанса кодирования кодировщик заполняет буферы мультимедиа, на которые указывает пример выходного носителя, с закодированными данными.

Чтобы запустить сеанс кодирования, передайте входной образец носителя кодировщику, вызвав ProcessInput. Кодировщик запускает обработку и данные и создает один или несколько примеров выходных носителей, которые должны быть извлечены ProcessOutput, если он возвращает MF_E_TRANSFORM_NEED_MORE_INPUT. Если вы вызываете ProcessInput для передачи дополнительных входных данных, пока существуют выходные данные для получения, ProcessInput завершится с ошибкой MF_E_NOTACCEPTING. Кодировщик не принимает больше входных данных, пока клиент не вызывает ProcessOutput по крайней мере один раз.

Вы должны задать точные метки времени и длительность для всех переданных входных примеров. Метки времени не требуются строго, но помогают поддерживать синхронизацию звука и видео. Если у вас нет меток времени для ваших образцов, лучше их не включать, чем использовать сомнительные значения.

Пример обработки кодировщика

В следующем примере кода показано, как вызвать IMFTransform::P rocessOutput для получения закодированного примера. Полный контекст этого примера см. в разделе Пример кода кодировщика.

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;
};

мультиплексер ASF

создание экземпляра MFT кодировщика

Кодировщики Windows Media