简体   繁体   中英

Unable to encode single frame h264 (.mp4) video with FFmpeg. No video stream present

I have achieved this with ffmpeg command line tool using the command. The folder had only one image.

ffmpeg -r 24 -i image%03d.bmp -c:v libx264 -pix_fmt yuv420p oneframex.mp4

I would like to do the same with C++. If I encode a video of three or more frames, video encodes correctly, but the result of encoding a one or two frames video never has a video stream, as reported by ffprobe and some media players.

Comparing with ffprobe, my video (the one with three or more frames) and the one generated by the command tool show almost the same information. Only bitrate and encoder version are different.

I have tried adding force_key_frames to 1, tried with many encoding options and have be unsuccessful.

The application output gives me this information:

[libx264 @ 20d1b840] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX

[libx264 @ 20d1b840] profile High, level 4.0

[libx264 @ 20d1b840] 264 - core 142 r2431 ac76440 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=dia subme=8 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=0 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=1 keyint_min=1 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=10.0 qcomp=0.60 qpmin=0 qpmax=25 qpstep=4 ip_ratio=1.40 aq=1:1.00

These are my main parameters:

pCodecCtx->codec_id = AV_CODEC_ID_H264;
pCodecCtx->pix_fmt= AV_PIX_FMT_YUV420P; 
pCodecCtx->gop_size = 1;
pCodecCtx->bit_rate = 400000;
pCodecCtx->me_range = 16;
pCodecCtx->max_qdiff = 4;
pCodecCtx->qcompress = 0.6;
pCodecCtx->qmin = 0;
pCodecCtx->qmax = 25;
pCodecCtx->time_base.den = 24;
pCodecCtx->time_base.num = 1;

AVDictionary *param = 0;
            av_dict_set(&param, "preset", "slow", 0);
            av_dict_set(&param, "profile", "high", 0);
            av_dict_set(&param, "crf", "10", 0); //this gave me quality
            av_dict_set(&param, "force_key_frames", "1", 0);

In my encoding I just added

ppicture->pts = pCodecCtx->frame_number

to avoid non-strictly-monotonic PTS message. And tried the methods from this question in case it had something to do.

I'm sure I must be missing some important parameter to be able to create such a small video. I will take any suggestion.

After sending the single frame to encoder, a null frame must be sent to flush encoders.

avcodec_send_frame(enc, nullptr);
avcodec_receive_packet(enc, pkt);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM