Freigeben über


Verarbeiten von Daten im Encoder

Nachdem Sie den Eingabetyp und den Ausgabetyp für den Encoder MFT ausgehandelt haben, wie unter Medientypaushandlung für den Encoder beschrieben, können Sie mit der Verarbeitung von Mediendatenbeispielen beginnen. Die Daten werden in Form von Medienbeispielen (IMFSample-Schnittstelle ) übergeben und auch aus der Ausgabe als Medienbeispiele empfangen.

Bevor Sie Daten zur Verarbeitung an den Encoder senden, müssen Sie ein Medienbeispiel zuordnen und einen von weiteren Medienpuffern hinzufügen, die Mediendaten enthalten, die codiert werden müssen. Rufen Sie IMFTransform::P rocessInput auf, und übergeben Sie einen Zeiger auf das zugeordnete Medienbeispiel. Zusätzlich zum Medienbeispiel benötigt ProcessInput auch den Eingabedatenstrombezeichner. Um den Streambezeichner abzurufen, rufen Sie IMFTransform::GetStreamIDs auf. Da ein Encoder nur über eine ausgabe und eine Ausgabe ausgelegt ist, haben diese Streambezeichner immer den Wert 0.

Um Daten vom Encoder abzurufen, rufen Sie IMFTransform::P rocessOutput auf. Bevor Sie ProcessOutput aufrufen, müssen Sie herausfinden, ob der Encoder die Ausgabemedienbeispiele zuordnet, oder sie müssen dies explizit tun. Rufen Sie dazu IMFTransform::GetOutputStreamInfo auf. Dadurch werden Beispielinformationen für Ausgabemedien in der MFT_OUTPUT_STREAM_INFO-Struktur zurückgegeben. Wenn der Encoder Medienbeispiele zuordnet, gibt er das flag MFT_OUTPUT_STREAM_PROVIDES_SAMPLES im dwFlags-Element zurück, und das cbSize-Element enthält null. Wenn der Encoder erwartet, dass Sie den Ausgabepuffer zuordnen, erstellen Sie das Ausgabemedienbeispiel und den zugeordneten Medienpuffer basierend auf der in cbSize zurückgegebenen Größe. Wenn Sie ProcessSample aufrufen, übergeben Sie einen Zeiger auf das neu erstellte Medienbeispiel. Während der Codierungssitzung füllt der Encoder die Medienpuffer, auf die das Ausgabemedienbeispiel verweist, mit den codierten Daten auf.

Um die Codierungssitzung zu starten, übergeben Sie das Eingabemedienbeispiel an den Encoder, indem Sie ProcessInput aufrufen. Der Encoder beginnt mit der Verarbeitung der Daten und erzeugt ein oder mehrere Ausgabemedienbeispiele, die von ProcessOutput abgerufen werden müssen, solange MF_E_TRANSFORM_NEED_MORE_INPUT zurückgegeben wird. Wenn Sie ProcessInput aufrufen, um mehr Eingaben zu übergeben, solange Ausgabedaten abgerufen werden sollen, schlägt ProcessInput mit MF_E_NOTACCEPTING fehl. Der Encoder akzeptiert keine weiteren Eingaben, bis der Client ProcessOutput mindestens einmal aufruft.

Sie sollten genaue Zeitstempel und Dauer für alle übergebenen Eingabebeispiele festlegen. Zeitstempel sind nicht unbedingt erforderlich, tragen jedoch zur Aufrechterhaltung der Audio-/Videosynchronisierung bei. Wenn Sie nicht über die Zeitstempel für Ihre Stichproben verfügen, ist es besser, sie wegzulassen, als unsichere Werte zu verwenden.

Beispiel für die Encoderverarbeitung

Der folgende Beispielcode zeigt, wie SIE IMFTransform::P rocessOutput aufrufen, um ein codiertes Beispiel abzurufen. Den vollständigen Kontext dieses Beispiels finden Sie unter Encoder-Beispielcode.

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-Multiplexer

Instanziieren eines Encoders MFT

Windows Media Encoder