J'essaie de créer une petite application qui permettra d'enregistrer des images à partir du flux h264 inoming. J'ai pris un programme testRTSP comme exemple et fait plusieurs changements dans la fonction DummySink::afterGettingFrame
pour décoder les trames à l'aide de la bibliothèque ffmpeg. D'après ce que j'ai compris de frameSize, mes deux premières images sont des unités SPS, donc je les concatène avec ma troisième image et j'envoie une nouvelle image au décodeur ffmpeg. Mais ça ne marche pas. ffmpeg me dit que ma première image est trop grande pour SPS et ensuite elle me dit qu'il n'y a pas de frame ... Je ne sais pas ce que j'ai besoin de changer ici.LIVE555 comment utiliser h264 framer class pour obtenir des unités nal pour ffmpeg
void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
struct timeval presentationTime, unsigned /*durationInMicroseconds*/)
{
u_int8_t start_code[4] = { 0x00, 0x00, 0x00, 0x01 };
int stCodeLen = 4;
if (frameSize == 50)
{
//add start code
memcpy(bufferWithStartCode, start_code, stCodeLen);
shiftPtr += stCodeLen;
memcpy(bufferWithStartCode + shiftPtr, fReceiveBuffer, frameSize);
shiftPtr += frameSize;
}
else if (frameSize == 4)
{
memcpy(bufferWithStartCode + shiftPtr, fReceiveBuffer, frameSize);
shiftPtr += frameSize;
}
else
{
if (shiftPtr == 0)
{
memcpy(bufferWithStartCode, start_code, stCodeLen);
shiftPtr += stCodeLen;
}
memcpy(bufferWithStartCode + shiftPtr, fReceiveBuffer, frameSize);
avpkt.size = frameSize + shiftPtr;
avpkt.data = bufferWithStartCode;
shiftPtr = 0;
if (!avcodec_send_packet(cContext, &avpkt))
{
envir() << "error sending to decoder";
}
if (!avcodec_receive_frame(cContext, picture))
{
envir() << "error rx from decoder";
}
if (picture)
{
FILE *f;
char buffer[32]; // The filename buffer.
snprintf(buffer, sizeof(char) * 32, "file%i.txt", frame_num);
f = fopen(buffer, "w");
fprintf(f, "P5\n%d %d\n%d\n", fSubsession.videoWidth(), fSubsession.videoHeight(), 255);
for (int i = 0;i < fSubsession.videoHeight();i++)
fwrite(picture->data[0] + i * (picture->linesize[0]), 1, fSubsession.videoWidth(), f);
fclose(f);
}
}
envir() << frameSize << "\n";
frame_num++;
// Then continue, to request the next frame of data:
continuePlaying();
Les données SPS et PPS ont-elles une taille de 50 et 4 octets? Peut-être que ce sont mes deux premiers "cadres"? Et comment pourrais-je référencer deux variables différentes dans 'extradata'? – Aleksey
La taille de sps et pps n'est pas fixe, comme mentionné dans la réponse supprimée vous ne pouvez pas faire de suppositions basées sur la taille - vous devez vérifier le type nal réel (les cinq bits les plus à droite du premier octet).En ce qui concerne le 'extradata' - si ma mémoire est correcte, il suffit de les passer dans un seul tampon divisé par le code de préfixe que vous utilisez déjà et de définir le' extradata_size' en conséquence. Btw, si vous voulez que ffmpeg décode le flux, pourquoi ne pas utiliser aussi ffmpeg (avio_open) pour la gestion RTSP? Ensuite, vous n'auriez pas à vous embêter avec cela et tout se ferait en interne. –