-
Notifications
You must be signed in to change notification settings - Fork 7
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
[RSDK-9846] - Add broader mpeg4 support #89
base: main
Are you sure you want to change the base?
Conversation
I can take @nicksanford off this review if priority is an issue |
rtsp.go
Outdated
|
||
// List of formats/codecs in priority order | ||
codecFormats := []codecFormat{ | ||
{&h264, H264}, | ||
{&h265, H265}, | ||
{&mjpeg, MJPEG}, | ||
{&mpeg4, MPEG4}, | ||
{nil, MPEG4}, // ambiguous codec, MPEG4 can be in a generic format |
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 you add more context here?
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.
Added
@@ -976,22 +1043,33 @@ func modelToCodec(model resource.Model) (videoCodec, error) { | |||
|
|||
// getAvailableCodec determines the first supported codec from a session's SDP data | |||
// returning Unknown if none are found. | |||
func getAvailableCodec(session *description.Session) videoCodec { | |||
func (rc *rtspCamera) getAvailableCodec(session *description.Session) videoCodec { |
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.
This function does not need to be on the struct. I don't see it accessing any of the struct's elements,
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.
rc.logger
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.
Ah I see. But why not just return the error there rather than swallow it?
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 we return the error, we may skip over the other codecs if we ever change the priority order / add another codec
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.
Add a comment on why we swallow the error there.
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.
Added
rtsp.go
Outdated
if codecFormat.codec == MPEG4 { | ||
mpeg4, _, err := findMPEG4InSession(session) | ||
switch { | ||
case err != nil: | ||
rc.logger.Debugf("error checking for MPEG4 format: %v", err) | ||
case mpeg4 != nil: | ||
return MPEG4 | ||
} | ||
continue | ||
} | ||
|
||
// For all other codecs, check if format exists directly | ||
if media := session.FindFormat(codecFormat.formatPointer); media != nil { |
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.
Let's make this entire thing a case structure.
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 swapped the order s.t. the special case handling happens after the direct checking of the session. Should we still use case structure? It would cause duplicate code.
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.
Nah this is okay, my goal was readability and this is more readable.
rtsp.go
Outdated
switch { | ||
case err != nil: | ||
rc.logger.Debugf("error checking for MPEG4 format: %v", err) | ||
case mpeg4 != nil: | ||
return MPEG4 | ||
} | ||
continue |
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.
So... We check from mpeg4 to special case it because it's format is sufficiently generic, and when we have an error in this case, return. What is the continue for? Should this be default case to return the other codecs?
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.
The continue was to avoid redundant checking of media := session.FindFormat(codecFormat.formatPointer)
since findMPEG4InSession
already does that. I refactored it so that we don't continue and decoupled the special generic handling from the direct check.
rtsp.go
Outdated
if !strings.HasPrefix(strings.ToUpper(generic.RTPMap()), "MP4V-ES/") { | ||
return nil, fmt.Errorf("generic format is not MPEG4: %s", forma.Codec()) |
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.
Does blueenviron have a checker for this logic?
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.
After looking for a bit, I could not find one
rtsp.go
Outdated
if profileID, ok := fmtp["profile-level-id"]; ok { | ||
id, err := strconv.Atoi(profileID) |
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.
Let's return after !ok
and err
rather than nesting if statements.
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.
Using early return now
…n session from special handling (handling consequent refactor)
Do we have a plan for testing? |
So far I've tested
|
Hinges on upstream PR here to allow for dynamic clock rate configuration.
Other big change is massaging the
Generic
codec format into mpeg4, when it is secretly an mpeg4 track.Edit: tested that setting the clock rate dynamically is not needed for a healthy MPEG4 stream with mediamtx and the office physical camera. Closing upstream change for the time being.
Image of manual test with physical cam in a relevant Slack thread