static void gst_vaapi_video_allocator_finalize (GObject * object) { GstVaapiVideoAllocator *const allocator = GST_VAAPI_VIDEO_ALLOCATOR_CAST (object); gst_vaapi_video_pool_replace (&allocator->surface_pool, NULL); gst_vaapi_video_pool_replace (&allocator->image_pool, NULL); G_OBJECT_CLASS (gst_vaapi_video_allocator_parent_class)->finalize (object); }
static void gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); /* Wait for the last frame to complete redraw */ gst_vaapi_window_wayland_sync (window); if (priv->last_frame) { frame_state_free (priv->last_frame); priv->last_frame = NULL; } if (priv->shell_surface) { wl_shell_surface_destroy (priv->shell_surface); priv->shell_surface = NULL; } if (priv->surface) { wl_surface_destroy (priv->surface); priv->surface = NULL; } if (priv->event_queue) { wl_event_queue_destroy (priv->event_queue); priv->event_queue = NULL; } gst_vaapi_filter_replace (&priv->filter, NULL); gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); gst_poll_free (priv->poll); }
/* Base encoder cleanup (internal) */ void gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); klass->finalize (encoder); gst_vaapi_object_replace (&encoder->context, NULL); gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; if (encoder->properties) { g_ptr_array_unref (encoder->properties); encoder->properties = NULL; } gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL); if (encoder->codedbuf_queue) { g_async_queue_unref (encoder->codedbuf_queue); encoder->codedbuf_queue = NULL; } g_cond_clear (&encoder->surface_free); g_cond_clear (&encoder->codedbuf_free); g_mutex_clear (&encoder->mutex); }
static void gst_vaapi_video_meta_destroy_image (GstVaapiVideoMeta * meta) { if (meta->image) { if (meta->image_pool) gst_vaapi_video_pool_put_object (meta->image_pool, meta->image); gst_vaapi_object_unref (meta->image); meta->image = NULL; } gst_vaapi_video_pool_replace (&meta->image_pool, NULL); }
static void coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy) { if (proxy->buffer) { if (proxy->pool) gst_vaapi_video_pool_put_object (proxy->pool, proxy->buffer); gst_vaapi_object_unref (proxy->buffer); proxy->buffer = NULL; } gst_vaapi_video_pool_replace (&proxy->pool, NULL); coded_buffer_proxy_set_user_data (proxy, NULL, NULL); /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); }
/* Reconfigures the encoder with the new properties */ static GstVaapiEncoderStatus gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; GstVaapiVideoPool *pool; guint codedbuf_size; /* Generate a keyframe every second */ if (!encoder->keyframe_period) encoder->keyframe_period = (vip->fps_n + vip->fps_d - 1) / vip->fps_d; status = klass->reconfigure (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; codedbuf_size = encoder->codedbuf_pool ? gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL (encoder)) : 0; if (codedbuf_size != encoder->codedbuf_size) { pool = gst_vaapi_coded_buffer_pool_new (encoder, encoder->codedbuf_size); if (!pool) goto error_alloc_codedbuf_pool; gst_vaapi_video_pool_set_capacity (pool, 5); gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, pool); gst_vaapi_video_pool_unref (pool); } return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ error_alloc_codedbuf_pool: { GST_ERROR ("failed to initialize coded buffer pool"); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } error_reset_context: { GST_ERROR ("failed to update VA context"); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } }
static void frame_state_free (FrameState * frame) { if (!frame) return; if (frame->surface) { if (frame->surface_pool) gst_vaapi_video_pool_put_object (frame->surface_pool, frame->surface); frame->surface = NULL; } gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); if (frame->callback) { wl_callback_destroy (frame->callback); frame->callback = NULL; } g_slice_free (FrameState, frame); }
static gboolean gst_vaapi_window_wayland_resize (GstVaapiWindow * window, guint width, guint height) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GstVaapiDisplayWaylandPrivate *const priv_display = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); GST_DEBUG ("resize window, new size %ux%u", width, height); gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); if (priv->opaque_region) wl_region_destroy (priv->opaque_region); GST_VAAPI_OBJECT_LOCK_DISPLAY (window); priv->opaque_region = wl_compositor_create_region (priv_display->compositor); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); wl_region_add (priv->opaque_region, 0, 0, width, height); return TRUE; }
static void gst_vaapi_surface_proxy_finalize (GstVaapiSurfaceProxy * proxy) { if (proxy->surface) { if (proxy->pool && !proxy->parent) gst_vaapi_video_pool_put_object (proxy->pool, proxy->surface); gst_vaapi_object_unref (proxy->surface); proxy->surface = NULL; } gst_vaapi_video_pool_replace (&proxy->pool, NULL); gst_vaapi_surface_proxy_replace (&proxy->parent, NULL); /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); #if USE_H264_FEI_ENCODER if (proxy->mvpred) gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & proxy->mvpred, NULL); if (proxy->mbcntrl) gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & proxy->mbcntrl, NULL); if (proxy->qp) gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & proxy->qp, NULL); if (proxy->mbcode) gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & proxy->mbcode, NULL); if (proxy->mv) gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & proxy->mv, NULL); if (proxy->dist) gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & proxy->dist, NULL); #endif }
static int app_run (App * app) { GstVaapiImage *image; GstVaapiVideoPool *pool; GThread *buffer_thread; gsize id; int ret = EXIT_FAILURE; image = gst_vaapi_image_new (app->display, GST_VIDEO_FORMAT_I420, app->parser->width, app->parser->height); { GstVideoInfo vi; gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, app->parser->width, app->parser->height); pool = gst_vaapi_surface_pool_new_full (app->display, &vi, 0); } buffer_thread = g_thread_new ("get buffer thread", get_buffer_thread, app); while (1) { GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; if (!load_frame (app, image)) break; if (!gst_vaapi_image_unmap (image)) break; proxy = gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool)); if (!proxy) { g_warning ("Could not get surface proxy from pool."); break; } surface = gst_vaapi_surface_proxy_get_surface (proxy); if (!surface) { g_warning ("Could not get surface from proxy."); break; } if (!gst_vaapi_surface_put_image (surface, image)) { g_warning ("Could not update surface"); break; } if (!upload_frame (app->encoder, proxy)) { g_warning ("put frame failed"); break; } app->read_frames++; id = gst_vaapi_surface_get_id (surface); g_debug ("input frame %d, surface id = %" G_GSIZE_FORMAT, app->read_frames, id); gst_vaapi_surface_proxy_unref (proxy); } app->input_stopped = TRUE; g_thread_join (buffer_thread); if (!app->encode_failed && feof (app->parser->fp)) ret = EXIT_SUCCESS; gst_vaapi_video_pool_replace (&pool, NULL); gst_vaapi_object_unref (image); return ret; }