Copie de flux sans décompression des données

La façon la plus simple et la plus courante de copier un flux d’un fichier vers un autre consiste à récupérer les exemples dans leur état compressé, puis à les écrire dans le nouveau fichier sans les décompresser et les recompresser. Les échantillons obtenus à partir d’un fichier dans leur état compressé sont appelés exemples de flux, car ils ne sont pas affectés de leur représentation dans le flux. Il est recommandé de toujours utiliser des exemples de flux pour copier des flux, car la décompression et la recompression des données multimédias numériques dégradent la qualité. Si vous devez copier un flux à partir de données décompressées, consultez Copie de flux à l’aide d’exemples décompressés.

Il est possible de concaténer deux ou plusieurs flux en un seul flux à l’aide d’exemples compressés, mais uniquement si les débits binaires sont identiques. Le processus est essentiellement le même que les étapes décrites ci-dessous, sauf que vous devez lire plusieurs fichiers d’origine pour obtenir tout le contenu dont vous avez besoin. Toutefois, vous ne pouvez écrire des exemples compressés à partir de plusieurs fichiers dans un seul flux que si les structures WM_MEDIA_TYPE (y compris tous les membres de la structure pbFormat ) de tous les flux compressés sont identiques. Pour combiner des données provenant de plusieurs flux qui ne sont pas du même format, vous devez décompresser le contenu et le recompresser dans le flux de destination. En outre, lorsque vous combinez des données de deux flux ou plus en un seul flux, vous devez ajouter les valeurs de la fenêtre de mémoire tampon pour tous les flux afin d’obtenir la fenêtre de mémoire tampon du nouveau flux. Cela est dû au fait qu’il est impossible de déterminer la quantité de la mémoire tampon utilisée à la fin d’un flux et au début d’un autre.

Vous pouvez récupérer des exemples de flux avec le lecteur asynchrone à l’aide de IWMReaderAdvanced::SetReceiveStreamSamples. Les exemples de flux sont remis à IWMReaderCallbackAdvanced::OnStreamSample, et non à IWMReaderCallback::OnSample. Si vous lisez un fichier et récupérez des flux compressés et d’autres décompressés, vous devez implémenter les deux méthodes de rappel.

Le lecteur synchrone offre plus de flexibilité pour récupérer des exemples. Vous pouvez basculer librement entre les exemples compressés et décompressés pendant la lecture à l’aide de IWMSyncReader::SetReadStreamSamples.

Pour copier un flux entier d’un fichier ASF vers un nouveau fichier ASF, procédez comme suit. Ces étapes utilisent le lecteur synchrone, car il est beaucoup plus simple à utiliser pour ce type d’opération.

  1. Créez un objet lecteur synchrone en appelant la fonction WMCreateSyncReader .
  2. Ouvrez un fichier dans le lecteur avec un appel à IWMSyncReader::Open.
  3. Obtenez un pointeur vers l’interface IWMProfile de l’objet lecteur synchrone en appelant IWMSyncReader::QueryInterface.
  4. Récupérez les propriétés du flux souhaité en appelant IWMProfile::GetStreamByNumber. Cette opération récupère un pointeur vers l’interface IWMStreamConfig de l’objet de configuration de flux pour le flux souhaité.
  5. Obtenez une copie de la structure WM_MEDIA_TYPE pour le flux. Effectuez deux appels à IWMMediaProps::GetMediaType : le premier pour obtenir la taille de la structure, le second pour obtenir la structure elle-même.
  6. Créez un objet de gestionnaire de profils en appelant la fonction WMCreateProfileManager .
  7. Appelez IWMProfileManager::CreateEmptyProfile pour créer un profil (ou ouvrir un profil existant auquel vous souhaitez ajouter le flux). Appelez IWMProfile::AddStream sur le nouveau profil pour ajouter le flux à partir du fichier existant. Lors de l’ajout du flux, utilisez le pointeur IWMStreamConfig obtenu à l’étape 4.
  8. Créez un objet writer avec un appel à la fonction WMCreateWriter . Définissez le profil nouvellement créé comme profil actif dans l’enregistreur en appelant IWMWriter::SetProfile. Créez un fichier pour la sortie en appelant IWMWriter::SetOutputFilename.
  9. Pour chaque entrée associée au ou aux flux que vous copiez, appelez IWMWriter::SetInputProps, en passant null pour l’interface IWMInputMediaProps . Cela informe l’objet writer qu’il n’a pas besoin de valider les données que vous transmettez. Vous devez effectuer cet appel avant d’appeler BeginWriting (étape 14), sinon un objet de lecture peut ne pas être en mesure de décoder le contenu.
  10. Définissez le lecteur synchrone pour qu’il fournisse des exemples de flux compressés pour le flux sélectionné en appelant IWMSyncReader::SetReadStreamSamples avec le paramètre fCompressed défini sur True.
  11. Obtenez des informations de codec pour chaque flux copié et ajoutez les informations de codec à l’en-tête avant d’écrire. Pour obtenir les informations de codec, appelez IWMHeaderInfo2::GetCodecInfoCount et IWMHeaderInfo2::GetCodecInfo pour énumérer les codecs associés au fichier dans le lecteur. Sélectionnez les informations de codec qui correspondent à la configuration du flux. Définissez ensuite les informations de codec dans l’enregistreur en appelant IWMHeaderInfo3::AddCodecInfo, en transmettant les informations obtenues à partir du lecteur.
  12. Obtenez un pointeur vers l’interface IWMWriterAdvanced en appelant IWMWriter::QueryInterface.
  13. Définissez l’enregistreur sur le mode d’écriture en appelant IWMWriter::BeginWriting.
  14. Effectuez des appels répétés à IWMSyncReader::GetNextSample, en spécifiant le numéro de flux souhaité. Lorsque des exemples sont reçus, passez-les au writer avec des appels à IWMWriterAdvanced::WriteStreamSample. Pour les flux vidéo, vous devez case activée les indicateurs (le cas échéant) définis par l’enregistreur à chaque appel à GetNextSample. Si WM_SF_CLEANPOINT est défini, vous devez également le définir lors de votre appel à WriteStreamSample.
  15. Une fois la lecture terminée, appelez IWMWriter::EndWriting. Le flux doit être transféré.

Notes

Les flux d’images ne peuvent pas être copiés d’un fichier à un autre à l’aide d’exemples de flux. Pour copier des données de flux d’images, récupérez les exemples non compressés, puis traitez-les via l’enregistreur comme vous le feriez normalement.

 

Copie de données d’un fichier vers un autre

Copie de flux à l’aide d’exemples décompressés