30constexpr guint kProposedMinBuffers = 4;
34void addConsumedAllocationMetas(GstQuery* query)
36 gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL);
37 gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE, NULL);
38#if defined(QGC_HAS_GST_VIDEO_ORIENTATION_META)
39 gst_query_add_allocation_meta(query, GST_VIDEO_ORIENTATION_META_API_TYPE, NULL);
41#if defined(QGC_HAS_GST_GLMEMORY_GPU_PATH)
43 gst_query_add_allocation_meta(query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
47 gst_query_add_allocation_meta(query, GST_GL_SYNC_META_API_TYPE, NULL);
51#if defined(Q_OS_WIN) && defined(QGC_HAS_GST_D3D11_GPU_PATH)
54bool tryProposeD3D11Pool(GstQuery* query, GstCaps* caps,
const GstVideoInfo* vinfo, gsize size)
56 GstD3D11Device* device = GstD3D11ContextBridge::currentDevice();
60 bool proposed =
false;
61 if (GstBufferPool* pool = gst_d3d11_buffer_pool_new(device)) {
62 GstStructure*
config = gst_buffer_pool_get_config(pool);
63 gst_buffer_pool_config_set_params(
config, caps, size, kProposedMinBuffers, 0);
64 gst_buffer_pool_config_add_option(
config, GST_BUFFER_POOL_OPTION_VIDEO_META);
65 if (GstD3D11AllocationParams* params = gst_d3d11_allocation_params_new(
66 device, vinfo, GST_D3D11_ALLOCATION_FLAG_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0)) {
67 gst_buffer_pool_config_set_d3d11_allocation_params(
config, params);
68 gst_d3d11_allocation_params_free(params);
70 if (gst_buffer_pool_set_config(pool,
config)) {
72 GstStructure* updated = gst_buffer_pool_get_config(pool);
73 guint poolSize =
static_cast<guint
>(size);
74 gst_buffer_pool_config_get_params(updated,
nullptr, &poolSize,
nullptr,
nullptr);
75 gst_structure_free(updated);
76 gst_query_add_allocation_pool(query, pool, poolSize, kProposedMinBuffers, 0);
79 gst_object_unref(pool);
81 gst_object_unref(device);
86#if defined(Q_OS_WIN) && defined(QGC_HAS_GST_D3D12_GPU_PATH)
88bool tryProposeD3D12Pool(GstQuery* query, GstCaps* caps,
const GstVideoInfo* vinfo, gsize size)
90 GstD3D12Device* device = GstD3D12ContextBridge::currentDevice();
94 bool proposed =
false;
95 if (GstBufferPool* pool = gst_d3d12_buffer_pool_new(device)) {
96 GstStructure*
config = gst_buffer_pool_get_config(pool);
97 gst_buffer_pool_config_set_params(
config, caps, size, kProposedMinBuffers, 0);
98 gst_buffer_pool_config_add_option(
config, GST_BUFFER_POOL_OPTION_VIDEO_META);
99 if (GstD3D12AllocationParams* params = gst_d3d12_allocation_params_new(
100 device, vinfo, GST_D3D12_ALLOCATION_FLAG_DEFAULT, D3D12_RESOURCE_FLAG_NONE,
101 D3D12_HEAP_FLAG_NONE)) {
102 gst_buffer_pool_config_set_d3d12_allocation_params(
config, params);
103 gst_d3d12_allocation_params_free(params);
105 if (gst_buffer_pool_set_config(pool,
config)) {
106 GstStructure* updated = gst_buffer_pool_get_config(pool);
107 guint poolSize =
static_cast<guint
>(size);
108 gst_buffer_pool_config_get_params(updated,
nullptr, &poolSize,
nullptr,
nullptr);
109 gst_structure_free(updated);
110 gst_query_add_allocation_pool(query, pool, poolSize, kProposedMinBuffers, 0);
113 gst_object_unref(pool);
115 gst_object_unref(device);
121bool tryProposeDeviceBoundPool(GstQuery* query, GstCaps* caps,
const GstVideoInfo* vinfo, gsize size)
123 GstCapsFeatures* features = gst_caps_get_features(caps, 0);
127#if defined(Q_OS_WIN) && defined(QGC_HAS_GST_D3D11_GPU_PATH)
128 if (gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
129 return tryProposeD3D11Pool(query, caps, vinfo, size);
132#if defined(Q_OS_WIN) && defined(QGC_HAS_GST_D3D12_GPU_PATH)
133 if (gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_D3D12_MEMORY)) {
134 return tryProposeD3D12Pool(query, caps, vinfo, size);
143bool tryProposeMetaPool(GstQuery* query, GstCaps* caps, gsize size)
145 GstBufferPool* pool = gst_buffer_pool_new();
150 bool proposed =
false;
151 GstStructure*
config = gst_buffer_pool_get_config(pool);
152 gst_buffer_pool_config_set_params(
config, caps, size, kProposedMinBuffers, 0);
153 gst_buffer_pool_config_add_option(
config, GST_BUFFER_POOL_OPTION_VIDEO_META);
154 if (gst_buffer_pool_set_config(pool,
config)) {
155 gst_query_add_allocation_pool(query, pool, size, kProposedMinBuffers, 0);
158 gst_object_unref(pool);
166 GstCaps* caps =
nullptr;
167 gboolean need_pool = FALSE;
168 gst_query_parse_allocation(query, &caps, &need_pool);
177 const gsize size = GST_VIDEO_INFO_SIZE(&vinfo);
179 GstCapsFeatures* features = gst_caps_get_features(caps, 0);
180 const bool is_system_memory =
181 !features || gst_caps_features_is_equal(features, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
183 if (!is_system_memory) {
184 if (!tryProposeDeviceBoundPool(query, caps, &vinfo, size)) {
185 gst_query_add_allocation_pool(query, NULL, size, kProposedMinBuffers, 0);
187 addConsumedAllocationMetas(query);
192 addConsumedAllocationMetas(query);
196 (void) tryProposeMetaPool(query, caps, size);
197 addConsumedAllocationMetas(query);
204 GstQuery* query = GST_PAD_PROBE_INFO_QUERY(info);
206 return GST_PAD_PROBE_OK;
209 switch (GST_QUERY_TYPE(query)) {
210 case GST_QUERY_ALLOCATION:
212 return GST_PAD_PROBE_HANDLED;
213 case GST_QUERY_CONTEXT:
217 return GST_PAD_PROBE_HANDLED;
219 return GST_PAD_PROBE_OK;
221 return GST_PAD_PROBE_OK;