GstVaapiImage * image_generate( GstVaapiDisplay *display, GstVaapiImageFormat format, guint width, guint height ) { const guint w = width; const guint h = height; GstVaapiImage *image; image = gst_vaapi_image_new(display, format, w, h); if (!image) return NULL; if (image_draw_rectangle(image, 0, 0, w/2, h/2, 0xffff0000) && image_draw_rectangle(image, w/2, 0, w/2, h/2, 0xff00ff00) && image_draw_rectangle(image, 0, h/2, w/2, h/2, 0xff0000ff) && image_draw_rectangle(image, w/2, h/2, w/2, h/2, 0xff000000)) return image; g_object_unref(image); return NULL; }
static GstVaapiImage * new_image (GstVaapiDisplay * display, const GstVideoInfo * vip) { if (!GST_VIDEO_INFO_WIDTH (vip) || !GST_VIDEO_INFO_HEIGHT (vip)) return NULL; return gst_vaapi_image_new (display, GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); }
static gpointer gst_vaapi_image_pool_alloc_object (GstVaapiVideoPool * base_pool) { GstVaapiImagePool *const pool = GST_VAAPI_IMAGE_POOL (base_pool); return gst_vaapi_image_new (base_pool->display, pool->format, pool->width, pool->height); }
gpointer gst_vaapi_image_pool_alloc_object( GstVaapiVideoPool *pool, GstVaapiDisplay *display ) { GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv; return gst_vaapi_image_new(display, priv->format, priv->width, priv->height); }
GstVaapiImage * image_generate_full (GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height, guint32 flags) { GstVaapiImage *image; static const guint32 rgb_colors[4] = { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000 }; static const guint32 bgr_colors[4] = { 0xff000000, 0xff0000ff, 0xff00ff00, 0xffff0000 }; static const guint32 inv_colors[4] = { 0xffdeadc0, 0xffdeadc0, 0xffdeadc0, 0xffdeadc0 }; image = gst_vaapi_image_new (display, format, width, height); if (!image) return NULL; if (flags) { if (!image_draw_color_rectangles (image, width, height, ((flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) ? rgb_colors : inv_colors), GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)) goto error; if (!image_draw_color_rectangles (image, width, height, ((flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ? bgr_colors : inv_colors), GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)) goto error; } else if (!image_draw_color_rectangles (image, width, height, rgb_colors, 0)) goto error; return image; error: gst_vaapi_object_unref (image); return NULL; }
static gboolean ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) { GArray *formats, *out_formats; GstVaapiSurface *surface; guint i; GstCaps *out_caps; gboolean ret = FALSE; if (plugin->allowed_raw_caps) return TRUE; out_formats = formats = NULL; surface = NULL; formats = gst_vaapi_display_get_image_formats (plugin->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 (plugin->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 (plugin->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); return ret; }
/** * gst_vaapi_subpicture_new_from_overlay_rectangle: * @display: a #GstVaapiDisplay * @rect: a #GstVideoOverlayRectangle * * Helper function that creates a new #GstVaapiSubpicture from a * #GstVideoOverlayRectangle. A new #GstVaapiImage is also created * along the way and attached to the resulting subpicture. The * subpicture holds a unique reference to the underlying image. * * Return value: the newly allocated #GstVaapiSubpicture object */ GstVaapiSubpicture * gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display, GstVideoOverlayRectangle * rect) { GstVaapiSubpicture *subpicture; GstVideoFormat format; GstVaapiImage *image; GstVaapiImageRaw raw_image; GstBuffer *buffer; guint8 *data; gfloat global_alpha; guint width, height, stride; guint hw_flags, flags; GstVideoMeta *vmeta; GstMapInfo map_info; g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rect), NULL); /* XXX: use gst_vaapi_image_format_from_video() */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN format = GST_VIDEO_FORMAT_BGRA; #else format = GST_VIDEO_FORMAT_ARGB; #endif if (!gst_vaapi_display_has_subpicture_format (display, format, &hw_flags)) return NULL; flags = hw_flags & from_GstVideoOverlayFormatFlags (gst_video_overlay_rectangle_get_flags (rect)); buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect, to_GstVideoOverlayFormatFlags (flags)); if (!buffer) return NULL; vmeta = gst_buffer_get_video_meta (buffer); if (!vmeta) return NULL; width = vmeta->width; height = vmeta->height; if (!gst_video_meta_map (vmeta, 0, &map_info, (gpointer *) & data, (gint *) & stride, GST_MAP_READ)) return NULL; image = gst_vaapi_image_new (display, format, width, height); if (!image) return NULL; raw_image.format = format; raw_image.width = width; raw_image.height = height; raw_image.num_planes = 1; raw_image.pixels[0] = data; raw_image.stride[0] = stride; if (!gst_vaapi_image_update_from_raw (image, &raw_image, NULL)) { GST_WARNING ("could not update VA image with subtitle data"); gst_vaapi_object_unref (image); return NULL; } subpicture = gst_vaapi_subpicture_new (image, flags); gst_vaapi_object_unref (image); gst_video_meta_unmap (vmeta, 0, &map_info); if (!subpicture) return NULL; if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) { global_alpha = gst_video_overlay_rectangle_get_global_alpha (rect); if (!gst_vaapi_subpicture_set_global_alpha (subpicture, global_alpha)) return NULL; } return subpicture; }
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; }