static GstVaapiVideoMemory * gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, gssize offset, gssize size) { GstVaapiVideoMeta *meta; GstMemory *out_mem; gsize maxsize; g_return_val_if_fail (mem, NULL); g_return_val_if_fail (mem->meta, NULL); /* XXX: this implements a soft-copy, i.e. underlying VA surfaces are not copied */ (void) gst_memory_get_sizes (GST_MEMORY_CAST (mem), NULL, &maxsize); if (offset != 0 || (size != -1 && (gsize) size != maxsize)) goto error_unsupported; if (!ensure_surface_is_current (mem)) goto error_no_current_surface; meta = gst_vaapi_video_meta_copy (mem->meta); if (!meta) goto error_allocate_memory; out_mem = gst_vaapi_video_memory_new (GST_MEMORY_CAST (mem)->allocator, meta); gst_vaapi_video_meta_unref (meta); if (!out_mem) goto error_allocate_memory; return GST_VAAPI_VIDEO_MEMORY_CAST (out_mem); /* ERRORS */ error_no_current_surface: GST_ERROR ("failed to make surface current"); return NULL; error_unsupported: GST_ERROR ("failed to copy partial memory (unsupported operation)"); return NULL; error_allocate_memory: GST_ERROR ("failed to allocate GstVaapiVideoMemory copy"); return NULL; }
static GstFlowReturn gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params) { GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; GstVaapiVideoBufferPoolAcquireParams *const priv_params = (GstVaapiVideoBufferPoolAcquireParams *) params; GstVaapiVideoMeta *meta; GstMemory *mem; GstBuffer *buffer; const gboolean alloc_vaapi_video_meta = !params || !(params->flags & GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC); if (!priv->allocator) goto error_no_allocator; if (alloc_vaapi_video_meta) { meta = gst_vaapi_video_meta_new (priv->display); if (!meta) goto error_create_meta; buffer = gst_vaapi_video_buffer_new (meta); } else { meta = NULL; buffer = gst_vaapi_video_buffer_new_empty (); } if (!buffer) goto error_create_buffer; if (priv_params && priv_params->proxy) gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); if (priv->use_dmabuf_memory) mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); else mem = gst_vaapi_video_memory_new (priv->allocator, meta); if (!mem) goto error_create_memory; gst_vaapi_video_meta_replace (&meta, NULL); gst_buffer_append_memory (buffer, mem); if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META) { GstVideoInfo *const vip = &priv->vmeta_vinfo; GstVideoMeta *vmeta; vmeta = gst_buffer_add_video_meta_full (buffer, 0, GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), GST_VIDEO_INFO_N_PLANES (vip), &GST_VIDEO_INFO_PLANE_OFFSET (vip, 0), &GST_VIDEO_INFO_PLANE_STRIDE (vip, 0)); if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) { vmeta->map = gst_video_meta_map_vaapi_memory; vmeta->unmap = gst_video_meta_unmap_vaapi_memory; } } #if (USE_GLX || USE_EGL) if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) gst_buffer_add_texture_upload_meta (buffer); #endif *out_buffer_ptr = buffer; return GST_FLOW_OK; /* ERRORS */ error_no_allocator: { GST_ERROR_OBJECT (pool, "no GstAllocator in buffer pool"); return GST_FLOW_ERROR; } error_create_meta: { GST_ERROR_OBJECT (pool, "failed to allocate vaapi video meta"); return GST_FLOW_ERROR; } error_create_buffer: { GST_ERROR_OBJECT (pool, "failed to create video buffer"); gst_vaapi_video_meta_unref (meta); return GST_FLOW_ERROR; } error_create_memory: { GST_ERROR_OBJECT (pool, "failed to create video memory"); gst_buffer_unref (buffer); gst_vaapi_video_meta_unref (meta); return GST_FLOW_ERROR; } }