Condividi tramite


Generazione di nuovi pacchetti di dati ASF

Il multiplexer ASF è un componente livello WMContainer che funziona con l'oggetto dati ASF e offre a un'applicazione la possibilità di generare pacchetti di dati ASF per un flusso che corrisponda ai requisiti definiti nell'oggetto ContentInfo.

Il multiplexer ha un input e un output. Riceve un esempio di flusso che contiene dati multimediali digitali e produce uno o più pacchetti di dati che possono essere scritti in un contenitore ASF.

L'elenco seguente riepiloga il processo di generazione di pacchetti di dati ASF:

  1. Passare i dati di input al multiplexer in IMFASFMultiplexer::P rocessSample.
  2. Raccogliere i pacchetti di dati chiamando IMFASFMultiplexer::GetNextPacket in un ciclo fino a quando non vengono recuperati tutti i pacchetti completi.
  3. Dopo che i dati di input sono stati convertiti in pacchetti completi, potrebbero essere presenti alcuni dati in sospeso nel multiplexer, che non è stato recuperato da GetNextPacket. Chiama IMFASFMultiplexer::Flush per pacchettizzare gli esempi in sospeso e raccoglierli dal multiplexer chiamando nuovamente GetNextPacket .
  4. Aggiornare gli oggetti intestazione ASF associati chiamando IMFASFMultiplexer::End per riflettere le modifiche apportate dal multiplexer durante la generazione di pacchetti di dati.

Il diagramma seguente illustra la generazione di pacchetti di dati per un file ASF tramite multiplexer.

Diagramma che mostra la generazione di pacchetti di dati per un file asf

Creazione di pacchetti di dati ASF

Dopo aver creato e inizializzato il multiplexer come descritto in Creazione dell'oggetto Multiplexer, chiamare IMFASFMultiplexer::P rocessSample per passare i dati di input al multiplexer per l'elaborazione in pacchetti di dati. L'input specificato deve trovarsi in un campione multimediale (interfaccia IMFSample ) che può avere uno o più buffer multimediali (interfaccia IMFMediaBuffer ) contenenti i dati per un flusso. In caso di transcodifica da ASF ad ASF, l'esempio di supporto di input può essere generato dal divisore che crea esempi di flusso in pacchetti. Per altre informazioni, vedere Divisione ASF.

Prima di chiamare ProcessSample, assicurarsi che il timestamp dell'esempio di supporto di input sia un'ora di presentazione valida; in caso contrario , ProcessSample ha esito negativo e restituisce il codice MF_E_NO_SAMPLE_TIMESTAMP.

Il multiplexer può accettare l'input come campioni di supporti compressi o non compressi tramite ProcessSample. Il multiplexer assegna i tempi di invio a questi campioni a seconda dell'utilizzo della larghezza di banda del flusso. Durante questo processo, il multiplexer controlla i parametri bucket persi (velocità di bit e utilizzo della finestra del buffer) e può rifiutare campioni che non rispettano tali valori. L'esempio di supporto di input può non riuscire a verificare la larghezza di banda per uno dei motivi seguenti:

  • Se l'esempio di supporto di input è arrivato in ritardo perché l'ora di invio dell'ultima assegnazione è maggiore del timestamp in questo esempio multimediale. ProcessSample ha esito negativo e restituisce il codice di errore MF_E_LATE_SAMPLE .
  • Se il timestamp nell'esempio di supporto di input è precedente al tempo di invio assegnato (indica l'overflow del buffer). Il multiplexer può ignorare questa situazione se è configurato per regolare la frequenza di bit impostando il flag MFASF_MULTIPLEXER_AUTOADJUST_BITRATE durante l'inizializzazione multiplexer. Per altre informazioni, vedere "Multiplexer Initialization and Leaky Bucket Settings" in Creating the Multiplexer Object.For more information, see "Multiplexer Initialization and Leaky Bucket Settings" in Creating the Multiplexer Object. Se questo flag non è impostato e il multiplexer rileva un sovraccarico della larghezza di banda, ProcessSample ha esito negativo e restituisce il codice di errore MF_E_BANDWIDTH_OVERRUN .

Dopo che il multiplexer assegna il tempo di invio, l'esempio di supporto di input viene aggiunto alla finestra di invio, ovvero un elenco di campioni multimediali di input ordinati in base ai tempi di invio e pronti per l'elaborazione in pacchetti di dati. Durante la costruzione di pacchetti di dati, l'esempio di supporto di input viene analizzato e i dati pertinenti vengono scritti in un pacchetto di dati come payload. Un pacchetto di dati completo può contenere dati da uno o più esempi di supporti di input.

Quando arrivano nuovi esempi di supporti di input nella finestra di invio, vengono aggiunti a una coda fino a quando non sono disponibili campioni multimediali sufficienti per formare un pacchetto completo. I dati nei buffer multimediali contenuti nell'esempio di supporto di input non vengono copiati nel pacchetto di dati generato. I riferimenti al blocco di pacchetti di dati ai buffer multimediali di input fino a quando l'esempio di supporto di input non è stato completamente pacchettizzato e il pacchetto completo è stato raccolto dal multiplexer.

Quando è disponibile un pacchetto di dati completo, può essere recuperato chiamando IMFASFMultiplexer::GetNextPacket. Se si chiama ProcessSample mentre sono pronti pacchetti completi per il recupero, l'operazione ha esito negativo e restituisce il codice di errore MF_E_NOTACCEPTING . Ciò indica che il multiplexer non può accettare più input ed è necessario chiamare GetNextPacket per recuperare i pacchetti in attesa. Idealmente, ogni chiamata ProcessSample deve essere seguita da una o più chiamate GetNextPacket per ottenere i pacchetti di dati completi. Per creare un pacchetto di dati completo, potrebbero essere necessari più esempi di supporti di input. Viceversa, i dati in un campione di supporti di input potrebbero estendersi su più pacchetti. Pertanto, non tutte le chiamate a ProcessSample produrranno campioni multimediali di output.

Se l'esempio di supporto di input contiene un fotogramma chiave indicato dall'attributo MFSampleExtension_CleanPoint , il multiplexer copia l'attributo nel pacchetto.

Recupero di pacchetti di dati ASF

Per raccogliere gli esempi di supporti di output per un pacchetto di dati completo generato dal multiplexer, chiamare IMFASFMultiplexer::GetNextPacket in un ciclo fino a quando non sono rimasti altri esempi multimediali di output per il pacchetto. Di seguito sono elencati i casi di esito positivo:

  • Se è disponibile un pacchetto di dati completo, GetNextPacket riceve il flag ASF_STATUS_FLAGS_INCOMPLETE nel parametro pdwStatusFlags ; il parametro ppIPacket riceve un puntatore al primo pacchetto di dati. È necessario chiamare questo metodo purché riceva questo flag. Con ogni iterazione, ppIPacket punta al pacchetto successivo nella coda.
  • Se è presente un solo pacchetto di dati, ppIPacket punta a esso e il flag ASF_STATUS_FLAGS_INCOMPLETE non viene ricevuto in pdwStatusFlags.
  • GetNextPacket può avere esito positivo senza produrre pacchetti di dati se il multiplexer è ancora in fase di creazione di pacchetti e aggiunta di pacchetti di dati. In questo caso ppIPacket punta a NULL. Per continuare, è necessario fornire al multiplexer più esempi di supporti di input chiamando ProcessSample.

Il codice di esempio seguente mostra una funzione che genera pacchetti di dati usando il multiplexer. Il contenuto del pacchetto di dati generato verrà scritto nel flusso di byte dei dati allocato dal chiamante.

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

La WriteBufferToByteStream funzione viene visualizzata nell'argomento IMFByteStream::Write.

Per visualizzare un'applicazione completa che usa questo esempio di codice, vedere Esercitazione: Copia di flussi ASF da un file a un altro.

Post Packet-Generation Chiamate

Per assicurarsi che non siano presenti pacchetti di dati completi in attesa nel multiplexer, chiamare IMFASFMultiplexer::Flush. In questo modo il multiplexer deve creare pacchetti per tutti gli esempi multimediali in corso. L'applicazione può raccogliere questi pacchetti sotto forma di esempi multimediali tramite GetNextPacket in un ciclo fino a quando non sono stati recuperati altri pacchetti.

Dopo aver generato tutti gli esempi multimediali, chiamare IMFASFMultiplexer::End per aggiornare l'oggetto intestazione ASF associato a questi pacchetti di dati. L'oggetto Header viene specificato passando l'oggetto ContentInfo utilizzato per inizializzare il multiplexer. Questa chiamata aggiorna vari oggetti intestazione per riflettere le modifiche apportate dal multiplexer durante la generazione di pacchetti di dati. Queste informazioni includono il numero di pacchetti, la durata di invio, la durata di riproduzione e i numeri di flusso di tutti i flussi. Viene aggiornata anche la dimensione complessiva dell'intestazione.

È necessario assicurarsi che End venga chiamato dopo che tutti i pacchetti di dati sono stati recuperati. Se sono presenti pacchetti in attesa nel multiplexer, End avrà esito negativo e restituirà il codice di errore MF_E_FLUSH_NEEDED . In questo caso, ottenere il pacchetto in attesa chiamando Flush e GetNextPacket in un ciclo.

Nota

Per la codifica VBR, dopo aver chiamato End, è necessario impostare le statistiche di codifica nelle proprietà di codifica dell'oggetto ContentInfo. Per informazioni su questo processo, vedere "Configurazione dell'oggetto ContentInfo con impostazioni del codificatore" in Impostazione delle proprietà nell'oggetto ContentInfo. L'elenco seguente mostra le proprietà specifiche da impostare:

  • MFPKEY_RAVG è la velocità media in bit del contenuto VBR.
  • MFPKEY_BAVG è la finestra del buffer per la velocità media dei bit.
  • MFPKEY_RMAX è il picco della velocità in bit del contenuto VBR.
  • MFPKEY_BMAX è la finestra del buffer di picco.

 

ASF Multiplexer

Esercitazione: Copia di flussi ASF da un file a un altro

Esercitazione: Scrittura di un file WMA tramite codifica CBR