static gboolean ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, guint * size) { GstVideoInfo vinfo; const GstVideoInfo *image_info; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; if (!gst_video_info_from_caps (&vinfo, caps)) goto error_invalid_caps; if (!reset_allocator (plugin->sinkpad_allocator, &vinfo)) goto bail; if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { plugin->sinkpad_allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vinfo, GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE, GST_PAD_SINK); goto bail; } /* enable direct upload if upstream requests raw video */ if (gst_caps_is_video_raw (caps)) { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; GST_INFO_OBJECT (plugin, "enabling direct upload in sink allocator"); } plugin->sinkpad_allocator = gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, usage_flag); bail: if (!plugin->sinkpad_allocator) goto error_create_allocator; image_info = gst_allocator_get_vaapi_video_info (plugin->sinkpad_allocator, NULL); g_assert (image_info); /* allocator ought set its image info */ /* update the size with the one generated by the allocator */ *size = GST_VIDEO_INFO_SIZE (image_info); return TRUE; /* ERRORS */ error_invalid_caps: { GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); return FALSE; } error_create_allocator: { GST_ERROR_OBJECT (plugin, "failed to create sink pad's allocator"); return FALSE; } }
static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { gboolean different_caps; GstVideoInfo vi; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; /* the received caps are the "allocation caps" which may be * different from the "negotiation caps". In this case, we should * indicate the allocator to store the negotiation caps since they * are the one should be used for frame mapping with GstVideoMeta */ different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps && !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); if (different_caps) { vi = plugin->srcpad_info; } else { vi = *vinfo; } if (!reset_allocator (plugin->srcpad_allocator, &vi)) return TRUE; plugin->srcpad_allocator = NULL; if (caps && gst_caps_is_video_raw (caps)) { if (plugin->srcpad_can_dmabuf) { if (GST_IS_VIDEO_DECODER (plugin) || GST_IS_BASE_TRANSFORM (plugin)) { plugin->srcpad_allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, get_dmabuf_surface_allocation_flags (), GST_PAD_SRC); } } else if (plugin->enable_direct_rendering) { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); } } if (!plugin->srcpad_allocator) { plugin->srcpad_allocator = gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); } if (!plugin->srcpad_allocator) goto error_create_allocator; if (different_caps) { guint i, flags = 0; const GstVideoInfo *alloc_vi = gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, &flags); /* update the planes and the size with the allocator image info, * but not the resolution */ if (alloc_vi) { for (i = 0; i < GST_VIDEO_INFO_N_PLANES (alloc_vi); i++) { GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = GST_VIDEO_INFO_PLANE_OFFSET (alloc_vi, i); GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = GST_VIDEO_INFO_PLANE_STRIDE (alloc_vi, i); } GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (alloc_vi); gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, flags); } } return TRUE; /* ERRORS */ error_create_allocator: { GST_ERROR_OBJECT (plugin, "failed to create src pad's allocator"); return FALSE; } }
static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { gboolean different_caps; const GstVideoInfo *image_info; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; if (!reset_allocator (plugin->srcpad_allocator, vinfo)) goto valid_allocator; plugin->srcpad_allocator = NULL; if (caps && gst_caps_is_video_raw (caps)) { GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, !plugin->srcpad_can_dmabuf); if (!allocator && plugin->enable_direct_rendering) { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); } plugin->srcpad_allocator = allocator; } else if (caps && gst_vaapi_caps_feature_contains (caps, GST_VAAPI_CAPS_FEATURE_DMABUF)) { plugin->srcpad_allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE); if (!plugin->srcpad_allocator) goto error_create_allocator; } if (!plugin->srcpad_allocator) { plugin->srcpad_allocator = gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); } if (!plugin->srcpad_allocator) goto error_create_allocator; valid_allocator: image_info = gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL); g_assert (image_info); /* both allocators ought set its image * info */ /* update the size with the one generated by the allocator */ GST_VIDEO_INFO_SIZE (vinfo) = GST_VIDEO_INFO_SIZE (image_info); /* the received caps are the "allocation caps" which may be * different from the "negotiation caps". In this case, we should * indicate the allocator to store the negotiation caps since they * are the one should be used for frame mapping with GstVideoMeta */ different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps && !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); if (different_caps) { guint i; GstVideoInfo vi = plugin->srcpad_info; /* update the planes and the size with the allocator image/surface * info, but not the resolution */ for (i = 0; i < GST_VIDEO_INFO_N_PLANES (image_info); i++) { GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = GST_VIDEO_INFO_PLANE_OFFSET (image_info, i); GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = GST_VIDEO_INFO_PLANE_STRIDE (image_info, i); } GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info); gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, &vi); } return TRUE; /* ERRORS */ error_create_allocator: { GST_ERROR_OBJECT (plugin, "failed to create src pad's allocator"); return FALSE; } }