Generieren neuer ASF-Datenpakete

Der ASF-Multiplexer ist eine WMContainer-Schichtkomponente, die mit dem ASF-Datenobjekt funktioniert und einer Anwendung die Möglichkeit gibt, ASF-Datenpakete für einen Stream zu generieren, die den im ContentInfo-Objekt definierten Anforderungen entsprechen.

Der Multiplexer verfügt über eine Eingabe und eine Ausgabe. Es empfängt ein Datenstrombeispiel, das digitale Mediendaten enthält, und erzeugt ein oder mehrere Datenpakete, die in einen ASF-Container geschrieben werden können.

Die folgende Liste fasst den Prozess zum Generieren von ASF-Datenpaketen zusammen:

  1. Übergeben Sie Eingabedaten an den Multiplexer in IMFASFMultiplexer::P rocessSample.
  2. Sammeln Sie die Datenpakete, indem Sie IMFASFMultiplexer::GetNextPacket in einer Schleife aufrufen, bis alle vollständigen Pakete abgerufen wurden.
  3. Nachdem die Eingabedaten in vollständige Pakete konvertiert wurden, können einige ausstehende Daten im Multiplexer vorhanden sein, die nicht von GetNextPacket abgerufen wurden. Rufen Sie IMFASFMultiplexer::Flush auf, um die ausstehenden Beispiele zu packen und sie aus dem Multiplexer zu sammeln, indem Sie GetNextPacket erneut aufrufen.
  4. Aktualisieren Sie die zugeordneten ASF-Headerobjekte, indem Sie IMFASFMultiplexer::End aufrufen, um änderungen widerzuspiegeln, die der Multiplexer während der Datenpaketgenerierung vorgenommen hat.

Das folgende Diagramm veranschaulicht die Datenpaketgenerierung für eine ASF-Datei über den Multiplexer.

Diagramm der Datenpaketgenerierung für eine ASF-Datei

Erstellen von ASF-Datenpaketen

Nachdem Sie den Multiplexer wie unter Erstellen des Multiplexer-Objekts beschrieben erstellt und initialisiert haben, rufen Sie IMFASFMultiplexer::P rocessSample auf, um Eingabedaten zur Verarbeitung in Datenpakete an den Multiplexer zu übergeben. Die angegebene Eingabe muss sich in einem Medienbeispiel (IMFSample-Schnittstelle ) befinden, das über einen oder mehrere Medienpuffer (IMFMediaBuffer-Schnittstelle ) verfügen kann, die die Daten für einen Stream enthalten. Im Fall der ASF-zu-ASF-Transcodierung kann das Eingabemedienbeispiel aus dem Splitter generiert werden, der paketierte Datenstrombeispiele erstellt. Weitere Informationen finden Sie unter ASF-Splitter.

Stellen Sie vor dem Aufrufen von ProcessSample sicher, dass der Zeitstempel des Eingabemedienbeispiels eine gültige Präsentationszeit ist. Andernfalls schlägt ProcessSample fehl und gibt den MF_E_NO_SAMPLE_TIMESTAMP Code zurück.

Der Multiplexer kann Eingaben als komprimierte oder unkomprimierte Medienbeispiele über ProcessSample akzeptieren. Der Multiplexer weist diesen Beispielen abhängig von der Bandbreitennutzung des Datenstroms Sendezeiten zu. Während dieses Prozesses überprüft der Multiplexer die undichten Bucketparameter (Bitrate und Pufferfensterauslastung) und kann Stichproben ablehnen, die diesen Werten nicht entsprechen. Beim Beispiel für Eingabemedien kann die Bandbreitenüberprüfung aus einem der folgenden Gründe fehlschlagen:

  • Wenn das Eingabemedienbeispiel verspätet eingetroffen ist, weil die zuletzt zugewiesene Sendezeit größer als der Zeitstempel für dieses Medienbeispiel ist. ProcessSample schlägt fehl und gibt den MF_E_LATE_SAMPLE Fehlercode zurück.
  • Wenn der Zeitstempel auf dem Eingabemedienbeispiel früher als die zugewiesene Sendezeit liegt (dies bedeutet pufferüberlauf). Der Multiplexer kann diese Situation ignorieren, wenn er für die Anpassung der Bitrate konfiguriert ist, indem das flag MFASF_MULTIPLEXER_AUTOADJUST_BITRATE während der Multiplexerinitialisierung festgelegt wird. Weitere Informationen finden Sie unter "Multiplexer-Initialisierung und Leaky Bucket-Einstellungen" unter Erstellen des Multiplexer-Objekts. Wenn dieses Flag nicht festgelegt ist und der Multiplexer auf einen Bandbreitenüberlauf stößt, schlägt ProcessSample fehl und gibt den MF_E_BANDWIDTH_OVERRUN Fehlercode zurück.

Nachdem der Multiplexer die Sendezeit zugewiesen hat, wird das Eingabemedienbeispiel dem Sendefenster hinzugefügt– eine Liste von Eingabemedienbeispielen, die nach Sendezeiten sortiert sind und bereit für die Verarbeitung in Datenpakete sind. Während der Datenpaketerstellung werden die Eingabemedienbeispiele analysiert, und relevante Daten werden als Nutzlast in ein Datenpaket geschrieben. Ein vollständiges Datenpaket kann Daten aus einem oder mehreren Eingabemedienbeispielen enthalten.

Wenn neue Eingabemedienbeispiele im Sendefenster eintreffen, werden sie einer Warteschlange hinzugefügt, bis genügend Medienbeispiele vorhanden sind, um ein vollständiges Paket zu bilden. Die Daten in Medienpuffern, die im Eingabemedienbeispiel enthalten sind, werden nicht in das generierte Datenpaket kopiert. Das Datenpaket enthält Verweise auf die Eingabemedienpuffer, bis das Eingabemedienbeispiel vollständig paketiert und das gesamte Paket vom Multiplexer erfasst wurde.

Wenn ein vollständiges Datenpaket verfügbar ist, kann es durch Aufrufen von IMFASFMultiplexer::GetNextPacket abgerufen werden. Wenn Sie ProcessSample aufrufen, während vollständige Pakete für den Abruf bereit sind, schlägt dies fehl und gibt den MF_E_NOTACCEPTING Fehlercode zurück. Dies bedeutet, dass der Multiplexer keine weiteren Eingaben akzeptieren kann und Sie GetNextPacket aufrufen müssen, um die wartenden Pakete abzurufen. Im Idealfall sollte jedem ProcessSample-Aufruf ein oder mehrere GetNextPacket-Aufrufe folgen, um die vollständigen Datenpakete abzurufen. Es kann mehrere Eingabemedienbeispiele zum Erstellen eines vollständigen Datenpakets dauern. Umgekehrt können daten in einem Eingabemedienbeispiel mehrere Pakete umfassen. Daher liefern nicht alle Aufrufe von ProcessSample Ausgabemedienbeispiele.

Wenn das Eingabemedienbeispiel einen keyframe enthält, der durch das attribut MFSampleExtension_CleanPoint angegeben wird, kopiert der Multiplexer das Attribut in das Paket.

Abrufen von ASF-Datenpaketen

Um die Ausgabemedienbeispiele für ein vollständiges Datenpaket zu sammeln, das vom Multiplexer generiert wird, rufen Sie IMFASFMultiplexer::GetNextPacket in einer Schleife auf, bis keine weiteren Ausgabemedienbeispiele für das Paket vorhanden sind. Im Folgenden werden die Erfolgsfälle aufgelistet:

  • Wenn ein vollständiges Datenpaket verfügbar ist, empfängt GetNextPacket das flag ASF_STATUS_FLAGS_INCOMPLETE im pdwStatusFlags-Parameter ; Der ppIPacket-Parameter empfängt einen Zeiger auf das erste Datenpaket. Sie müssen diese Methode aufrufen, solange sie dieses Flag empfängt. Bei jeder Iteration zeigt ppIPacket auf das nächste Paket in der Warteschlange.
  • Wenn nur ein Datenpaket vorhanden ist, zeigt ppIPacket darauf, und das ASF_STATUS_FLAGS_INCOMPLETE-Flag wird in pdwStatusFlags nicht empfangen.
  • GetNextPacket kann erfolgreich sein, ohne Datenpakete zu erhalten, wenn der Multiplexer noch Datenpakete packt und hinzufügt. In diesem Fall zeigt ppIPacket auf NULL. Um fortzufahren, müssen Sie dem Multiplexer weitere Eingabemedienbeispiele bereitstellen, indem Sie ProcessSample aufrufen.

Der folgende Beispielcode zeigt eine Funktion, die Datenpakete mithilfe des Multiplexers generiert. Der generierte Datenpaketinhalt wird in den vom Aufrufer zugeordneten Datenbytestream geschrieben.

//-------------------------------------------------------------------
// GenerateASFDataPackets
// 
// Gets data packets from the mux. This function is called after 
// calling IMFASFMultiplexer::ProcessSample. 
//-------------------------------------------------------------------

HRESULT GenerateASFDataPackets( 
    IMFASFMultiplexer *pMux, 
    IMFByteStream *pDataStream
    )
{
    HRESULT hr = S_OK;

    IMFSample *pOutputSample = NULL;
    IMFMediaBuffer *pDataPacketBuffer = NULL;

    DWORD dwMuxStatus = ASF_STATUSFLAGS_INCOMPLETE;

    while (dwMuxStatus & ASF_STATUSFLAGS_INCOMPLETE)
    {
        hr = pMux->GetNextPacket(&dwMuxStatus, &pOutputSample);

        if (FAILED(hr))
        {
            break;
        }

        if (pOutputSample)
        {
            //Convert to contiguous buffer
            hr = pOutputSample->ConvertToContiguousBuffer(&pDataPacketBuffer);
            
            if (FAILED(hr))
            {
                break;
            }

            //Write buffer to byte stream
            hr = WriteBufferToByteStream(pDataStream, pDataPacketBuffer, NULL);

            if (FAILED(hr))
            {
                break;
            }
        }

        SafeRelease(&pDataPacketBuffer);
        SafeRelease(&pOutputSample);
    }

    SafeRelease(&pOutputSample);
    SafeRelease(&pDataPacketBuffer);
    return hr;
}

Die WriteBufferToByteStream Funktion wird im Thema IMFByteStream::Write angezeigt.

Eine vollständige Anwendung, die dieses Codebeispiel verwendet, finden Sie unter Tutorial: Kopieren von ASF-Streams aus einer Datei in eine andere.

Posten von Packet-Generation Anrufen

Um sicherzustellen, dass keine vollständigen Datenpakete im Multiplexer warten, rufen Sie IMFASFMultiplexer::Flush auf. Dadurch wird erzwungen, dass der Multiplexer alle in Bearbeitung betreffenden Medienbeispiele packt. Die Anwendung kann diese Pakete in Form von Medienbeispielen über GetNextPacket in einer Schleife sammeln, bis keine weiteren Pakete mehr abgerufen werden.

Nachdem alle Medienbeispiele generiert wurden, rufen Sie IMFASFMultiplexer::End auf, um das ASF-Headerobjekt zu aktualisieren, das diesen Datenpaketen zugeordnet ist. Das Header-Objekt wird durch Übergeben des ContentInfo-Objekts angegeben, das zum Initialisieren des Multiplexers verwendet wurde. Dieser Aufruf aktualisiert verschiedene Headerobjekte, um änderungen widerzuspiegeln, die der Multiplexer während der Datenpaketgenerierung vorgenommen hat. Diese Informationen umfassen Paketanzahl, Sendedauer, Wiedergabedauer und Streamnummern aller Streams. Die Gesamtgröße des Headers wird ebenfalls aktualisiert.

Sie müssen sicherstellen, dass End aufgerufen wird, nachdem alle Datenpakete abgerufen wurden. Wenn pakete im Multiplexer warten, schlägt End fehl und gibt den MF_E_FLUSH_NEEDED Fehlercode zurück. Rufen Sie in diesem Fall das wartende Paket ab, indem Sie Flush und GetNextPacket in einer Schleife aufrufen.

Hinweis

Für die VBR-Codierung müssen Sie nach dem Aufrufen von End die Codierungsstatistiken in den Codierungseigenschaften des ContentInfo-Objekts festlegen. Weitere Informationen zu diesem Vorgang finden Sie unter Konfigurieren des ContentInfo-Objekts mit Encodereinstellungen unter Festlegen von Eigenschaften im ContentInfo-Objekt. In der folgenden Liste sind die festzulegenden Eigenschaften aufgeführt:

  • MFPKEY_RAVG ist die durchschnittliche Bitrate des VBR-Inhalts.
  • MFPKEY_BAVG ist das Pufferfenster für die durchschnittliche Bitrate.
  • MFPKEY_RMAX ist die Spitzenbitrate des VBR-Inhalts.
  • MFPKEY_BMAX ist das Spitzenpufferfenster.

 

ASF-Multiplexer

Tutorial: Kopieren von ASF-Streams aus einer Datei in eine andere

Tutorial: Schreiben einer WMA-Datei mithilfe der CBR-Codierung