我的程序(使用libav)和ffprobe之间的总帧数略有不同
出于学习目的,我制作了一个例程,将给定容器内的每个流的每个帧解码。
我注意到对于某些视频,我的代码返回的帧量与工具FFProbe计算的帧不同(随FFMPEG随附)。
我正在使用这样的ffprobe:
ffprobe <media file> -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames
音频等替换“ v:0”
。
void showFrames(char *szFilename) {
int iError;
char szError[AV_ERROR_MAX_STRING_SIZE];
AVFormatContext *fcFormatCtx;
AVCodec *cdCodec;
AVCodecParameters *cdpCodecParams;
AVCodecContext *ccCodecCtx;
AVPacket *pkPacket;
AVFrame *frFrame;
fcFormatCtx=avformat_alloc_context();
iError=avformat_open_input(&fcFormatCtx,szFilename,NULL,NULL);
if(0>iError) {
av_strerror(iError,szError,sizeof(szError));
fprintf(stderr,"avformat_open_input() failed: %s\n",szError);
return;
}
iError=avformat_find_stream_info(fcFormatCtx,NULL);
if(0>iError) {
av_strerror(iError,szError,sizeof(szError));
fprintf(stderr,"avformat_find_stream_info() failed: %s\n",szError);
avformat_close_input(&fcFormatCtx);
return;
}
for(uint uiSt=0;uiSt<fcFormatCtx->nb_streams;uiSt++) {
cdpCodecParams=fcFormatCtx->streams[uiSt]->codecpar;
cdCodec=avcodec_find_decoder(cdpCodecParams->codec_id);
if(NULL==cdCodec) {
fprintf(stderr,"no codec found for stream %u\n",uiSt);
continue;
}
fprintf(stderr,"stream %u\n",uiSt);
if(AVMEDIA_TYPE_VIDEO==cdpCodecParams->codec_type)
fprintf(stderr,"video codec id=%d name='%s'\n",
cdCodec->id,cdCodec->long_name);
else if(AVMEDIA_TYPE_AUDIO==cdpCodecParams->codec_type)
fprintf(stderr,"audio codec id=%d name='%s'\n",
cdCodec->id,cdCodec->long_name);
else {
fprintf(stderr,"unsupported codec id=%d name='%s'\n",
cdCodec->id,cdCodec->long_name);
continue;
}
ccCodecCtx=avcodec_alloc_context3(cdCodec);
avcodec_parameters_to_context(ccCodecCtx,cdpCodecParams);
iError=avcodec_open2(ccCodecCtx,cdCodec,NULL);
if(0>iError) {
av_strerror(iError,szError,sizeof(szError));
fprintf(stderr,"avcodec_open2() failed: %s\n",szError);
avcodec_free_context(&ccCodecCtx);
continue;
}
pkPacket=av_packet_alloc();
frFrame=av_frame_alloc();
av_seek_frame(fcFormatCtx,uiSt,0,AVSEEK_FLAG_FRAME);
while(0==av_read_frame(fcFormatCtx,pkPacket)) {
if(uiSt==pkPacket->stream_index) {
iError=avcodec_send_packet(ccCodecCtx,pkPacket);
if(0>iError) {
av_strerror(iError,szError,sizeof(szError));
fprintf(stderr,"avcodec_send_packet() failed: %s\n",szError);
break;
}
while(true) {
iError=avcodec_receive_frame(ccCodecCtx,frFrame);
if(0>iError)
break;
fprintf(stderr,"stream %u, frame %d\n",
uiSt,ccCodecCtx->frame_number);
av_frame_unref(frFrame);
}
if(AVERROR(EAGAIN)!=iError&&AVERROR_EOF!=iError) {
av_strerror(iError,szError,sizeof(szError));
fprintf(stderr,"avcodec_receive_frame() failed: %s\n",szError);
break;
}
}
av_packet_unref(pkPacket);
}
av_packet_free(&pkPacket);
av_frame_free(&frFrame);
avcodec_free_context(&ccCodecCtx);
}
avformat_close_input(&fcFormatCtx);
}
用 em> while 在致电 av_seek_frame()之后。这是正在读取实际帧的地方。
顺便说一句,我正在使用av_seek_frame(),因为此程序通过流进行流,将框架分开,因此我需要在发现的每个流中倒带。
无论如何,我已经使用以下文件测试了先前的代码:
#1。 sample-10s.mp4来自 https://samplelib.com/sampamplem.com/sample-mp4.html 。 ..
我的程序: 301 视频帧; 440音频帧
ffprobe: 303 视频帧; 440音频帧
#2。生产ID_3997798.MP4来自 ...
我的程序: 736 视频帧;没有音频帧
ffprobe: 738 视频帧;没有音频帧
我发现了更多具有此差异的视频,但仅在视频流中发生。
我忘记了什么吗? FFProbe显示的内容似乎总是有2帧。
谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论