Question

J'apprécierais vraiment de l'aide avec le problème suivant:

J'ai un gadget avec une caméra, produisant des cadres vidéo compressés H264, ces cadres sont envoyés à mon application. Ces cadres ne sont pas dans un conteneur, juste des données brutes.

Je souhaite utiliser les fonctions FFMPEG et LiBav pour créer un fichier vidéo, qui peut être utilisé plus tard.

Si je décode les cadres, puis encodez, tout fonctionne bien, j'obtiens un fichier vidéo valide. (Les étapes de décodage / d'encodage sont les commandes libav habituelles, rien d'extraordinaire ici, je les ai pris de l'Internet Tout-Puissant, ils sont solides du roc Ignorez cette étape et placez directement les trames dans le flux de sortie. Maintenant, les problèmes arrivent.

Voici le code que j'ai trouvé pour produire le codage:

AVFrame* picture;

avpicture_fill((AVPicture*) picture, (uint8_t*)frameData, 
                 codecContext->pix_fmt, codecContext->width,
                 codecContext->height);
int outSize = avcodec_encode_video(codecContext, videoOutBuf, 
                 sizeof(videoOutBuf), picture);
if (outSize > 0) 
{
    AVPacket packet;
    av_init_packet(&packet);
    packet.pts = av_rescale_q(codecContext->coded_frame->pts,
                  codecContext->time_base, videoStream->time_base);
    if (codecContext->coded_frame->key_frame) 
    {
        packet.flags |= PKT_FLAG_KEY;
    }
    packet.stream_index = videoStream->index;
    packet.data =  videoOutBuf;
    packet.size =  outSize;

    av_interleaved_write_frame(context, &packet);
    put_flush_packet(context->pb);
}

Où les variables sont comme:

frameData est les données de cadre décodées, qui proviennent de la caméra, elle a été décodée dans une étape précédente et videoOutBuf est un tampon uint8_t simple pour maintenir les données

J'ai modifié l'application afin de ne pas décoder les cadres, mais de passer simplement les données comme:

    AVPacket packet;
    av_init_packet(&packet);

    packet.stream_index = videoStream->index;
    packet.data = (uint8_t*)frameData;
    packet.size = currentFrameSize;

    av_interleaved_write_frame(context, &packet);
    put_flush_packet(context->pb);

frameData est le cadre H264 brut et currentFrameSize est la taille du cadre H264 brut, c'est-à-dire. Le nombre d'octets que j'obtiens du gadget pour chaque cadre.

Et soudain, l'application ne fonctionne plus correctement, la vidéo produite est injouable. C'est évident, car je ne définissais pas de pts corrects pour le paquet. Ce que j'ai fait était ce qui suit (je suis désespéré, vous pouvez le voir à partir de cette approche :))

    packet.pts = timestamps[timestamp_counter ++];

timestamps est en fait une liste des PTS produits par le code de travail ci-dessus, et écrit dans un fichier (oui, vous l'avez lu correctement, j'ai enregistré tous les PTS pour une session de 10 minutes et je voulais les utiliser).

L'application ne fonctionne toujours pas.

Maintenant, ici je suis sans aucune idée de ce qu'il faut faire, alors voici la question:

Je voudrais créer un flux vidéo "MPEGTS" à l'aide de fonctions Libav, insérer dans le flux déjà encodé des cadres vidéo et créer un fichier vidéo avec. Comment fait-on ça?

Merci F.

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top