diff --git a/src/config.c b/src/config.c index 5222e50..7f9c41f 100644 --- a/src/config.c +++ b/src/config.c @@ -33,30 +33,98 @@ #include +VAStatus SunxiCedrusCreateConfig(VADriverContextP context, VAProfile profile, + VAEntrypoint entrypoint, VAConfigAttrib *attributes, + int attributes_count, VAConfigID *config_id) +{ + struct sunxi_cedrus_driver_data *driver_data = + (struct sunxi_cedrus_driver_data *) context->pDriverData; + struct object_config *config_object; + VAConfigID id; + int i, index; + + switch (profile) { + case VAProfileMPEG2Simple: + case VAProfileMPEG2Main: + if (entrypoint != VAEntrypointVLD && entrypoint != VAEntrypointMoComp) + return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; + break; + + default: + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + + if (attributes_count > SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES) + attributes_count = SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES; + + id = object_heap_allocate(&driver_data->config_heap); + config_object = CONFIG(id); + if (config_object == NULL) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + config_object->profile = profile; + config_object->entrypoint = entrypoint; + config_object->attributes[0].type = VAConfigAttribRTFormat; + config_object->attributes[0].value = VA_RT_FORMAT_YUV420; + config_object->attributes_count = 1; + + for (i = 1; i < attributes_count; i++) { + index = config_object->attributes_count++; + config_object->attributes[index].type = attributes[index].type; + config_object->attributes[index].value = attributes[index].value; + } + + *config_id = id; + + return VA_STATUS_SUCCESS; +} + +VAStatus SunxiCedrusDestroyConfig(VADriverContextP context, + VAConfigID config_id) +{ + struct sunxi_cedrus_driver_data *driver_data = + (struct sunxi_cedrus_driver_data *) context->pDriverData; + struct object_config *config_object; + + config_object = CONFIG(config_id); + if (config_object == NULL) + return VA_STATUS_ERROR_INVALID_CONFIG; + + object_heap_free(&driver_data->config_heap, (struct object_base *) config_object); + + return VA_STATUS_SUCCESS; +} + VAStatus SunxiCedrusQueryConfigProfiles(VADriverContextP context, VAProfile *profiles, int *profiles_count) { struct sunxi_cedrus_driver_data *driver_data = (struct sunxi_cedrus_driver_data *) context->pDriverData; - int i = 0; - struct v4l2_fmtdesc vid_fmtdesc; - memset(&vid_fmtdesc, 0, sizeof(vid_fmtdesc)); - vid_fmtdesc.index = 0; - vid_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + struct v4l2_fmtdesc format_description; + unsigned int index = 0; + int rc; - while(ioctl(driver_data->mem2mem_fd, VIDIOC_ENUM_FMT, &vid_fmtdesc) == 0) - { - switch(vid_fmtdesc.pixelformat) { - case V4L2_PIX_FMT_MPEG2_FRAME: - profiles[i++] = VAProfileMPEG2Simple; - profiles[i++] = VAProfileMPEG2Main; + memset(&format_description, 0, sizeof(format_description)); + format_description.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + format_description.index = 0; + + for (format_description.index = 0; index < SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES ; format_description.index++) { + rc = ioctl(driver_data->mem2mem_fd, VIDIOC_ENUM_FMT, &format_description); + if (rc < 0) break; + + switch (format_description.pixelformat) { + case V4L2_PIX_FMT_MPEG2_FRAME: + if (index >= (SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES - 2)) + break; + + profiles[index++] = VAProfileMPEG2Simple; + profiles[index++] = VAProfileMPEG2Main; + break; } - vid_fmtdesc.index++; } - assert(i <= SUNXI_CEDRUS_MAX_PROFILES); - *profiles_count = i; + *profiles_count = index; return VA_STATUS_SUCCESS; } @@ -67,9 +135,9 @@ VAStatus SunxiCedrusQueryConfigEntrypoints(VADriverContextP context, switch (profile) { case VAProfileMPEG2Simple: case VAProfileMPEG2Main: - *entrypoints_count = 2; entrypoints[0] = VAEntrypointVLD; entrypoints[1] = VAEntrypointMoComp; + *entrypoints_count = 2; break; default: @@ -77,135 +145,6 @@ VAStatus SunxiCedrusQueryConfigEntrypoints(VADriverContextP context, break; } - assert(*entrypoints_count <= SUNXI_CEDRUS_MAX_ENTRYPOINTS); - return VA_STATUS_SUCCESS; -} - -VAStatus SunxiCedrusGetConfigAttributes(VADriverContextP context, - VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attributes, - int attributes_count) -{ - int i; - - for (i = 0; i < attributes_count; i++) - { - switch (attributes[i].type) - { - case VAConfigAttribRTFormat: - attributes[i].value = VA_RT_FORMAT_YUV420; - break; - - default: - /* Do nothing */ - attributes[i].value = VA_ATTRIB_NOT_SUPPORTED; - break; - } - } - - return VA_STATUS_SUCCESS; -} - -VAStatus sunxi_cedrus_update_attribute(struct object_config *obj_config, - VAConfigAttrib *attrib) -{ - int i; - /* Check existing attributes */ - for(i = 0; obj_config->attributes_count < i; i++) - { - if (obj_config->attributes[i].type == attrib->type) - { - /* Update existing attribute */ - obj_config->attributes[i].value = attrib->value; - return VA_STATUS_SUCCESS; - } - } - if (obj_config->attributes_count < SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES) - { - i = obj_config->attributes_count; - obj_config->attributes[i].type = attrib->type; - obj_config->attributes[i].value = attrib->value; - obj_config->attributes_count++; - return VA_STATUS_SUCCESS; - } - return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; -} - -VAStatus SunxiCedrusCreateConfig(VADriverContextP context, VAProfile profile, - VAEntrypoint entrypoint, VAConfigAttrib *attributes, - int attributes_count, VAConfigID *config_id) -{ - struct sunxi_cedrus_driver_data *driver_data = - (struct sunxi_cedrus_driver_data *) context->pDriverData; - VAStatus vaStatus; - int configID; - struct object_config *obj_config; - int i; - - /* Validate profile & entrypoint */ - switch (profile) { - case VAProfileMPEG2Simple: - case VAProfileMPEG2Main: - if ((VAEntrypointVLD == entrypoint) || - (VAEntrypointMoComp == entrypoint)) - vaStatus = VA_STATUS_SUCCESS; - else - vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - break; - - default: - vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - break; - } - - if (VA_STATUS_SUCCESS != vaStatus) - return vaStatus; - - configID = object_heap_allocate(&driver_data->config_heap); - obj_config = CONFIG(configID); - if (NULL == obj_config) - { - vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; - return vaStatus; - } - - obj_config->profile = profile; - obj_config->entrypoint = entrypoint; - obj_config->attributes[0].type = VAConfigAttribRTFormat; - obj_config->attributes[0].value = VA_RT_FORMAT_YUV420; - obj_config->attributes_count = 1; - - for(i = 0; i < attributes_count; i++) - { - vaStatus = sunxi_cedrus_update_attribute(obj_config, &(attributes[i])); - if (VA_STATUS_SUCCESS != vaStatus) - break; - } - - /* Error recovery */ - if (VA_STATUS_SUCCESS != vaStatus) - object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); - else - *config_id = configID; - - return vaStatus; -} - -VAStatus SunxiCedrusDestroyConfig(VADriverContextP context, - VAConfigID config_id) -{ - struct sunxi_cedrus_driver_data *driver_data = - (struct sunxi_cedrus_driver_data *) context->pDriverData; - VAStatus vaStatus; - struct object_config *obj_config; - - obj_config = CONFIG(config_id); - if (NULL == obj_config) - { - vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; - return vaStatus; - } - - object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); return VA_STATUS_SUCCESS; } @@ -215,20 +154,48 @@ VAStatus SunxiCedrusQueryConfigAttributes(VADriverContextP context, { struct sunxi_cedrus_driver_data *driver_data = (struct sunxi_cedrus_driver_data *) context->pDriverData; - VAStatus vaStatus = VA_STATUS_SUCCESS; - struct object_config *obj_config; + struct object_config *config_object; int i; - obj_config = CONFIG(config_id); - assert(obj_config); + config_object = CONFIG(config_id); + if (config_object == NULL) + return VA_STATUS_ERROR_INVALID_CONFIG; - *profile = obj_config->profile; - *entrypoint = obj_config->entrypoint; - *attributes_count = obj_config->attributes_count; - for(i = 0; i < obj_config->attributes_count; i++) - attributes[i] = obj_config->attributes[i]; + if (profile != NULL) + *profile = config_object->profile; - return vaStatus; + if (entrypoint != NULL) + *entrypoint = config_object->entrypoint; + + if (attributes_count != NULL) + *attributes_count = config_object->attributes_count; + + /* Attributes might be NULL to retrieve the associated count. */ + if (attributes != NULL) + for (i = 0; i < config_object->attributes_count; i++) + attributes[i] = config_object->attributes[i]; + + return VA_STATUS_SUCCESS; +} + +VAStatus SunxiCedrusGetConfigAttributes(VADriverContextP context, + VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attributes, + int attributes_count) +{ + unsigned int i; + + for (i = 0; i < attributes_count; i++) { + switch (attributes[i].type) { + case VAConfigAttribRTFormat: + attributes[i].value = VA_RT_FORMAT_YUV420; + break; + default: + attributes[i].value = VA_ATTRIB_NOT_SUPPORTED; + break; + } + } + + return VA_STATUS_SUCCESS; } VAStatus SunxiCedrusQueryDisplayAttributes(VADriverContextP context, diff --git a/src/config.h b/src/config.h index 8a3cd9a..9e9d2b8 100644 --- a/src/config.h +++ b/src/config.h @@ -42,21 +42,21 @@ struct object_config { int attributes_count; }; -VAStatus SunxiCedrusQueryConfigProfiles(VADriverContextP context, - VAProfile *profiles, int *profiles_count); -VAStatus SunxiCedrusQueryConfigEntrypoints(VADriverContextP context, - VAProfile profile, VAEntrypoint *entrypoints, int *entrypoints_count); -VAStatus SunxiCedrusGetConfigAttributes(VADriverContextP context, - VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attributes, - int attributes_count); VAStatus SunxiCedrusCreateConfig(VADriverContextP context, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attributes, int attributes_count, VAConfigID *config_id); VAStatus SunxiCedrusDestroyConfig(VADriverContextP context, VAConfigID config_id); +VAStatus SunxiCedrusQueryConfigProfiles(VADriverContextP context, + VAProfile *profiles, int *profiles_count); +VAStatus SunxiCedrusQueryConfigEntrypoints(VADriverContextP context, + VAProfile profile, VAEntrypoint *entrypoints, int *entrypoints_count); VAStatus SunxiCedrusQueryConfigAttributes(VADriverContextP context, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attributes, int *attributes_count); +VAStatus SunxiCedrusGetConfigAttributes(VADriverContextP context, + VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attributes, + int attributes_count); VAStatus SunxiCedrusQueryDisplayAttributes(VADriverContextP context, VADisplayAttribute *attributes, int *attributes_count); VAStatus SunxiCedrusGetDisplayAttributes(VADriverContextP context,