other_android_mediacodec.tex 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. \section{Cadre du projet}
  2. La mission s'inscrivait dans le cadre de la diffusion d'un flux vidéo vers un
  3. chromecast. Il s'avère que le chromecast ne supporte pas de recevoir des flux de
  4. sous-titre, ou alors certains formats seulement. Ceci parce qu'il était à la
  5. base prévu pour Youtube qui n'est jamais très loin du format Webm.
  6. Le webm est un format utilisant une sous-partie du format Matroska, en étant
  7. spécialement dédié à la diffusion de vidéo sur le web et dans un navigateur.
  8. % TODO: expliquer demuxage
  9. L'idée pour intégrer les sous-titres lors de la diffusion est donc de démuxer
  10. les fichiers, puis de rendre ces sous-titres avant directement sur la vidéo
  11. avant de remuxer puis envoyer au chromecast, le tout en temps réel.
  12. Lors de la diffusion d'une vidéo depuis un téléphone, on tombe alors sur un
  13. nouveau problème: l'usage de la batterie. Décoder et réencoder de la vidéo
  14. consomme beaucoup de CPU et le téléphone finit par chauffer et se décharger très
  15. vite.
  16. On peut alors utiliser plutôt les circuits d'encodage intégrés sur presque tous
  17. les téléphones. Ces derniers consomment beaucoup moins d'énergie que leur
  18. pendant logiciel, mais leurs fonctionnalités sont matériellement figées dans les
  19. circuits qui les composent. Ils sont également limités en nombre de sessions
  20. possible, et peuvent avoir des comportements différents entre chaque téléphone
  21. ou faire crasher le programme, voire le téléphone en cas d'utilisation
  22. incorrecte.
  23. % TODO: reference MediaCodec
  24. Pour les téléphones Android, c'est l'API MediaCodec
  25. \footnote{\url{https://developer.android.com/reference/android/media/MediaCodec}}
  26. qu'il faut utiliser afin de manipuler les décodeurs/encodeurs disponibles sur le
  27. téléphone. Un décodeur MediaCodec étant déjà existant, il s'agit plus ou moins
  28. d'étendre les fonctionnalités déjà en place pour pouvoir également instancier un
  29. encodeur.
  30. Dans cette partie-là, nous allons voir ce qu'est un encodeur, comment ils sont
  31. construits et utilisés au sein de VLC ainsi que quelques détails de
  32. l'implémentation finale de l'encodeur utilisant l'API MediaCodec d'Android.
  33. \section{Qu'est-ce qu'un encodeur}
  34. L'encodeur est le module qui récupère des images dans un format fixé et produit
  35. un bytestream vidéo correspondant au format d'encodage vidéo choisi. Il se situe
  36. donc après les filtres vidéos et avant le muxer. Pour la plupart des formats,
  37. l'encodeur a besoin de données spéciales relative au format utilisé. Pour h264,
  38. il s'agit du SPS et PPS, décrivant les informations communes aux images
  39. encodées.
  40. L'encodeur dans MediaCodec fonctionne comme une machine à état asynchone. Il est
  41. probablement important de noter que l'API n'indique pas qu'elle est thread-safe.
  42. % TODO: rôle dans la chaine avec schéma
  43. % TODO: codec specific data
  44. % TODO: état de l'encodeur
  45. % TODO: flux de données
  46. \section{Fonctionnement d'un encodeur dans VLC}
  47. Dans VLC, l'encodeur est principalement utilisé par un seul module: le module
  48. \og{}transcode\fg{}. À ce jour, il utilise un flux multimédia complet en entrée,
  49. c'est-à-dire plusieurs \og{}elementary streams\fg{} que sont les les sous-titres, les
  50. flux vidéos et les flux audios. Il produit ensuite le même flux multimédia
  51. encodé par un muxer.
  52. % TODO: exemple d'utilisation du module transcode en console
  53. L'encodeur est définit par la structure suivante dans le core de VLC.
  54. \begin{code}{c}{Structure d'un encodeur dans VLC}
  55. struct encoder_t
  56. {
  57. /* common fields */
  58. /* ... */
  59. /* Properties of the input data fed to the encoder */
  60. es_format_t fmt_in;
  61. /* Properties of the output of the encoder */
  62. es_format_t fmt_out;
  63. block_t * ( * pf_encode_video )( encoder_t *, picture_t * );
  64. block_t * ( * pf_encode_audio )( encoder_t *, block_t * );
  65. block_t * ( * pf_encode_sub )( encoder_t *, subpicture_t * );
  66. /* Common encoder options */
  67. /* ... */
  68. };
  69. \end{code}
  70. La première remarque est que l'encodage se fait de façon asynchrone. En effet,
  71. malgré l'interface ici, le module a la possibilité de renvoyer des
  72. pointeur \inltype{block_t} vers \inltype{NULL} pour indiquer qu'il n'a pas fini
  73. de décoder.
  74. % TODO: encodage synchrone : on remplit les pf des types de flux qu'on supporte
  75. % TODO: fmt_in / fmt_out => pas modifiable après ouverture de l'encodeur
  76. % TODO :modifier paragraphe d'apres
  77. \section{Implémentation de l'encodeur}
  78. Des problèmes arrivent dès le début de l'implémentation. Il n'est en effet pas
  79. possible de modifier le format de sortie de l'encodeur après son initialisation
  80. dans la fonction \inltype{OpenEncoder}. Or les informations sur le codec --
  81. codec specific data -- ne sont disponibles qu'après avoir commencé à encoder les
  82. premières images.
  83. L'implémentation que j'ai réalisée fait en sorte de retarder la création du flux
  84. de sortie jusqu'au moment où les premières images encodées sont disponibles. Or,
  85. certains muxeur en sortie ne permettent pas de réaliser ce délai. Des
  86. modifications sur l'architecture étaient donc nécessaires pour l'intégration de
  87. mon travail et étaient en cours à la fin de mon stage.
  88. L'encodeur fonctionne à travers l'API java de MediaCodec, appelé depuis
  89. l'interface JNI. La raison de ce choix est l'impossibilité d'effectuer certaines
  90. actions essentielles à partir de l'interface proposée par le NDK d'android.
  91. Les principales difficultés ont été de:
  92. \begin{itemize}
  93. \item Comprendre le fonctionnement de l'encodeur dans VLC.
  94. \item Comprendre les interactions avec le muxer.
  95. \item Déterminer la façon la plus correcte de définir des PTS et DTS.\@
  96. \end{itemize}
  97. La réalisation du module a été une excellente occasion pour comprendre en
  98. profondeur l'agencement des différents modules du pipeline de VLC.