Skip to content

[timecode] Truncate instead of rounding up in get_timecode(use_rounding=False) - #602

Closed
rishi02102017 wants to merge 1 commit into
Breakthrough:mainfrom
rishi02102017:fix/get-timecode-truncation
Closed

rishi02102017 wants to merge 1 commit into
Breakthrough:mainfrom
rishi02102017:fix/get-timecode-truncation

Conversation

@rishi02102017

Copy link
Copy Markdown
Contributor

FrameTimecode.get_timecode() is documented to truncate to the requested precision when use_rounding=False. It currently formats the seconds with one extra digit and then drops it, but formatting rounds that digit, which can carry into the digits that are kept:

>>> from fractions import Fraction
>>> from scenedetect import FrameTimecode
>>> from scenedetect.common import Timecode
>>> tc = FrameTimecode(Timecode(pts=179997, time_base=Fraction(1, 90000)), Fraction(30000, 1001))
>>> tc.get_timecode(use_rounding=False)   # 1.99997s
'00:00:01.000'                            # expected '00:00:01.999'
>>> FrameTimecode(911, Fraction(24000, 1001)).get_timecode(precision=1, use_rounding=False)  # 37.996s
'00:00:37.0'                              # expected '00:00:37.9'

When the carry reaches the whole seconds it is lost, so the result can be almost a second early. This reproduces on 0.7.3 and on main.

This change truncates the value to the requested precision before it is split into hours, minutes and seconds, allowing for float error so exact frame times are not truncated down (for example, 504 frames at 23.976 fps is exactly 21.021 seconds and still prints 00:00:21.021). Output with use_rounding=True is unchanged.

  • Added test_precision_truncation to tests/test_timecode.py; it fails on main and passes with this change.
  • pytest, ruff check and ruff format --check pass.
  • Added a changelog entry under 0.8.

…ng=False)

get_timecode() truncated by formatting the seconds with one extra digit
and dropping it, but formatting rounds that extra digit, which can carry
into the digits that are kept. With use_rounding=False, 0.4996 seconds
at precision 2 gave 00:00:00.50, and 1.99997 seconds gave 00:00:01.000
(the carry was lost once it reached the whole seconds).

Truncate the value to the requested precision before splitting it into
hours, minutes and seconds instead, allowing for float error so exact
frame times such as 504 frames at 23.976 fps (21.021 seconds) are not
truncated down.

@MuhammadBilalKhan267 MuhammadBilalKhan267 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this! #591 already fixes the same truncation bug in Timecode, and we’re planning to remove FrameTimecode in 0.8.

@rishi02102017

Copy link
Copy Markdown
Contributor Author

Ah, makes sense, thanks. Since #591 is still a draft, would it be worth having this in 0.7.x until 0.8 is out? If not, I'm happy to close it.

@MuhammadBilalKhan267

Copy link
Copy Markdown
Collaborator

Unfortunately, the next planned release is 0.8. Feel free to pick up any other issues though.

@rishi02102017

Copy link
Copy Markdown
Contributor Author

Got it, closing this then. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants