Copia di flussi senza decompressione dei dati
Il modo più semplice e più comune per copiare un flusso da un file a un altro consiste nel recuperare gli esempi nello stato compresso e quindi scriverli nel nuovo file senza decompressirli e ricomprimerli. Gli esempi ottenuti da un file nello stato compresso vengono chiamati campioni di flusso, perché non sono alterati dalla loro rappresentazione nel flusso. È consigliabile usare sempre esempi di flusso per copiare i flussi, perché la decompressione e la ricompressione dei dati multimediali digitali riduce la qualità. Se è necessario copiare un flusso da dati decompressi, vedere Copia di flussi usando esempi decompressi.
È possibile concatenare due o più flussi in un singolo flusso usando esempi compressi, ma solo se le velocità dei bit sono identiche. Il processo è essenzialmente uguale ai passaggi descritti di seguito, ad eccezione del fatto che è necessario leggere più file originali per ottenere tutto il contenuto necessario. Tuttavia, è possibile scrivere solo esempi compressi da più file a un singolo flusso se le strutture WM_MEDIA_TYPE (inclusi tutti i membri della struttura pbFormat ) di tutti i flussi compressi sono identici. Per combinare i dati da più flussi che non sono dello stesso formato, è necessario decomprimere il contenuto e ricomprimerlo nel flusso di destinazione. Inoltre, quando si combinano i dati da due o più flussi in un singolo flusso, è necessario aggiungere i valori della finestra del buffer per tutti i flussi insieme per ottenere la finestra del buffer per il nuovo flusso. Ciò è dovuto al fatto che non è possibile determinare la quantità di buffer impiegato alla fine di un flusso e all'inizio di un altro.
È possibile recuperare esempi di flusso con il lettore asincrono usando IWMReaderAdvanced::SetReceiveStreamSamples. Gli esempi di flusso vengono recapitati a IWMReaderCallbackAdvanced::OnStreamSample, non a IWMReaderCallback::OnSample. Se si legge un file e si recuperano alcuni flussi compressi e alcuni decompressi, è necessario implementare entrambi i metodi di callback.
Il lettore sincrono offre maggiore flessibilità per il recupero di campioni. È possibile passare liberamente tra esempi compressi e decompressi durante la riproduzione usando IWMSyncReader::SetReadStreamSamples.
Per copiare un intero flusso da un file ASF a un nuovo file ASF, seguire questa procedura. Questi passaggi usano il lettore sincrono perché è molto più semplice da usare per questo tipo di operazione.
- Creare un oggetto lettore sincrono chiamando la funzione WMCreateSyncReader .
- Aprire un file nel lettore con una chiamata a IWMSyncReader::Open.
- Ottenere un puntatore all'interfaccia IWMProfile dell'oggetto lettore sincrono chiamando IWMSyncReader::QueryInterface.
- Recuperare le proprietà del flusso desiderato chiamando IWMProfile::GetStreamByNumber. Verrà recuperato un puntatore all'interfaccia IWMStreamConfig dell'oggetto di configurazione del flusso desiderato.
- Ottenere una copia della struttura WM_MEDIA_TYPE per il flusso. Effettuare due chiamate a IWMMediaProps::GetMediaType: la prima per ottenere le dimensioni della struttura, la seconda per ottenere la struttura stessa.
- Creare un oggetto profile manager chiamando la funzione WMCreateProfileManager .
- Chiamare IWMProfileManager::CreateEmptyProfile per creare un nuovo profilo (o aprire un profilo esistente a cui si vuole aggiungere il flusso). Chiamare IWMProfile::AddStream nel nuovo profilo per aggiungere il flusso dal file esistente. Quando si aggiunge il flusso, usare il puntatore IWMStreamConfig ottenuto nel passaggio 4.
- Creare un oggetto writer con una chiamata alla funzione WMCreateWriter . Impostare il profilo appena creato come profilo attivo nel writer chiamando IWMWriter::SetProfile. Creare un file per l'output chiamando IWMWriter::SetOutputFilename.
- Per ogni input associato al flusso o ai flussi copiati, chiamare IWMWriter::SetInputProps, passando NULL per l'interfaccia IWMInputMediaProps . In questo modo viene informato l'oggetto writer che non deve convalidare i dati passati. È necessario effettuare questa chiamata prima di chiamare BeginWriting (passaggio 14), in caso contrario, un oggetto di lettura potrebbe non essere in grado di decodificare il contenuto.
- Impostare il lettore sincrono per distribuire esempi di flusso compressi per il flusso selezionato chiamando IWMSyncReader::SetReadStreamSamples con il parametro fCompressed impostato su True.
- Ottenere informazioni sui codec per ogni flusso copiato e aggiungere le informazioni sul codec all'intestazione prima di scrivere. Per ottenere le informazioni sul codec, chiamare IWMHeaderInfo2::GetCodecInfoCount e IWMHeaderInfo2::GetCodecInfo per enumerare i codec associati al file nel lettore. Selezionare le informazioni sul codec corrispondenti alla configurazione del flusso. Impostare quindi le informazioni sul codec nel writer chiamando IWMHeaderInfo3::AddCodecInfo, passando le informazioni ottenute dal lettore.
- Ottenere un puntatore all'interfaccia IWMWriterAdvanced chiamando IWMWriter::QueryInterface.
- Impostare il writer su modalità di scrittura chiamando IWMWriter::BeginWriting.
- Effettuare chiamate ripetute a IWMSyncReader::GetNextSample, specificando il numero di flusso desiderato. Quando vengono ricevuti esempi, passarli al writer con chiamate a IWMWriterAdvanced::WriteStreamSample. Per i flussi video, è necessario controllare i flag (se presenti) impostati dal writer in ogni chiamata a GetNextSample. Se WM_SF_CLEANPOINT è impostato, è necessario impostarlo anche sulla chiamata a WriteStreamSample.
- Al termine della lettura, chiamare IWMWriter::EndWriting. Il flusso deve essere trasferito.
Nota
I flussi di immagine non possono essere copiati da un file a un altro usando esempi di flusso. Per copiare i dati del flusso di immagini, recuperare gli esempi non compressi e quindi elaborarli tramite il writer come si farebbe normalmente.
Argomenti correlati