The latest use of ffmpeg+x264 encoded video, before using the old version of FFmpeg encoded video files no problem, but after the latest version (FFmpeg version number 2.8.2), the encoded video frame rate is particularly large problem.
Looking for a long time, finally solved, here to record the exploration process.
First of all, I set the frame rate of the video is 25 frames/s, but the encoded video frame rate is thousands of, as shown in the figure below
You can see that the frame rate and the bitrate are illegal values, which is why.
Here is the resolution process.
First, it is known that this frame rate is present in the Avstream, that is, the Avstream time_base field. But I clearly set this field is 25 frames per second, why the last encoded video is like this.
No way, had to see FFmpeg documentation, in Avstream's time_base introduction There is such a sentence.
A simple translation, this means that in the Avformat_write_header, this mixer (do not know how to translate, simply to mix the video stream and audio stream) will re-overwrite this value, the value of this overlay and you set the value is irrelevant, It relies on this stored format.
Well, it gave me an indication that I would see avformat_write_header right away. Unfortunately, only the simple introduction of the function in the document does not explain how the value changes.
There is no way to use the most primitive way, open source insight, view ffmpeg source bar.
Can see Avformat_write_header or relatively simple, only to call a few interfaces, the following question is to find out which interface changed this value.
This simple can be used in the most primitive way to make a log resolution. You can find this value changed in Write_header by logging.
This write_header is you set Outputforamt Write_header method, here I set is MP4, so muxer is ff_mp4_muxer, global search This field is OK.
The Write_header method to find this muxer is Mov_write_header
Well, finally found the root, let's take a look at this mov_write_header method,
This function is longer, I do not take it all down, if you do not want to see the code, find the root can also use the Universal method (I will not tell you)
The code to intercept the source directly here
Note The Code of the red box, where the Track->timescale will recalculate the Avstream time_base, which changes the value I set. If the above if determine the value of Video_track_timescale, then he will take this value, if not set this value, the use of the denominator of our avstream time_base, and so on, you under the while loop is what ghost, If I set the denominator to less than 10000. You always multiply by 2 until it is greater than 10000, no wonder I coded the video so wonderful. You're the one who's doing it.
Well, finally, we found the roots. Here's the solution. By looking at the source code, we know that if we set up Video_track_timescale, he will use this value. Well, now that's it. Let's set this value before Avformat_write_header.
avdictionary* opt = NULL;
Av_dict_set_int (&opt, "Video_track_timescale", 25, 0);
Avformat_write_header (M_pformatctx, &opt);
Well, try coding again. The result is as I expected, this frame rate is normal, the code rate is normal.
PS: The previous version of FFmpeg in this place does not have the following while loop, of course, the old version of the code and the new version of the code is also very large, do not know what the meaning of this while loop.
Younger brother is also a beginner ffmpeg and audio and video coding, many of the basic nouns do not know what meaning (such as the above Video_track_timescale), understand the ffmpeg is also bucket, so if there is any problem, but also hope that everyone correct.