Copiando fluxos sem descompactar os dados
A maneira mais simples e comum de copiar um fluxo de um arquivo para outro é recuperar os exemplos em seu estado compactado e, em seguida, gravá-los no novo arquivo sem descompactá-los e recompactá-los. Exemplos obtidos de um arquivo em seu estado compactado são chamados de exemplos de fluxo, pois são separados de sua representação no fluxo. É recomendável que você sempre use exemplos de fluxo para copiar fluxos, pois descompactar e recompactar dados de mídia digital degrada a qualidade. Se você precisar copiar um fluxo de dados descompactados, consulte Copiando fluxos usando amostras descompactadas.
É possível concatenar dois ou mais fluxos em um único fluxo usando amostras compactadas, mas somente se as taxas de bits forem idênticas. O processo é essencialmente o mesmo que as etapas descritas abaixo, exceto que você deve ler vários arquivos originais para obter todo o conteúdo necessário. No entanto, você só poderá gravar amostras compactadas de vários arquivos em um único fluxo se as estruturas de WM_MEDIA_TYPE (incluindo todos os membros da estrutura pbFormat ) de todos os fluxos compactados forem idênticas. Para combinar dados de vários fluxos que não são do mesmo formato, você deve descompactar o conteúdo e recompactá-lo no fluxo de destino. Além disso, ao combinar dados de dois ou mais fluxos em um único fluxo, você deve adicionar os valores da janela de buffer para todos os fluxos juntos para obter a janela de buffer para o novo fluxo. Isso ocorre porque é impossível determinar quanto do buffer é usado no final de um fluxo e no início de outro.
Você pode recuperar exemplos de fluxo com o leitor assíncrono usando IWMReaderAdvanced::SetReceiveStreamSamples. Os exemplos de fluxo são entregues a IWMReaderCallbackAdvanced::OnStreamSample, não a IWMReaderCallback::OnSample. Se você estiver lendo um arquivo e recuperando alguns fluxos compactados e alguns descompactados, deverá implementar ambos os métodos de retorno de chamada.
O leitor síncrono fornece mais flexibilidade para recuperar exemplos. Você pode alternar entre amostras compactadas e descompactadas livremente durante a reprodução usando IWMSyncReader::SetReadStreamSamples.
Para copiar um fluxo inteiro de um arquivo ASF para um novo arquivo ASF, execute as etapas a seguir. Essas etapas usam o leitor síncrono porque é muito mais simples de usar para esse tipo de operação.
- Crie um objeto de leitor síncrono chamando a função WMCreateSyncReader .
- Abra um arquivo no leitor com uma chamada para IWMSyncReader::Open.
- Obtenha um ponteiro para a interface IWMProfile do objeto de leitor síncrono chamando IWMSyncReader::QueryInterface.
- Recupere as propriedades do fluxo desejado chamando IWMProfile::GetStreamByNumber. Isso recuperará um ponteiro para a interface IWMStreamConfig do objeto de configuração de fluxo para o fluxo desejado.
- Obtenha uma cópia da estrutura de WM_MEDIA_TYPE para o fluxo. Faça duas chamadas para IWMMediaProps::GetMediaType: a primeira para obter o tamanho da estrutura, a segunda para obter a própria estrutura.
- Crie um objeto do gerenciador de perfil chamando a função WMCreateProfileManager .
- Chame IWMProfileManager::CreateEmptyProfile para criar um novo perfil (ou abra um perfil existente ao qual você deseja adicionar o fluxo). Chame IWMProfile::AddStream no novo perfil para adicionar o fluxo do arquivo existente. Ao adicionar o fluxo, use o ponteiro IWMStreamConfig obtido na etapa 4.
- Crie um objeto writer com uma chamada para a função WMCreateWriter . Defina o perfil recém-criado como o perfil ativo no gravador chamando IWMWriter::SetProfile. Crie um arquivo para saída chamando IWMWriter::SetOutputFilename.
- Para cada entrada associada ao fluxo ou fluxos que você está copiando, chame IWMWriter::SetInputProps, passando NULL para a interface IWMInputMediaProps . Isso informa ao objeto gravador que ele não precisa validar os dados que você está passando. Você deve fazer essa chamada antes de chamar BeginWriting (etapa 14), caso contrário, um objeto de leitura pode não ser capaz de decodificar o conteúdo.
- Defina o leitor síncrono para fornecer exemplos de fluxo compactados para o fluxo selecionado chamando IWMSyncReader::SetReadStreamSamples com o parâmetro fCompressed definido como True.
- Obtenha informações de codec para cada fluxo que está sendo copiado e adicione as informações de codec ao cabeçalho antes de gravar. Para obter as informações de codec, chame IWMHeaderInfo2::GetCodecInfoCount e IWMHeaderInfo2::GetCodecInfo para enumerar os codecs associados ao arquivo no leitor. Selecione as informações de codec que correspondem à configuração de fluxo. Em seguida, defina as informações de codec no gravador chamando IWMHeaderInfo3::AddCodecInfo, passando as informações obtidas do leitor.
- Obtenha um ponteiro para a interface IWMWriterAdvanced chamando IWMWriter::QueryInterface.
- Defina o gravador como modo de escrita chamando IWMWriter::BeginWriting.
- Faça chamadas repetidas para IWMSyncReader::GetNextSample, especificando o número de fluxo desejado. Quando os exemplos forem recebidos, passe-os para o gravador com chamadas para IWMWriterAdvanced::WriteStreamSample. Para fluxos de vídeo, você deve marcar os sinalizadores (se houver) definidos pelo gravador em cada chamada para GetNextSample. Se WM_SF_CLEANPOINT estiver definido, você também deverá defini-lo em sua chamada para WriteStreamSample.
- Quando a leitura for concluída, chame IWMWriter::EndWriting. O fluxo deve ser transferido.
Observação
Os fluxos de imagem não podem ser copiados de um arquivo para outro usando exemplos de fluxo. Para copiar dados de fluxo de imagem, recupere os exemplos descompactados e processe-os por meio do gravador como faria normalmente.
Tópicos relacionados