11
votes

I am recording video with FFmpeg and I would like the frame rate it is written with to at least be in the right ballpark. Right now I take the frame rate that my input claims to have and use that to set the frame rate (time_base) for my output video stream. However this is sometimes wildly different from the actual frame rate that I am getting (I have seen a stream claiming 50 fps but publishing at 9 fps).

What I would like to do is use a elapsed timer and count the frames I record to calculate the actual frame rate I recorded at when I am finished recording. I would seem though that the frame rate is set in my AVStream is used in avcodec_open2 before I write any frames. If I set it later (such as while I am writing frames) while ffplay can play it (complaining that the time increment bits is 6 not 4) other video players cannot. Is there a way to set the frame rate for the whole file after writing the frames? If not is there a way to tell the frames themselves some sort of timestamp or frame rate while I am recording that will result in a valid recorded file?

2
hi, I will look more, but just wanted to ask about avconv. found it after a quick google search, looks like it can change a file's frame rate. perhaps you could write the file at an arbitrary frame rate and then after detecting the real rate, finish writing and run avconv with the new rate? just a thought, not a real answer ;) will keep looking though. let me know.cure
avconv is the binary name for the libav project. (superuser.com/questions/507386/…) has a pretty decent summary of all the names which had me confused for quite some time. Anything avconv does should be possible with the libraries it uses.Chris
were you able to solve the issue? I have the same issue too(Irina
@Irina See my answer down below. Basically you set the timebase to the granularity of your timer, then every frame set the PTS to the elapsed time.Chris

2 Answers

2
votes

The trick seems to be to use AVCodecContext time_base and AVFrame pts in a more intelligent way than I was. If you are recording with a fixed frame rate then time_base is set to 1/framerate and the pts is just a incremented number for the recorded frame.

Instead now I start a elapsed timer when I begin my recording and set time_base to 1 over the granularity of the timer (in my case it has millisecond accuracy so 1000). I set frame pts to the amount of elapsed time before it is encoded. This combination results in a video file with a variable framerate that plays back correctly.

0
votes

Chris. You need to develop new video stream write engine. So if you set frame rate as [N], the writing engine write frames as per rate.

  • Checking Timestamp For Each Frame When Writing
  • If you have less frames than N for a second, you need to make duplicate frames.
  • If you have more frames than N for a second, you need to drop some frames.

Before writing, you need to specify exact framerate.

And your video file writing engine has to work with specified framerate.

You can implement this by using ffmpeg.