/* Updates video context */ static gboolean set_context_info (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); const GstVaapiEncoderClassData *const cdata = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; if (cdata->codec != GST_VAAPI_CODEC_JPEG) cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; else cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = encoder->num_ref_frames; if (!cip->chroma_type && (format != GST_VIDEO_FORMAT_ENCODED)) goto error_unsupported_format; if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && format != GST_VIDEO_FORMAT_ENCODED) { GST_ERROR ("We are only supporting YUV:4:2:0 for encoding," "please try to use vaapipostproc to convert the input format!"); goto error_unsupported_format; } memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); config->packed_headers = get_packed_headers (encoder); return TRUE; /* ERRORS */ error_unsupported_format: { GST_ERROR ("failed to determine chroma type for format %s", gst_vaapi_video_format_to_string (format)); return FALSE; } }
/** * gst_vaapi_surface_new_full: * @display: a #GstVaapiDisplay * @vip: the pointer to a #GstVideoInfo * @flags: (optional) allocation flags * * Creates a new #GstVaapiSurface with the specified video information * and optional #GstVaapiSurfaceAllocFlags * * Return value: the newly allocated #GstVaapiSurface object, or %NULL * if creation of VA surface with explicit pixel format is not * supported or failed. */ GstVaapiSurface * gst_vaapi_surface_new_full (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags) { GstVaapiSurface *surface; GST_DEBUG ("size %ux%u, format %s, flags 0x%08x", GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), flags); surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); if (!surface) return NULL; if (!gst_vaapi_surface_create_full (surface, vip, flags)) goto error; return surface; error: gst_vaapi_object_unref (surface); return NULL; }
static void print_formats(GArray *formats, const gchar *name) { guint i; g_print("%u %s caps\n", formats->len, name); for (i = 0; i < formats->len; i++) { const GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); const VAImageFormat *va_format; g_print(" %s:", gst_vaapi_video_format_to_string(format)); va_format = gst_vaapi_video_format_to_va_format(format); if (!va_format) g_error("could not determine VA format"); if (gst_vaapi_video_format_is_yuv(format)) print_format_yuv(va_format); else print_format_rgb(va_format); g_print("\n"); } }
static gboolean gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) { #if VA_CHECK_VERSION (0,36,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); GstVideoFormat format; VASurfaceID surface_id; VAStatus status; guint chroma_type, va_chroma_format; const VAImageFormat *va_format; VASurfaceAttrib attribs[2], *attrib; VASurfaceAttribExternalBuffers extbuf; unsigned long extbuf_handle; guint i, width, height; format = GST_VIDEO_INFO_FORMAT (vip); width = GST_VIDEO_INFO_WIDTH (vip); height = GST_VIDEO_INFO_HEIGHT (vip); gst_vaapi_buffer_proxy_replace (&surface->extbuf_proxy, proxy); va_format = gst_vaapi_video_format_to_va_format (format); if (!va_format) goto error_unsupported_format; chroma_type = gst_vaapi_video_format_get_chroma_type (format); if (!chroma_type) goto error_unsupported_format; va_chroma_format = from_GstVaapiChromaType (chroma_type); if (!va_chroma_format) goto error_unsupported_format; extbuf_handle = GST_VAAPI_BUFFER_PROXY_HANDLE (proxy); extbuf.pixel_format = va_format->fourcc; extbuf.width = width; extbuf.height = height; extbuf.data_size = GST_VAAPI_BUFFER_PROXY_SIZE (proxy); extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); for (i = 0; i < extbuf.num_planes; i++) { extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); } extbuf.buffers = &extbuf_handle; extbuf.num_buffers = 1; extbuf.flags = 0; extbuf.private_data = NULL; attrib = attribs; attrib->type = VASurfaceAttribExternalBufferDescriptor; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->value.type = VAGenericValueTypePointer; attrib->value.value.p = &extbuf; attrib++; attrib->type = VASurfaceAttribMemoryType; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->value.type = VAGenericValueTypeInteger; attrib->value.value.i = from_GstVaapiBufferMemoryType (GST_VAAPI_BUFFER_PROXY_TYPE (proxy)); attrib++; GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), va_chroma_format, width, height, &surface_id, 1, attribs, attrib - attribs); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; surface->format = format; surface->chroma_type = chroma_type; surface->width = width; surface->height = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; return TRUE; /* ERRORS */ error_unsupported_format: GST_ERROR ("unsupported format %s", gst_vaapi_video_format_to_string (format)); return FALSE; #else return FALSE; #endif }
static gboolean gst_vaapi_surface_create_full (GstVaapiSurface * surface, const GstVideoInfo * vip, guint flags) { #if VA_CHECK_VERSION(0,34,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); VASurfaceID surface_id; VAStatus status; guint chroma_type, va_chroma_format, i; const VAImageFormat *va_format; VASurfaceAttrib attribs[3], *attrib; VASurfaceAttribExternalBuffers extbuf; gboolean extbuf_needed = FALSE; va_format = gst_vaapi_video_format_to_va_format (format); if (!va_format) goto error_unsupported_format; chroma_type = gst_vaapi_video_format_get_chroma_type (format); if (!chroma_type) goto error_unsupported_format; va_chroma_format = from_GstVaapiChromaType (chroma_type); if (!va_chroma_format) goto error_unsupported_format; memset (&extbuf, 0, sizeof (extbuf)); extbuf.pixel_format = va_format->fourcc; extbuf.width = GST_VIDEO_INFO_WIDTH (vip); extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); extbuf_needed = ! !(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { for (i = 0; i < extbuf.num_planes; i++) extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); extbuf_needed = TRUE; } if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) { for (i = 0; i < extbuf.num_planes; i++) extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); extbuf_needed = TRUE; } attrib = attribs; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribPixelFormat; attrib->value.type = VAGenericValueTypeInteger; attrib->value.value.i = va_format->fourcc; attrib++; if (extbuf_needed) { attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribMemoryType; attrib->value.type = VAGenericValueTypeInteger; attrib->value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA; attrib++; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribExternalBufferDescriptor; attrib->value.type = VAGenericValueTypePointer; attrib->value.value.p = &extbuf; attrib++; } GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), va_chroma_format, extbuf.width, extbuf.height, &surface_id, 1, attribs, attrib - attribs); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; surface->format = format; surface->chroma_type = chroma_type; surface->width = extbuf.width; surface->height = extbuf.height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; return TRUE; /* ERRORS */ error_unsupported_format: GST_ERROR ("unsupported format %s", gst_vaapi_video_format_to_string (format)); return FALSE; #else return FALSE; #endif }
static GstVaapiSurface * vpp_convert (GstVaapiWindow * window, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, guint flags) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); GstVaapiSurface *vpp_surface = NULL; GstVaapiFilterStatus status; /* Ensure VA surface pool is created */ /* XXX: optimize the surface format to use. e.g. YUY2 */ if (!priv->surface_pool) { priv->surface_pool = gst_vaapi_surface_pool_new (display, priv->surface_format, window->width, window->height); if (!priv->surface_pool) return NULL; gst_vaapi_filter_replace (&priv->filter, NULL); } /* Ensure VPP pipeline is built */ if (!priv->filter) { priv->filter = gst_vaapi_filter_new (display); if (!priv->filter) goto error_create_filter; if (!gst_vaapi_filter_set_format (priv->filter, priv->surface_format)) goto error_unsupported_format; } if (!gst_vaapi_filter_set_cropping_rectangle (priv->filter, src_rect)) return NULL; if (!gst_vaapi_filter_set_target_rectangle (priv->filter, dst_rect)) return NULL; /* Post-process the decoded source surface */ vpp_surface = gst_vaapi_video_pool_get_object (priv->surface_pool); if (!vpp_surface) return NULL; status = gst_vaapi_filter_process (priv->filter, surface, vpp_surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) goto error_process_filter; return vpp_surface; /* ERRORS */ error_create_filter: { GST_WARNING ("failed to create VPP filter. Disabling"); priv->use_vpp = FALSE; return NULL; } error_unsupported_format: { GST_ERROR ("unsupported render target format %s", gst_vaapi_video_format_to_string (priv->surface_format)); priv->use_vpp = FALSE; return NULL; } error_process_filter: { GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); gst_vaapi_video_pool_put_object (priv->surface_pool, vpp_surface); return NULL; } }