IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Décodage d'une vidéo H264 sur RTP


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 23
    Points : 20
    Points
    20
    Par défaut Décodage d'une vidéo H264 sur RTP
    Bonjour,

    J'ai une Camera IP qui envoit un flux video codé en H264 sur RTP.

    Je suis capable de réceptionner les paquets et de les stocker dans dans un buffer de Byte ainsi que de les décomposer pour retrouver toutes les caractéristiques du paquets (header RTP ->timestanmp, nO de séquence, SSRC, CSRC ... ; le payload RTP avec son type, mon cas est, par ailleurs, le type FU-A).

    Cependant je suis incapable de de décoder ces paquets.

    Avec une caméra envoyant du MPEG sur RTP, j'ai pu facilement rendre une vidéo en utilisant ffmpeg: je passais directement les paquets reçus à la fonction avcodec_decode_video() sans traitement préalable.

    Avec H-264 aucun résultat ...

    Du coup j'ai reconstitué moi-même les NALUS pour les transmettre au décoder comme indiqué page 33 de la RFC 3984 :
    If a decapsulated packet is an FU-A, all the fragments of the fragmented NAL unit are concatenated and passed to the decoder
    Sans aucun résultat ...

    Je pense que cela vient du réglage de mon décodeur. Du coup j'ai voulu utilisé le préréglage de décodage H264 de ffmpeg (VLC) pour définir le codecContext.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     AVCodec h264_decoder = {
         "h264",
        AVMEDIA_TYPE_VIDEO,
         CODEC_ID_H264,
         sizeof(H264Context),
         ff_h264_decode_init,
        NULL,
        ff_h264_decode_end,
        decode_frame,
        /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY,
        .flush= flush_dpb,
       .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC /MPEG-4 part 10"),
     };
    Mais impossible de l'utiliser dans mon code ...


    Bref, je suis un peu perdu d'autant plus que j'ai aussi essayé d'utiliser DirectShow en faisant un filtre source recevant mes paquets et transmettant mes NALUs reconstituées à des filtres de décodages mais sans résultats non plus.

    Donc si vous avez une idée, n'hésitez pas

    PS: dans vlc la vidéo marche très bien donc normalement avec ffmpeg on devrait y arriver

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 23
    Points : 20
    Points
    20
    Par défaut Décodage de vidéo H264 sur RTP avec ffmpeg (libavcodec)
    J'ai un peu avancé sur la question mais le décodage global ne fonctionne pas.

    Tout d'abord, j'ai récupéré quelques données du SDP que j'avais oublié (profile-level-id et sprop-parameter-set) afin d'alimenter les champs profile_idc, level_idc, extradata et extradata_size de ma structure AvCodecContext.

    Ensuite j'ai séparé le décodage des paquets dits Coded Slice, SPS, PPS et NAL_IDR_SLICE.

    Pour faire simple, les paquets Coded Slice allégés du header RTP sont directement passés au décodeur (avcodec_decode_video) avec le préfixe 0x000001. La fonction me renvoie bien la taille du paquet ConsumedBytes (indique que tous les bytes ont été utilisés pour le décodage) et le paramètre GotPicture indiquant que la frame est bien décodée devient supérieur à zéro à la suite du décodage.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
           uint8_t start_sequence[]= {0, 0, 1};
           int size= recv(id_de_la_socket,(char*) rtpReceive,65535,0);
     
     
           char *z = new char[size-16+sizeof(start_sequence)];
    	memcpy(z,&start_sequence,sizeof(start_sequence));
    	memcpy(z+sizeof(start_sequence),rtpReceive+16,size-16);
    	ConsumedBytes = avcodec_decode_video(codecContext,pFrame,&GotPicture,(uint8_t*)z,size-16+sizeof(start_sequence));
    	delete z;
    Les paquets SPS et PPS subissent les mêmes instructions. Cependant, le &GotPicture reste à zéro ce qui est normal.

    A chaque fois qu'un nouveau couple SPS/PPS est trouvé, j'actualise les champs extradata et extradata_size de mon AvCodecContext. Cela devrait normalement me permettre de décoder ma prochaine Idr frame ...


    Mes iDR Frame sont fragmentés selon le type FU-A. J'ai donc tenté deux méthodes pour les décoder :
    1) à chaque fragment ayant le start_bit à 1, je lui préfixe la séquence 0x000001 et l'envoie à avcodec_decode_video. J'envoie le reste des fragments FU-A jusqu'au paquet ayant le end_bit =1.

    2) je préfixe la séquence 0x000001 au premier paquet FU-A et lui concatène ensuite tous les autres fragments arrivant. Une fois de dernier fragment arrivé, j'envoie cette chaîne au décodeur.


    Dans les deux cas la fonction ne me renvoie pas d'erreurs (ConsumedBytes >0) cependant elle ne détecte aucune frame (GotPicture reste à zéro).


    Avez-vous des idées ? Qu'est-ce que je règle mal ? Quelle autre méthode puis-je employer ?

    Merci d'avance

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Je n'obtiens pas de réponse, ma question serait-elle mal posée ?


    J'ai ouvert un autre topic dans lequel je décris plus amplement mon problème : lien

Discussions similaires

  1. Réponses: 0
    Dernier message: 18/08/2010, 12h22
  2. Intégrer une vidéo FLV sur le site
    Par nicky69larson dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 02/12/2007, 00h35
  3. Copier une vidéo située sur internet
    Par dondano dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 17/01/2007, 16h44
  4. Lire une vidéo stockée sur serveur distant
    Par zoidy dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 22/05/2006, 13h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo