Beispiel #1
0
VAStatus
vlVaQueryImageFormats(VADriverContextP ctx, VAImageFormat *format_list, int *num_formats)
{
   struct pipe_screen *pscreen;
   enum pipe_format format;
   int i;

   STATIC_ASSERT(ARRAY_SIZE(formats) == VL_VA_MAX_IMAGE_FORMATS);

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   if (!(format_list && num_formats))
      return VA_STATUS_ERROR_INVALID_PARAMETER;

   *num_formats = 0;
   pscreen = VL_VA_PSCREEN(ctx);
   for (i = 0; i < ARRAY_SIZE(formats); ++i) {
      format = VaFourccToPipeFormat(formats[i].fourcc);
      if (pscreen->is_video_format_supported(pscreen, format,
          PIPE_VIDEO_PROFILE_UNKNOWN,
          PIPE_VIDEO_ENTRYPOINT_BITSTREAM))
         format_list[(*num_formats)++] = formats[i];
   }

   return VA_STATUS_SUCCESS;
}
Beispiel #2
0
VAStatus
vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile,
                           VAEntrypoint *entrypoint_list, int *num_entrypoints)
{
   struct pipe_screen *pscreen;
   enum pipe_video_profile p;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   *num_entrypoints = 0;

   if (profile == VAProfileNone) {
      entrypoint_list[(*num_entrypoints)++] = VAEntrypointVideoProc;
      return VA_STATUS_SUCCESS;
   }

   p = ProfileToPipe(profile);
   if (p == PIPE_VIDEO_PROFILE_UNKNOWN)
      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;

   pscreen = VL_VA_PSCREEN(ctx);
   if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
				PIPE_VIDEO_CAP_SUPPORTED))
      entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD;

   if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE,
				PIPE_VIDEO_CAP_SUPPORTED))
      entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice;

   if (num_entrypoints == 0)
      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;

   return VA_STATUS_SUCCESS;
}
Beispiel #3
0
VAStatus
vlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles)
{
   struct pipe_screen *pscreen;
   enum pipe_video_profile p;
   VAProfile vap;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   *num_profiles = 0;

   pscreen = VL_VA_PSCREEN(ctx);
   for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_HEVC_MAIN_444; ++p) {
      if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4())
         continue;

      if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) {
         vap = PipeToProfile(p);
         if (vap != VAProfileNone)
            profile_list[(*num_profiles)++] = vap;
      }
   }

   /* Support postprocessing through vl_compositor */
   profile_list[(*num_profiles)++] = VAProfileNone;

   return VA_STATUS_SUCCESS;
}
Beispiel #4
0
VAStatus
vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
                 VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id)
{
   struct pipe_screen *pscreen;
   enum pipe_video_profile p;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) {
      *config_id = PIPE_VIDEO_PROFILE_UNKNOWN;
      return VA_STATUS_SUCCESS;
   }

   p = ProfileToPipe(profile);
   if (p == PIPE_VIDEO_PROFILE_UNKNOWN)
      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;

   pscreen = VL_VA_PSCREEN(ctx);
   if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED))
      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;

   if (entrypoint != VAEntrypointVLD)
      return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;

   *config_id = p;

   return VA_STATUS_SUCCESS;
}
Beispiel #5
0
VAStatus
vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
                    unsigned int width, unsigned int height,
                    VASurfaceID *surfaces, unsigned int num_surfaces,
                    VASurfaceAttrib *attrib_list, unsigned int num_attribs)
{
    vlVaDriver *drv;
    VASurfaceAttribExternalBuffers *memory_attibute;
    struct pipe_video_buffer templat;
    struct pipe_screen *pscreen;
    int i;
    int memory_type;
    int expected_fourcc;
    VAStatus vaStatus;

    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;

    if (!(width && height))
       return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;

    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;

    /* Default. */
    memory_attibute = NULL;
    memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
    expected_fourcc = 0;

    for (i = 0; i < num_attribs && attrib_list; i++) {
        if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
            if (attrib_list[i].value.type != VAGenericValueTypeInteger)
                return VA_STATUS_ERROR_INVALID_PARAMETER;
            expected_fourcc = attrib_list[i].value.value.i;
        }

        if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {

            if (attrib_list[i].value.type != VAGenericValueTypeInteger)
                return VA_STATUS_ERROR_INVALID_PARAMETER;

            switch (attrib_list[i].value.value.i) {
                case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
                case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
                   memory_type = attrib_list[i].value.value.i;
                   break;
                default:
                   return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
            }
        }

        if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
            (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
            if (attrib_list[i].value.type != VAGenericValueTypePointer)
                return VA_STATUS_ERROR_INVALID_PARAMETER;
            memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
        }
    }

    if (VA_RT_FORMAT_YUV420 != format &&
        VA_RT_FORMAT_YUV422 != format &&
        VA_RT_FORMAT_YUV444 != format &&
        VA_RT_FORMAT_RGB32  != format) {
        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
    }

    switch (memory_type) {
        case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
            break;
        case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
            if (!memory_attibute)
               return VA_STATUS_ERROR_INVALID_PARAMETER;

            expected_fourcc = memory_attibute->pixel_format;
            break;
        default:
            assert(0);
    }

    memset(&templat, 0, sizeof(templat));

    if (expected_fourcc) {
       templat.buffer_format = VaFourccToPipeFormat(expected_fourcc);
       templat.interlaced = 0;
    } else {
        templat.buffer_format = pscreen->get_video_param
        (
           pscreen,
           PIPE_VIDEO_PROFILE_UNKNOWN,
           PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
           PIPE_VIDEO_CAP_PREFERED_FORMAT
        );
        templat.interlaced = pscreen->get_video_param
        (
           pscreen,
           PIPE_VIDEO_PROFILE_UNKNOWN,
           PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
           PIPE_VIDEO_CAP_PREFERS_INTERLACED
        );
    }

    templat.chroma_format = ChromaToPipe(format);

    templat.width = width;
    templat.height = height;

    memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));

    for (i = 0; i < num_surfaces; i++) {
        vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
        if (!surf)
            goto no_res;

        surf->templat = templat;

        switch (memory_type) {
            case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
                surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
                if (!surf->buffer)
                    goto no_res;
                util_dynarray_init(&surf->subpics);
                surfaces[i] = handle_table_add(drv->htab, surf);
                break;
            case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
                vaStatus = suface_from_external_memory(ctx, surf, memory_attibute, i, surfaces, &templat);
                if (vaStatus != VA_STATUS_SUCCESS)
                  goto no_res;
                break;
            default:
                assert(0);
        }
    }

    return VA_STATUS_SUCCESS;

no_res:
   if (i)
      vlVaDestroySurfaces(ctx, surfaces, i);

   return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
Beispiel #6
0
static VAStatus
suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface,
                            VASurfaceAttribExternalBuffers *memory_attibute,
                            int index, VASurfaceID *surfaces,
                            struct pipe_video_buffer *templat)
{
    vlVaDriver *drv;
    struct pipe_screen *pscreen;
    struct pipe_resource *resource;
    struct pipe_resource res_templ;
    struct winsys_handle whandle;
    struct pipe_resource *resources[VL_NUM_COMPONENTS];

    if (!ctx)
        return VA_STATUS_ERROR_INVALID_PARAMETER;

    pscreen = VL_VA_PSCREEN(ctx);
    drv = VL_VA_DRIVER(ctx);

    if (!memory_attibute || !memory_attibute->buffers ||
        index > memory_attibute->num_buffers)
        return VA_STATUS_ERROR_INVALID_PARAMETER;

    if (surface->templat.width != memory_attibute->width ||
        surface->templat.height != memory_attibute->height ||
        memory_attibute->num_planes < 1)
        return VA_STATUS_ERROR_INVALID_PARAMETER;

    switch (memory_attibute->pixel_format) {
    case VA_FOURCC_RGBA:
    case VA_FOURCC_RGBX:
    case VA_FOURCC_BGRA:
    case VA_FOURCC_BGRX:
        if (memory_attibute->num_planes != 1)
            return VA_STATUS_ERROR_INVALID_PARAMETER;
        break;
    default:
        return VA_STATUS_ERROR_INVALID_PARAMETER;
    }

    memset(&res_templ, 0, sizeof(res_templ));
    res_templ.target = PIPE_TEXTURE_2D;
    res_templ.last_level = 0;
    res_templ.depth0 = 1;
    res_templ.array_size = 1;
    res_templ.width0 = memory_attibute->width;
    res_templ.height0 = memory_attibute->height;
    res_templ.format = surface->templat.buffer_format;
    res_templ.bind = PIPE_BIND_SAMPLER_VIEW;
    res_templ.usage = PIPE_USAGE_DEFAULT;

    memset(&whandle, 0, sizeof(struct winsys_handle));
    whandle.type = DRM_API_HANDLE_TYPE_FD;
    whandle.handle = memory_attibute->buffers[index];
    whandle.stride = memory_attibute->pitches[index];

    resource = pscreen->resource_from_handle(pscreen, &res_templ, &whandle);

    if (!resource)
       return VA_STATUS_ERROR_ALLOCATION_FAILED;

    memset(resources, 0, sizeof resources);
    resources[0] = resource;

    surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, resources);
    if (!surface->buffer)
        return VA_STATUS_ERROR_ALLOCATION_FAILED;

    util_dynarray_init(&surface->subpics);
    surfaces[index] = handle_table_add(drv->htab, surface);

    if (!surfaces[index])
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

    return VA_STATUS_SUCCESS;
}
Beispiel #7
0
VAStatus
vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config,
                           VASurfaceAttrib *attrib_list, unsigned int *num_attribs)
{
    vlVaDriver *drv;
    VASurfaceAttrib *attribs;
    struct pipe_screen *pscreen;
    int i;

    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 = 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(VASurfaceAttribCount, sizeof(VASurfaceAttrib));

    if (!attribs)
        return VA_STATUS_ERROR_ALLOCATION_FAILED;

    i = 0;

    if (config == PIPE_VIDEO_PROFILE_UNKNOWN) {
       /* vlVaCreateConfig returns PIPE_VIDEO_PROFILE_UNKNOWN
          only for VAEntrypointVideoProc. */
       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_BGRA;
       i++;

       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_RGBA;
       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;
}
Beispiel #8
0
VAStatus
vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
                        VABufferInfo *out_buf_info)
{
   uint32_t i;
   uint32_t mem_type;
   vlVaBuffer *buf ;
   struct pipe_screen *screen;

   /* List of supported memory types, in preferred order. */
   static const uint32_t mem_types[] = {
      VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
      0
   };

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);

   if (!buf)
      return VA_STATUS_ERROR_INVALID_BUFFER;

   /* Only VA surface|image like buffers are supported for now .*/
   if (buf->type != VAImageBufferType)
      return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;

   if (!out_buf_info)
      return VA_STATUS_ERROR_INVALID_PARAMETER;

   if (!out_buf_info->mem_type)
      mem_type = mem_types[0];
   else {
      mem_type = 0;
      for (i = 0; mem_types[i] != 0; i++) {
         if (out_buf_info->mem_type & mem_types[i]) {
            mem_type = out_buf_info->mem_type;
            break;
         }
      }
      if (!mem_type)
         return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
   }

   if (!buf->derived_surface.resource)
      return VA_STATUS_ERROR_INVALID_BUFFER;

   screen = VL_VA_PSCREEN(ctx);

   if (buf->derived_surface.fence) {
      screen->fence_finish(screen, buf->derived_surface.fence, PIPE_TIMEOUT_INFINITE);
      screen->fence_reference(screen, &buf->derived_surface.fence, NULL);
   }

   if (buf->export_refcount > 0) {
      if (buf->export_state.mem_type != mem_type)
         return VA_STATUS_ERROR_INVALID_PARAMETER;
   } else {
      VABufferInfo * const buf_info = &buf->export_state;

      switch (mem_type) {
      case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
         struct winsys_handle whandle;

         memset(&whandle, 0, sizeof(whandle));
         whandle.type = DRM_API_HANDLE_TYPE_FD;

         if (!screen->resource_get_handle(screen, buf->derived_surface.resource, &whandle))
            return VA_STATUS_ERROR_INVALID_BUFFER;

         buf_info->handle = (intptr_t)whandle.handle;
         break;
      }
      default:
         return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
      }

      buf_info->type = buf->type;
      buf_info->mem_type = mem_type;
      buf_info->mem_size = buf->num_elements * buf->size;
   }

   buf->export_refcount++;

   *out_buf_info = buf->export_state;

   return VA_STATUS_SUCCESS;
}
Beispiel #9
0
VAStatus
vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
                 VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id)
{
   vlVaDriver *drv;
   vlVaConfig *config;
   struct pipe_screen *pscreen;
   enum pipe_video_profile p;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   drv = VL_VA_DRIVER(ctx);

   if (!drv)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   config = CALLOC(1, sizeof(vlVaConfig));
   if (!config)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

   if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) {
      config->entrypoint = VAEntrypointVideoProc;
      config->profile = PIPE_VIDEO_PROFILE_UNKNOWN;
      for (int i = 0; i < num_attribs; i++) {
         if (attrib_list[i].type == VAConfigAttribRTFormat) {
            if (attrib_list[i].value & (VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_RGB32)) {
               config->rt_format = attrib_list[i].value;
            } else {
               FREE(config);
               return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
            }
         }
      }

      /* Default value if not specified in the input attributes. */
      if (!config->rt_format)
         config->rt_format = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_RGB32;

      pipe_mutex_lock(drv->mutex);
      *config_id = handle_table_add(drv->htab, config);
      pipe_mutex_unlock(drv->mutex);
      return VA_STATUS_SUCCESS;
   }

   p = ProfileToPipe(profile);
   if (p == PIPE_VIDEO_PROFILE_UNKNOWN) {
      FREE(config);
      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
   }

   pscreen = VL_VA_PSCREEN(ctx);

   switch (entrypoint) {
   case VAEntrypointVLD:
      if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
				    PIPE_VIDEO_CAP_SUPPORTED)) {
         FREE(config);
         return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
      }

      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
      break;

   case VAEntrypointEncSlice:
      if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE,
				    PIPE_VIDEO_CAP_SUPPORTED)) {
         FREE(config);
         return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
      }

      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE;
      break;

   default:
      FREE(config);
      return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
   }

   config->profile = p;

   for (int i = 0; i <num_attribs ; i++) {
      if (attrib_list[i].type == VAConfigAttribRateControl) {
         if (attrib_list[i].value == VA_RC_CBR)
            config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT;
         else if (attrib_list[i].value == VA_RC_VBR)
            config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE;
         else
            config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE;
      }
      if (attrib_list[i].type == VAConfigAttribRTFormat) {
         if (attrib_list[i].value == VA_RT_FORMAT_YUV420) {
            config->rt_format = attrib_list[i].value;
         } else {
            FREE(config);
            return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
         }
      }
   }

   /* Default value if not specified in the input attributes. */
   if (!config->rt_format)
      config->rt_format = VA_RT_FORMAT_YUV420;

   pipe_mutex_lock(drv->mutex);
   *config_id = handle_table_add(drv->htab, config);
   pipe_mutex_unlock(drv->mutex);

   return VA_STATUS_SUCCESS;
}
Beispiel #10
0
VAStatus
vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config_id,
                           VASurfaceAttrib *attrib_list, unsigned int *num_attribs)
{
   vlVaDriver *drv;
   vlVaConfig *config;
   VASurfaceAttrib *attribs;
   struct pipe_screen *pscreen;
   int i, j;

   STATIC_ASSERT(ARRAY_SIZE(vpp_surface_formats) <= VL_VA_MAX_IMAGE_FORMATS);

   if (config_id == 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;

   pipe_mutex_lock(drv->mutex);
   config = handle_table_get(drv->htab, config_id);
   pipe_mutex_unlock(drv->mutex);

   if (!config)
      return VA_STATUS_ERROR_INVALID_CONFIG;

   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->profile == PIPE_VIDEO_PROFILE_UNKNOWN) {
      if (config->rt_format & VA_RT_FORMAT_RGB32) {
         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++;
         }
      }
      if (config->rt_format & VA_RT_FORMAT_YUV420) {
         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++;
      }
   } 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;
}