vlc_explanations.tex 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. \section{Architecture de VLC}
  2. VLC est découpé en plusieurs parties. Deux parties ressortent particulièrement
  3. comme étant des bibliothèques charnières pour le fonctionnement du logiciel.
  4. D'un côté, les applications finales utilisent l'interface exposée par la
  5. LibVLC. L'objectif est d'avoir quelque chose de très haut niveau pour
  6. construire un pipeline sans avoir besoin des considérations techniques liées au
  7. multimédia.
  8. De l'autre LibVLC fonctionne à travers la LibVLCCore qui expose les fonctions
  9. bas niveau de chargement de module et contrôle les threads, les modules, les
  10. horloges, la liste de lecture et tout le contrôle bas niveau dans VLC. Les
  11. modules sont alors linkés à la LibVLCCore pour profiter des fonctions bas
  12. niveau.
  13. % Mettre schéma
  14. En résumé LibVLC expose l'API tandis que LibVLCCore réalise le lien entre les
  15. différents modules. La sélection des modules à utiliser est donc au cœur du
  16. développement de VLC, ce qui rend le core bien plus maintenable que les modules
  17. eux-mêmes.
  18. Il faut néanmoins noter que les modules sont chargés à partir du moment où un
  19. autre module le demande. C'est ce qui crée la notion de pipeline dynamique:
  20. seuls les modules apportant les fonctionnalités requises par un autre module
  21. sont injectés dans le pipeline. Ces modules sont alors chargés soit de façon
  22. statique, soit depuis une bibliothèque de code dynamique.
  23. Actuellement, le développement de VLC est beaucoup centré sur son approche
  24. multi-thread, par exemple pour que les décodeurs et les sorties fonctionnent de
  25. manière indépendante et correctement synchroniser le temps. Le décodeur et la
  26. sortie vidéo fonctionnent ainsi de manière asynchrone. L'idée centrale est
  27. qu'avoir plusieurs entrées en lecture et plusieurs sorties simultanément ne doit
  28. pas être impossible. Une démonstration de cette fonction a d'ailleurs été mis en
  29. place en tant que «VLM», qui permet de contrôler plusieurs flux en entrées et de
  30. choisir comment les utiliser en sortie; que ce soit en les diffusant, en créant
  31. une mosaïque ou en affichant des flux dans de nouvelles sorties.
  32. \section{Variables de configuration}
  33. La gestion de la configuration des modules dans VLC passe principalement par un
  34. système d'objet à travers le type \inltype{vlc_object_t}. Tous les modules de
  35. VLC sont représentés comme un \inltype{vlc_object_t} tout comme certains
  36. éléments du core et la LibVLC elle-même. Ces objets sont liés à un objet
  37. \inltype{libvlc_instance_t} particulier et sont agencés en arbre d'objet.
  38. On peut associer des variables à ces objets en leur faisant suivre certaines
  39. règles. On peut par exemple les créer avec une valeur par défaut, les créer sans
  40. leur donner de valeur ou bien les créer en les initialisant récursivement avec
  41. la valeur du parent.
  42. Ces variables portent ainsi une configuration qui leur est propre, venant de la
  43. configuration imposée ou suggérée par leur parent, qui vient de la configuration
  44. donnée en ligne de commande ou qui vient du fichier de configuration de VLC.\@
  45. Il s'agit donc d'un mélange entre une interface utilisateur et une interface
  46. entre modules.
  47. \section{Modules}
  48. Le principal de l'architecture actuelle de VLC est organisé autour de la notion
  49. de module. D'un côté, le core contrôle le chargement des fonctionnalités et joue
  50. un rôle d'orchestrateur. De l'autre côté chaque fonctionnalité est apportée par
  51. un module qui peut être chargé dynamiquement ou lié statiquement à
  52. l'application.
  53. Les modules sont manipulés à travers les \inltype{vlc_plugin_t} qui eux-même
  54. manipulent les \inltype{module_t} contenant la représentation interne du module.
  55. % TODO: décrire plus exactement ce qu'il faut highlight, en particulier
  56. % chargement des modules dans la sandbox, stockage des options, etc
  57. \begin{code}{c}{Structure d'un plugin}
  58. typedef struct vlc_plugin_t
  59. {
  60. struct vlc_plugin_t *next;
  61. module_t *module;
  62. unsigned modules_count;
  63. const char *textdomain; /**< gettext domain (or NULL) */
  64. /* Variables set by the module to store its config options */
  65. struct
  66. {
  67. module_config_t *items; /**< Table of configuration parameters */
  68. size_t size; /**< Size of items table */
  69. size_t count; /**< Number of configuration items */
  70. size_t booleans; /**< Number of booleal config items */
  71. } conf;
  72. #ifdef HAVE_DYNAMIC_PLUGINS
  73. bool unloadable; /**< Whether the plug-in can be unloaded safely */
  74. atomic_uintptr_t handle; /**< Run-time linker handle (or nul) */
  75. char *abspath; /**< Absolute path */
  76. char *path; /**< Relative path (within plug-in directory) */
  77. int64_t mtime; /**< Last modification time */
  78. uint64_t size; /**< File size */
  79. #endif
  80. } vlc_plugin_t;
  81. \end{code}
  82. \inltype{vlc_plugin_t} contient ainsi les informations pour charger et décharger
  83. les modules.
  84. \begin{code}{c}{Structure d'un module}
  85. struct module_t
  86. {
  87. vlc_plugin_t *plugin; /**< Plug-in/library containing the module */
  88. module_t *next;
  89. /** Shortcuts to the module */
  90. unsigned i_shortcuts;
  91. const char **pp_shortcuts;
  92. /*
  93. * Variables set by the module to identify itself
  94. */
  95. const char *psz_shortname; /**< Module name */
  96. const char *psz_longname; /**< Module descriptive name */
  97. const char *psz_help; /**< Long help string for "special" modules */
  98. const char *psz_capability; /**< Capability */
  99. int i_score; /**< Score for the capability */
  100. /* Callbacks */
  101. const char *activate_name;
  102. const char *deactivate_name;
  103. void *pf_activate;
  104. void *pf_deactivate;
  105. };
  106. \end{code}
  107. De l'autre côté, \inltype{module_t} contient la description d'un module, qu'il
  108. soit chargé dynamiquement ou non.
  109. Chaque module dispose d'une priorité, qui correspond au score \inltype{i_score}
  110. dans \inltype{module_t}.
  111. Ces modules sont chargés dans l'application depuis deux fonctions du core:
  112. \begin{itemize}
  113. \item \inltype{module_need} permet de charger un module correspondant au nom ou à la
  114. fonction \inltype{i_capability} du module, en utilisant le premier module de plus forte
  115. priorité qui est capable de se charger sans erreur.
  116. \item \inltype{module_need_var} qui dans les faits appelle \inltype{module_need} en lui donnant le
  117. contenu d'une variable au lieu d'une recherche hardcodée.
  118. \end{itemize}
  119. Les détails de ces fonctions sont décrits ici car il s'agit de l'interface
  120. exposée par VLC pour charger un nouveau module. C'est donc un point d'entrée
  121. potentiel pour l'injection des abstractions de la sandbox.
  122. \begin{code}{c}{API de requête de module}
  123. module_t *vlc_module_load(vlc_object_t *obj, const char *capability,
  124. const char *name, bool strict,
  125. vlc_activate_t probe, ...);
  126. module_t *module_need(vlc_object_t *obj, const char *cap, const char *name,
  127. bool strict)
  128. \end{code}
  129. Ces fonctions sont généralement appelées après avoir créé un objet correspondant
  130. au type du module en question. Si dessous, on peut voir un exemple au sein de
  131. l'api de gestion des documents XML.\@
  132. \begin{code}{c}{Création d'objet VLC puis chargement de modules}
  133. /* from src/misc/xml.c */
  134. p_xml = vlc_custom_create( p_this, sizeof( *p_xml ), "xml" );
  135. p_xml->p_module = module_need( p_xml, "xml", NULL, false );
  136. reader = vlc_custom_create(obj, sizeof(*reader), "xml reader");
  137. reader->p_module = module_need(reader, "xml reader", NULL, false);
  138. \end{code}
  139. Par exemple, nous avons ici la création d'un objet représentant un module
  140. d'analyse syntaxique XML. Le module est ensuite chargé dans l'objet. Puis un
  141. autre couple d'objet et module est chargé, cette fois-ci pour une \inltype{i_capability}
  142. de type \inltype{xml_reader}.
  143. % TODO: décrire module_need en détail et comment on peut vouloir la patcher pour
  144. % prendre en compte la sandbox.
  145. % TODO: parler de libvlc et vlc_object
  146. + parler des variables VLC