Récepteurs multimédias

Les récepteurs multimédias sont les objets de pipeline qui reçoivent des données multimédias. Un récepteur multimédia est la destination d’un ou plusieurs flux multimédias. Les récepteurs multimédias se répartissent en deux catégories générales :

  • Un convertisseur est un récepteur multimédia qui présente des données pour la lecture. Le convertisseur vidéo amélioré (EVR) affiche des trames vidéo, et le convertisseur audio lit les flux audio via le carte audio ou tout autre périphérique audio.

  • Un récepteur d’archivage est un récepteur multimédia qui écrit des données dans un fichier ou un autre stockage.

La main différence entre elles est qu’un récepteur d’archivage ne consomme pas les données à un taux de lecture fixe. Au lieu de cela, il écrit les données qu’il reçoit aussi rapidement que possible.

Les récepteurs multimédias exposent l’interface IMFMediaSink . Chaque récepteur multimédia contient un ou plusieurs récepteurs de flux. Chaque récepteur de flux reçoit les données d’un flux. Les récepteurs de flux exposent l’interface IMFStreamSink . En règle générale, une application ne crée pas directement de récepteurs multimédias. Au lieu de cela, l’application crée un ou plusieurs objets d’activation, que la session multimédia utilise pour créer le récepteur. Toutes les autres opérations sur le récepteur sont gérées par la session multimédia, et l’application n’appelle aucune méthode sur le récepteur multimédia ou l’un des récepteurs de flux. Pour plus d’informations sur les objets d’activation, consultez Objets d’activation.

Vous devez lire le reste de cette rubrique si vous écrivez un récepteur multimédia personnalisé ou si vous souhaitez utiliser un récepteur multimédia directement sans la session multimédia.

Récepteurs de flux

Un récepteur multimédia peut avoir un nombre fixe de récepteurs de flux, ou il peut prendre en charge l’ajout et la suppression de récepteurs de flux. Si elle a un nombre fixe de récepteurs de flux, la méthode IMFMediaSink::GetCharacteristics retourne l’indicateur MEDIASINK_FIXED_STREAMS. Sinon, vous pouvez ajouter et supprimer des récepteurs de flux. Pour ajouter un nouveau récepteur de flux, appelez IMFMediaSink::AddStreamSink. Pour supprimer un récepteur de flux, appelez IMFMediaSink::RemoveStreamSink. L’indicateur MEDIASINK_FIXED_STREAMS indique que le récepteur multimédia ne prend pas en charge ces deux méthodes. (Il peut prendre en charge une autre façon de configurer le nombre de flux, par exemple en définissant des paramètres d’initialisation lors de la création du récepteur.) La liste des récepteurs de flux est triée. Pour les énumérer par valeur d’index, appelez la méthode IMFMediaSink::GetStreamSinkByIndex .

Les récepteurs de flux ont également des identificateurs. Les identificateurs de flux sont uniques au sein du récepteur multimédia, mais ne doivent pas être consécutifs. Selon le récepteur multimédia, les identificateurs de flux peuvent avoir une signification liée au contenu. Par exemple, un récepteur d’archivage peut écrire les identificateurs de flux dans l’en-tête de fichier. Sinon, elles sont arbitraires. Pour obtenir un récepteur de flux par son identificateur, appelez IMFMediaSink::GetStreamSinkById.

Horloge de présentation

La fréquence à laquelle un récepteur multimédia consomme des échantillons est contrôlée par l’horloge de présentation. La session multimédia sélectionne l’horloge de présentation et la définit sur le récepteur multimédia en appelant la méthode IMFMediaSink::SetPresentationClock du récepteur multimédia. L’horloge de présentation doit être définie sur le récepteur multimédia avant que la diffusion en continu puisse commencer. Chaque récepteur multimédia a besoin d’une horloge de présentation pour s’exécuter. Le récepteur multimédia utilise l’horloge de présentation à deux fins :

  • Pour recevoir des notifications lorsque la diffusion en continu démarre ou s’arrête. Le récepteur multimédia reçoit ces notifications via l’interface IMFClockStateSink , que tous les récepteurs multimédias doivent implémenter.

  • Pour déterminer quand il doit afficher les échantillons. Lorsque le récepteur multimédia reçoit un nouvel exemple, il obtient l’horodatage de l’exemple et tente de restituer l’exemple au moment de la présentation.

L’horloge de présentation dérive ses heures d’horloge d’un autre objet appelé source de temps de présentation. Les sources de temps de présentation exposent l’interface IMFPresentationTimeSource . Certains récepteurs multimédias ayant accès à une horloge précise, ils exposent cette interface. Cela signifie qu’un récepteur multimédia peut planifier des échantillons par rapport à une heure fournie par sa propre horloge. Toutefois, le récepteur multimédia ne peut pas supposer que c’est le cas. Il doit toujours utiliser l’heure de l’horloge de présentation, que l’horloge de présentation soit pilotée par le récepteur multimédia lui-même ou par une autre horloge.

Si un récepteur multimédia ne peut pas faire correspondre des taux à une horloge autre que la sienne, la méthode GetCharacteristics renvoie l’indicateur MEDIASINK_CANNOT_MATCH_CLOCK. Si cet indicateur est présent et que l’horloge de présentation utilise une source d’heure de présentation différente, le récepteur multimédia est susceptible de fonctionner mal. Par exemple, il peut y avoir un problème lors de la lecture.

Un récepteur sans débit est un récepteur multimédia qui ignore les horodatages sur les échantillons et consomme des données dès que chaque échantillon arrive. Un récepteur de média sans taux retourne l’indicateur MEDIASINK_RATELESS à partir de la méthode GetCharacteristics . En règle générale, cet indicateur s’applique aux récepteurs d’archivage. Si chaque récepteur multimédia dans le pipeline est sans débit, la session multimédia utilise une horloge de présentation sans débit spéciale. Cette horloge s’exécute aussi rapidement que les récepteurs consomment des échantillons.

Formats de flux

Avant que le récepteur multimédia puisse recevoir des exemples, le client doit définir le type de média sur les récepteurs de flux. Pour définir le type de média, appelez la méthode IMFStreamSink::GetMediaTypeHandler du récepteur de flux. Cette méthode retourne un pointeur vers l’interface IMFMediaTypeHandler . Utilisez cette interface pour obtenir la liste des types de médias préférés, obtenir le type de média actuel et définir le type de média.

Pour obtenir la liste des types de médias préférés, appelez IMFMediaTypeHandler::GetMediaTypeByIndex. Les types préférés doivent être pris en tant qu’indicateur pour le client. La liste peut être incomplète ou inclure des types de médias partiels. Un type de média partiel est un type qui n’a pas tous les attributs nécessaires pour décrire un format valide. Par exemple, un type de vidéo partielle peut spécifier l’espace de couleur et la profondeur de bits, mais pas la largeur ou la hauteur de l’image. Un type audio partiel peut spécifier le format de compression et la fréquence d’échantillonnage, mais pas le nombre de canaux audio.

Pour obtenir le type de média actuel du récepteur de flux, appelez IMFMediaTypeHandler::GetCurrentMediaType. Lorsqu’un récepteur de flux est créé pour la première fois, il peut avoir un type de média par défaut déjà défini, ou il peut ne pas avoir de type de média tant que le client n’en a pas défini un.

Pour définir le type de média, appelez IMFMediaTypeHandler::SetCurrentMediaType. Certains récepteurs de flux peuvent ne pas prendre en charge la modification du type une fois que a été défini. Par conséquent, il est utile de tester les types de supports avant de les définir. Pour tester si le récepteur multimédia accepte un type de média (sans définir le type), appelez IMFMediaTypeHandler::IsMediaTypeSupported.

Data Flow

Les récepteurs multimédias utilisent un modèle d’extraction, ce qui signifie que les récepteurs de flux demandent des données en fonction de leurs besoins. Le client doit répondre en temps opportun pour éviter les démangeaisons.

Certains récepteurs multimédias prennent en charge la pré-inscription. La pré-inscription est le processus qui consiste à fournir des données au récepteur multimédia avant le démarrage de l’horloge de présentation. Si un récepteur multimédia prend en charge la préinsuration, le récepteur multimédia expose l’interface IMFMediaSinkPreroll , et la méthode GetCharacteristics retourne l’indicateur MEDIASINK_CAN_PREROLL. La pré-inscription garantit que le récepteur multimédia est prêt à présenter le premier exemple au démarrage de l’horloge de la présentation. Il est recommandé que le client se prérolle toujours si le récepteur multimédia le prend en charge, car il peut éviter les problèmes de blocage ou les lacunes pendant la lecture.

Le flux de données vers un récepteur multimédia fonctionne comme suit :

  1. Le client définit les types de supports et l’horloge de présentation. Le récepteur multimédia s’inscrit lui-même auprès de l’horloge de présentation pour recevoir des notifications sur les changements d’état d’horloge.
  2. Si vous le souhaitez, le client interroge IMFMediaSinkPreroll. Si le récepteur multimédia expose cette interface, le client appelle IMFMediaSinkPreroll::NotifyPreroll. Sinon, le client passe à l’étape 5.
  3. Chaque récepteur de flux envoie un ou plusieurs événements MEStreamSinkRequestSample . En réponse à chacun de ces événements, le client obtient l’échantillon de données suivant pour ce flux et appelle IMFStreamSink::P rocessSample.
  4. Lorsque chaque récepteur de flux reçoit suffisamment de données de pré-inscription, il envoie un événement MEStreamSinkPrerolled .
  5. Le client appelle IMFPresentationClock::Start pour démarrer l’horloge de présentation.
  6. L’horloge de présentation avertit le récepteur multimédia que l’horloge démarre, en appelant IMFClockStateSink::OnClockStart.
  7. Pour obtenir plus de données, chaque récepteur de flux envoie des événements MEStreamSinkRequestSample . En réponse à chacun de ces événements, le client obtient l’exemple suivant et appelle ProcessSample. Cette étape est répétée jusqu’à la fin de la présentation.

La plupart des récepteurs multimédias traitent des exemples de manière asynchrone, de sorte que les récepteurs de flux peuvent envoyer plusieurs exemples de requête à la fois.

Pendant la diffusion en continu, le client peut appeler IMFStreamSink::P laceMarker et IMFStreamSink::Flush à tout moment. Les marqueurs sont décrits dans la section suivante. Le vidage entraîne la suppression par le récepteur de flux de tous les échantillons qu’il a mis en file d’attente, mais qui n’ont pas encore été rendus.

Marqueurs

Les marqueurs permettent au client d’indiquer des points spécifiques dans le flux. Un marqueur se compose des informations suivantes :

  • Type de marqueur, défini comme membre de l’énumération MFSTREAMSINK_MARKER_TYPE .
  • Données associées au marqueur. La signification des données dépend du type de marqueur. Certains types de marqueurs n’ont pas de données.
  • Données facultatives pour la propre utilisation du client.

Pour placer un marqueur, le client appelle IMFStreamSink::P laceMarker. Le récepteur de flux termine le traitement des échantillons qu’il a reçus avant l’appel PlaceMarker , puis envoie un événement MEStreamSinkMarker .

La plupart des récepteurs multimédias conservent une file d’attente d’exemples en attente, qu’ils traitent de manière asynchrone. Les événements de marqueur doivent être sérialisés avec un traitement d’échantillon, de sorte que le récepteur multimédia doit placer les marqueurs dans la même file d’attente. Par exemple, supposons que le client effectue les appels de méthode suivants :

  1. ProcessSample (exemple n°1)
  2. ProcessSample (exemple n°2)
  3. PlaceMarker (Marqueur n°1)
  4. ProcessSample (exemple n°3)
  5. PlaceMarker (Marqueur n°2)

Dans cet exemple, le récepteur de flux doit envoyer l’événement MEStreamSinkMarker pour le marqueur n°1 après le traitement de l’exemple #2, et l’événement pour le marqueur #2 après le traitement de l’exemple #3.

Si le client vide un récepteur de flux, le récepteur de flux traite immédiatement tous les marqueurs qui se trouvaient dans la file d’attente. Il définit le code status de E_ABORT sur ces événements.

Certains marqueurs contiennent des informations pertinentes pour le récepteur multimédia :

  • MFSTREAMSINK_MARKER_TICK : indique qu’il existe un écart dans le flux. L’exemple suivant sera une discontinuité.
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT : indique la fin d’un segment ou la fin d’un flux. L’exemple suivant (le cas échéant) peut être une discontinuité.
  • MFSTREAMSINK_MARKER_EVENT : contient un événement. Selon le type d’événement et l’implémentation du récepteur multimédia, le récepteur multimédia peut gérer l’événement ou l’ignorer.

Changements d'état

Un récepteur multimédia est averti des changements d’état dans l’horloge de présentation via l’interface IMFClockStateSink du récepteur multimédia. Lorsque le client définit l’horloge de présentation, le récepteur multimédia appelle IMFPresentationClock::AddClockStateSink pour s’inscrire aux notifications à partir de l’horloge. Le tableau suivant récapitule le comportement d’un récepteur multimédia en réponse aux changements d’état d’horloge.

Changement d’état de l’horloge Exemple de traitement Traitement des marqueurs
OnClockStart Traiter des exemples dont l’horodatage est égal ou supérieur à l’heure de début de l’horloge. Envoyez l’événement MEStreamSinkMarker lorsque tous les échantillons reçus avant le marqueur ont été traités.
OnClockPause Le récepteur multimédia peut faire échouer ProcessSample en pause.
Si le récepteur multimédia accepte des exemples en pause, il doit les mettre en file d’attente jusqu’à ce que l’horloge redémarre. Ne traitez aucun exemple mis en file d’attente pendant la pause.
S’il existe des exemples mis en file d’attente, placez les marqueurs dans la même file d’attente. Envoyez l’événement de marqueur lorsque l’horloge redémarre.
Sinon, envoyez immédiatement l’événement de marqueur.
OnClockRestart Traitez tous les échantillons mis en file d’attente pendant la pause, puis traitez la même chose que OnClockStart. Envoyez des événements MEStreamSinkMarker pour les marqueurs mis en file d’attente (sérialisés avec un traitement d’exemple), puis traitez la même chose que OnClockStart.
OnClockStop Supprimez tous les exemples mis en file d’attente. D’autres appels à ProcessSample peuvent échouer. Envoyer des événements de marqueur mis en file d’attente. Lors des appels suivants à PlaceMarker, envoyez immédiatement l’événement de marqueur.

 

En outre, les récepteurs de flux doivent envoyer les événements suivants lorsqu’ils ont terminé les transitions d’état :

En cours de finalisation

Certains récepteurs multimédias nécessitent une étape de traitement supplémentaire après la livraison du dernier échantillon. En règle générale, cette exigence s’applique aux récepteurs d’archivage, qui doivent écrire des en-têtes ou des index dans le fichier. Si un récepteur multimédia nécessite un traitement final, il expose l’interface IMFFinalizableMediaSink .

Une fois que le client a livré le dernier exemple, le client interroge cette interface. Si le récepteur multimédia prend en charge l’interface, le client appelle IMFFinalizableMediaSink::BeginFinalize pour effectuer le traitement final de façon asynchrone. Cette méthode suit le modèle asynchrone Media Foundation standard, décrit dans Méthodes de rappel asynchrones. Le récepteur multimédia peut supposer que le client appelle BeginFinalize. L’échec de l’appel de BeginFinalize peut entraîner la création d’un fichier incorrect.

Fermeture

Lorsque le client a terminé d’utiliser le récepteur multimédia, il appelle IMFMediaSink::Shutdown. À l’intérieur de cette méthode, le récepteur multimédia doit interrompre les nombres de références circulaires. En règle générale, il y a des références circulaires entre le récepteur multimédia et les récepteurs de flux.

Si vous utilisez l’objet d’assistance de file d’attente d’événements pour implémenter IMFMediaEventGenerator, appelez IMFMediaEventQueue::Shutdown dans la file d’attente d’événements. Cette méthode arrête la file d’attente d’événements et signale tout appelant en attente d’un événement.

Après l’arrêt, toutes les méthodes sur le récepteur multimédia retournent MF_E_SHUTDOWN, à l’exception des méthodes IUnknown .

Interfaces du récepteur multimédia

Le tableau suivant répertorie les interfaces standard que les récepteurs multimédias peuvent exposer via QueryInterface. Les récepteurs multimédias peuvent également exposer des interfaces personnalisées.

Interface Description
IMFMediaSink Interface principale pour les récepteurs multimédias. (Obligatoire.)
IMFClockStateSink Permet d’avertir le récepteur multimédia lorsque l’horloge de présentation change d’état. (Obligatoire.)
IMFFinalizableMediaSink Implémentez si le récepteur de média doit effectuer une dernière étape de traitement. (Facultatif.)
IMFGetService Implémentez si le récepteur multimédia expose des interfaces de service. (Facultatif.)
IMFMediaEventGenerator Implémentez si le récepteur multimédia envoie des événements. (Facultatif.)
IMFMediaSinkPreroll Implémentez si le récepteur multimédia prend en charge le préroll. (Facultatif.)
IMFPresentationTimeSource Implémentez si le récepteur multimédia peut fournir une source de temps pour l’horloge de présentation. (Facultatif.)
IMFQualityAdvise Implémentez si le récepteur multimédia peut ajuster la qualité de lecture. (Facultatif.)

 

Si vous le souhaitez, un récepteur multimédia peut implémenter l’interface suivante en tant que service.

Interface de service Description
IMFRateSupport Indique la plage des taux de lecture pris en charge.

 

Pour plus d’informations sur les interfaces de service et IMFGetService, consultez Interfaces de service.

Interfaces de récepteur de flux

Les récepteurs de flux doivent exposer les interfaces suivantes via QueryInterface.

Interface Description
IMFStreamSink Interface principale pour les récepteurs de flux. (Obligatoire.)
IMFMediaEventGenerator Événements de file d’attente. L’interface IMFStreamSink hérite de cette interface. (Obligatoire.)

 

Actuellement, aucune interface de service n’est définie pour les récepteurs de flux.

Événements de récepteur de flux

Le tableau suivant répertorie les événements définis pour les récepteurs de flux génériques. Les récepteurs de flux peuvent également envoyer des événements personnalisés qui ne sont pas répertoriés ici.

Événement Description
MEStreamSinkFormatChanged Le type de média du récepteur de flux n’est plus valide. (Facultatif.)
MEStreamSinkMarker Un marqueur a été traité. (Obligatoire.)
MEStreamSinkPaused Le récepteur de flux a été suspendu. (Obligatoire.)
MEStreamSinkPrerolled Le préroll est terminé. (Facultatif.)
MEStreamSinkRateChanged La fréquence de lecture du récepteur de flux a changé. (Facultatif.)
MEStreamSinkRequestSample Un nouvel exemple est demandé. (Obligatoire.)
MEStreamSinkScrubSampleComplete Une demande de nettoyage a été effectuée. (Facultatif.)
MEStreamSinkStarted Le récepteur de flux a démarré. (Obligatoire.)
MEStreamSinkstopped Le récepteur de flux s’est arrêté. (Obligatoire.)

 

Actuellement, aucun événement à usage général n’est défini pour les récepteurs multimédias. Certains récepteurs multimédias peuvent envoyer des événements personnalisés.

Media Foundation Pipeline

Architecture Media Foundation