FFmpeg,C ++ - 在程序中获取帧率

5

我有一个视频,它的帧率是23.98 fps,在Quicktime和ffmpeg命令行中都能看到。但OpenCV错误地认为它的帧率是23 fps。我想找到一种程序化的方法来从ffmpeg中获取视频的帧率信息。


我使用的ffmpeg fps命令行版本是在Linux中ffmpeg -i yourfilenamehere.avi -vcodec copy -acodec copy -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' ',在Windows(XP及以上版本)中是ffmpeg -i yourfilenamehere.avi -vcodec copy -acodec copy -f null /dev/null 2>&1 | findstr 'frame=' - GMasucci
3个回答

13

使用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 */
 double videoFPS = av_q2d(ptrAVFormatContext->streams[VideoStreamIndx]->r_frame_rate);
 std::cout<<"fps :"<<videoFPS<<std::endl;

2
从ffmpeg版本3.4开始,AVCodecContext已经弃用了编解码器参数。现在,pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO需要更改为pAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO - Gatothgaj
1
在FFmpeg的avformat.h文件中,靠近r_frame_rate的地方有一条注释,它说:“注意,这个值只是一个猜测!” - Gediminas
https://abdullahfarwees.blogspot.com/2023/01/how-to-get-frames-per-second-value-from.html 这是一个旧博客,但对一些人可能会有用! - undefined

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;
}

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

编辑

如果进行调试,请查看r_frame_rateavg_frame_rate是否不同,因为根据此处的说明,它们倾向于根据所使用的编解码器而异。由于您没有提到视频格式,因此很难猜测,但至少对于H264,您应该直接使用avg_frame_rate,从r_frame_rate获得的值可能会弄乱事情。


2

自2013-03-29发布的libavformat版本55.1.100起,新增了av_guess_frame_rate()函数。

/**
 * Guess the frame rate, based on both the container and codec information.
 *
 * @param ctx the format context which the stream is part of
 * @param stream the stream which the frame is part of
 * @param frame the frame for which the frame rate should be determined, may be NULL
 * @return the guessed (valid) frame rate, 0/1 if no idea
 */
AVRational av_guess_frame_rate(AVFormatContext *ctx, AVStream *stream, AVFrame *frame);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接