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

Support all raw formats #258

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

joaoantoniocardoso
Copy link
Collaborator

@joaoantoniocardoso joaoantoniocardoso commented Aug 9, 2023

This patch adds a Raw(String), instead of defining each known Raw format by hand.

There are three main fragilities for this approach:

  1. RTP payloads only accept some of the GStreamer's known Raw fourcc (I defined them as KNOWN_RTP_RAW_FORMATS)
  2. The fourccs from the v4l API (defined by the Linux Kernel) don't have the same name as the fourccs used by GStreamer, so we'd always need to manually create the map from one to the other, like v4l's YUYV to GSt's YUY2. An alternative is to use a GstDeviceMonitor to get that information instead of using the v4l API directly. (I wrote this issue to tackle that)
  3. Because of the tricky nature of having two Enum fields both encapsulating Strings, plus to create a validation of what is accepted from GStreamer/V4l, I had to write a custom deserializer.

Despite that, it seems to be working for those formats that were already working, and I can't test other formats because all cameras I have are either H264, MJPG, or YUYV.

@joaoantoniocardoso joaoantoniocardoso force-pushed the support_all_raw_formats branch 2 times, most recently from ede3fa3 to 6bf19ba Compare August 9, 2023 21:21
@joaoantoniocardoso joaoantoniocardoso marked this pull request as ready for review August 10, 2023 00:41
Copy link
Member

@patrickelectric patrickelectric left a comment

Choose a reason for hiding this comment

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

Some suggestions

pub const KNOWN_RTP_RAW_FORMATS: [&str; 9] = [
"RGB", "RGBA", "BGR", "BGRA", "AYUV", "UYVY", "I420", "Y41B", "UYVP",
];
pub const DEFAULT_RAW_FORMAT: &str = "I420";
Copy link
Member

Choose a reason for hiding this comment

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

Did you look at https://docs.rs/gstreamer-video/latest/gstreamer_video/struct.VideoFormatInfo.html#method.name ?

Where the types are defined here:
https://docs.rs/gstreamer-video/latest/gstreamer_video/enum.VideoFormat.html

let info = VideoFormatInfo::from_format(crate::VideoFormat::RGB);
dbg!(info)'

"H264" => return VideoEncodeType::H264,
"MJPG" => return VideoEncodeType::Mjpg,
// TODO: We can implement a [GstDeviceMonitor](https://gstreamer.freedesktop.org/documentation/gstreamer/gstdevicemonitor.html?gi-language=c) and then this manual mapping between v4l's and gst's fourcc will not be neccessary anymore.
// A list of possible v4l fourcc from the Linux docs:
Copy link
Member

Choose a reason for hiding this comment

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

I believe that my previous comment shows how to do it with gstreamer VideoFormatInfo

Copy link
Member

Choose a reason for hiding this comment

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

if let Ok(c_char_array) = CString::new(fourcc.clone()).map(|c_str| c_str.into_raw()) {
use gst_video::ffi::*;

let gst_video_format = unsafe { gst_video_format_from_string(c_char_array) };
Copy link
Member

Choose a reason for hiding this comment

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

I believe that my previous comment would also simplify this code.

VideoEncodeType::Unknown(fourcc)
}
}
impl<'de> Deserialize<'de> for VideoEncodeType {
Copy link
Member

Choose a reason for hiding this comment

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

please add a space between the implementations.

VideoEncodeType::Unknown(fourcc)
}
}
impl<'de> Deserialize<'de> for VideoEncodeType {
Copy link
Member

Choose a reason for hiding this comment

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

Can you provide more information about why this implementation is necessary ? looking at the code this is not clear why.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because of the tricky nature of having two Enum fields both encapsulating Strings, plus to create a validation of what is accepted from GStreamer/V4l, I had to write a custom deserializer.

Like, if we define the Unknown(String) as untagged, everything different from the other options will be Unknown. If we then add another untagged Raw(String), then it goes to who is defined first, and we actually want to use custom logic to define if it is Raw or Unknown.

Copy link
Member

Choose a reason for hiding this comment

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

So, it would be nice to have such explanation as a comment.

@joaoantoniocardoso joaoantoniocardoso linked an issue Jan 12, 2024 that may be closed by this pull request
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.

Allow all v4l2src RAW formats
2 participants