@@ -333,6 +333,11 @@ void FFmpegReader::UpdateAudioInfo()
333333 info.height = 480 ;
334334 }
335335
336+ // Fix invalid video lengths for certain types of files (MP3 for example)
337+ if (info.has_video && ((info.duration * info.fps .ToDouble ()) - info.video_length > 60 )) {
338+ info.video_length = info.duration * info.fps .ToDouble ();
339+ }
340+
336341 // Add audio metadata (if any found)
337342 AVDictionaryEntry *tag = NULL ;
338343 while ((tag = av_dict_get (aStream->metadata , " " , tag, AV_DICT_IGNORE_SUFFIX))) {
@@ -422,7 +427,7 @@ void FFmpegReader::UpdateVideoInfo()
422427 }
423428
424429 // Override an invalid framerate
425- if (info.fps .ToFloat () > 240 .0f || (info.fps .num == 0 || info.fps .den == 0 )) {
430+ if (info.fps .ToFloat () > 240 .0f || (info.fps .num <= 0 || info.fps .den <= 0 ) || info. video_length <= 0 ) {
426431 // Calculate FPS, duration, video bit rate, and video length manually
427432 // by scanning through all the video stream packets
428433 CheckFPS ();
@@ -1864,14 +1869,14 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram
18641869void FFmpegReader::CheckFPS ()
18651870{
18661871 check_fps = true ;
1867- AV_ALLOCATE_IMAGE (pFrame, AV_GET_CODEC_PIXEL_FORMAT (pStream, pCodecCtx), info.width , info.height );
18681872
18691873 int first_second_counter = 0 ;
18701874 int second_second_counter = 0 ;
18711875 int third_second_counter = 0 ;
18721876 int forth_second_counter = 0 ;
18731877 int fifth_second_counter = 0 ;
18741878 int frames_detected = 0 ;
1879+ int64_t pts = 0 ;
18751880
18761881 // Loop through the stream
18771882 while (true )
@@ -1891,7 +1896,7 @@ void FFmpegReader::CheckFPS()
18911896 UpdatePTSOffset (true );
18921897
18931898 // Get PTS of this packet
1894- int64_t pts = GetVideoPTS ();
1899+ pts = GetVideoPTS ();
18951900
18961901 // Remove pFrame
18971902 RemoveAVFrame (pFrame);
@@ -1922,7 +1927,7 @@ void FFmpegReader::CheckFPS()
19221927
19231928 // Double check that all counters have greater than zero (or give up)
19241929 if (second_second_counter != 0 && third_second_counter != 0 && forth_second_counter != 0 && fifth_second_counter != 0 ) {
1925- // Calculate average FPS
1930+ // Calculate average FPS (average of first few seconds)
19261931 int sum_fps = second_second_counter + third_second_counter + forth_second_counter + fifth_second_counter;
19271932 int avg_fps = round (sum_fps / 4 .0f );
19281933
@@ -1931,22 +1936,32 @@ void FFmpegReader::CheckFPS()
19311936
19321937 // Update Duration and Length
19331938 info.video_length = frames_detected;
1934- info.duration = frames_detected / round (sum_fps / 4 .0f );
1939+ info.duration = frames_detected / (sum_fps / 4 .0f );
19351940
19361941 // Update video bit rate
19371942 info.video_bit_rate = info.file_size / info.duration ;
1938- } else {
1943+ } else if (second_second_counter != 0 && third_second_counter != 0 ) {
1944+ // Calculate average FPS (only on second 2)
1945+ int sum_fps = second_second_counter;
1946+
1947+ // Update FPS
1948+ info.fps = Fraction (sum_fps, 1 );
19391949
1950+ // Update Duration and Length
1951+ info.video_length = frames_detected;
1952+ info.duration = frames_detected / float (sum_fps);
1953+
1954+ // Update video bit rate
1955+ info.video_bit_rate = info.file_size / info.duration ;
1956+ } else {
19401957 // Too short to determine framerate, just default FPS
19411958 // Set a few important default video settings (so audio can be divided into frames)
19421959 info.fps .num = 30 ;
19431960 info.fps .den = 1 ;
1944- info.video_timebase .num = info.fps .den ;
1945- info.video_timebase .den = info.fps .num ;
19461961
19471962 // Calculate number of frames
19481963 info.video_length = frames_detected;
1949- info.duration = frames_detected / info.video_timebase .ToFloat ();
1964+ info.duration = frames_detected / info.fps .ToFloat ();
19501965 }
19511966}
19521967
0 commit comments