static inline void allocator_configure_image_info (GstVaapiDisplay * display, GstVaapiVideoAllocator * allocator) { GstVaapiImage *image = NULL; const GstVideoInfo *vinfo; if (allocator->has_direct_rendering) { allocator->image_info = allocator->surface_info; return; } vinfo = &allocator->video_info; if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_I420, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); else allocator->image_info = *vinfo; image = new_image (display, &allocator->image_info); if (!image) goto bail; if (!gst_vaapi_image_map (image)) goto bail; gst_video_info_update_from_image (&allocator->image_info, image); gst_vaapi_image_unmap (image); bail: if (image) gst_vaapi_object_unref (image); }
gboolean gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info) { GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); g_return_val_if_fail (mem, FALSE); g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance. allocator), FALSE); g_return_val_if_fail (mem->meta, FALSE); g_return_val_if_fail (mem->surface, FALSE); g_return_val_if_fail (mem->image, FALSE); if (--mem->map_count == 0) { mem->map_type = 0; /* Unmap VA image used for read/writes */ if (info->flags & GST_MAP_READWRITE) { gst_vaapi_image_unmap (mem->image); if (info->flags & GST_MAP_WRITE) { GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } } } return TRUE; }
static gboolean load_frame (App * app, GstVaapiImage * image) { gboolean ret = FALSE; if (!gst_vaapi_image_map (image)) return FALSE; ret = y4m_reader_load_image (app->parser, image); if (!gst_vaapi_image_unmap (image)) return FALSE; return ret; }
static inline void allocator_configure_surface_info (GstVaapiDisplay * display, GstVaapiVideoAllocator * allocator) { const GstVideoInfo *vinfo; GstVaapiSurface *surface = NULL; GstVaapiImage *image = NULL; gboolean updated; GstVideoFormat fmt; vinfo = &allocator->video_info; fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); gst_video_info_set_format (&allocator->surface_info, fmt, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); /* nothing to configure */ if (USE_NATIVE_FORMATS || GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) return; surface = new_surface (display, vinfo); if (!surface) goto bail; image = gst_vaapi_surface_derive_image (surface); if (!image) goto bail; if (!gst_vaapi_image_map (image)) goto bail; updated = gst_video_info_update_from_image (&allocator->surface_info, image); allocator->has_direct_rendering = !USE_NATIVE_FORMATS && updated && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); GST_INFO ("has direct-rendering for %s surfaces: %s", GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info), allocator->has_direct_rendering ? "yes" : "no"); gst_vaapi_image_unmap (image); bail: if (surface) gst_vaapi_object_unref (surface); if (image) gst_vaapi_object_unref (image); }
GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags) { GstAllocator *allocator = NULL; GstVaapiSurface *surface = NULL; GstVaapiImage *image = NULL; GstVideoInfo alloc_info; g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (vip != NULL, NULL); do { surface = gst_vaapi_surface_new_full (display, vip, flags); if (!surface) break; image = gst_vaapi_surface_derive_image (surface); if (!image || !gst_vaapi_image_map (image)) break; gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); gst_video_info_update_from_image (&alloc_info, image); gst_vaapi_image_unmap (image); allocator = gst_dmabuf_allocator_new (); if (!allocator) break; gst_allocator_set_vaapi_video_info (allocator, &alloc_info, flags); } while (0); gst_vaapi_object_replace (&image, NULL); gst_vaapi_object_replace (&surface, NULL); return allocator; }
static void gst_vaapi_video_memory_unmap (GstVaapiVideoMemory * mem) { if (mem->map_count == 1) { switch (mem->map_type) { case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); break; case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: gst_vaapi_image_unmap (mem->image); break; default: goto error_incompatible_map; } mem->map_type = 0; } mem->map_count--; return; /* ERRORS */ error_incompatible_map: GST_ERROR ("incompatible map type (%d)", mem->map_type); return; }
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; }