-
Notifications
You must be signed in to change notification settings - Fork 141
Handle negative ctts sample_offset values in mp4 parsing #790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ptpt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments about naming and readability. Thanks for providing the test and the sample video
|
|
||
| def _convert_to_signed_offset(offset: int) -> int: | ||
| """Convert unsigned 32-bit offset to signed if high bit is set.""" | ||
| if (offset & 0x80000000) == 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 << 31 is easier to understand than 0x80000000 IMO, or add it as a comment
| if (offset & 0x80000000) == 0: | ||
| return offset | ||
| else: | ||
| return offset - 0x100000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
offset - (1 << 32)?
| from . import construct_mp4_parser as cparser, simple_mp4_parser as sparser | ||
|
|
||
|
|
||
| def _convert_to_signed_offset(offset: int) -> int: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming can be generalized as _convert_to_int32(n: int) -> int
| # ctts version to 0 instead of 1 even when using signed offsets. | ||
| # Leigitimate positive values are relatively small so we can assume the value is signed. | ||
| composition_offsets.append( | ||
| _convert_to_signed_offset(entry.sample_offset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use entry["sample_offset"] to be consistent?
They are same, but looks in this context dict access is preferred
|
@caglarpir A more clean solution IMO is use signed int32 instead of unit32 in CTTS's construct parser directly:
So a negative CTTS offset can be also correctly constructed when we build the mp4 data before uploading |
2d97f5c to
878ce18
Compare
Summary:
Some encodings like H.264 and H.265 support negative offsets.
We cannot rely on the version field since some encoders incorrectly set
ctts version to 0 instead of 1 even when using signed offsets.
Leigitimate positive values are relatively small so we can assume the value is signed.
The unsigned to signed conversion could have been gated based on the encoding. However I chose not to since large positive values exceeding 2^31 is unrealistic.
For reference the stsd and ctts boxes from a video:
stsd box: Container:
size = 233
type = b'stsd' (total 4)
data = Container:
version = 0
flags = 0
entries = ListContainer:
Container:
format = b'hvc1' (total 4)
ctts box Container:
size = 128480
type = b'ctts' (total 4)
data = Container:
version = 0
flags = 0
entries = ListContainer:
Container:
sample_count = 1
sample_offset = 0
Container:
sample_count = 1
sample_offset = 60
Container:
sample_count = 1
sample_offset = 0
Container:
sample_count = 1
sample_offset = 4294967256
Container:
sample_count = 1
sample_offset = 4294967276
878ce18 to
0f8e800
Compare
Some encodings like H.264 and H.265 support negative offsets.
We cannot rely on the version field since some encoders incorrectly set
ctts version to 0 instead of 1 even when using signed offsets.
Legitimate positive values are relatively small so we can assume the value is signed.
The unsigned to signed conversion could have been gated based on the encoding. However I chose not to since large positive values exceeding 2^31 is unrealistic.
For reference the stsd and ctts boxes from a video: