ffmpeg,C++ - 在程序中获取fps

Rup*_*ton 4 c++ ffmpeg

我有一个23.98 fps的视频,这可以从命令行中的Quicktime和ffmpeg看到.错误地认为OpenCV有23 fps.我有兴趣找到一种程序化的方法来从ffmpeg中找到一个视频fps'.

小智 9

使用FFMPEG-C++获取每秒视频帧数(fps)

/* find first stream */
for(int i=0; i<pAVFormatContext->nb_streams ;i++ )
{
if( pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ) 
/* if video stream found then get the index */
{
  VideoStreamIndx = i;
  break;
}
}


 /* if video stream not availabe */
 if((VideoStreamIndx) == -1)
 {
   std::cout<<"video streams not found"<<std::endl;
   return -1;
 }
 /* get video fps */
 int videoFPS = av_q2d(ptrAVFormatContext->streams[VideoStreamIndx]->r_frame_rate);
 std::cout<<"fps :"<<videoFPS<<std::endl;
Run Code Online (Sandbox Code Playgroud)

  • 从3.4版本的ffmpeg开始,AVCodecContext已弃用了编解码器参数。现在,此“ pAVFormatContext-&gt; streams [i]-&gt;编解码器-&gt; codec_type == AVMEDIA_TYPE_VIDEO”将需要更改为“ pAVFormatContext-&gt; streams [i]-&gt; codecpar-&gt; codec_type == AVMEDIA_TYPE_VIDEO” (2认同)

Rud*_*lis 3

快速浏览一下 OpenCV 源代码可以发现:

double CvCapture_FFMPEG::get_fps()
{
    double fps = r2d(ic->streams[video_stream]->r_frame_rate);

#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
    if (fps < eps_zero)
    {
        fps = r2d(ic->streams[video_stream]->avg_frame_rate);
    }
#endif

    if (fps < eps_zero)
    {
        fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base);
    }

    return fps;
}
Run Code Online (Sandbox Code Playgroud)

所以看起来很正确。也许通过这部分运行调试会话来验证此时的值?avg_frame_rateAVStream 的是一个所以AVRational它应该能够保存精确的值。也许如果您的代码由于较旧的 ffmpeg 版本而使用第二个 if 块,则time_base设置不正确?

编辑

如果您调试,请查看 和r_frame_rate是否avg_frame_rate不同,因为至少根据此,它们往往会根据所使用的编解码器而有所不同。由于您没有提到视频格式,所以很难猜测,但似乎至少对于 H264 您应该使用avg_ frame_rate简单的方法,并且从 获得的值r_frame_rate可能会弄乱事情。