-
Notifications
You must be signed in to change notification settings - Fork 615
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
Fix HEVC video handling #3247
Fix HEVC video handling #3247
Conversation
CI MESSAGE: [2749122]: BUILD STARTED |
CI MESSAGE: [2749122]: BUILD FAILED |
105197c
to
fef4d38
Compare
CI MESSAGE: [2749188]: BUILD STARTED |
CI MESSAGE: [2749188]: BUILD PASSED |
NVIDIA/DALI_extra#65 is a prerequisite. |
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.
I think some counter how many key frames we've seen and the required number as a constant would feel more natural.
Also, doesn't this impact performance? Shouldn't we do this based on the format that we are dealing with?
I can add it.
It may but I don't see any other way to fix that.
Probably but I don't have sufficient knowledge which one needs that. |
Anyway done. |
CI MESSAGE: [2760006]: BUILD STARTED |
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.
I'm not sure if I understand this correctly. Is the req.count the distance between keyframes? If so, there is a bug and we can simplify.
@@ -533,6 +533,11 @@ void VideoLoader::read_file() { | |||
bool is_first_frame = true; | |||
bool key = false; | |||
bool seek_must_succeed = false; | |||
// how many key frames following the last requested frames we need to see so far |
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.
// how many key frames following the last requested frames we need to see so far | |
// how many key frames following the last requested frames we saw so far |
int key_frames_count = 0; | ||
// how many key frames following the last requested frames we need to see before we stop | ||
// feeding the decoder | ||
const int key_frames_treshold = 1; |
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.
IMO we want to see two, so I would probably write here 2, and use greater equal, but it's a nitpick:
const int key_frames_treshold = 1; | |
const int key_frames_treshold = 2; |
@@ -585,10 +590,16 @@ void VideoLoader::read_file() { | |||
if (!is_first_frame) { | |||
nonkey_frame_count = 0; | |||
if (frame > req.frame + req.count) { |
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.
Shouldn't we check for:
if (frame > req.frame + req.count) { | |
if (frame > req.frame + (1 + key_frames_count) * req.count) { |
or something?
I mean, if key frame is every req.count
(just guessing), we need to see the multiple of the distance to detect key frame.
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.
No, keyframe is the video stream property and it doesn't have to be equally placed in the video. req.count
is how many frames we need to decode to between first and the last frame in the sequence.
if (frame > req.frame + req.count) { | ||
// Found a key frame past the requested range. We can stop searching | ||
// Found a second key frame past the requested range. We can stop searching | ||
// (If there were missing frames in the range they won't be found after | ||
// the next key frame) | ||
break; | ||
// in case HEVC it seems that preceding frames can appear after a given key frame | ||
// but rather not after the next one | ||
if (key_frames_count > key_frames_treshold) { | ||
key_frames_count = 0; | ||
break; | ||
} | ||
++key_frames_count; | ||
} |
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.
If my comment is right, this can be replaced with (note the 2):
const int key_frames_treshold = 2;
if (frame > req.frame + key_frames_treshold * req.count) {
break;
}
Which is probably simpler.
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.
key_frames_treshold * req.count
doesn't make any sense. req.count
has nothing to do with keyframes.
It is the number of frames between the first and the last in the sequence including stride. |
CI MESSAGE: [2760331]: BUILD STARTED |
CI MESSAGE: [2760006]: BUILD PASSED |
CI MESSAGE: [2760331]: BUILD PASSED |
int key_frames_count = 0; | ||
// how many key frames following the last requested frames we need to see before we stop | ||
// feeding the decoder | ||
const int key_frames_treshold = 2; |
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.
Can we infer this from the file info somehow? I think that there are relatively few formats that support bidirectional prediction - for others, that's just waste of time.
Even in case of HEVC, I think that you don't need the whole interval between keyframes - just from the keyframe to the requested frame (in forward prediction) and from the requested frame to the keyframe (in reverse prediction) - but determining which keyframe is relevant might be non-trivial.
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.
I can add check only for HEVC but I'm not aware of any simple way to determine what kind of prediction is used in a given stream - I afraid it would require parsing headers/stream on our own what is much beyond the scope of this task.
Even in case of HEVC, I think that you don't need the whole interval between keyframes - just from the keyframe to the requested frame (in forward prediction) and from the requested frame to the keyframe (in reverse prediction) - but determining which keyframe is relevant might be non-trivial.
In some cases we don't get any meaningful timestamp from the frame we read from the stream. So it may not work at all.
Please rename the PR from "Improve" to "Fix" - after all, before this PR it just doesn't work for some valid HEVC videos. |
- it seems that preceding frames may appear after the following keyframe so the logic that stops sending frames to the decoder assuming that each keyframe is IDR doesn't work anymore. Improve the logic to stop after seeing the next keyframe as it should be very unlikely to have a frame from two keyframes behind - adds HEVC test Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
588719e
to
2c68549
Compare
Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
2c68549
to
a8f7624
Compare
a8f7624
to
4963631
Compare
Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
4963631
to
f2b47d0
Compare
CI MESSAGE: [2877236]: BUILD STARTED |
CI MESSAGE: [2877236]: BUILD PASSED |
keyframe so the logic that stops sending frames to the decoder
assuming that each keyframe is IDR doesn't work anymore. Improve
the logic to stop after seeing the next keyframe as it should be
very unlikely to have a frame from two keyframes behind
Signed-off-by: Janusz Lisiecki jlisiecki@nvidia.com
Description
What happened in this PR
keyframe so the logic that stops sending frames to the decoder
assuming that each keyframe is IDR doesn't work anymore. Improve
the logic to stop after seeing the next keyframe as it should be
very unlikely to have a frame from two keyframes behind
Additional information
Checklist
Tests
Documentation
DALI team only
Requirements
REQ IDs: N/A
Relates to #3243
JIRA TASK: DALI-2243