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.

  1. Creare un oggetto lettore sincrono chiamando la funzione WMCreateSyncReader .
  2. Aprire un file nel lettore con una chiamata a IWMSyncReader::Open.
  3. Ottenere un puntatore all'interfaccia IWMProfile dell'oggetto lettore sincrono chiamando IWMSyncReader::QueryInterface.
  4. Recuperare le proprietà del flusso desiderato chiamando IWMProfile::GetStreamByNumber. Verrà recuperato un puntatore all'interfaccia IWMStreamConfig dell'oggetto di configurazione del flusso desiderato.
  5. 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.
  6. Creare un oggetto profile manager chiamando la funzione WMCreateProfileManager .
  7. 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.
  8. 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.
  9. 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.
  10. Impostare il lettore sincrono per distribuire esempi di flusso compressi per il flusso selezionato chiamando IWMSyncReader::SetReadStreamSamples con il parametro fCompressed impostato su True.
  11. 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.
  12. Ottenere un puntatore all'interfaccia IWMWriterAdvanced chiamando IWMWriter::QueryInterface.
  13. Impostare il writer su modalità di scrittura chiamando IWMWriter::BeginWriting.
  14. 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.
  15. 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.

 

Copia di dati da un file a un altro

Copia di flussi con esempi decompressi