Skip to content
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-8274, RSDK-8624, RSDK-8647, RSDK-8687] Video Storage and Save/Fetch DoCommand #7

Closed
wants to merge 129 commits into from

Conversation

seanavery
Copy link
Collaborator

@seanavery seanavery commented Sep 4, 2024

Description

This PR includes a POC for the video-store module. The module contains the following core elements:

  • cam.go Camera interface, module configuration, do_command handlers.
  • encoder.go Encodes frames from source camera.
  • segmenter.go Splits encoded feed into video segments.
  • concater.go Combines video segments for save/fetch.
  • utils.go Various ffmpeg, datetime, and file helpers.

Tests

  • config_test.go Tests module configuration and validation.
  • save_test.go Tests save do_command.
  • fetch_test.go Tests fetch do_command.

FFmpeg Refs

Profiling

TODO

@seanavery seanavery changed the title POC: Video Storage and Save do_command [RSDK-8274, RSDK-8624, RSDK-8647, RSDK-8687] Video Storage and Save/Fetch DoCommand Sep 9, 2024
Copy link

@randhid randhid left a comment

Choose a reason for hiding this comment

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

Few nits, I'd like more testing and sanitization around the datamanager filepath, since that's a big initial useability pain point. We can make the storage more robust and cpu in a follow up ticket, that can be part of the epic since it's directly related to the scope asks.

Comment on lines +82 to +90
type Config struct {
Camera string `json:"camera"`
Sync string `json:"sync"`
Storage storage `json:"storage"`
Video video `json:"video,omitempty"`

// TODO(seanp): Remove once camera properties are returned from camera component.
Properties cameraProperties `json:"cam_props"`
}
Copy link

Choose a reason for hiding this comment

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

[readability] Add validate immediately after the config struct.

Copy link
Collaborator Author

@seanavery seanavery Sep 10, 2024

Choose a reason for hiding this comment

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

Moved

cam/cam.go Outdated

// Create segmenter to handle segmentation of video stream into clips.
if newConf.Storage.SegmentSeconds == 0 {
newConf.Storage.SegmentSeconds = defaultSegmentSeconds
Copy link

Choose a reason for hiding this comment

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

do not overwrite the config struct, I can't tell if there will ever be a case with a read/write race in this code as of now, so let's do the dumb but safe thing and just set a variable to a default and overwrite it with the configured value. Do the same fo other writes of the config variable in the constructor code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good - moved to that flow.

cam/cam.go Outdated
Comment on lines 165 to 166
if newConf.Storage.UploadPath == "" {
newConf.Storage.UploadPath = filepath.Join(getHomeDir(), defaultUploadPath, vs.name.Name)
Copy link

Choose a reason for hiding this comment

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

[q] we test this specific part of your pr for all edge cases?

  • upload path unset
  • bad/malformed upload path

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • If path is unset uses default $HOME/.viam/capture/video-upload
  • If path is malformed it will error out when it attempts to create the directory later on in the constructor.

cam/cam.go Outdated
return
default:
}
frame, _, err := vs.stream.Next(ctx)
Copy link

Choose a reason for hiding this comment

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

[q] why do we never call release returned from Next here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good call out, I was meaning to add a TODO comment here.

Added in release call after encoding. Tested that things are still working.

tests/config_test.go Outdated Show resolved Hide resolved
test.That(t, err, test.ShouldBeNil)
defer r.Close(timeoutCtx)
_, err = camera.FromRobot(r, videoStoreComponentName)
test.That(t, err, test.ShouldNotBeNil)
Copy link

Choose a reason for hiding this comment

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

Test the error, since you gave this a timeoutCtx to test with.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added check for error msg contents.

Copy link
Collaborator

@hexbabe hexbabe left a comment

Choose a reason for hiding this comment

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

Good stuff!! LGTM

Makefile Outdated
--enable-protocol=crypto \
--enable-bsf=h264_mp4toannexb

# TODO(seanp): cleanup libx264 static link.
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's currently wrong with the static link?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • Linked by absolute path instead of by lib name.
  • Relies on libx264 static build in canon.

I think relying on canon build is fine since we can use canon containers in CI matrix.

Removed TODO comment.

}
```

## Do Commands
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need to document do commands? Is it so that someone could integrate with this module in their own app if they wanted to?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, I think we need to document DoCommands in the README since the module is pretty much worthless without save/fetch interface.

cam/cam.go Outdated
p, err := vs.cam.Properties(ctx)
if err == nil {
p.SupportsPCD = false
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

confused at the above conditional, why does having no error mean that supporting pcd is false

Copy link

Choose a reason for hiding this comment

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

This camera has no intrinsics or distortion parameters in it's config, and so has no way of producing pointclouds from the underlying 2D image. The camera it depends on might be able to, and we could use the intrinsic and distortion properties from the underlying camera to produce point clouds, but we don't need to and don't, so we tell the truth about this camera's properties - it does not support point clouds.

A question here though - do we need to pass through the dependent camera's properties?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good points - I think we should just return empty props here.

Matt Vella asked me about returning images from underlying camera here for the Event Manager, which would then make sense to have this props passthrough.

But AFAIK, the current plan is to use GetDetectionsFromCamera from the Vision Service.

Copy link

Choose a reason for hiding this comment

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

Cool, check in with him again, but let's get this merged and a POC module in the registry first!

@seanavery
Copy link
Collaborator Author

OK merged code in. Had to do a force push to main instead of merging against empty-ref branch in this PR. Closing out.

@seanavery seanavery closed this Sep 11, 2024
@randhid
Copy link

randhid commented Sep 11, 2024

OK merged code in. Had to do a force push to main instead of merging against empty-ref branch in this PR. Closing out.

To keep track of what was merged in, you can create commits so that JIRA can track them too:
Screenshot 2024-09-11 at 10 59 41

Or just make a pr with the linked tickets. I wouldn't recommend using an empty ref in the future. It's okay, you can ask people to expand the code and read it for more context.

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.

3 participants