Reputation: 663
I have a video which has 23.98 fps, this can be seen from Quicktime and ffmpeg in the command line. OpenCV, wrongly, thinks it has 23 fps. I am interested in finding a programmatic way to find out a video fps' from ffmpeg.
Upvotes: 5
Views: 12458
Reputation: 931
To get video Frames per Second (fps) value using FFMPEG-C++
/* 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;
Upvotes: 13
Reputation: 10107
From libavformat
version 55.1.100
released in 2013-03-29, av_guess_frame_rate()
is added.
/**
* 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);
Upvotes: 2
Reputation: 11954
A quick look into the OpenCV sources show the following:
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;
}
so looks quite right. Maybe run a debug session through this part to verify the values at this point? The avg_frame_rate
of AVStream is an AVRational
so it should be able to hold the precise value. Maybe if your code uses the second if block due to an older ffmpeg version the time_base
is not set right?
EDIT
If you debug take a look if the r_frame_rate
and avg_frame_rate
differ, since at least according to this they tend to differ based on the codec used. Since you have not mentioned the video format it's hard to guess, but seems that at least for H264 you should use avg_ frame_rate
straightforward and a value obtained from r_frame_rate
could mess things up.
Upvotes: 3