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?
There are two ways to change the output frame rate: With the -r option used as an output option. With the fps filter.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With