/** * gst_vaapi_object_new: * @klass: The object class * @display: The #GstVaapiDisplay * * Creates a new #GstVaapiObject. The @klass argument shall not be * %NULL, and it must reference a statically allocated descriptor. * * This function zero-initializes the derived object data. Also note * that this is an internal function that shall not be used outside of * libgstvaapi libraries. * * Returns: The newly allocated #GstVaapiObject */ gpointer gst_vaapi_object_new (const GstVaapiObjectClass * klass, GstVaapiDisplay * display) { const GstVaapiMiniObjectClass *const object_class = GST_VAAPI_MINI_OBJECT_CLASS (klass); GstVaapiObject *object; guint sub_size; g_return_val_if_fail (klass != NULL, NULL); g_return_val_if_fail (display != NULL, NULL); object = (GstVaapiObject *) gst_vaapi_mini_object_new (object_class); if (!object) return NULL; object->display = gst_vaapi_display_ref (display); object->object_id = VA_INVALID_ID; sub_size = object_class->size - sizeof (*object); if (sub_size > 0) memset (((guchar *) object) + sizeof (*object), 0, sub_size); if (klass && klass->init) klass->init (object); return object; }
/** * gst_vaapi_video_meta_copy: * @meta: a #GstVaapiVideoMeta * * Creates a copy of #GstVaapiVideoMeta object @meta. The original * @meta object shall not contain any VA objects created from a * #GstVaapiVideoPool. * * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error */ GstVaapiVideoMeta * gst_vaapi_video_meta_copy (GstVaapiVideoMeta * meta) { GstVaapiVideoMeta *copy; g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); if (meta->image_pool) return NULL; copy = _gst_vaapi_video_meta_create (); if (!copy) return NULL; copy->buffer = NULL; copy->ref_count = 1; copy->display = gst_vaapi_display_ref (meta->display); copy->image_pool = NULL; copy->image = meta->image ? gst_vaapi_object_ref (meta->image) : NULL; copy->proxy = meta->proxy ? gst_vaapi_surface_proxy_copy (meta->proxy) : NULL; copy->converter = meta->converter; copy->render_flags = meta->render_flags; copy->has_render_rect = meta->has_render_rect; if (copy->has_render_rect) copy->render_rect = meta->render_rect; return copy; }
static gboolean ensure_vpp (GstVaapiDecodeBin * vaapidecbin) { GstVaapiDisplay *display; if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN) return TRUE; display = GST_VAAPI_PLUGIN_BASE_DISPLAY (vaapidecbin->decoder); if (display) { GST_INFO_OBJECT (vaapidecbin, "Got display from vaapidecode"); gst_vaapi_display_ref (display); } else { GST_INFO_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); display = gst_vaapi_create_test_display (); } if (!display) return FALSE; vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? HAS_VPP_YES : HAS_VPP_NO; gst_vaapi_display_unref (display); return TRUE; }
void gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, GstVaapiVideoPoolObjectType object_type) { pool->object_type = object_type; pool->display = gst_vaapi_display_ref (display); pool->used_objects = NULL; pool->used_count = 0; pool->capacity = 0; g_queue_init (&pool->free_objects); g_mutex_init (&pool->mutex); }
/* Base encoder initialization (internal) */ static gboolean gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); g_return_val_if_fail (display != NULL, FALSE); #define CHECK_VTABLE_HOOK(FUNC) do { \ if (!klass->FUNC) \ goto error_invalid_vtable; \ } while (0) CHECK_VTABLE_HOOK (init); CHECK_VTABLE_HOOK (finalize); CHECK_VTABLE_HOOK (get_default_properties); CHECK_VTABLE_HOOK (reconfigure); CHECK_VTABLE_HOOK (encode); CHECK_VTABLE_HOOK (reordering); CHECK_VTABLE_HOOK (flush); #undef CHECK_VTABLE_HOOK encoder->display = gst_vaapi_display_ref (display); encoder->va_display = gst_vaapi_display_get_display (display); encoder->va_context = VA_INVALID_ID; gst_video_info_init (&encoder->video_info); g_mutex_init (&encoder->mutex); g_cond_init (&encoder->surface_free); g_cond_init (&encoder->codedbuf_free); encoder->codedbuf_queue = g_async_queue_new_full ((GDestroyNotify) gst_vaapi_coded_buffer_proxy_unref); if (!encoder->codedbuf_queue) return FALSE; if (!klass->init (encoder)) return FALSE; if (!gst_vaapi_encoder_init_properties (encoder)) return FALSE; return TRUE; /* ERRORS */ error_invalid_vtable: { GST_ERROR ("invalid subclass hook (internal error)"); return FALSE; } }
static void gst_vaapi_video_buffer_pool_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (object)->priv; switch (prop_id) { case PROP_DISPLAY: priv->display = gst_vaapi_display_ref (g_value_get_pointer (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean gst_vaapi_decoder_init (GstVaapiDecoder * decoder, GstVaapiDisplay * display, GstCaps * caps) { const GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder); GstVideoCodecState *codec_state; guint sub_size; parser_state_init (&decoder->parser_state); codec_state = g_slice_new0 (GstVideoCodecState); codec_state->ref_count = 1; gst_video_info_init (&codec_state->info); decoder->user_data = NULL; decoder->display = gst_vaapi_display_ref (display); decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); decoder->context = NULL; decoder->va_context = VA_INVALID_ID; decoder->codec = 0; decoder->codec_state = codec_state; decoder->codec_state_changed_func = NULL; decoder->codec_state_changed_data = NULL; decoder->buffers = g_async_queue_new_full ((GDestroyNotify) gst_buffer_unref); decoder->frames = g_async_queue_new_full ((GDestroyNotify) gst_video_codec_frame_unref); if (!set_caps (decoder, caps)) return FALSE; sub_size = GST_VAAPI_MINI_OBJECT_CLASS (klass)->size - sizeof (*decoder); if (sub_size > 0) memset (((guchar *) decoder) + sizeof (*decoder), 0, sub_size); if (klass->create && !klass->create (decoder)) return FALSE; return TRUE; }
static gboolean ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) { GArray *formats, *out_formats; GstVaapiSurface *surface; GstVaapiDisplay *display; guint i; GstCaps *out_caps; gboolean ret = FALSE; if (plugin->allowed_raw_caps) return TRUE; out_formats = formats = NULL; surface = NULL; display = gst_vaapi_display_ref (plugin->display); formats = gst_vaapi_display_get_image_formats (display); if (!formats) goto bail; out_formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len); if (!out_formats) goto bail; surface = gst_vaapi_surface_new (display, GST_VAAPI_CHROMA_TYPE_YUV420, 64, 64); if (!surface) goto bail; for (i = 0; i < formats->len; i++) { const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); GstVaapiImage *image; if (format == GST_VIDEO_FORMAT_UNKNOWN) continue; image = gst_vaapi_image_new (display, format, 64, 64); if (!image) continue; if (gst_vaapi_surface_put_image (surface, image)) g_array_append_val (out_formats, format); gst_vaapi_object_unref (image); } out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); if (!out_caps) goto bail; gst_caps_replace (&plugin->allowed_raw_caps, out_caps); gst_caps_unref (out_caps); ret = TRUE; bail: if (formats) g_array_unref (formats); if (out_formats) g_array_unref (out_formats); if (surface) gst_vaapi_object_unref (surface); gst_vaapi_display_unref (display); return ret; }
static GstVaapiDisplay * gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) { #if USE_GST_GL_HELPERS GstGLContext *const gl_context = GST_GL_CONTEXT (gl_context_object); GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context); gpointer native_display = GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); GstVaapiDisplay *display, *out_display; GstVaapiDisplayType display_type; switch (gst_gl_display_get_handle_type (gl_display)) { #if USE_X11 case GST_GL_DISPLAY_TYPE_X11: display_type = GST_VAAPI_DISPLAY_TYPE_X11; break; #endif #if USE_WAYLAND case GST_GL_DISPLAY_TYPE_WAYLAND: display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; break; #endif case GST_GL_DISPLAY_TYPE_ANY:{ /* Derive from the active window */ GstGLWindow *const gl_window = gst_gl_context_get_window (gl_context); const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); display_type = GST_VAAPI_DISPLAY_TYPE_ANY; if (!gl_window) break; native_display = GSIZE_TO_POINTER (gst_gl_window_get_display (gl_window)); if (gl_window_type) { #if USE_X11 if (!display_type && g_strcmp0 (gl_window_type, "x11") == 0) display_type = GST_VAAPI_DISPLAY_TYPE_X11; #endif #if USE_WAYLAND if (!display_type && g_strcmp0 (gl_window_type, "wayland") == 0) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif } else { #if USE_X11 if (!display_type && GST_GL_HAVE_WINDOW_X11) display_type = GST_VAAPI_DISPLAY_TYPE_X11; #endif #if USE_WAYLAND if (!display_type && GST_GL_HAVE_WINDOW_WAYLAND) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif } break; } default: display_type = GST_VAAPI_DISPLAY_TYPE_ANY; break; } if (!display_type) return NULL; display = gst_vaapi_create_display_from_handle (display_type, native_display); if (!display) return NULL; switch (gst_gl_context_get_gl_platform (gl_context)) { #if USE_EGL case GST_GL_PLATFORM_EGL:{ guint gles_version; switch (gst_gl_context_get_gl_api (gl_context)) { case GST_GL_API_GLES1: gles_version = 1; goto create_egl_display; case GST_GL_API_GLES2: gles_version = 2; goto create_egl_display; case GST_GL_API_OPENGL: case GST_GL_API_OPENGL3: gles_version = 0; create_egl_display: out_display = gst_vaapi_display_egl_new (display, gles_version); break; default: out_display = NULL; break; } if (!out_display) return NULL; gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display), GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); break; } #endif default: out_display = gst_vaapi_display_ref (display); break; } gst_vaapi_display_unref (display); return out_display; #endif GST_ERROR ("unsupported GStreamer version %s", GST_API_VERSION_S); return NULL; }