コード例 #1
0
/* 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;
  }
}
コード例 #2
0
/**
 * 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;
}
コード例 #3
0
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");
    }
}
コード例 #4
0
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
}
コード例 #5
0
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
}
コード例 #6
0
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;
    }
}