web-dev-qa-db-fra.com

Décodage du flux Raw H264 dans Android?

J'ai un projet où on m'a demandé d'afficher un flux vidéo dans Android, le flux est brut H.264 et je me connecte à un serveur et je recevrai un flux d'octets du serveur.

Fondamentalement, je me demande s'il existe un moyen d'envoyer des octets bruts à un décodeur dans Android et de l'afficher sur une surface?

J'ai réussi à décoder le H264 enveloppé dans un conteneur mp4 en utilisant les nouvelles API MediaCodec et MediaExtractor dans Android 4.1, malheureusement je n'ai pas trouvé de moyen de décoder un fichier ou un flux H264 brut en utilisant ces API. .

Je comprends qu'une façon est de compiler et d'utiliser FFmpeg mais je préfère utiliser une méthode intégrée qui peut utiliser l'accélération matérielle. Je comprends également que le streaming RTSP est pris en charge dans Android mais ce n'est pas une option. Android n'est pas un problème.

33
will

Je ne peux malheureusement pas fournir de code pour cela, mais je ferai de mon mieux pour l'expliquer en fonction de la façon dont je l'ai fait fonctionner.

Voici donc mon aperçu de la façon dont j'ai réussi à faire fonctionner la vidéo codée H.264 brute à l'aide de la classe MediaCodec .

En utilisant le lien ci-dessus, il y a un exemple pour obtenir la configuration du décodeur et comment l'utiliser, vous devrez le configurer pour décoder le H264 AVC.

Le format de H.264 est qu'il est composé d'unités NAL, chacune commençant par un préfixe de début de trois octets avec les valeurs 0x00, 0x00, 0x01 et chaque unité a un type différent en fonction de la valeur du 4e octet juste après celles-ci 3 octets de départ. Une unité NAL N'EST PAS une image dans la vidéo, chaque image est composée d'un certain nombre d'unités NAL.

Fondamentalement, j'ai écrit une méthode qui trouve chaque unité individuelle et la transmet au décodeur (une unité NAL étant le préfixe de départ et tous les octets après jusqu'au préfixe de démarrage suivant).

Maintenant, si vous avez la configuration du décodeur pour décoder le H.264 AVC et avez un InputBuffer du décodeur, alors vous êtes prêt à partir. Vous devez remplir ce InputBuffer avec une unité NAL et le renvoyer au décodeur et continuer à le faire pour la longueur du flux. Mais, pour que cela fonctionne, je devais d'abord passer au décodeur une unité NAL SPS (Sequence Parameter Set). Cette unité a une valeur d'octet de 0x67 après le préfixe de départ (le 4ème octet), sur certains appareils, le décodeur plantait à moins qu'il n'ait reçu cette unité en premier. Fondamentalement, jusqu'à ce que vous trouviez cette unité, ignorez toutes les autres unités NAL et continuez d'analyser le flux jusqu'à ce que vous obteniez cette unité, puis vous pouvez passer toutes les autres unités au décodeur.

Certains appareils n'avaient pas besoin du SPS en premier et d'autres en avaient besoin, mais il vaut mieux le passer en premier.

Maintenant, si vous aviez une surface que vous avez transmise au décodeur lorsque vous l'avez configurée, une fois qu'il obtient suffisamment d'unités NAL pour un cadre, il devrait l'afficher sur la surface.

29
will

Voici les ressources que j'ai trouvées utiles dans un projet similaire:

  1. Cette vidéo a été très utile pour comprendre comment MediaCodec gère les flux h.264 bruts à un niveau élevé.
  2. Ce fil va un peu plus en détail quant à la gestion des NALU SPS/PPS en particulier. Comme mentionné ci-dessus, vous devez séparer les unités NAL individuelles à l'aide du préfixe de démarrage, puis remettre les données restantes au MediaCodec.
  3. Ce dépôt (libstreaming) est un excellent exemple de décodage d'un flux H264 dans Android utilisant RTSP/RTP pour la transmission.
1
Jk Jensen