• Aucun résultat trouvé

Dans cette sous-section, nous parlons du fonctionnement interne de la librairie FFmpeg lors de la génération d’un fichier d’examen (ou d’un flux réseau). Pour ce faire, nous parcourrons les différentes structures proposées par FFmpeg pour faire ce traitement. La figure 30 schématise l’organisation des structures utiles à la création d’un fichier BIO-MKV. Nous ne rentrons pas dans tous les détails de ces structures dans cette sous-section. Davantage d’informations peuvent être lues dans l’annexe A. Aussi, dans ces explications, certains noms de variable ont été changés par rapport à leur implémentation dans FFmpeg, de manière à être plus parlant. Par exemple, le nom de variable codec est utilisé dans deux structures différentes pour faire référence à deux objets distincts. Nous en avons renommé un des deux pour écarter l’ambiguïté.

Dans le processus de création d’un fichier, le nœud principal est l’objet AVFormat-Contextpermettant de créer un contexte de multiplexage. Ce contexte, disponible à l’utilisateur, contient toutes les informations relatives à la création d’un fichier multimé-dia. Nous y trouvons plusieurs références vers des objets gérant les codecs, le format du flux et la sortie du flux. La première référence format pointe vers la variable de type AVOutputFormatgérant la construction d’un flux dans un format précis. Dans notre cas, format pointera vers notre implémentation de BIO-MKV. La deuxième référence io pointe vers une variable AVIOContext permettant de gérer les différentes formes de sortie que supporte FFmpeg. C’est à travers cet objet que les écritures vers un fichier ou que les envois de paquet sont effectués. Nous utilisons soit une sortie vers un fichier soit

une sortie réseau utilisant le protocole TCP/IP. En pratique, pour former un paquet, une fonction spécifique au format de la structure AVOutputFormat est appelée. Dans cette fonction, des appels aux méthodes de la structure AVIOContext sont faits pour écrire le flux dans sa forme finale. Les dernières références définies par la variable streams est un tableau de flux. Ces flux, tous décrits par une variable AVStream, gèrent les données propres à une piste du format BIO-MKV comme l’avancement de l’encodage, le temps courant et également un contexte de compression.

AVFormatContext streams format io AVStream codec_ctx AVCodecContext codec AVCodec encode(frame, pkt) decode(pkt, frame) AVIOContext write(buffer) AVOutputFormat write_header(ctx) write_packet(ctx, pkt) 1 n

Figure 30. Diagramme UML des objets utiles à la création d’un fichier BIO-MKV

Le contexte de compression, matérialisé par la structure AVCodecContext, stocke toutes les informations relatives au codec utilisé pour la piste décrite. Elle contient entre autres le type de données traité. Dans le cas des modalités audio, vidéo et anno-tations, ce type est celui défini par FFmpeg comme étant AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_VIDEOet AVMEDIA_TYPE_SUBTITLE. Par contre, FFmpeg ne sup-porte pas nativement les données physiologiques. Nous avons donc dû les intégrer dans un type de données de FFmpeg. Nous avons choisi d’utiliser le type AVME-DIA_TYPE_DATAdisponible par défaut dans la librairie. C’est un type abstrait pour FFmpeg. De ce fait, à aucun moment dans le code de la librairie, il n’y a d’hypothèse de faite sur le contenu des paquets de ce type. Nous aurions pu intégrer un nouveau type physiologique mais cela aurait impacté beaucoup de condition et d’hypothèse que fait la librairie et aurait requis un effort de développement peu justifié. La structure AVCodecContextcontient également l’identifiant du codec utilisé. Dans le cas des signaux physiologiques, nous avons alloué un nouvel identifiant décrivant le codec EDF+. Cette structure est présente même si FFmpeg ne gère pas la compression de la piste décrite. Dans ce cas, c’est à la charge du développeur de générer les paquets pour les écrire dans le format. Nous avons utilisé cette méthode pour l’encapsulation des signaux physiologiques en nous chargeant nous-mêmes de la création des paquets pour FFmpeg. Pour toutes les autres modalités, nous sommes passé par les implémentations de FFmpeg pour la compression. Dans ces derniers cas, la structure AVCodecContext

contient le champ codec qui pointe vers l’implémentation du codec contenu dans une structure AVCodec.

Dans le cas de la génération d’un fichier d’un examen EEG BIO-MKV comme décrit dans la sous-section 2.1.2, nous aurons un objet AVFormatContext pointant vers notre implémentation de BIO-MKV et vers une sortie fichier. Dans ce contexte seront contenues quatre pistes (signaux physiologiques, vidéo, audio et annotations). Cela implique donc que nous aurons 4 objets de type AVStream, chacun décrivant une piste du flux BIO-MKV. Les trois pistes vidéo, audio et sous-titre (pour les annotations) sont identifiées comme des flux et utilise les implémentations de FFmpeg pour la compression des données. La dernière piste contenant les signaux physiologiques est simplement déclarée comme un flux de type AVMEDIA_TYPE_DATA et encodée avec le codec EDF+ mais dont FFmpeg n’a pas d’implémentation.

Une fois cette phase d’initialisation des structures finie, l’utilisateur peut demander l’écriture de l’entête du fichier BIO-MKV par l’appel de fonction avformat_write_header. Des vérifications sont alors faites sur les pistes présentes dans le contexte AVFormatCon-text, pour savoir si l’implémentation du format en question les supporte. L’écriture du fichier commence par les balises d’entête et de DocType puis par l’unique segment de ce fichier. En effet, notre implémentation ne contient qu’un seul segment contenant l’intégralité de l’examen. Les informations du segment sont placées au début de celui-ci de manière à pouvoir interpréter directement le reste du segment. Elles sont donc écrites à ce moment en indiquant que l’échelle des timestamps est une nanoseconde, que l’heure de création du fichier est l’instant courant et que l’application écrivant le fichier est l’encodeur Smart-EEG. Ensuite, les différentes pistes du format sont déclarées dans la balise tracks. C’est à ce moment-là que le lien est fait entre la déclaration d’un flux dans la structure AVFormatContext et la déclaration de la piste dans le fichier BIO-MKV. Pour chaque flux, une nouvelle balise track est créée. Elles sont numérotées de 1 à n (n étant le nombre de pistes du fichier). Ce numéro correspond à l’identifiant de la piste qui est écrit dans le fichier. Le nom du codec est récupéré dans la structure AVCodecContext et permet au décodeur de connaître le codec utilisé pour la piste. L’écriture du type de flux pour la vidéo, l’audio, les annotations et les données physiologiques est respectivement une piste vidéo avec le type 1, une piste audio avec le type 2, un piste sous-titre avec le type 10 et pour finir une physio avec le type 17. Les informations propres à chaque modalité sont ensuite écrites (taille de la vidéo, fréquence audio, etc.). La balise track de la piste en question est ensuite fermée pour passer à la suivante. Quand toutes les pistes sont écrites dans l’entête, la balise tracks est fermée et le contenu de l’examen peut commencer à être écrit.

L’utilisateur peut à présent faire des appels à av_interleaved_write_frame qui est une des fonctions permettant d’écrire un paquet dans le format de sortie. Même si son nom est trompeur, la fonction prend en argument le paquet à écrire dans le fichier. La fonction prend également en argument le contexte du format contenant toutes les

informations du multiplexage. Son premier travail est de déterminer si le paquet à écrire peut être placé dans le cluster précédemment ouvert (par un ancien appel à la même fonction). Pour ce faire, elle calcule la taille et le temps accumulé du cluster courant. Si le précédent cluster dépasse 5 s ou 5 MO, alors un nouveau cluster est créé dans le fichier. Dans ce cas, elle enregistre la taille du fichier à ce moment-là pour pouvoir mesurer la taille du cluster dans les prochains appels de cette fonction et procède à la fermeture du cluster précédent et à l’écriture d’une nouvelle balise cluster dans laquelle elle écrit le timestamp du nouveau cluster. L’écriture du bloc en lui-même est ensuite effectuée en commençant par l’entête du bloc qui précise la taille du bloc, son identifiant de piste, son timestamp et si le bloc contient une trame de référence. Les données compressées du paquet sont ensuite écrites dans le fichier. Dans le cas où le bloc n’est pas un simple bloc, l’identifiant du bloc de référence est ajouté après les données. La balise du bloc peut alors être fermée. Nous pouvons remarquer que dans l’étape d’écriture du paquet, il n’y a pas de différence de traitement dû à la nature du paquet, tous les paquets sont traités de la même manière en utilisant les informations présentes dans la structure AVCodecContext.

Lorsque tous les paquets ont été écrits, l’utilisateur appelle la fonction av_write_trailer pour clôturer le fichier. Les derniers paquets qui auraient été placés en tampon sont alors écrits. Dans le cas d’un fichier, les tags , les chapitres ainsi que les pistes sont écrits et les informations présentes au début du fichier (la durée, la taille du fichier ainsi le placement des dernières balises tracks, chapters et tags) sont mises à jour. La balise de segment global ainsi que le fichier sont fermés.

Grâce à cette interface, nous pouvons écrire un programme C qui va produire un fichier examen BIO-MKV. Ce programme C réalisera des appels vers les fonctions contenues dans la librairie FFmpeg. C’est dans la librairie que la création du bitstream du fichier est implémentée. Il est à noter qu’en remplaçant la sortie du flux par une sortie de réseau TCP/IP, le fichier est envoyé à l’adresse précisée.