There is pipeline:
v4l2src ! decodebin ! queue ! videoconvert ! xvimagesink
After start v4l2src finds many caps with media type image/jpeg and different image resolutions. v4l2src choose the first caps with 1920x1080. I want to 320x240. And I really don't understand how to set this resolution.
Okay, I can do it:
v4l2src ! image/jpeg,width=320,height=240 ! decodebin ! queue ! videoconvert ! xvimagesink
or:
v4l2src ! jpegdec ! video/x-raw,width=320,height=240 ! queue ! videoconvert ! xvimagesink
But it's not universal. What if the webcamera has a different format?
For example, at this moment I work on the virtual machine and virtual webcamera has only image/jpeg, but on the native system webcam has also video/x-raw. And video/x-raw is the first available set.
What if the another webcamera has video/x-h264 or something else?
Do I understand correctly that GStreamer does not have the ability to somehow universally set the image resolution?
v4l2src ! <all-media-type>,width=320,height=240 ! decodebin ! queue ! videoconvert ! xvimagesink
I must somewhere in my program detect the media type and set the resolution with detected type, right?
What did I try to do?
In gst-inspect-1.0 I found out that v4l2src has signal prepare-format. Okay, what if add capsfilter between v4l2src and decodebin? When prepare-format-callback is calling, I will get the media type and set caps to capsfilter, hoping that pipeline will somehow magically update)
void onV4l2Prepare(GstElement *src, gint /*arg0*/, GstCaps *arg1, GstElement *pipeline_)
{
GstStructure *structure = gst_caps_get_structure(arg1, 0);
const gchar *media_type = gst_structure_get_name(structure);
GstElement *capsfilter = gst_bin_get_by_name(GST_BIN(pipeline_), "capsfilter");
GString *caps_str = g_string_new(nullptr);
g_string_printf(caps_str, "%s,width=320,height=240", media_type, NULL);
g_object_set(G_OBJECT(capsfilter), "caps", caps_str, NULL);
g_string_free(caps_str, TRUE);
// want to check update
GstPad *pad = gst_element_get_static_pad(src, "src");
GstCaps *caps = gst_pad_get_current_caps(pad);
gchar *str = gst_caps_to_string(caps);
g_print(str, NULL); // no updates
g_free(str);
gst_caps_unref(caps);
gst_object_unref(pad);
}
I really have no idea how to do this. Help me, pls)
There are several points in your question. You can rescale into a given resolution using videoscale. For managing different paths depending on received caps, you can use switchbin. Try: