diff --git a/src/context.c b/src/context.c index e757847..15a677f 100644 --- a/src/context.c +++ b/src/context.c @@ -42,104 +42,119 @@ VAStatus SunxiCedrusCreateContext(VADriverContextP context, VASurfaceID *surfaces_ids, int surfaces_count, VAContextID *context_id) { - struct sunxi_cedrus_driver_data *driver_data = - (struct sunxi_cedrus_driver_data *) context->pDriverData; - VAStatus vaStatus = VA_STATUS_SUCCESS; - struct object_config *obj_config; - int i; - struct v4l2_create_buffers create_bufs; - struct v4l2_format fmt; + struct dump_driver_data *driver_data = (struct dump_driver_data *) context->pDriverData; + struct object_config *config_object; + struct object_surface *surface_object; + struct object_context *context_object = NULL; + VASurfaceID *ids = NULL; + VAContextID id; + VAStatus status; + struct v4l2_create_buffers create_buffers; + struct v4l2_format format; enum v4l2_buf_type type; + unsigned int i; - obj_config = CONFIG(config_id); - if (NULL == obj_config) - { - vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; - return vaStatus; + config_object = CONFIG(config_id); + if (config_object == NULL) { + status = VA_STATUS_ERROR_INVALID_CONFIG; + goto error; } - int contextID = object_heap_allocate(&driver_data->context_heap); - struct object_context *obj_context = CONTEXT(contextID); - if (NULL == obj_context) - { - vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; - return vaStatus; + id = object_heap_allocate(&driver_data->context_heap); + context_object = CONTEXT(id); + if (context_object == NULL) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; } - obj_context->config_id = config_id; - obj_context->render_surface_id = VA_INVALID; - obj_context->surfaces_ids = (VASurfaceID *) malloc(surfaces_count * sizeof(VASurfaceID)); - obj_context->surfaces_count = surfaces_count; - obj_context->picture_width = picture_width; - obj_context->picture_height = picture_height; - obj_context->num_rendered_surfaces = 0; - - *context_id = contextID; - - struct v4l2_ctrl_mpeg2_frame_hdr mpeg2_frame_hdr; - uint32_t num_rendered_surfaces; - - if (obj_context->surfaces_ids == NULL) - { - vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; - return vaStatus; + ids = malloc(surfaces_count * sizeof(VASurfaceID)); + if (ids == NULL) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; } - for(i = 0; i < surfaces_count; i++) - { - if (NULL == SURFACE(surfaces_ids[i])) - { - vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; - break; + for (i = 0; i < surfaces_count; i++) { + surface_object = SURFACE(surfaces_ids[i]); + if (surface_object == NULL) { + status = VA_STATUS_ERROR_INVALID_SURFACE; + goto error; } - obj_context->surfaces_ids[i] = surfaces_ids[i]; - } - obj_context->flags = flag; - /* Error recovery */ - if (VA_STATUS_SUCCESS != vaStatus) - { - obj_context->config_id = -1; - free(obj_context->surfaces_ids); - obj_context->surfaces_ids = NULL; - obj_context->surfaces_count = 0; - obj_context->flags = 0; - object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); + ids[i] = surfaces_ids[i]; } - memset(&(fmt), 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.width = picture_width; - fmt.fmt.pix_mp.height = picture_height; - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = INPUT_BUFFER_MAX_SIZE * INPUT_BUFFERS_NB; - switch(obj_config->profile) { + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + format.fmt.pix_mp.width = picture_width; + format.fmt.pix_mp.height = picture_height; + format.fmt.pix_mp.plane_fmt[0].sizeimage = INPUT_BUFFER_MAX_SIZE * INPUT_BUFFERS_NB; + format.fmt.pix_mp.field = V4L2_FIELD_ANY; + format.fmt.pix_mp.num_planes = 1; + + switch (config_object->profile) { case VAProfileMPEG2Simple: case VAProfileMPEG2Main: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG2_FRAME; + format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG2_FRAME; break; default: - vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - return vaStatus; - break; + status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + goto error; } - fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; - fmt.fmt.pix_mp.num_planes = 1; - assert(ioctl(driver_data->mem2mem_fd, VIDIOC_S_FMT, &fmt)==0); - memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers)); - create_bufs.count = INPUT_BUFFERS_NB; - create_bufs.memory = V4L2_MEMORY_MMAP; - create_bufs.format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - assert(ioctl(driver_data->mem2mem_fd, VIDIOC_G_FMT, &create_bufs.format)==0); - assert(ioctl(driver_data->mem2mem_fd, VIDIOC_CREATE_BUFS, &create_bufs)==0); + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_S_FMT, &format); + if (rc < 0) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; + } + + memset(&create_buffers, 0, sizeof(create_buffers)); + create_buffers.count = INPUT_BUFFERS_NB; + create_buffers.memory = V4L2_MEMORY_MMAP; + create_buffers.format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_G_FMT, &create_buffers.format); + if (rc < 0) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; + } + + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_CREATE_BUFS, &create_buffers); + if (rc < 0) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; + } type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - assert(ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMON, &type)==0); + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMON, &type); + if (rc < 0) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; + } type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - assert(ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMON, &type)==0); + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMON, &type); + if (rc < 0) { + status = VA_STATUS_ERROR_ALLOCATION_FAILED; + goto error; + } - return vaStatus; + context_object->config_id = config_id; + context_object->surfaces_ids = ids; + + *context_id = id; + + status = VA_STATUS_SUCCESS; + goto complete; + +error: + if (ids != NULL) + free(ids); + + if (context_object != NULL) + object_heap_free(&driver_data->context_heap, (struct object_base *) context_object); + +complete: + return status; } VAStatus SunxiCedrusDestroyContext(VADriverContextP context, @@ -147,27 +162,24 @@ VAStatus SunxiCedrusDestroyContext(VADriverContextP context, { struct sunxi_cedrus_driver_data *driver_data = (struct sunxi_cedrus_driver_data *) context->pDriverData; - struct object_context *obj_context = CONTEXT(context_id); - assert(obj_context); + struct object_context *context_object; enum v4l2_buf_type type; + context_object = (struct object_context *) object_heap_lookup(&driver_data->context_heap, context_id); + if (context_object == NULL) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + object_heap_free(&driver_data->context_heap, (struct object_base *) context_object); + type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMOFF, &type); + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMOFF, &type); + if (rc < 0) + return VA_STATUS_ERROR_UNKNOWN; + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMOFF, &type); - - obj_context->config_id = -1; - obj_context->picture_width = 0; - obj_context->picture_height = 0; - if (obj_context->surfaces_ids) - free(obj_context->surfaces_ids); - obj_context->surfaces_ids = NULL; - obj_context->surfaces_count = 0; - obj_context->flags = 0; - - obj_context->render_surface_id = -1; - - object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMOFF, &type); + if (rc < 0) + return VA_STATUS_ERROR_UNKNOWN; return VA_STATUS_SUCCESS; }