/** * ensure_sinkpad_buffer_pool: * @plugin: a #GstVaapiPluginBase * @caps: the initial #GstCaps for the resulting buffer pool * * Makes sure the sink pad video buffer pool is created with the * appropriate @caps. * * Returns: %TRUE if successful, %FALSE otherwise. */ static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; guint size; /* video decoders don't use a buffer pool in the sink pad */ if (GST_IS_VIDEO_DECODER (plugin)) return TRUE; if (!gst_vaapi_plugin_base_ensure_display (plugin)) return FALSE; if (plugin->sinkpad_buffer_pool) { if (gst_vaapi_buffer_pool_caps_is_equal (plugin->sinkpad_buffer_pool, caps)) return TRUE; gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, FALSE); g_clear_object (&plugin->sinkpad_buffer_pool); g_clear_object (&plugin->sinkpad_allocator); plugin->sinkpad_buffer_size = 0; } if (!ensure_sinkpad_allocator (plugin, caps, &size)) return FALSE; pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, BUFFER_POOL_SINK_MIN_BUFFERS, 0, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) return FALSE; plugin->sinkpad_buffer_pool = pool; plugin->sinkpad_buffer_size = size; return TRUE; }
static inline GstAllocator * create_dmabuf_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, gboolean check_for_map) { GstAllocator *allocator; if (!GST_IS_VIDEO_DECODER (plugin) && !GST_IS_BASE_TRANSFORM (plugin)) return NULL; allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, get_dmabuf_surface_allocation_flags (), GST_PAD_SRC); if (!allocator || !check_for_map) return allocator; /* the dmabuf allocator *must* be capable to map a buffer with raw * caps and the there's no evidence of downstream dmabuf * importation */ if (!gst_vaapi_dmabuf_can_map (plugin->display, allocator)) { GST_INFO_OBJECT (plugin, "dmabuf allocator generates unmappable buffers"); gst_object_replace ((GstObject **) & allocator, NULL); } return allocator; }
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; } }