Esempio n. 1
0
VAStatus
vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
{
   vlVaDriver *drv;
   vlVaSurface *surf;
   vlVaBuffer *img_buf;
   VAImage *img;
   struct pipe_surface **surfaces;
   int w;
   int h;
   int i;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   drv = VL_VA_DRIVER(ctx);

   if (!drv)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   surf = handle_table_get(drv->htab, surface);

   if (!surf || !surf->buffer || surf->buffer->interlaced)
      return VA_STATUS_ERROR_INVALID_SURFACE;

   surfaces = surf->buffer->get_surfaces(surf->buffer);
   if (!surfaces || !surfaces[0]->texture)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

   img = CALLOC(1, sizeof(VAImage));
   if (!img)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

   img->format.fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
   img->buf = VA_INVALID_ID;
   img->width = surf->buffer->width;
   img->height = surf->buffer->height;
   img->num_palette_entries = 0;
   img->entry_bytes = 0;
   w = align(surf->buffer->width, 2);
   h = align(surf->buffer->height, 2);

   for (i = 0; i < ARRAY_SIZE(formats); ++i) {
      if (img->format.fourcc == formats[i].fourcc) {
         img->format = formats[i];
         break;
      }
   }

   switch (img->format.fourcc) {
   case VA_FOURCC('U','Y','V','Y'):
   case VA_FOURCC('Y','U','Y','V'):
      img->num_planes = 1;
      img->pitches[0] = w * 2;
      img->offsets[0] = 0;
      img->data_size  = w * h * 2;
      break;

   case VA_FOURCC('B','G','R','A'):
   case VA_FOURCC('R','G','B','A'):
   case VA_FOURCC('B','G','R','X'):
   case VA_FOURCC('R','G','B','X'):
      img->num_planes = 1;
      img->pitches[0] = w * 4;
      img->offsets[0] = 0;
      img->data_size  = w * h * 4;
      break;

   default:
      /* VaDeriveImage is designed for contiguous planes. */
      FREE(img);
      return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
   }

   img_buf = CALLOC(1, sizeof(vlVaBuffer));
   if (!img_buf) {
      FREE(img);
      return VA_STATUS_ERROR_ALLOCATION_FAILED;
   }

   pipe_mutex_lock(drv->mutex);
   img->image_id = handle_table_add(drv->htab, img);

   img_buf->type = VAImageBufferType;
   img_buf->size = img->data_size;
   img_buf->num_elements = 1;

   pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture);

   img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf);
   pipe_mutex_unlock(drv->mutex);

   *image = *img;

   return VA_STATUS_SUCCESS;
}
Esempio n. 2
0
VAStatus
vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config,
                           VASurfaceAttrib *attrib_list, unsigned int *num_attribs)
{
   vlVaDriver *drv;
   VASurfaceAttrib *attribs;
   struct pipe_screen *pscreen;
   int i, j;

   STATIC_ASSERT(ARRAY_SIZE(vpp_surface_formats) <= VL_VA_MAX_IMAGE_FORMATS);

   if (config == VA_INVALID_ID)
      return VA_STATUS_ERROR_INVALID_CONFIG;

   if (!attrib_list && !num_attribs)
      return VA_STATUS_ERROR_INVALID_PARAMETER;

   if (!attrib_list) {
      *num_attribs = VL_VA_MAX_IMAGE_FORMATS + VASurfaceAttribCount;
      return VA_STATUS_SUCCESS;
   }

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   drv = VL_VA_DRIVER(ctx);

   if (!drv)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   pscreen = VL_VA_PSCREEN(ctx);

   if (!pscreen)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   attribs = CALLOC(VL_VA_MAX_IMAGE_FORMATS + VASurfaceAttribCount,
                    sizeof(VASurfaceAttrib));

   if (!attribs)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

   i = 0;

   /* vlVaCreateConfig returns PIPE_VIDEO_PROFILE_UNKNOWN
    * only for VAEntrypointVideoProc. */
   if (config == PIPE_VIDEO_PROFILE_UNKNOWN) {
      for (j = 0; j < ARRAY_SIZE(vpp_surface_formats); ++j) {
         attribs[i].type = VASurfaceAttribPixelFormat;
         attribs[i].value.type = VAGenericValueTypeInteger;
         attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
         attribs[i].value.value.i = PipeFormatToVaFourcc(vpp_surface_formats[j]);
         i++;
      }
   } else {
      /* Assume VAEntrypointVLD for now. */
      attribs[i].type = VASurfaceAttribPixelFormat;
      attribs[i].value.type = VAGenericValueTypeInteger;
      attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
      attribs[i].value.value.i = VA_FOURCC_NV12;
      i++;
   }

   attribs[i].type = VASurfaceAttribMemoryType;
   attribs[i].value.type = VAGenericValueTypeInteger;
   attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
   attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
         VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
   i++;

   attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
   attribs[i].value.type = VAGenericValueTypePointer;
   attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
   attribs[i].value.value.p = NULL; /* ignore */
   i++;

   attribs[i].type = VASurfaceAttribMaxWidth;
   attribs[i].value.type = VAGenericValueTypeInteger;
   attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
   attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
   i++;

   attribs[i].type = VASurfaceAttribMaxHeight;
   attribs[i].value.type = VAGenericValueTypeInteger;
   attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
   attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
   i++;

   if (i > *num_attribs) {
      *num_attribs = i;
      FREE(attribs);
      return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
   }

   *num_attribs = i;
   memcpy(attrib_list, attribs, i * sizeof(VASurfaceAttrib));
   FREE(attribs);

   return VA_STATUS_SUCCESS;
}