Partager via


Génération de nouveaux paquets de données ASF

Le multiplexeur ASF est un composant de couche WMContainer qui fonctionne avec l’objet de données ASF et donne à une application la possibilité de générer des paquets de données ASF pour un flux qui correspondent aux exigences définies dans l’objet ContentInfo.

Le multiplexeur a une entrée et une sortie. Il reçoit un exemple de flux qui contient des données multimédias numériques et produit un ou plusieurs paquets de données qui peuvent être écrits dans un conteneur ASF.

La liste suivante récapitule le processus de génération de paquets de données ASF :

  1. Transmettez les données d’entrée au multiplexeur dans IMFASFMultiplexer::P rocessSample.
  2. Collectez les paquets de données en appelant IMFASFMultiplexer::GetNextPacket dans une boucle jusqu’à ce que tous les paquets complets aient été récupérés.
  3. Une fois que les données d’entrée ont été converties en paquets complets, il peut y avoir des données en attente dans le multiplexeur, qui n’a pas été récupéré par GetNextPacket. Appelez IMFASFMultiplexer::Flush pour empaqueter les échantillons en attente et les collecter à partir du multiplexeur en appelant à nouveau GetNextPacket .
  4. Mettez à jour les objets d’en-tête ASF associés en appelant IMFASFMultiplexer::End pour refléter les modifications apportées par le multiplexeur pendant la génération de paquets de données.

Le diagramme suivant illustre la génération de paquets de données pour un fichier ASF via le multiplexeur.

diagram showing data packet generation for an asf file

Création de paquets de données ASF

Après avoir créé et initialisé le multiplexeur comme décrit dans Création de l’objet Multiplexer, appelez IMFASFMultiplexer::P rocessSample pour transmettre les données d’entrée au multiplexeur pour traitement dans les paquets de données. L’entrée spécifiée doit se trouver dans un exemple de média (interface IMFSample ) qui peut avoir un ou plusieurs tampons multimédias (interface IMFMediaBuffer ) contenant les données d’un flux. En cas de transcodage ASF à ASF, l’exemple de média d’entrée peut être généré à partir du séparateur qui crée des exemples de flux paquets. Pour plus d’informations, consultez le séparateur ASF.

Avant d’appeler ProcessSample, assurez-vous que l’horodatage de l’exemple de média d’entrée est une heure de présentation valide ; Sinon , ProcessSample échoue et retourne le code MF_E_NO_SAMPLE_TIMESTAMP.

Le multiplexeur peut accepter l’entrée en tant qu’exemples multimédias compressés ou non compressés via ProcessSample. Le multiplexeur affecte des temps d’envoi à ces exemples en fonction de l’utilisation de la bande passante du flux. Pendant ce processus, le multiplexeur vérifie les paramètres de compartiment fuite (débit de bits et utilisation de la fenêtre de mémoire tampon) et peut rejeter les échantillons qui ne respectent pas ces valeurs. L’exemple de média d’entrée peut échouer pour l’une des raisons suivantes :

  • Si l’exemple de média d’entrée est arrivé en retard, car l’heure d’envoi affectée pour la dernière fois est supérieure à l’horodatage de cet exemple de média. ProcessSample échoue et retourne le code d’erreur MF_E_LATE_SAMPLE.
  • Si l’horodatage de l’exemple de média d’entrée est antérieur à l’heure d’envoi affectée (cela indique le dépassement de capacité de mémoire tampon). Le multiplexeur peut ignorer cette situation s’il est configuré pour ajuster le débit binaire en définissant l’indicateur MFASF_MULTIPLEXER_AUTOADJUST_BITRATE lors de l’initialisation du multiplexeur. Pour plus d’informations, consultez « Multiplexer Initialization and Leaky Bucket Paramètres » dans Création de l’objet Multiplexer. Si cet indicateur n’est pas défini et que le multiplexeur rencontre un dépassement de bande passante, ProcessSample échoue et retourne le code d’erreur MF_E_BANDWIDTH_OVERRUN .

Une fois que le multiplexeur a affecté l’heure d’envoi, l’exemple de média d’entrée est ajouté à la fenêtre d’envoi: une liste d’échantillons de média d’entrée triés par des heures d’envoi et prêtes à être traitées dans des paquets de données. Pendant la construction des paquets de données, l’exemple de support d’entrée est analysé et les données pertinentes sont écrites dans un paquet de données en tant que charge utile. Un paquet de données complet peut contenir des données d’un ou plusieurs exemples de supports d’entrée.

Lorsque de nouveaux échantillons multimédias d’entrée arrivent dans la fenêtre d’envoi, ils sont ajoutés à une file d’attente jusqu’à ce qu’il y ait suffisamment d’échantillons multimédias pour former un paquet complet. Les données contenues dans les mémoires tampons multimédias contenues dans l’exemple de média d’entrée ne sont pas copiées dans le paquet de données généré. Le paquet de données contient des références aux mémoires tampons du média d’entrée jusqu’à ce que l’exemple de média d’entrée ait été entièrement paqueté et que le paquet complet ait été collecté à partir du multiplexeur.

Lorsqu’un paquet de données complet est disponible, il peut être récupéré en appelant IMFASFMultiplexer::GetNextPacket. Si vous appelez ProcessSample pendant qu’il existe des paquets complets prêts à être extraits, il échoue et retourne le code d’erreur MF_E_NOTACCEPTING . Cela indique que le multiplexeur ne peut pas accepter plus d’entrée et que vous devez appeler GetNextPacket pour récupérer les paquets en attente. Dans l’idéal, chaque appel ProcessSample doit être suivi d’un ou plusieurs appels GetNextPacket pour obtenir les paquets de données complets. Plusieurs exemples de média d’entrée peuvent être pris pour créer un paquet de données complet. À l’inverse, les données d’un exemple de média d’entrée peuvent s’étendre sur plusieurs paquets. Par conséquent, tous les appels à ProcessSample ne produisent pas d’échantillons multimédias de sortie.

Si l’exemple de média d’entrée contient un frame clé indiqué par l’attribut MFSampleExtension_CleanPoint , le multiplexeur copie l’attribut dans le paquet.

Obtention de paquets de données ASF

Pour collecter les échantillons de média de sortie pour un paquet de données complet généré par le multiplexeur, appelez IMFASFMultiplexer::GetNextPacket dans une boucle jusqu’à ce qu’il n’y ait plus d’échantillons de média de sortie laissés pour le paquet. Voici les cas de réussite :

  • S’il existe un paquet de données complet disponible, GetNextPacket reçoit l’indicateur ASF_STATUS_FLAGS_INCOMPLETE dans le paramètre pdwStatusFlags ; Le paramètre ppIPacket reçoit un pointeur vers le premier paquet de données. Vous devez appeler cette méthode tant qu’elle reçoit cet indicateur. Avec chaque itération, ppIPacket pointe vers le paquet suivant dans la file d’attente.
  • S’il n’existe qu’un seul paquet de données, ppIPacket pointe vers celui-ci et l’indicateur ASF_STATUS_FLAGS_INCOMPLETE n’est pas reçu dans pdwStatusFlags.
  • GetNextPacket peut réussir sans générer de paquets de données si le multiplexeur est toujours en cours de paquets de paquets et d’ajout de paquets de données. Dans ce cas, ppIPacket pointe vers NULL. Pour continuer, vous devez fournir au multiplexeur davantage d’exemples de média d’entrée en appelant ProcessSample.

L’exemple de code suivant montre une fonction qui génère des paquets de données à l’aide du multiplexeur. Le contenu du paquet de données généré est écrit dans le flux d’octets de données alloué par l’appelant.

//-------------------------------------------------------------------
// 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 fonction est affichée dans la rubrique IMFByteStream::Write.

Pour voir une application complète qui utilise cet exemple de code, consultez Tutoriel : Copie d’ASF Flux d’un fichier vers un autre.

Publier des appels Packet-Generation

Pour vous assurer qu’il n’y a pas de paquets de données complets en attente dans le multiplexeur, appelez IMFASFMultiplexer::Flush. Cela force le multiplexeur à paqueter tous les échantillons multimédias en cours. L’application peut collecter ces paquets sous forme d’exemples multimédias via GetNextPacket dans une boucle jusqu’à ce qu’il n’y ait plus de paquets à récupérer.

Une fois tous les exemples multimédias générés, appelez IMFASFMultiplexer::End pour mettre à jour l’objet d’en-tête ASF associé à ces paquets de données. L’objet Header est spécifié en transmettant l’objet ContentInfo utilisé pour initialiser le multiplexeur. Cet appel met à jour différents objets d’en-tête pour refléter les modifications apportées par le multiplexeur pendant la génération de paquets de données. Ces informations incluent le nombre de paquets, la durée d’envoi, la durée de lecture et les nombres de flux de tous les flux. La taille d’en-tête globale est également mise à jour.

Vous devez vous assurer que End est appelé une fois que tous les paquets de données ont été récupérés. S’il existe des paquets en attente dans le multiplexeur, End échoue et retourne le code d’erreur MF_E_FLUSH_NEEDED . Dans ce cas, récupérez le paquet en attente en appelant Flush et GetNextPacket dans une boucle.

Notes

Pour l’encodage VBR, après avoir appelé End, vous devez définir les statistiques d’encodage dans les propriétés d’encodage de l’objet ContentInfo. Pour plus d’informations sur ce processus, consultez « Configuration de l’objet ContentInfo avec l’encodeur Paramètres » dans La définition des propriétés dans l’objet ContentInfo. La liste suivante affiche les propriétés spécifiques à définir :

  • MFPKEY_RAVG est le taux de bits moyen du contenu VBR.
  • MFPKEY_BAVG est la fenêtre de mémoire tampon pour le débit de bits moyen.
  • MFPKEY_RMAX est le débit de bits maximal du contenu VBR.
  • MFPKEY_BMAX est la fenêtre de mémoire tampon maximale.

 

Multiplexeur ASF

Tutoriel : Copier des Flux ASF d’un fichier vers un autre

Tutoriel : Écriture d’un fichier WMA à l’aide de l’encodage CBR