From 650adf639de2d27a6763d8e0fd92934bd15a0279 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 11 Sep 2020 00:55:50 -0500 Subject: [PATCH 1/2] Fix the PTS offset logic error when first reading a file on FFmpegReader. Use the calculated 0 - PTS, unless it is too large (more than 1 second off from zero) --- src/FFmpegReader.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index dfd8eb8d9..097bc8d7c 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1868,8 +1868,18 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // VIDEO PACKET if (video_pts_offset == 99999) // Has the offset been set yet? { - // Find the difference between PTS and frame number (no more than 10 timebase units allowed) - video_pts_offset = 0 - std::max(GetVideoPTS(), (int64_t) info.video_timebase.ToInt() * 10); + // Find the difference between PTS and frame number + video_pts_offset = 0 - GetVideoPTS(); + + // Find the difference between PTS and frame number + // Also, determine if PTS is invalid (too far away from zero) + // We compare the PTS to the timebase value equal to 1 second (which means the PTS + // must be within the -1 second to +1 second of zero, otherwise we ignore it) + int64_t max_offset = info.video_timebase.Reciprocal().ToFloat(); + if (video_pts_offset < -max_offset || video_pts_offset > max_offset) { + // Ignore PTS, it seems invalid + video_pts_offset = 0; + } // debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::UpdatePTSOffset (Video)", "video_pts_offset", video_pts_offset, "is_video", is_video); @@ -1878,8 +1888,16 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // AUDIO PACKET if (audio_pts_offset == 99999) // Has the offset been set yet? { - // Find the difference between PTS and frame number (no more than 10 timebase units allowed) - audio_pts_offset = 0 - std::max(packet->pts, (int64_t) info.audio_timebase.ToInt() * 10); + // Find the difference between PTS and frame number + // Also, determine if PTS is invalid (too far away from zero) + // We compare the PTS to the timebase value equal to 1 second (which means the PTS + // must be within the -1 second to +1 second of zero, otherwise we ignore it) + audio_pts_offset = 0 - packet->pts; + int64_t max_offset = info.audio_timebase.Reciprocal().ToFloat(); + if (audio_pts_offset < -max_offset || audio_pts_offset > max_offset) { + // Ignore PTS, it seems invalid + audio_pts_offset = 0; + } // debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::UpdatePTSOffset (Audio)", "audio_pts_offset", audio_pts_offset, "is_video", is_video); From 7dc9eb6927b0d4f72fbb908e703fdc7073ffbe42 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sat, 12 Sep 2020 17:05:33 -0500 Subject: [PATCH 2/2] Adding TODO for future improvements --- src/FFmpegReader.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 097bc8d7c..c047ea51c 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1875,6 +1875,8 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // Also, determine if PTS is invalid (too far away from zero) // We compare the PTS to the timebase value equal to 1 second (which means the PTS // must be within the -1 second to +1 second of zero, otherwise we ignore it) + // TODO: Please see https://github.com/OpenShot/libopenshot/pull/565#issuecomment-690985272 + // for ideas to improve this logic. int64_t max_offset = info.video_timebase.Reciprocal().ToFloat(); if (video_pts_offset < -max_offset || video_pts_offset > max_offset) { // Ignore PTS, it seems invalid @@ -1892,6 +1894,8 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // Also, determine if PTS is invalid (too far away from zero) // We compare the PTS to the timebase value equal to 1 second (which means the PTS // must be within the -1 second to +1 second of zero, otherwise we ignore it) + // TODO: Please see https://github.com/OpenShot/libopenshot/pull/565#issuecomment-690985272 + // for ideas to improve this logic. audio_pts_offset = 0 - packet->pts; int64_t max_offset = info.audio_timebase.Reciprocal().ToFloat(); if (audio_pts_offset < -max_offset || audio_pts_offset > max_offset) {