Check for the correct frames per second (FPS) value by scanning the 1st few seconds of video packets.
| 2919 | |
| 2920 | // Check for the correct frames per second (FPS) value by scanning the 1st few seconds of video packets. |
| 2921 | void FFmpegReader::CheckFPS() { |
| 2922 | if (check_fps) { |
| 2923 | // Do not check FPS more than 1 time |
| 2924 | return; |
| 2925 | } else { |
| 2926 | check_fps = true; |
| 2927 | } |
| 2928 | |
| 2929 | int frames_per_second[3] = {0,0,0}; |
| 2930 | int max_fps_index = sizeof(frames_per_second) / sizeof(frames_per_second[0]); |
| 2931 | int fps_index = 0; |
| 2932 | |
| 2933 | int all_frames_detected = 0; |
| 2934 | int starting_frames_detected = 0; |
| 2935 | |
| 2936 | // Loop through the stream |
| 2937 | while (true) { |
| 2938 | // Get the next packet (if any) |
| 2939 | if (GetNextPacket() < 0) |
| 2940 | // Break loop when no more packets found |
| 2941 | break; |
| 2942 | |
| 2943 | // Video packet |
| 2944 | if (packet->stream_index == videoStream) { |
| 2945 | // Get the video packet start time (in seconds) |
| 2946 | double video_seconds = (double(GetPacketPTS()) * info.video_timebase.ToDouble()) + pts_offset_seconds; |
| 2947 | fps_index = int(video_seconds); // truncate float timestamp to int (second 1, second 2, second 3) |
| 2948 | |
| 2949 | // Is this video packet from the first few seconds? |
| 2950 | if (fps_index >= 0 && fps_index < max_fps_index) { |
| 2951 | // Yes, keep track of how many frames per second (over the first few seconds) |
| 2952 | starting_frames_detected++; |
| 2953 | frames_per_second[fps_index]++; |
| 2954 | } |
| 2955 | |
| 2956 | // Track all video packets detected |
| 2957 | all_frames_detected++; |
| 2958 | } |
| 2959 | } |
| 2960 | |
| 2961 | // Calculate FPS (based on the first few seconds of video packets) |
| 2962 | float avg_fps = 30.0; |
| 2963 | if (starting_frames_detected > 0 && fps_index > 0) { |
| 2964 | avg_fps = float(starting_frames_detected) / std::min(fps_index, max_fps_index); |
| 2965 | } |
| 2966 | |
| 2967 | // Verify average FPS is a reasonable value |
| 2968 | if (avg_fps < 8.0) { |
| 2969 | // Invalid FPS assumed, so switching to a sane default FPS instead |
| 2970 | avg_fps = 30.0; |
| 2971 | } |
| 2972 | |
| 2973 | // Update FPS (truncate average FPS to Integer) |
| 2974 | info.fps = Fraction(int(avg_fps), 1); |
| 2975 | |
| 2976 | // Update Duration and Length |
| 2977 | if (all_frames_detected > 0) { |
| 2978 | // Use all video frames detected to calculate # of frames |