Example #1
0
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);
}
Example #5
0
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;
}