Пример #1
0
VAStatus
vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
                 unsigned int size, unsigned int num_elements, void *data,
                 VABufferID *buf_id)
{
   vlVaBuffer *buf;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   buf = CALLOC(1, sizeof(vlVaBuffer));
   if (!buf)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

   buf->type = type;
   buf->size = size;
   buf->num_elements = num_elements;
   buf->data = MALLOC(size * num_elements);

   if (!buf->data) {
      FREE(buf);
      return VA_STATUS_ERROR_ALLOCATION_FAILED;
   }

   if (data)
      memcpy(buf->data, data, size * num_elements);

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

   return VA_STATUS_SUCCESS;
}
Пример #2
0
DHGLRC APIENTRY
DrvCreateLayerContext(
   HDC hdc,
   INT iLayerPlane )
{
   int iPixelFormat;
   const struct stw_pixelformat_info *pfi;
   struct st_context_attribs attribs;
   struct stw_context *ctx = NULL;
   
   if(!stw_dev)
      return 0;
   
   if (iLayerPlane != 0)
      return 0;

   iPixelFormat = GetPixelFormat(hdc);
   if(!iPixelFormat)
      return 0;
   
   pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
   
   ctx = CALLOC_STRUCT( stw_context );
   if (ctx == NULL)
      goto no_ctx;

   ctx->hdc = hdc;
   ctx->iPixelFormat = iPixelFormat;

   memset(&attribs, 0, sizeof(attribs));
   attribs.profile = ST_PROFILE_DEFAULT;
   attribs.visual = pfi->stvis;

   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
         stw_dev->smapi, &attribs, NULL);
   if (ctx->st == NULL) 
      goto no_st_ctx;

   ctx->st->st_manager_private = (void *) ctx;

   pipe_mutex_lock( stw_dev->ctx_mutex );
   ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
   pipe_mutex_unlock( stw_dev->ctx_mutex );
   if (!ctx->dhglrc)
      goto no_hglrc;

   return ctx->dhglrc;

no_hglrc:
   ctx->st->destroy(ctx->st);
no_st_ctx:
   FREE(ctx);
no_ctx:
   return 0;
}
Пример #3
0
vlHandle vlAddDataHTAB(void *data)
{
   assert(data);
#ifdef VL_HANDLES
   vlHandle handle = 0;
   pipe_mutex_lock(htab_lock);
   if (htab)
      handle = handle_table_add(htab, data);
   pipe_mutex_unlock(htab_lock);
   return handle;
#else
   return (vlHandle)data;
#endif
}
Пример #4
0
VAStatus
vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
                  int picture_height, int flag, VASurfaceID *render_targets,
                  int num_render_targets, VAContextID *context_id)
{
   vlVaDriver *drv;
   vlVaContext *context;
   vlVaConfig *config;
   int is_vpp;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

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

   is_vpp = config->profile == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width &&
            !picture_height && !flag && !render_targets && !num_render_targets;

   if (!(picture_width && picture_height) && !is_vpp)
      return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;

   context = CALLOC(1, sizeof(vlVaContext));
   if (!context)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;

   if (is_vpp) {
      context->decoder = NULL;
   } else {
      context->templat.profile = config->profile;
      context->templat.entrypoint = config->entrypoint;
      context->templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
      context->templat.width = picture_width;
      context->templat.height = picture_height;
      context->templat.expect_chunked_decode = true;

      switch (u_reduce_video_profile(context->templat.profile)) {
      case PIPE_VIDEO_FORMAT_MPEG12:
      case PIPE_VIDEO_FORMAT_VC1:
      case PIPE_VIDEO_FORMAT_MPEG4:
         context->templat.max_references = 2;
         break;

      case PIPE_VIDEO_FORMAT_MPEG4_AVC:
         context->templat.max_references = 0;
         if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
            context->desc.h264.pps = CALLOC_STRUCT(pipe_h264_pps);
            if (!context->desc.h264.pps) {
               FREE(context);
               return VA_STATUS_ERROR_ALLOCATION_FAILED;
            }
            context->desc.h264.pps->sps = CALLOC_STRUCT(pipe_h264_sps);
            if (!context->desc.h264.pps->sps) {
               FREE(context->desc.h264.pps);
               FREE(context);
               return VA_STATUS_ERROR_ALLOCATION_FAILED;
            }
         }
         break;

     case PIPE_VIDEO_FORMAT_HEVC:
         context->templat.max_references = num_render_targets;
         context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps);
         if (!context->desc.h265.pps) {
            FREE(context);
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
         }
         context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps);
         if (!context->desc.h265.pps->sps) {
            FREE(context->desc.h265.pps);
            FREE(context);
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
         }
         break;

      default:
         break;
      }
   }

   context->desc.base.profile = config->profile;
   context->desc.base.entry_point = config->entrypoint;
   if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
      context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc;

   pipe_mutex_lock(drv->mutex);
   *context_id = handle_table_add(drv->htab, context);
   pipe_mutex_unlock(drv->mutex);

   return VA_STATUS_SUCCESS;
}
Пример #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;
}
Пример #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;
}
Пример #7
0
/**
 * Called via DrvCreateContext(), DrvCreateLayerContext() and
 * wglCreateContextAttribsARB() to actually create a rendering context.
 * \param handle  the desired DHGLRC handle to use for the context, or zero
 *                if a new handle should be allocated.
 * \return the handle for the new context or zero if there was a problem.
 */
DHGLRC
stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
                           int majorVersion, int minorVersion,
                           int contextFlags, int profileMask,
                           DHGLRC handle)
{
    int iPixelFormat;
    struct stw_framebuffer *fb;
    const struct stw_pixelformat_info *pfi;
    struct st_context_attribs attribs;
    struct stw_context *ctx = NULL;
    struct stw_context *shareCtx = NULL;
    enum st_context_error ctx_err = 0;

    if (!stw_dev)
        return 0;

    if (iLayerPlane != 0)
        return 0;

    iPixelFormat = GetPixelFormat(hdc);
    if(!iPixelFormat)
        return 0;

    /*
     * GDI only knows about displayable pixel formats, so determine the pixel
     * format from the framebuffer.
     *
     * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
     */
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb) {
        assert(iPixelFormat == fb->iDisplayablePixelFormat);
        iPixelFormat = fb->iPixelFormat;
        stw_framebuffer_release(fb);
    }

    pfi = stw_pixelformat_get_info( iPixelFormat );

    if (hShareContext != 0) {
        pipe_mutex_lock( stw_dev->ctx_mutex );
        shareCtx = stw_lookup_context_locked( hShareContext );
        pipe_mutex_unlock( stw_dev->ctx_mutex );
    }

    ctx = CALLOC_STRUCT( stw_context );
    if (ctx == NULL)
        goto no_ctx;

    ctx->hdc = hdc;
    ctx->iPixelFormat = iPixelFormat;

    memset(&attribs, 0, sizeof(attribs));
    attribs.visual = pfi->stvis;
    attribs.major = majorVersion;
    attribs.minor = minorVersion;
    if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
        attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
    if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
        attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

    switch (profileMask) {
    case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
        /* There are no profiles before OpenGL 3.2.  The
         * WGL_ARB_create_context_profile spec says:
         *
         *     "If the requested OpenGL version is less than 3.2,
         *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
         *     of the context is determined solely by the requested version."
         */
        if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
            attribs.profile = ST_PROFILE_OPENGL_CORE;
            break;
        }
    /* fall-through */
    case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
        /*
         * The spec also says:
         *
         *     "If version 3.1 is requested, the context returned may implement
         *     any of the following versions:
         *
         *       * Version 3.1. The GL_ARB_compatibility extension may or may not
         *         be implemented, as determined by the implementation.
         *       * The core profile of version 3.2 or greater."
         *
         * and because Mesa doesn't support GL_ARB_compatibility, the only chance to
         * honour a 3.1 context is through core profile.
         */
        if (majorVersion == 3 && minorVersion == 1) {
            attribs.profile = ST_PROFILE_OPENGL_CORE;
        } else {
            attribs.profile = ST_PROFILE_DEFAULT;
        }
        break;
    case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
        if (majorVersion >= 2) {
            attribs.profile = ST_PROFILE_OPENGL_ES2;
        } else {
            attribs.profile = ST_PROFILE_OPENGL_ES1;
        }
        break;
    default:
        assert(0);
        goto no_st_ctx;
    }

    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
              stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
    if (ctx->st == NULL)
        goto no_st_ctx;

    ctx->st->st_manager_private = (void *) ctx;

    if (ctx->st->cso_context) {
        ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
    }

    pipe_mutex_lock( stw_dev->ctx_mutex );
    if (handle) {
        /* We're replacing the context data for this handle. See the
         * wglCreateContextAttribsARB() function.
         */
        struct stw_context *old_ctx =
            stw_lookup_context_locked((unsigned) handle);
        if (old_ctx) {
            /* free the old context data associated with this handle */
            if (old_ctx->hud) {
                hud_destroy(old_ctx->hud);
            }
            ctx->st->destroy(old_ctx->st);
            FREE(old_ctx);
        }

        /* replace table entry */
        handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
    }
    else {
        /* create new table entry */
        handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
    }

    ctx->dhglrc = handle;

    pipe_mutex_unlock( stw_dev->ctx_mutex );
    if (!ctx->dhglrc)
        goto no_hglrc;

    return ctx->dhglrc;

no_hglrc:
    if (ctx->hud) {
        hud_destroy(ctx->hud);
    }
    ctx->st->destroy(ctx->st);
no_st_ctx:
    FREE(ctx);
no_ctx:
    return 0;
}
Пример #8
0
VAStatus
vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int height, VAImage *image)
{
   VAStatus status;
   vlVaDriver *drv;
   VAImage *img;
   int w, h;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   if (!(format && image && width && height))
      return VA_STATUS_ERROR_INVALID_PARAMETER;

   drv = VL_VA_DRIVER(ctx);

   img = CALLOC(1, sizeof(VAImage));
   if (!img)
      return VA_STATUS_ERROR_ALLOCATION_FAILED;
   pipe_mutex_lock(drv->mutex);
   img->image_id = handle_table_add(drv->htab, img);
   pipe_mutex_unlock(drv->mutex);

   img->format = *format;
   img->width = width;
   img->height = height;
   w = align(width, 2);
   h = align(height, 2);

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

   case VA_FOURCC('I','4','2','0'):
   case VA_FOURCC('Y','V','1','2'):
      img->num_planes = 3;
      img->pitches[0] = w;
      img->offsets[0] = 0;
      img->pitches[1] = w / 2;
      img->offsets[1] = w * h;
      img->pitches[2] = w / 2;
      img->offsets[2] = w * h * 5 / 4;
      img->data_size  = w * h * 3 / 2;
      break;

   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:
      return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
   }

   status =  vlVaCreateBuffer(ctx, 0, VAImageBufferType,
                           align(img->data_size, 16),
                           1, NULL, &img->buf);
   if (status != VA_STATUS_SUCCESS)
      return status;
   *image = *img;

   return status;
}
Пример #9
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;
}
Пример #10
0
DHGLRC
stw_create_context_attribs(
   HDC hdc,
   INT iLayerPlane,
   DHGLRC hShareContext,
   int majorVersion, int minorVersion,
   int contextFlags, int profileMask)
{
   int iPixelFormat;
   struct stw_framebuffer *fb;
   const struct stw_pixelformat_info *pfi;
   struct st_context_attribs attribs;
   struct stw_context *ctx = NULL;
   struct stw_context *shareCtx = NULL;
   enum st_context_error ctx_err = 0;

   if (!stw_dev)
      return 0;

   if (iLayerPlane != 0)
      return 0;

   iPixelFormat = GetPixelFormat(hdc);
   if(!iPixelFormat)
      return 0;

   /*
    * GDI only knows about displayable pixel formats, so determine the pixel format
    * from the framebuffer.
    *
    * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
    */
   fb = stw_framebuffer_from_hdc( hdc );
   if (fb) {
      assert(iPixelFormat == fb->iDisplayablePixelFormat);
      iPixelFormat = fb->iPixelFormat;
      stw_framebuffer_release(fb);
   }

   pfi = stw_pixelformat_get_info( iPixelFormat );

   if (hShareContext != 0) {
      pipe_mutex_lock( stw_dev->ctx_mutex );
      shareCtx = stw_lookup_context_locked( hShareContext );
      pipe_mutex_unlock( stw_dev->ctx_mutex );
   }

   ctx = CALLOC_STRUCT( stw_context );
   if (ctx == NULL)
      goto no_ctx;

   ctx->hdc = hdc;
   ctx->iPixelFormat = iPixelFormat;

   memset(&attribs, 0, sizeof(attribs));
   attribs.visual = pfi->stvis;
   attribs.major = majorVersion;
   attribs.minor = minorVersion;
   if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
   if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

   /* There are no profiles before OpenGL 3.2.  The
    * WGL_ARB_create_context_profile spec says:
    *
    *     "If the requested OpenGL version is less than 3.2,
    *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
    *     context is determined solely by the requested version."
    *
    * The spec also says:
    *
    *     "The default value for WGL_CONTEXT_PROFILE_MASK_ARB is
    *     WGL_CONTEXT_CORE_PROFILE_BIT_ARB."
    */
   attribs.profile = ST_PROFILE_DEFAULT;
   if ((majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2))
       && ((profileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) == 0))
      attribs.profile = ST_PROFILE_OPENGL_CORE;

   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
         stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
   if (ctx->st == NULL)
      goto no_st_ctx;

   ctx->st->st_manager_private = (void *) ctx;

   pipe_mutex_lock( stw_dev->ctx_mutex );
   ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
   pipe_mutex_unlock( stw_dev->ctx_mutex );
   if (!ctx->dhglrc)
      goto no_hglrc;

   return ctx->dhglrc;

no_hglrc:
   ctx->st->destroy(ctx->st);
no_st_ctx:
   FREE(ctx);
no_ctx:
   return 0;
}
Пример #11
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;
}