Ho iniziato a utilizzare ffmpeg e voglio convertire il file avi nel file mp4/h264. Ho letto molti post tra cui this, ma non sono riuscito a trovare alcun buon esempio su come salvare i frame in file mp4. Il codice seguente è semplificato da quello che decodifica i fotogrammi dal file avi e lo codifica nel file H264/mp4, ma quando salgo i frame il file mp4 non può essere riprodotto. Penso di non sbagliare nella codificaPerché decodificare i frame dal contenitore avi e codificarli su h264/mp4 non funziona?
Apprezzerò se potessi dirmi cosa c'è che non va e come risolverlo.
const char* aviFileName = "aviFrom.avi";
const char* mp4FileName = "mp4To.mp4";
// Filling pFormatCtx by open video file and Retrieve stream information
// ...
// Retrieving codecCtxDecode and opening codecDecode
//...
// Get encoder
codecCtxEncode = avcodec_alloc_context();
codecCtxEncode->qmax = 69;
codecCtxEncode->max_qdiff = 4;
codecCtxEncode->bit_rate = 400000;
codecCtxEncode->width = codecCtxDecode->width;
codecCtxEncode->height = codecCtxDecode->height;
codecCtxEncode->pix_fmt = AV_PIX_FMT_YUV420P;
codecEncode = avcodec_find_encoder(CODEC_ID_H264);
if(codecEncode == NULL)
return -1;
if(avcodec_open2(codecCtxEncode, codecEncode, NULL))
return -1;
SwsContext *sws_ctx = sws_getContext(codecCtxDecode->width, codecCtxDecode->height, codecCtxDecode->pix_fmt,
codecCtxDecode->width, codecCtxDecode->height, AV_PIX_FMT_YUV420P,
SWS_BILINEAR, NULL, NULL, NULL);
// Allocate an AVFrame structure
frameDecoded = avcodec_alloc_frame();
frameEncoded = avcodec_alloc_frame();
avpicture_alloc((AVPicture *)frameEncoded, AV_PIX_FMT_YUV420P, codecCtxDecode->width, codecCtxDecode->height);
while(av_read_frame(pFormatCtx, &packet)>=0)
{
// Is this a packet from the video stream?
if(packet.stream_index==videoStreamIndex) {
avcodec_decode_video2(codecCtxDecode, frameDecoded, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished)
{
fwrite(packet.data, packet.size,
sws_scale(sws_ctx, frameDecoded->data, frameDecoded->linesize, 0, codecCtxDecode->height,
frameEncoded->data, frameEncoded->linesize);
int64_t pts = packet.pts;
av_free_packet(&packet);
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
frameEncoded->pts = pts;
int failed = avcodec_encode_video2(codecCtxEncode, &packet, frameEncoded, &got_output);
if(failed)
{
exit(1);
}
fwrite(packet.data,1,packet.size, mp4File);
}
}
av_free_packet(&packet);
}
Ipoteticamente, se lo farei manualmente aggiungere l'intestazione e il piè di pagina al file, sarebbe OK? – theateist
Per alcuni formati, può funzionare, ma in generale, questo è il modo sbagliato. – pogorskiy
come per sperimentare ciò che hai scritto ho provato a leggere dal file avi e scrivere gli stessi pacchetti che ho letto (senza decodificare) in un nuovo file avi. Mi aspettavo di ottenere lo stesso file ma il nuovo file è più grande su 3KB e il lettore multimediale non può aprirlo – theateist