mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
v4l2object: try matching buffer layout from downstream
Ask v4l2 to produce buffers matching the buffer layout requested downstream.
This commit is contained in:
parent
31c753a3fb
commit
91002389b9
1 changed files with 84 additions and 1 deletions
|
@ -4456,6 +4456,79 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
validate_video_meta_struct (GstV4l2Object * obj, const GstStructure * s)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < gst_structure_n_fields (s); i++) {
|
||||||
|
const gchar *name = gst_structure_nth_field_name (s, i);
|
||||||
|
|
||||||
|
if (!g_str_equal (name, "padding-top")
|
||||||
|
&& !g_str_equal (name, "padding-bottom")
|
||||||
|
&& !g_str_equal (name, "padding-left")
|
||||||
|
&& !g_str_equal (name, "padding-right")) {
|
||||||
|
GST_WARNING_OBJECT (obj->dbg_obj, "Unknown video meta field: '%s'", name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_object_match_buffer_layout_from_struct (GstV4l2Object * obj,
|
||||||
|
const GstStructure * s, GstCaps * caps, guint buffer_size)
|
||||||
|
{
|
||||||
|
GstVideoInfo info;
|
||||||
|
GstVideoAlignment align;
|
||||||
|
gsize plane_size[GST_VIDEO_MAX_PLANES];
|
||||||
|
|
||||||
|
if (!validate_video_meta_struct (obj, s))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!gst_video_info_from_caps (&info, caps)) {
|
||||||
|
GST_WARNING_OBJECT (obj->dbg_obj, "Failed to create video info");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_video_alignment_reset (&align);
|
||||||
|
|
||||||
|
gst_structure_get_uint (s, "padding-top", &align.padding_top);
|
||||||
|
gst_structure_get_uint (s, "padding-bottom", &align.padding_bottom);
|
||||||
|
gst_structure_get_uint (s, "padding-left", &align.padding_left);
|
||||||
|
gst_structure_get_uint (s, "padding-right", &align.padding_right);
|
||||||
|
|
||||||
|
if (align.padding_top || align.padding_bottom || align.padding_left ||
|
||||||
|
align.padding_right) {
|
||||||
|
GST_DEBUG_OBJECT (obj->dbg_obj,
|
||||||
|
"Upstream requested padding (top: %d bottom: %d left: %d right: %d)",
|
||||||
|
align.padding_top, align.padding_bottom, align.padding_left,
|
||||||
|
align.padding_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_video_info_align_full (&info, &align, plane_size)) {
|
||||||
|
GST_WARNING_OBJECT (obj->dbg_obj, "Failed to align video info");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GST_VIDEO_INFO_SIZE (&info) != buffer_size) {
|
||||||
|
GST_WARNING_OBJECT (obj->dbg_obj,
|
||||||
|
"Requested buffer size (%d) doesn't match video info size (%"
|
||||||
|
G_GSIZE_FORMAT ")", buffer_size, GST_VIDEO_INFO_SIZE (&info));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (obj->dbg_obj,
|
||||||
|
"try matching buffer layout requested by downstream");
|
||||||
|
|
||||||
|
gst_v4l2_object_match_buffer_layout (obj, GST_VIDEO_INFO_N_PLANES (&info),
|
||||||
|
info.offset, info.stride, buffer_size,
|
||||||
|
GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
|
gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
@ -4468,6 +4541,7 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
|
||||||
gboolean can_share_own_pool, pushing_from_our_pool = FALSE;
|
gboolean can_share_own_pool, pushing_from_our_pool = FALSE;
|
||||||
GstAllocator *allocator = NULL;
|
GstAllocator *allocator = NULL;
|
||||||
GstAllocationParams params = { 0 };
|
GstAllocationParams params = { 0 };
|
||||||
|
guint video_idx;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (obj->dbg_obj, "decide allocation");
|
GST_DEBUG_OBJECT (obj->dbg_obj, "decide allocation");
|
||||||
|
|
||||||
|
@ -4498,7 +4572,16 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
|
||||||
GST_PTR_FORMAT, size, min, max, pool);
|
GST_PTR_FORMAT, size, min, max, pool);
|
||||||
|
|
||||||
has_video_meta =
|
has_video_meta =
|
||||||
gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE,
|
||||||
|
&video_idx);
|
||||||
|
|
||||||
|
if (has_video_meta) {
|
||||||
|
const GstStructure *params;
|
||||||
|
gst_query_parse_nth_allocation_meta (query, video_idx, ¶ms);
|
||||||
|
|
||||||
|
if (params)
|
||||||
|
gst_v4l2_object_match_buffer_layout_from_struct (obj, params, caps, size);
|
||||||
|
}
|
||||||
|
|
||||||
can_share_own_pool = (has_video_meta || !obj->need_video_meta);
|
can_share_own_pool = (has_video_meta || !obj->need_video_meta);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue