| /* |
| * Copyright (c) 2011 Intel Corporation. All Rights Reserved. |
| * Copyright (c) Imagination Technologies Limited, UK |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sub license, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial portions |
| * of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
| * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| * Authors: |
| * Waldo Bastian <waldo.bastian@intel.com> |
| * |
| */ |
| |
| #include <va/va_backend.h> |
| #include <va/va_backend_tpi.h> |
| #include <va/va_backend_egl.h> |
| #ifdef PSBVIDEO_MRFL_VPP |
| #include <va/va_backend_vpp.h> |
| #endif |
| #ifdef PSBVIDEO_MFLD |
| #include <va/va_backend_vpp.h> |
| #endif |
| #include <va/va_drmcommon.h> |
| #include <va/va_android.h> |
| #include <va/va_tpi.h> |
| |
| #include "psb_drv_video.h" |
| #include "psb_texture.h" |
| #include "psb_cmdbuf.h" |
| #ifndef BAYTRAIL |
| #include "pnw_cmdbuf.h" |
| #include "tng_cmdbuf.h" |
| #endif |
| #ifdef PSBVIDEO_MRFL_VPP |
| #include "vsp_cmdbuf.h" |
| #endif |
| #include "psb_surface.h" |
| |
| #include "pnw_MPEG2.h" |
| #include "pnw_MPEG4.h" |
| #include "pnw_H264.h" |
| #include "pnw_VC1.h" |
| #include "tng_jpegdec.h" |
| #include "tng_VP8.h" |
| #include "tng_yuv_processor.h" |
| |
| #ifdef PSBVIDEO_MFLD |
| #include "pnw_MPEG4ES.h" |
| #include "pnw_H264ES.h" |
| #include "pnw_H263ES.h" |
| #include "pnw_jpeg.h" |
| #endif |
| #ifdef PSBVIDEO_MRFL |
| #include "tng_H264ES.h" |
| #include "tng_H263ES.h" |
| #include "tng_MPEG4ES.h" |
| #include "tng_jpegES.h" |
| #endif |
| #ifdef PSBVIDEO_MRFL_VPP |
| #include "vsp_VPP.h" |
| #include "vsp_vp8.h" |
| #endif |
| #include "psb_output.h" |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdarg.h> |
| #include <time.h> |
| #include <unistd.h> |
| #include <wsbm/wsbm_pool.h> |
| #include <wsbm/wsbm_manager.h> |
| #include <wsbm/wsbm_util.h> |
| #include <wsbm/wsbm_fencemgr.h> |
| #include <linux/videodev2.h> |
| #include <errno.h> |
| |
| #include "psb_def.h" |
| #include "psb_drv_debug.h" |
| #ifndef BAYTRAIL |
| #include "psb_ws_driver.h" |
| #endif |
| #include "pnw_rotate.h" |
| #include "psb_surface_attrib.h" |
| #include "android/psb_gralloc.h" |
| |
| #ifndef PSB_PACKAGE_VERSION |
| #define PSB_PACKAGE_VERSION "Undefined" |
| #endif |
| |
| #define PSB_DRV_VERSION PSB_PACKAGE_VERSION |
| #define PSB_CHG_REVISION "(0X00000071)" |
| |
| #define PSB_STR_VENDOR_MRST "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION |
| #define PSB_STR_VENDOR_MFLD "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION |
| #define PSB_STR_VENDOR_MRFL "Intel GMA500-MRFL-" PSB_DRV_VERSION " " PSB_CHG_REVISION |
| #define PSB_STR_VENDOR_BAYTRAIL "Intel GMA500-BAYTRAIL-" PSB_DRV_VERSION " " PSB_CHG_REVISION |
| #define PSB_STR_VENDOR_LEXINGTON "Intel GMA500-LEXINGTON-" PSB_DRV_VERSION " " PSB_CHG_REVISION |
| |
| #define MAX_UNUSED_BUFFERS 16 |
| |
| #define PSB_SURFACE_UNAVAILABLE 0x40000000 |
| |
| #define PSB_MAX_FLIP_DELAY (1000/30/10) |
| |
| #define PSB_SURFACE_UNAVAILABLE 0x40000000 |
| |
| #include <signal.h> |
| |
| #define EXPORT __attribute__ ((visibility("default"))) |
| |
| #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; |
| |
| #ifdef PSBVIDEO_MRFL_VPP |
| #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL; |
| #endif |
| #ifdef PSBVIDEO_MFLD |
| #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL; |
| #endif |
| |
| #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) |
| #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) |
| #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) |
| #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) |
| |
| #define CONFIG_ID_OFFSET 0x01000000 |
| #define CONTEXT_ID_OFFSET 0x02000000 |
| #define SURFACE_ID_OFFSET 0x03000000 |
| #define BUFFER_ID_OFFSET 0x04000000 |
| #define IMAGE_ID_OFFSET 0x05000000 |
| #define SUBPIC_ID_OFFSET 0x06000000 |
| |
| static int psb_get_device_info(VADriverContextP ctx); |
| |
| |
| void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data); |
| void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data); |
| |
| VAStatus psb_QueryConfigProfiles( |
| VADriverContextP ctx, |
| VAProfile *profile_list, /* out */ |
| int *num_profiles /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| (void) ctx; /* unused */ |
| int i = 0; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| INIT_DRIVER_DATA |
| |
| CHECK_INVALID_PARAM(profile_list == NULL); |
| CHECK_INVALID_PARAM(num_profiles == NULL); |
| |
| #ifdef PSBVIDEO_MRFL_VPP |
| profile_list[i++] = VAProfileNone; |
| #endif |
| // profile_list[i++] = VAProfileMPEG2Simple; |
| profile_list[i++] = VAProfileMPEG2Main; |
| profile_list[i++] = VAProfileMPEG4Simple; |
| profile_list[i++] = VAProfileMPEG4AdvancedSimple; |
| // profile_list[i++] = VAProfileMPEG4Main; |
| profile_list[i++] = VAProfileH264Baseline; |
| profile_list[i++] = VAProfileH264Main; |
| profile_list[i++] = VAProfileH264High; |
| profile_list[i++] = VAProfileH264StereoHigh; |
| profile_list[i++] = VAProfileVC1Simple; |
| profile_list[i++] = VAProfileVC1Main; |
| profile_list[i++] = VAProfileVC1Advanced; |
| |
| if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) { |
| profile_list[i++] = VAProfileH263Baseline; |
| profile_list[i++] = VAProfileJPEGBaseline; |
| profile_list[i++] = VAProfileVP8Version0_3; |
| } else if (IS_MFLD(driver_data)) { |
| profile_list[i++] = VAProfileH263Baseline; |
| profile_list[i++] = VAProfileJPEGBaseline; |
| } |
| profile_list[i++] = VAProfileH264ConstrainedBaseline; |
| |
| /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */ |
| ASSERT(i <= PSB_MAX_PROFILES); |
| *num_profiles = i; |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus psb_QueryConfigEntrypoints( |
| VADriverContextP ctx, |
| VAProfile profile, |
| VAEntrypoint *entrypoint_list, /* out */ |
| int *num_entrypoints /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| int entrypoints = 0; |
| int i; |
| |
| CHECK_INVALID_PARAM(entrypoint_list == NULL); |
| CHECK_INVALID_PARAM((num_entrypoints == NULL) || (profile >= PSB_MAX_PROFILES)); |
| |
| for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) { |
| #ifndef BAYTRAIL |
| #ifdef PSBVIDEO_MRFL_VPP |
| if (profile == VAProfileNone && driver_data->vpp_profile && |
| i == VAEntrypointVideoProc) { |
| entrypoints++; |
| *entrypoint_list++ = i; |
| } else |
| #endif |
| #endif |
| if (profile != VAProfileNone && driver_data->profile2Format[profile][i]) { |
| entrypoints++; |
| *entrypoint_list++ = i; |
| } |
| } |
| |
| /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */ |
| ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS); |
| |
| if (0 == entrypoints) { |
| return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; |
| } |
| |
| *num_entrypoints = entrypoints; |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /* |
| * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE |
| * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT |
| */ |
| static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint __maybe_unused entrypoint) |
| { |
| /* Does the driver support _any_ entrypoint for this profile? */ |
| if (profile < PSB_MAX_PROFILES) { |
| int i; |
| |
| /* Do the parameter check for MFLD and MRFLD */ |
| if (profile == VAProfileNone) |
| return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; |
| |
| for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) { |
| if (driver_data->profile2Format[profile][i]) { |
| /* There is an entrypoint, so the profile is supported */ |
| return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; |
| } |
| } |
| } |
| return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; |
| } |
| |
| VAStatus psb_GetConfigAttributes( |
| VADriverContextP ctx, |
| VAProfile profile, |
| VAEntrypoint entrypoint, |
| VAConfigAttrib *attrib_list, /* in/out */ |
| int num_attribs |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| |
| #if defined(BAYTRAIL) |
| format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint]; |
| #elif defined(PSBVIDEO_MRFL_VPP) |
| INIT_FORMAT_VTABLE |
| #else |
| format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint]; |
| #endif |
| int i; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| if (NULL == format_vtable) { |
| return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint); |
| } |
| |
| CHECK_INVALID_PARAM(attrib_list == NULL); |
| CHECK_INVALID_PARAM(num_attribs <= 0); |
| |
| /* Generic attributes */ |
| for (i = 0; i < num_attribs; i++) { |
| switch (attrib_list[i].type) { |
| case VAConfigAttribRTFormat: |
| attrib_list[i].value = VA_RT_FORMAT_YUV420; |
| if (entrypoint == VAEntrypointEncPicture) |
| attrib_list[i].value |= VA_RT_FORMAT_YUV422; |
| if ((profile == VAProfileJPEGBaseline) && (entrypoint == VAEntrypointVLD)) |
| attrib_list[i].value |= VA_RT_FORMAT_YUV444; |
| break; |
| |
| default: |
| attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; |
| break; |
| } |
| } |
| /* format specific attributes */ |
| format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs); |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib) |
| { |
| int i; |
| /* Check existing attributes */ |
| for (i = 0; i < obj_config->attrib_count; i++) { |
| if (obj_config->attrib_list[i].type == attrib->type) { |
| /* Update existing attribute */ |
| obj_config->attrib_list[i].value = attrib->value; |
| return VA_STATUS_SUCCESS; |
| } |
| } |
| if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) { |
| i = obj_config->attrib_count; |
| obj_config->attrib_list[i].type = attrib->type; |
| obj_config->attrib_list[i].value = attrib->value; |
| obj_config->attrib_count++; |
| return VA_STATUS_SUCCESS; |
| } |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| |
| static VAStatus psb__validate_config(object_config_p obj_config) |
| { |
| int i; |
| /* Check all attributes */ |
| for (i = 0; i < obj_config->attrib_count; i++) { |
| switch (obj_config->attrib_list[i].type) { |
| case VAConfigAttribRTFormat: |
| if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420 |
| || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 && |
| obj_config->entrypoint == VAEntrypointEncPicture) |
| || (obj_config->attrib_list[i].value == (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV420 )))) { |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| break; |
| |
| default: |
| /* |
| * Ignore unknown attributes here, it |
| * may be format specific. |
| */ |
| break; |
| } |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static int psb_get_active_entrypoint_number( |
| VADriverContextP ctx, |
| unsigned int entrypoint) |
| { |
| INIT_DRIVER_DATA; |
| struct drm_lnc_video_getparam_arg arg; |
| int count = 0; |
| int ret; |
| |
| if (VAEntrypointVLD > entrypoint || |
| entrypoint > VAEntrypointEncPicture) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "%s :Invalid entrypoint %d.\n", |
| __FUNCTION__, entrypoint); |
| return -1; |
| } |
| |
| arg.key = PNW_VIDEO_QUERY_ENTRY; |
| arg.value = (uint64_t)((unsigned long) &count); |
| arg.arg = (uint64_t)((unsigned int)&entrypoint); |
| ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, |
| &arg, sizeof(arg)); |
| if (ret) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "%s drmCommandWriteRead fails %d.\n", |
| __FUNCTION__, ret); |
| return -1; |
| } |
| |
| return count; |
| } |
| |
| VAStatus psb_CreateConfig( |
| VADriverContextP ctx, |
| VAProfile profile, |
| VAEntrypoint entrypoint, |
| VAConfigAttrib *attrib_list, |
| int num_attribs, |
| VAConfigID *config_id /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| #if defined(BAYTRAIL) |
| format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint]; |
| #elif defined(PSBVIDEO_MRFL_VPP) |
| INIT_FORMAT_VTABLE |
| #else |
| format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint]; |
| #endif |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| int configID; |
| object_config_p obj_config; |
| int i; |
| |
| drv_debug_msg(VIDEO_DEBUG_INIT, "CreateConfig profile:%d, entrypoint:%d, num_attribs:%d.\n", |
| profile, entrypoint, num_attribs); |
| /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/ |
| if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) { |
| char ec_disable[2]; |
| FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r"); |
| if (ec_fp) { |
| if (fgets(ec_disable, 2, ec_fp) != NULL) { |
| /* force profile to VAProfileH264High */ |
| if (strcmp(ec_disable, "8") == 0) { |
| drv_debug_msg(VIDEO_DEBUG_INIT, "disabled error concealment by setting profile to VAProfileH264High\n"); |
| profile = VAProfileH264High; |
| } |
| } |
| fclose(ec_fp); |
| } |
| } |
| |
| CHECK_INVALID_PARAM(config_id == NULL); |
| CHECK_INVALID_PARAM(num_attribs < 0); |
| CHECK_INVALID_PARAM(attrib_list == NULL); |
| |
| if (NULL == format_vtable) { |
| vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint); |
| } |
| |
| CHECK_VASTATUS(); |
| |
| if ((IS_MFLD(driver_data)) && |
| ((VAEntrypointEncPicture == entrypoint) |
| || (VAEntrypointEncSlice == entrypoint))) { |
| int active_slc, active_pic; |
| /* Only allow one encoding entrypoint at the sametime. |
| * But if video encoding request comes when process JPEG encoding, |
| * it will wait until current JPEG picture encoding finish. |
| * Further JPEG encoding should fall back to software path.*/ |
| active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice); |
| active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture); |
| |
| if (active_slc > 0) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active video encoding entrypoint." |
| "Entrypoint %d isn't available.\n", entrypoint); |
| return VA_STATUS_ERROR_HW_BUSY; |
| } |
| else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active picture encoding entrypoint." |
| "Entrypoint %d isn't available.\n", entrypoint); |
| return VA_STATUS_ERROR_HW_BUSY; |
| } |
| } |
| |
| configID = object_heap_allocate(&driver_data->config_heap); |
| obj_config = CONFIG(configID); |
| CHECK_ALLOCATION(obj_config); |
| |
| MEMSET_OBJECT(obj_config, struct object_config_s); |
| |
| obj_config->profile = profile; |
| obj_config->format_vtable = format_vtable; |
| obj_config->entrypoint = entrypoint; |
| obj_config->attrib_list[0].type = VAConfigAttribRTFormat; |
| obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420; |
| obj_config->attrib_count = 1; |
| |
| for (i = 0; i < num_attribs; i++) { |
| if (attrib_list[i].type > VAConfigAttribTypeMax) |
| return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; |
| |
| vaStatus = psb__update_attribute(obj_config, &(attrib_list[i])); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| break; |
| } |
| } |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| vaStatus = psb__validate_config(obj_config); |
| } |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| vaStatus = format_vtable->validateConfig(obj_config); |
| } |
| |
| /* Error recovery */ |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); |
| } else { |
| *config_id = configID; |
| } |
| |
| #ifdef PSBVIDEO_MSVDX_EC |
| if((getenv("PSB_VIDEO_NOEC") == NULL) |
| && (profile == VAProfileH264ConstrainedBaseline)) { |
| drv_debug_msg(VIDEO_DEBUG_INIT, "profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n"); |
| driver_data->ec_enabled = 1; |
| } else { |
| driver_data->ec_enabled = 0; |
| } |
| |
| if (profile == VAProfileVP8Version0_3 || |
| profile == VAProfileH264Baseline || |
| profile == VAProfileH264Main || |
| profile == VAProfileH264High || |
| profile == VAProfileH264ConstrainedBaseline) |
| driver_data->ec_enabled = 1; |
| |
| if (!IS_MRFL(driver_data)) { |
| if (profile == VAProfileMPEG4Simple || |
| profile == VAProfileMPEG4AdvancedSimple || |
| profile == VAProfileMPEG4Main) |
| driver_data->ec_enabled = 1; |
| } |
| |
| #else |
| driver_data->ec_enabled = 0; |
| #endif |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_DestroyConfig( |
| VADriverContextP ctx, |
| VAConfigID config_id |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_config_p obj_config; |
| |
| obj_config = CONFIG(config_id); |
| CHECK_CONFIG(obj_config); |
| |
| object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_QueryConfigAttributes( |
| VADriverContextP ctx, |
| VAConfigID config_id, |
| VAProfile *profile, /* out */ |
| VAEntrypoint *entrypoint, /* out */ |
| VAConfigAttrib *attrib_list, /* out */ |
| int *num_attribs /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_config_p obj_config; |
| int i; |
| |
| CHECK_INVALID_PARAM(profile == NULL); |
| CHECK_INVALID_PARAM(entrypoint == NULL); |
| CHECK_INVALID_PARAM(attrib_list == NULL); |
| CHECK_INVALID_PARAM(num_attribs == NULL); |
| |
| obj_config = CONFIG(config_id); |
| CHECK_CONFIG(obj_config); |
| |
| *profile = obj_config->profile; |
| *entrypoint = obj_config->entrypoint; |
| *num_attribs = obj_config->attrib_count; |
| for (i = 0; i < obj_config->attrib_count; i++) { |
| attrib_list[i] = obj_config->attrib_list[i]; |
| } |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface) |
| { |
| if (NULL != obj_surface) { |
| /* delete subpicture association */ |
| psb_SurfaceDeassociateSubpict(driver_data, obj_surface); |
| |
| obj_surface->is_ref_surface = 0; |
| |
| psb_surface_sync(obj_surface->psb_surface); |
| psb_surface_destroy(obj_surface->psb_surface); |
| |
| if (obj_surface->out_loop_surface) { |
| psb_surface_destroy(obj_surface->out_loop_surface); |
| } |
| |
| if (obj_surface->scaling_surface) { |
| psb_surface_destroy(obj_surface->scaling_surface); |
| } |
| |
| free(obj_surface->psb_surface); |
| object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); |
| } |
| } |
| |
| VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height) |
| { |
| if (driver_data->video_sd_disabled) { |
| return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; |
| } |
| if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) { |
| return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; |
| } |
| if (driver_data->video_hd_disabled) { |
| if ((width > 1024) || (height > 576)) { |
| return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; |
| } |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus psb_GetSurfaceAttributes( |
| VADriverContextP __maybe_unused ctx, |
| VAConfigID __maybe_unused config, |
| VASurfaceAttrib *attrib_list, |
| unsigned int num_attribs |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| |
| uint32_t i; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| CHECK_INVALID_PARAM(attrib_list == NULL); |
| CHECK_INVALID_PARAM(num_attribs <= 0); |
| |
| /* Generic attributes */ |
| for (i = 0; i < num_attribs; i++) { |
| switch (attrib_list[i].type) { |
| case VASurfaceAttribMemoryType: |
| attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE | VA_SURFACE_ATTRIB_GETTABLE; |
| attrib_list[i].value.type = VAGenericValueTypeInteger; |
| attrib_list[i].value.value.i = |
| VA_SURFACE_ATTRIB_MEM_TYPE_VA | |
| VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR | |
| VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM | |
| VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC | |
| VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION; |
| break; |
| |
| case VASurfaceAttribExternalBufferDescriptor: |
| attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE; |
| attrib_list[i].value.type = VAGenericValueTypePointer; |
| break; |
| |
| default: |
| attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED; |
| break; |
| } |
| } |
| |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| |
| } |
| |
| #ifdef PSBVIDEO_MSVDX_DEC_TILING |
| unsigned long psb__tile_stride_log2_256(int w) |
| { |
| int stride_mode = 0; |
| |
| if (512 >= w) |
| stride_mode = 1; |
| else if (1024 >= w) |
| stride_mode = 2; |
| else if (2048 >= w) |
| stride_mode = 3; |
| else if (4096 >= w) |
| stride_mode = 4; |
| |
| return stride_mode; |
| } |
| |
| unsigned long psb__tile_stride_log2_512(int w) |
| { |
| int stride_mode = 0; |
| |
| if (512 >= w) |
| stride_mode = 0; |
| else if (1024 >= w) |
| stride_mode = 1; |
| else if (2048 >= w) |
| stride_mode = 2; |
| else if (4096 >= w) |
| stride_mode = 3; |
| |
| return stride_mode; |
| } |
| #endif |
| |
| VAStatus psb_CreateSurfaces( |
| VADriverContextP __maybe_unused ctx, |
| int __maybe_unused width, |
| int __maybe_unused height, |
| int __maybe_unused format, |
| int __maybe_unused num_surfaces, |
| VASurfaceID __maybe_unused * surface_list /* out */ |
| ) |
| { |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| VAStatus psb_CreateSurfaces2( |
| VADriverContextP ctx, |
| unsigned int format, |
| unsigned int width, |
| unsigned int height, |
| VASurfaceID *surface_list, /* out */ |
| unsigned int num_surfaces, |
| VASurfaceAttrib *attrib_list, |
| unsigned int num_attribs |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| unsigned int i; |
| int height_origin, buffer_stride = 0; |
| driver_data->protected = (VA_RT_FORMAT_PROTECTED & format); |
| unsigned long fourcc; |
| unsigned int flags = 0; |
| int memory_type = -1; |
| unsigned int initalized_info_flag = 1; |
| VASurfaceAttribExternalBuffers *pExternalBufDesc = NULL; |
| PsbSurfaceAttributeTPI attribute_tpi; |
| attribute_tpi.buffers = NULL; |
| bool attribute_tpi_buffersAlloced = false; |
| |
| CHECK_INVALID_PARAM(num_surfaces <= 0); |
| CHECK_SURFACE(surface_list); |
| |
| if ((attrib_list != NULL) && (num_attribs > 0)) { |
| for (i = 0; i < num_attribs; i++, attrib_list++) { |
| if (!attrib_list) { |
| if(attribute_tpi.buffers != NULL) |
| free(attribute_tpi.buffers); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| switch (attrib_list->type) { |
| case VASurfaceAttribExternalBufferDescriptor: |
| { |
| pExternalBufDesc = (VASurfaceAttribExternalBuffers *)attrib_list->value.value.p; |
| if (pExternalBufDesc == NULL) { |
| if(attribute_tpi.buffers != NULL) |
| free(attribute_tpi.buffers); |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid VASurfaceAttribExternalBuffers.\n"); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| attribute_tpi.type = memory_type; |
| if (attribute_tpi_buffersAlloced == true && attribute_tpi.buffers != NULL) { |
| free(attribute_tpi.buffers); |
| attribute_tpi.buffers = NULL; |
| } |
| attribute_tpi.buffers = malloc(sizeof(long) * pExternalBufDesc->num_buffers); |
| attribute_tpi_buffersAlloced = true; |
| attribute_tpi.width = pExternalBufDesc->width; |
| attribute_tpi.height = pExternalBufDesc->height; |
| attribute_tpi.count = pExternalBufDesc->num_buffers; |
| memcpy((void*)attribute_tpi.buffers, (void*)pExternalBufDesc->buffers, |
| sizeof(pExternalBufDesc->buffers[0]) * |
| pExternalBufDesc->num_buffers); |
| attribute_tpi.pixel_format = pExternalBufDesc->pixel_format; |
| attribute_tpi.size = pExternalBufDesc->data_size; |
| attribute_tpi.luma_stride = pExternalBufDesc->pitches[0]; |
| attribute_tpi.chroma_u_stride = pExternalBufDesc->pitches[1]; |
| attribute_tpi.chroma_v_stride = pExternalBufDesc->pitches[2]; |
| attribute_tpi.luma_offset = pExternalBufDesc->offsets[0]; |
| attribute_tpi.chroma_u_offset = pExternalBufDesc->offsets[1]; |
| attribute_tpi.chroma_v_offset = pExternalBufDesc->offsets[2]; |
| attribute_tpi.reserved[0] = (unsigned long) pExternalBufDesc->private_data; |
| if (pExternalBufDesc->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING) |
| attribute_tpi.tiling = 1; |
| else |
| attribute_tpi.tiling = 0; |
| } |
| break; |
| case VASurfaceAttribMemoryType: |
| { |
| switch (attrib_list->value.value.i) { |
| case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR: |
| memory_type = VAExternalMemoryUserPointer; |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: |
| memory_type = VAExternalMemoryKernelDRMBufffer; |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC: |
| memory_type = VAExternalMemoryAndroidGrallocBuffer; |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION: |
| memory_type = VAExternalMemoryIONSharedFD; |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_VA: |
| memory_type = VAExternalMemoryNULL; |
| break; |
| default: |
| if (attribute_tpi.buffers != NULL) |
| free(attribute_tpi.buffers); |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported memory type.\n"); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| |
| } |
| } |
| break; |
| case VASurfaceAttribUsageHint: |
| { |
| /* Share info is to be initialized when created sufaces by default (for the data producer) |
| * VPP Read indicate we do not NOT touch share info (for data consumer, which share buffer with data |
| * producer, such as of VPP). |
| */ |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "VASurfaceAttribUsageHint.\n"); |
| if ((attrib_list->value.value.i & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ)!= 0){ |
| initalized_info_flag = 0; |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "explicat not initialized share info.\n"); |
| } |
| } |
| break; |
| default: |
| if (attribute_tpi.buffers != NULL) |
| free(attribute_tpi.buffers); |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n"); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| } |
| } |
| |
| if ((memory_type == -1 && pExternalBufDesc != NULL) || |
| (memory_type != -1 && pExternalBufDesc == NULL)) { |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| else if(memory_type !=-1 && pExternalBufDesc != NULL) { |
| attribute_tpi.type = memory_type; |
| //set initialized share info in reserverd 1, by default we will initialized share_info |
| attribute_tpi.reserved[2] = (unsigned int)initalized_info_flag; |
| vaStatus = psb_CreateSurfacesWithAttribute(ctx, width, height, format, num_surfaces, surface_list, (VASurfaceAttributeTPI *)&attribute_tpi); |
| pExternalBufDesc->private_data = (void *)(attribute_tpi.reserved[1]); |
| if (attribute_tpi.buffers) free(attribute_tpi.buffers); |
| return vaStatus; |
| } |
| |
| format = format & (~VA_RT_FORMAT_PROTECTED); |
| |
| /* We only support one format */ |
| if ((VA_RT_FORMAT_YUV420 != format) |
| && (VA_RT_FORMAT_YUV422 != format) |
| && (VA_RT_FORMAT_YUV444 != format)) { |
| vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| DEBUG_FAILURE; |
| return vaStatus; |
| } |
| |
| vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); |
| CHECK_VASTATUS(); |
| |
| /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */ |
| height_origin = height; |
| height = (height + 0x1f) & ~0x1f; |
| |
| |
| for (i = 0; i < num_surfaces; i++) { |
| int surfaceID; |
| object_surface_p obj_surface; |
| psb_surface_p psb_surface; |
| |
| surfaceID = object_heap_allocate(&driver_data->surface_heap); |
| obj_surface = SURFACE(surfaceID); |
| if (NULL == obj_surface) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| MEMSET_OBJECT(obj_surface, struct object_surface_s); |
| |
| obj_surface->surface_id = surfaceID; |
| surface_list[i] = surfaceID; |
| obj_surface->context_id = -1; |
| obj_surface->width = width; |
| obj_surface->height = height; |
| obj_surface->width_r = width; |
| obj_surface->height_r = height; |
| obj_surface->height_origin = height_origin; |
| obj_surface->share_info = NULL; |
| |
| psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); |
| if (NULL == psb_surface) { |
| object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); |
| obj_surface->surface_id = VA_INVALID_SURFACE; |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| |
| switch (format) { |
| case VA_RT_FORMAT_YUV444: |
| fourcc = VA_FOURCC_YV32; /* allocate 4 planar */ |
| break; |
| case VA_RT_FORMAT_YUV422: |
| fourcc = VA_FOURCC_YV16; |
| break; |
| case VA_RT_FORMAT_YUV420: |
| default: |
| fourcc = VA_FOURCC_NV12; |
| break; |
| } |
| |
| flags |= driver_data->protected ? IS_PROTECTED : 0; |
| vaStatus = psb_surface_create(driver_data, width, height, fourcc, |
| flags, psb_surface); |
| |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(psb_surface); |
| object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); |
| obj_surface->surface_id = VA_INVALID_SURFACE; |
| DEBUG_FAILURE; |
| break; |
| } |
| buffer_stride = psb_surface->stride; |
| /* by default, surface fourcc is NV12 */ |
| psb_surface->extra_info[4] = fourcc; |
| psb_surface->extra_info[8] = fourcc; |
| obj_surface->psb_surface = psb_surface; |
| } |
| |
| /* Error recovery */ |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| /* surface_list[i-1] was the last successful allocation */ |
| for (; i--;) { |
| object_surface_p obj_surface = SURFACE(surface_list[i]); |
| psb__destroy_surface(driver_data, obj_surface); |
| surface_list[i] = VA_INVALID_SURFACE; |
| } |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n"); |
| return vaStatus; |
| } |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_DestroySurfaces( |
| VADriverContextP ctx, |
| VASurfaceID *surface_list, |
| int num_surfaces |
| ) |
| { |
| INIT_DRIVER_DATA |
| int i, j; |
| object_context_p obj_context = NULL; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| if (num_surfaces <= 0) { |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| CHECK_SURFACE(surface_list); |
| |
| #if 0 |
| /* Free PVR2D buffer wrapped from the surfaces */ |
| psb_free_surface_pvr2dbuf(driver_data); |
| #endif |
| |
| /* Make validation happy */ |
| for (i = 0; i < num_surfaces; i++) { |
| object_surface_p obj_surface = SURFACE(surface_list[i]); |
| if (obj_surface == NULL) { |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| } |
| if (obj_surface->derived_imgcnt > 0) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| |
| for (i = 0; i < num_surfaces; i++) { |
| object_surface_p obj_surface = SURFACE(surface_list[i]); |
| if (obj_surface == NULL) |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| |
| if (driver_data->cur_displaying_surface == surface_list[i]) { |
| /* Surface is being displaying. Need to stop overlay here */ |
| psb_coverlay_stop(ctx); |
| } |
| |
| obj_context = CONTEXT(obj_surface->context_id); |
| if (obj_context != NULL) { |
| for (j = 0; j < obj_context->num_render_targets; j++) { |
| if (obj_context->render_targets[j] == obj_surface->surface_id) { |
| obj_context->render_targets[j] = VA_INVALID_SURFACE; |
| break; |
| } |
| } |
| } |
| |
| drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id); |
| if (obj_surface->share_info) { |
| psb_DestroySurfaceGralloc(obj_surface); |
| } |
| psb__destroy_surface(driver_data, obj_surface); |
| surface_list[i] = VA_INVALID_SURFACE; |
| } |
| |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| } |
| |
| int psb_new_context(psb_driver_data_p driver_data, uint64_t ctx_type) |
| { |
| struct drm_lnc_video_getparam_arg arg; |
| int ret = 0; |
| |
| arg.key = IMG_VIDEO_NEW_CONTEXT; |
| arg.value = (uint64_t)((unsigned long) & ctx_type); |
| ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, |
| &arg, sizeof(arg)); |
| if (ret != 0) |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type); |
| |
| return ret; |
| } |
| |
| #ifdef PSBVIDEO_MSVDX_DEC_TILING |
| int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type) |
| { |
| struct drm_lnc_video_getparam_arg arg; |
| int ret = 0; |
| |
| arg.key = IMG_VIDEO_UPDATE_CONTEXT; |
| arg.value = (uint64_t)((unsigned long) & ctx_type); |
| ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, |
| &arg, sizeof(arg)); |
| if (ret != 0) |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Update context %d failed\n", ctx_type); |
| |
| return ret; |
| } |
| #endif |
| |
| int psb_rm_context(psb_driver_data_p driver_data) |
| { |
| struct drm_lnc_video_getparam_arg arg; |
| int tmp; |
| int ret = 0; |
| |
| arg.key = IMG_VIDEO_RM_CONTEXT; |
| arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */ |
| ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, |
| &arg, sizeof(arg)); |
| if (ret != 0) |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n"); |
| |
| return ret; |
| } |
| |
| VAStatus psb_CreateContext( |
| VADriverContextP ctx, |
| VAConfigID config_id, |
| int picture_width, |
| int picture_height, |
| int flag, |
| VASurfaceID *render_targets, |
| int num_render_targets, |
| VAContextID *context /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_config_p obj_config; |
| int cmdbuf_num, encode = 0, proc = 0; |
| int i; |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d, render_targets: %p.\n", |
| config_id, picture_width, picture_height, flag, num_render_targets, render_targets); |
| |
| CHECK_INVALID_PARAM(num_render_targets < 0); |
| |
| //CHECK_SURFACE(render_targets); |
| CHECK_CONTEXT(context); |
| |
| vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height); |
| CHECK_VASTATUS(); |
| |
| obj_config = CONFIG(config_id); |
| CHECK_CONFIG(obj_config); |
| |
| int contextID = object_heap_allocate(&driver_data->context_heap); |
| object_context_p obj_context = CONTEXT(contextID); |
| CHECK_ALLOCATION(obj_context); |
| |
| *context = contextID; |
| |
| MEMSET_OBJECT(obj_context, struct object_context_s); |
| |
| obj_context->driver_data = driver_data; |
| obj_context->current_render_target = NULL; |
| obj_context->ec_target = NULL; |
| obj_context->ec_candidate = NULL; |
| obj_context->is_oold = driver_data->is_oold; |
| obj_context->context_id = contextID; |
| obj_context->config_id = config_id; |
| obj_context->picture_width = picture_width; |
| obj_context->picture_height = picture_height; |
| obj_context->num_render_targets = num_render_targets; |
| obj_context->msvdx_scaling = 0; |
| #ifdef SLICE_HEADER_PARSING |
| obj_context->msvdx_frame_end = 0; |
| for (i = 0; i < obj_config->attrib_count; i++) { |
| if ((obj_config->attrib_list[i].type == VAConfigAttribDecSliceMode) && |
| (obj_config->attrib_list[i].value == VA_DEC_SLICE_MODE_SUBSAMPLE)) { |
| obj_context->modular_drm = 1; |
| break; |
| } |
| } |
| #endif |
| obj_context->scaling_width = 0; |
| obj_context->scaling_height = 0; |
| |
| if (num_render_targets > 0) { |
| obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID)); |
| if (obj_context->render_targets == NULL) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| |
| object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); |
| |
| return vaStatus; |
| } |
| } |
| |
| /* allocate buffer points for vaRenderPicture */ |
| obj_context->num_buffers = 10; |
| obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers); |
| if (obj_context->buffer_list == NULL) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| |
| if (NULL != obj_context->render_targets) |
| free(obj_context->render_targets); |
| object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); |
| |
| return vaStatus; |
| } |
| |
| memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused)); |
| memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count)); |
| memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail)); |
| memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active)); |
| |
| if (obj_config->entrypoint == VAEntrypointEncSlice |
| || obj_config->entrypoint == VAEntrypointEncPicture) { |
| encode = 1; |
| } |
| #ifdef PSBVIDEO_MRFL_VPP |
| if (obj_config->entrypoint == VAEntrypointVideoProc) |
| proc = 1; |
| |
| //todo: fixme |
| if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3){ |
| proc = 1; |
| encode = 0; |
| } |
| #endif |
| |
| if (encode) |
| cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE; |
| else if (proc) |
| cmdbuf_num = VSP_MAX_CMDBUFS; |
| else |
| cmdbuf_num = PSB_MAX_CMDBUFS; |
| |
| if (num_render_targets > 0 && (render_targets != NULL)) { |
| for (i = 0; i < num_render_targets; i++) { |
| object_surface_p obj_surface = SURFACE(render_targets[i]); |
| psb_surface_p psb_surface; |
| |
| if (NULL == obj_surface) { |
| vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; |
| DEBUG_FAILURE; |
| break; |
| } |
| |
| if (!driver_data->protected && obj_surface->share_info) |
| obj_surface->share_info->force_output_method = 0; |
| |
| psb_surface = obj_surface->psb_surface; |
| |
| /* Clear format specific surface info */ |
| obj_context->render_targets[i] = render_targets[i]; |
| obj_surface->context_id = contextID; /* Claim ownership of surface */ |
| #ifdef PSBVIDEO_MSVDX_DEC_TILING |
| if (GET_SURFACE_INFO_tiling(psb_surface)) { |
| #ifdef BAYTRAIL |
| obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width); |
| #else |
| if (obj_config->entrypoint == VAEntrypointVideoProc && obj_config->profile == VAProfileNone) |
| // It's for two pass rotation case |
| // Need the source surface width for tile stride setting |
| obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width); |
| else |
| obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width); |
| #endif |
| } |
| #endif |
| #if 0 |
| /* for decode, move the surface into |TT */ |
| if ((encode == 0) && /* decode */ |
| ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */ |
| psb_buffer_setstatus(&obj_surface->psb_surface->buf, |
| WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU); |
| #endif |
| } |
| } else if (num_render_targets > 0) { |
| for (i = 0; i < num_render_targets; i++) { |
| obj_context->render_targets[i] = VA_INVALID_SURFACE; |
| } |
| } |
| |
| obj_context->va_flags = flag; |
| obj_context->format_vtable = obj_config->format_vtable; |
| obj_context->format_data = NULL; |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config); |
| } |
| |
| /* Error recovery */ |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| obj_context->context_id = -1; |
| obj_context->config_id = -1; |
| obj_context->picture_width = 0; |
| obj_context->picture_height = 0; |
| if (NULL != obj_context->render_targets) |
| free(obj_context->render_targets); |
| free(obj_context->buffer_list); |
| obj_context->num_buffers = 0; |
| obj_context->render_targets = NULL; |
| obj_context->num_render_targets = 0; |
| obj_context->va_flags = 0; |
| object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); |
| |
| return vaStatus; |
| } |
| |
| /* initialize cmdbuf */ |
| for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) { |
| obj_context->pnw_cmdbuf_list[i] = NULL; |
| } |
| |
| #ifdef PSBVIDEO_MRFL |
| for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) { |
| obj_context->tng_cmdbuf_list[i] = NULL; |
| } |
| #endif |
| |
| #ifdef PSBVIDEO_MRFL_VPP |
| for (i = 0; i < VSP_MAX_CMDBUFS; i++) { |
| obj_context->vsp_cmdbuf_list[i] = NULL; |
| } |
| #endif |
| |
| for (i = 0; i < PSB_MAX_CMDBUFS; i++) { |
| obj_context->cmdbuf_list[i] = NULL; |
| } |
| |
| for (i = 0; i < cmdbuf_num; i++) { |
| #ifndef BAYTRAIL |
| if (encode) { /* Topaz encode context */ |
| #ifdef PSBVIDEO_MRFL |
| if (IS_MRFL(obj_context->driver_data)) { |
| obj_context->tng_cmdbuf_list[i] = calloc(1, sizeof(struct tng_cmdbuf_s)); |
| if (NULL == obj_context->tng_cmdbuf_list[i]) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| #ifdef PSBVIDEO_MFLD |
| if (IS_MFLD(obj_context->driver_data)) { |
| obj_context->pnw_cmdbuf_list[i] = calloc(1, sizeof(struct pnw_cmdbuf_s)); |
| if (NULL == obj_context->pnw_cmdbuf_list[i]) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| } else if (proc) { /* VSP VPP context */ |
| /* VED two pass rotation under VPP API */ |
| if (driver_data->ved_vpp) { |
| obj_context->cmdbuf_list[i] = calloc(1, sizeof(struct psb_cmdbuf_s)); |
| if (NULL == obj_context->cmdbuf_list[i]) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #ifdef PSBVIDEO_MRFL_VPP |
| else if (IS_MRFL(obj_context->driver_data)) { |
| obj_context->vsp_cmdbuf_list[i] = calloc(1, sizeof(struct vsp_cmdbuf_s)); |
| if (NULL == obj_context->vsp_cmdbuf_list[i]) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| } else /* MSVDX decode context */ { |
| #endif |
| obj_context->cmdbuf_list[i] = calloc(1, sizeof(struct psb_cmdbuf_s)); |
| if (NULL == obj_context->cmdbuf_list[i]) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| |
| #ifndef BAYTRAIL |
| if (encode) { /* Topaz encode context */ |
| |
| #ifdef PSBVIDEO_MRFL |
| if (IS_MRFL(obj_context->driver_data)) { |
| vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)obj_context->tng_cmdbuf_list[i]); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(obj_context->tng_cmdbuf_list[i]); |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| #ifdef PSBVIDEO_MFLD |
| if (IS_MFLD(obj_context->driver_data)) { |
| vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)obj_context->pnw_cmdbuf_list[i]); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(obj_context->pnw_cmdbuf_list[i]); |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| } else if (proc) { /* VSP VPP context */ |
| if (driver_data->ved_vpp) { |
| vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)obj_context->cmdbuf_list[i]); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(obj_context->cmdbuf_list[i]); |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #ifdef PSBVIDEO_MRFL_VPP |
| else if (IS_MRFL(obj_context->driver_data)) { |
| vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)obj_context->vsp_cmdbuf_list[i]); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(obj_context->vsp_cmdbuf_list[i]); |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| } else /* MSVDX decode context */ { |
| #endif |
| vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)obj_context->cmdbuf_list[i]); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(obj_context->cmdbuf_list[i]); |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| |
| #ifndef BAYTRAIL |
| if (encode) { /* Topaz encode context */ |
| if (i >= LNC_MAX_CMDBUFS_ENCODE) { |
| #ifdef PSBVIDEO_MRFL |
| tng_cmdbuf_destroy((tng_cmdbuf_p)obj_context->tng_cmdbuf_list[i]); |
| free(obj_context->tng_cmdbuf_list[i]); |
| #endif |
| #ifdef PSBVIDEO_MFLD |
| pnw_cmdbuf_destroy((pnw_cmdbuf_p)obj_context->pnw_cmdbuf_list[i]); |
| free(obj_context->pnw_cmdbuf_list[i]); |
| #endif |
| DEBUG_FAILURE; |
| break; |
| } |
| } |
| #endif |
| } |
| |
| obj_context->cmdbuf_current = -1; |
| obj_context->cmdbuf = NULL; |
| obj_context->pnw_cmdbuf = NULL; |
| obj_context->tng_cmdbuf = NULL; |
| #ifdef PSBVIDEO_MRFL_VPP |
| obj_context->vsp_cmdbuf = NULL; |
| #endif |
| obj_context->frame_count = 0; |
| obj_context->slice_count = 0; |
| obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) | |
| ((contextID & 0xff000000) >> 16); |
| #ifdef ANDROID |
| obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) | |
| ((unsigned int)gettid() & 0xf); |
| #endif |
| obj_context->profile = obj_config->profile; |
| obj_context->entry_point = obj_config->entrypoint; |
| |
| /* Error recovery */ |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE) |
| cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE; |
| for (i = 0; i < cmdbuf_num; i++) { |
| #ifndef BAYTRAIL |
| if (obj_context->pnw_cmdbuf_list[i]) { |
| pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]); |
| free(obj_context->pnw_cmdbuf_list[i]); |
| obj_context->pnw_cmdbuf_list[i] = NULL; |
| } |
| #endif |
| #ifdef PSBVIDEO_MRFL |
| if (obj_context->tng_cmdbuf_list[i]) { |
| tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]); |
| free(obj_context->tng_cmdbuf_list[i]); |
| obj_context->tng_cmdbuf_list[i] = NULL; |
| } |
| #endif |
| if (obj_context->cmdbuf_list[i]) { |
| psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]); |
| free(obj_context->cmdbuf_list[i]); |
| obj_context->cmdbuf_list[i] = NULL; |
| } |
| #ifdef PSBVIDEO_MRFL_VPP |
| if (obj_context->vsp_cmdbuf_list[i]) { |
| vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]); |
| free(obj_context->vsp_cmdbuf_list[i]); |
| obj_context->vsp_cmdbuf_list[i] = NULL; |
| } |
| #endif |
| } |
| |
| obj_context->cmdbuf = NULL; |
| #ifdef PSBVIDEO_MRFL_VPP |
| obj_context->vsp_cmdbuf = NULL; |
| #endif |
| |
| obj_context->context_id = -1; |
| obj_context->config_id = -1; |
| obj_context->picture_width = 0; |
| obj_context->picture_height = 0; |
| if (NULL != obj_context->render_targets) |
| free(obj_context->render_targets); |
| free(obj_context->buffer_list); |
| obj_context->num_buffers = 0; |
| obj_context->render_targets = NULL; |
| obj_context->num_render_targets = 0; |
| obj_context->va_flags = 0; |
| object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); |
| } |
| obj_context->ctp_type = (((obj_config->profile << 8) | |
| obj_config->entrypoint | driver_data->protected) & 0xffff); |
| |
| /* VSP's PM rely on VPP ctx, so ved vpp use diferent profile/level for ctx */ |
| if (driver_data->ved_vpp) |
| obj_context->ctp_type = (((obj_config->profile << 8) | |
| VAEntrypointVLD | driver_data->protected) & 0xffff); |
| |
| if (!encode) { |
| obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16); |
| } |
| |
| if (obj_context->ctp_type & VAEntrypointVLD) { |
| if (render_targets == NULL) { |
| obj_context->ctp_type |= PSB_SURFACE_UNAVAILABLE; |
| } |
| } |
| |
| if (obj_context->ctp_type & VAEntrypointVLD) { |
| if (render_targets == NULL) { |
| obj_context->ctp_type |= PSB_SURFACE_UNAVAILABLE; |
| } |
| } |
| |
| if (obj_config->profile == VAProfileVC1Simple || |
| obj_config->profile == VAProfileVC1Main || |
| obj_config->profile == VAProfileVC1Advanced || |
| obj_config->profile == VAProfileH264Baseline || |
| obj_config->profile == VAProfileH264Main || |
| obj_config->profile == VAProfileH264High || |
| obj_config->profile == VAProfileVP8Version0_3) { |
| uint64_t width_in_mb = ((driver_data->render_rect.x + driver_data->render_rect.width + 15) / 16); |
| uint64_t height_in_mb = ((driver_data->render_rect.y + driver_data->render_rect.height + 15) / 16); |
| obj_context->ctp_type |= (width_in_mb << 32); |
| obj_context->ctp_type |= (height_in_mb << 48); |
| } |
| |
| /* add ctx_num to save vp8 enc context num to support dual vp8 encoding */ |
| int ret = psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected); |
| if (ret) |
| vaStatus = VA_STATUS_ERROR_UNKNOWN; |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size); |
| CHECK_ALLOCATION(obj_buffer->buffer_data); |
| |
| return vaStatus; |
| } |
| |
| static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer); |
| |
| static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_context_p __maybe_unused obj_context, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| ASSERT(NULL == obj_buffer->buffer_data); |
| |
| if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id, |
| buffer_type_to_string(obj_buffer->type)); |
| /* need to set psb_buffer aside and get another one */ |
| obj_buffer->psb_buffer->status = psb_bs_abandoned; |
| obj_buffer->psb_buffer = NULL; |
| obj_buffer->size = 0; |
| obj_buffer->alloc_size = 0; |
| } |
| |
| if (type == VAProtectedSliceDataBufferType) { |
| if (obj_buffer->psb_buffer) { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n", |
| obj_buffer->psb_buffer->rar_handle, (uint32_t)data); |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n"); |
| obj_buffer->alloc_size = 0; |
| } |
| } |
| |
| if (obj_buffer->alloc_size < (unsigned int)size) { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size); |
| if (obj_buffer->psb_buffer) { |
| if (obj_buffer->buffer_data) { |
| psb__unmap_buffer(obj_buffer); |
| } |
| psb_buffer_destroy(obj_buffer->psb_buffer); |
| obj_buffer->alloc_size = 0; |
| } else { |
| obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s)); |
| if (NULL == obj_buffer->psb_buffer) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| DEBUG_FAILURE; |
| } |
| } |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n", |
| buffer_type_to_string(obj_buffer->type), size); |
| |
| size = (size + 0x7fff) & ~0x7fff; /* Round up */ |
| if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer |
| * should be shared between two process |
| */ |
| vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer); |
| #ifndef BAYTRAIL |
| else if (obj_buffer->type == VAProtectedSliceDataBufferType) { |
| vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer); |
| } |
| #endif |
| else if (obj_buffer->type == VAEncCodedBufferType) |
| vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer); |
| else |
| vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer); |
| |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| free(obj_buffer->psb_buffer); |
| obj_buffer->psb_buffer = NULL; |
| DEBUG_FAILURE; |
| } else { |
| obj_buffer->alloc_size = size; |
| } |
| } |
| } |
| return vaStatus; |
| } |
| |
| static VAStatus psb__map_buffer(object_buffer_p obj_buffer) |
| { |
| if (obj_buffer->psb_buffer) { |
| return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data); |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer) |
| { |
| if (obj_buffer->psb_buffer) { |
| obj_buffer->buffer_data = NULL; |
| return psb_buffer_unmap(obj_buffer->psb_buffer); |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer) |
| { |
| if (obj_buffer->psb_buffer) { |
| if (obj_buffer->buffer_data) { |
| psb__unmap_buffer(obj_buffer); |
| } |
| psb_buffer_destroy(obj_buffer->psb_buffer); |
| free(obj_buffer->psb_buffer); |
| obj_buffer->psb_buffer = NULL; |
| } |
| |
| if (NULL != obj_buffer->buffer_data) { |
| free(obj_buffer->buffer_data); |
| obj_buffer->buffer_data = NULL; |
| obj_buffer->size = 0; |
| } |
| |
| object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer); |
| } |
| |
| void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer) |
| { |
| if (obj_buffer->context) { |
| VABufferType type = obj_buffer->type; |
| object_context_p obj_context = obj_buffer->context; |
| |
| if (type >= PSB_MAX_BUFFERTYPES) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type); |
| return; |
| } |
| |
| /* Remove buffer from active list */ |
| *obj_buffer->pptr_prev_next = obj_buffer->ptr_next; |
| |
| /* Add buffer to tail of unused list */ |
| obj_buffer->ptr_next = NULL; |
| obj_buffer->last_used = obj_context->frame_count; |
| if (obj_context->buffers_unused_tail[type]) { |
| obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next); |
| } else { |
| obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]); |
| } |
| *obj_buffer->pptr_prev_next = obj_buffer; |
| obj_context->buffers_unused_tail[type] = obj_buffer; |
| obj_context->buffers_unused_count[type]++; |
| |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id, |
| buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]); |
| |
| object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */ |
| return; |
| } |
| |
| if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) { |
| /* need to set psb_buffer aside */ |
| obj_buffer->psb_buffer->status = psb_bs_abandoned; |
| obj_buffer->psb_buffer = NULL; |
| } |
| |
| psb__destroy_buffer(driver_data, obj_buffer); |
| } |
| |
| static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context) |
| { |
| int encode, i; |
| |
| if (obj_context->entry_point == VAEntrypointEncSlice) |
| encode = 1; |
| else |
| encode = 0; |
| |
| obj_context->format_vtable->destroyContext(obj_context); |
| |
| for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) { |
| object_buffer_p obj_buffer; |
| obj_buffer = obj_context->buffers_active[i]; |
| for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) { |
| drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id); |
| psb__destroy_buffer(driver_data, obj_buffer); |
| } |
| obj_buffer = obj_context->buffers_unused[i]; |
| for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) { |
| drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id); |
| psb__destroy_buffer(driver_data, obj_buffer); |
| } |
| obj_context->buffers_unused_count[i] = 0; |
| } |
| #ifndef BAYTRAIL |
| for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { |
| if (obj_context->pnw_cmdbuf_list[i]) { |
| pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]); |
| free(obj_context->pnw_cmdbuf_list[i]); |
| obj_context->pnw_cmdbuf_list[i] = NULL; |
| } |
| } |
| #endif |
| #ifdef PSBVIDEO_MRFL |
| for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) { |
| if (obj_context->tng_cmdbuf_list[i]) { |
| tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]); |
| free(obj_context->tng_cmdbuf_list[i]); |
| obj_context->tng_cmdbuf_list[i] = NULL; |
| } |
| } |
| #endif |
| #ifdef PSBVIDEO_MRFL_VPP |
| for (i = 0; i < VSP_MAX_CMDBUFS; i++) { |
| if (obj_context->vsp_cmdbuf_list[i]) { |
| vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]); |
| free(obj_context->vsp_cmdbuf_list[i]); |
| obj_context->vsp_cmdbuf_list[i] = NULL; |
| } |
| } |
| #endif |
| |
| for (i = 0; i < PSB_MAX_CMDBUFS; i++) { |
| if (obj_context->cmdbuf_list[i]) { |
| psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]); |
| free(obj_context->cmdbuf_list[i]); |
| obj_context->cmdbuf_list[i] = NULL; |
| } |
| } |
| obj_context->cmdbuf = NULL; |
| #ifdef PSBVIDEO_MRFL_VPP |
| obj_context->vsp_cmdbuf = NULL; |
| #endif |
| |
| obj_context->context_id = -1; |
| obj_context->config_id = -1; |
| obj_context->picture_width = 0; |
| obj_context->picture_height = 0; |
| if (obj_context->render_targets) |
| free(obj_context->render_targets); |
| obj_context->render_targets = NULL; |
| obj_context->num_render_targets = 0; |
| obj_context->va_flags = 0; |
| |
| obj_context->current_render_target = NULL; |
| obj_context->ec_target = NULL; |
| obj_context->ec_candidate = NULL; |
| if (obj_context->buffer_list) |
| free(obj_context->buffer_list); |
| obj_context->num_buffers = 0; |
| |
| object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); |
| |
| psb_rm_context(driver_data); |
| } |
| |
| VAStatus psb_DestroyContext( |
| VADriverContextP ctx, |
| VAContextID context |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_context_p obj_context = CONTEXT(context); |
| CHECK_CONTEXT(obj_context); |
| |
| psb__destroy_context(driver_data, obj_context); |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb__CreateBuffer( |
| psb_driver_data_p driver_data, |
| object_context_p obj_context, /* in */ |
| VABufferType type, /* in */ |
| unsigned int size, /* in */ |
| unsigned int num_elements, /* in */ |
| unsigned char *data, /* in */ |
| VABufferID *buf_desc /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| int bufferID; |
| object_buffer_p obj_buffer; |
| int unused_count; |
| |
| /*PSB_MAX_BUFFERTYPES is the size of array buffers_unused*/ |
| if (type >= PSB_MAX_BUFFERTYPES) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type); |
| return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; |
| } |
| |
| |
| obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL; |
| unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0; |
| |
| /* |
| * Buffer Management |
| * For each buffer type, maintain |
| * - a LRU sorted list of unused buffers |
| * - a list of active buffers |
| * We only create a new buffer when |
| * - no unused buffers are available |
| * - the last unused buffer is still queued |
| * - the last unused buffer was used very recently and may still be fenced |
| * - used recently is defined as within the current frame_count (subject to tweaks) |
| * |
| * The buffer that is returned will be moved to the list of active buffers |
| * - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers |
| */ |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements, |
| buffer_type_to_string(type)); |
| |
| /* on MFLD, data is IMR offset, and could be 0 */ |
| /* |
| if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) { |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n"); |
| return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ; |
| } |
| */ |
| |
| if (obj_buffer && obj_buffer->psb_buffer) { |
| if (psb_bs_queued == obj_buffer->psb_buffer->status) { |
| /* Buffer is still queued, allocate new buffer instead */ |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id); |
| obj_buffer = NULL; |
| } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) { |
| /* Buffer was used for this frame, allocate new buffer instead */ |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count); |
| obj_buffer = NULL; |
| } else if (obj_context->frame_count - obj_buffer->last_used < 5) { |
| /* Buffer was used for previous frame, allocate new buffer instead */ |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count); |
| obj_buffer = NULL; |
| } |
| } |
| |
| if (obj_buffer) { |
| bufferID = obj_buffer->base.id; |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID, |
| buffer_type_to_string(type), unused_count); |
| |
| /* Remove from unused list */ |
| obj_context->buffers_unused[type] = obj_buffer->ptr_next; |
| if (obj_context->buffers_unused[type]) { |
| obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]); |
| ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer); |
| } else { |
| ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer); |
| obj_context->buffers_unused_tail[type] = 0; |
| } |
| obj_context->buffers_unused_count[type]--; |
| |
| object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */ |
| ASSERT(type == obj_buffer->type); |
| ASSERT(obj_context == obj_buffer->context); |
| } else { |
| bufferID = object_heap_allocate(&driver_data->buffer_heap); |
| obj_buffer = BUFFER(bufferID); |
| CHECK_ALLOCATION(obj_buffer); |
| |
| MEMSET_OBJECT(obj_buffer, struct object_buffer_s); |
| |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type)); |
| obj_buffer->type = type; |
| obj_buffer->buffer_data = NULL; |
| obj_buffer->psb_buffer = NULL; |
| obj_buffer->size = 0; |
| obj_buffer->max_num_elements = 0; |
| obj_buffer->alloc_size = 0; |
| obj_buffer->context = obj_context; |
| } |
| if (obj_context) { |
| /* Add to front of active list */ |
| obj_buffer->ptr_next = obj_context->buffers_active[type]; |
| if (obj_buffer->ptr_next) { |
| obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next); |
| } |
| obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]); |
| *obj_buffer->pptr_prev_next = obj_buffer; |
| } |
| |
| switch (obj_buffer->type) { |
| case VABitPlaneBufferType: |
| case VASliceDataBufferType: |
| case VAResidualDataBufferType: |
| case VAImageBufferType: |
| case VASliceGroupMapBufferType: |
| case VAEncCodedBufferType: |
| case VAProtectedSliceDataBufferType: |
| #ifdef SLICE_HEADER_PARSING |
| case VAParseSliceHeaderGroupBufferType: |
| #endif |
| vaStatus = psb__allocate_BO_buffer(driver_data, obj_context,obj_buffer, size * num_elements, data, obj_buffer->type); |
| DEBUG_FAILURE; |
| break; |
| case VAPictureParameterBufferType: |
| case VAIQMatrixBufferType: |
| case VASliceParameterBufferType: |
| case VAMacroblockParameterBufferType: |
| case VADeblockingParameterBufferType: |
| case VAEncPackedHeaderParameterBufferType: |
| case VAEncPackedHeaderDataBufferType: |
| case VAEncSequenceParameterBufferType: |
| case VAEncPictureParameterBufferType: |
| case VAEncSliceParameterBufferType: |
| case VAQMatrixBufferType: |
| case VAEncMiscParameterBufferType: |
| case VAProbabilityBufferType: |
| case VAHuffmanTableBufferType: |
| case VAProcPipelineParameterBufferType: |
| case VAProcFilterParameterBufferType: |
| #ifdef SLICE_HEADER_PARSING |
| case VAParsePictureParameterBufferType: |
| #endif |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n", |
| buffer_type_to_string(type), size, obj_buffer->buffer_data); |
| vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements); |
| DEBUG_FAILURE; |
| break; |
| |
| default: |
| vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; |
| DEBUG_FAILURE; |
| break;; |
| } |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| obj_buffer->size = size; |
| obj_buffer->max_num_elements = num_elements; |
| obj_buffer->num_elements = num_elements; |
| if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) { |
| vaStatus = psb__map_buffer(obj_buffer); |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| memcpy(obj_buffer->buffer_data, data, size * num_elements); |
| |
| psb__unmap_buffer(obj_buffer); |
| } |
| } |
| } |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| *buf_desc = bufferID; |
| } else { |
| psb__destroy_buffer(driver_data, obj_buffer); |
| } |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_CreateBuffer( |
| VADriverContextP ctx, |
| VAContextID context, /* in */ |
| VABufferType type, /* in */ |
| unsigned int size, /* in */ |
| unsigned int num_elements, /* in */ |
| void *data, /* in */ |
| VABufferID *buf_desc /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| CHECK_INVALID_PARAM(num_elements <= 0); |
| |
| switch (type) { |
| case VABitPlaneBufferType: |
| case VASliceDataBufferType: |
| case VAProtectedSliceDataBufferType: |
| case VAResidualDataBufferType: |
| case VASliceGroupMapBufferType: |
| case VAPictureParameterBufferType: |
| case VAIQMatrixBufferType: |
| case VASliceParameterBufferType: |
| case VAMacroblockParameterBufferType: |
| case VADeblockingParameterBufferType: |
| case VAEncCodedBufferType: |
| case VAEncSequenceParameterBufferType: |
| case VAEncPictureParameterBufferType: |
| case VAEncSliceParameterBufferType: |
| case VAEncPackedHeaderParameterBufferType: |
| case VAEncPackedHeaderDataBufferType: |
| case VAQMatrixBufferType: |
| case VAEncMiscParameterBufferType: |
| case VAProbabilityBufferType: |
| case VAHuffmanTableBufferType: |
| case VAProcPipelineParameterBufferType: |
| case VAProcFilterParameterBufferType: |
| #ifdef SLICE_HEADER_PARSING |
| case VAParsePictureParameterBufferType: |
| case VAParseSliceHeaderGroupBufferType: |
| #endif |
| break; |
| |
| default: |
| vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; |
| DEBUG_FAILURE; |
| return vaStatus; |
| } |
| |
| object_context_p obj_context = CONTEXT(context); |
| CHECK_CONTEXT(obj_context); |
| CHECK_INVALID_PARAM(buf_desc == NULL); |
| |
| vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc); |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| |
| VAStatus psb_BufferInfo( |
| VADriverContextP ctx, |
| VABufferID buf_id, /* in */ |
| VABufferType *type, /* out */ |
| unsigned int *size, /* out */ |
| unsigned int *num_elements /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| object_buffer_p obj_buffer = BUFFER(buf_id); |
| CHECK_BUFFER(obj_buffer); |
| |
| *type = obj_buffer->type; |
| *size = obj_buffer->size; |
| *num_elements = obj_buffer->num_elements; |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| } |
| |
| |
| VAStatus psb_BufferSetNumElements( |
| VADriverContextP ctx, |
| VABufferID buf_id, /* in */ |
| unsigned int num_elements /* in */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_buffer_p obj_buffer = BUFFER(buf_id); |
| CHECK_BUFFER(obj_buffer); |
| |
| if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) { |
| vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| obj_buffer->num_elements = num_elements; |
| } |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_MapBuffer( |
| VADriverContextP ctx, |
| VABufferID buf_id, /* in */ |
| void **pbuf /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_buffer_p obj_buffer = BUFFER(buf_id); |
| CHECK_BUFFER(obj_buffer); |
| |
| CHECK_INVALID_PARAM(pbuf == NULL); |
| |
| vaStatus = psb__map_buffer(obj_buffer); |
| CHECK_VASTATUS(); |
| |
| if (NULL != obj_buffer->buffer_data) { |
| *pbuf = obj_buffer->buffer_data; |
| |
| /* specifically for Topaz encode |
| * write validate coded data offset in CodedBuffer |
| */ |
| if (obj_buffer->type == VAEncCodedBufferType) |
| psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf); |
| /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */ |
| } else { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_UnmapBuffer( |
| VADriverContextP ctx, |
| VABufferID buf_id /* in */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_buffer_p obj_buffer = BUFFER(buf_id); |
| CHECK_BUFFER(obj_buffer); |
| |
| vaStatus = psb__unmap_buffer(obj_buffer); |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| |
| VAStatus psb_DestroyBuffer( |
| VADriverContextP ctx, |
| VABufferID buffer_id |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_buffer_p obj_buffer = BUFFER(buffer_id); |
| if (NULL == obj_buffer) { |
| return vaStatus; |
| } |
| psb__suspend_buffer(driver_data, obj_buffer); |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| |
| VAStatus psb_BeginPicture( |
| VADriverContextP ctx, |
| VAContextID context, |
| VASurfaceID render_target |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_context_p obj_context; |
| object_surface_p obj_surface; |
| object_config_p obj_config; |
| unsigned int i = 0, j = VA_INVALID_ID; |
| |
| obj_context = CONTEXT(context); |
| CHECK_CONTEXT(obj_context); |
| |
| /* Must not be within BeginPicture / EndPicture already */ |
| ASSERT(obj_context->current_render_target == NULL); |
| |
| obj_surface = SURFACE(render_target); |
| CHECK_SURFACE(obj_surface); |
| |
| obj_context->current_render_surface_id = render_target; |
| obj_context->current_render_target = obj_surface; |
| obj_context->slice_count = 0; |
| |
| obj_config = CONFIG(obj_context->config_id); |
| if (obj_config == NULL) |
| return VA_STATUS_ERROR_INVALID_CONFIG; |
| |
| for (i = 0; i < (unsigned int)obj_context->num_render_targets; i++) { |
| if (obj_context->render_targets[i] == obj_surface->surface_id) { |
| break; |
| } else if (SURFACE(obj_context->render_targets[i]) == NULL) { |
| j = (i < j) ? i : j; |
| } |
| } |
| |
| if (i >= (unsigned int)obj_context->num_render_targets) { |
| if (j < (unsigned int)obj_context->num_render_targets) { |
| obj_context->render_targets[j] = obj_surface->surface_id; |
| obj_surface->context_id = obj_context->context_id; |
| |
| #ifdef PSBVIDEO_MSVDX_DEC_TILING |
| if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) { |
| #ifdef BAYTRAIL |
| obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width); |
| #else |
| if ( (obj_config != NULL) && |
| (obj_config->entrypoint == VAEntrypointVideoProc) && |
| (obj_config->profile == VAProfileNone)) { |
| obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width); |
| } else { |
| obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width); |
| } |
| #endif |
| } |
| |
| obj_context->msvdx_tile &= 0xf; /* clear rotate tile */ |
| obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */ |
| obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16); |
| obj_context->ctp_type &= (~PSB_SURFACE_UNAVAILABLE); |
| psb_update_context(driver_data, obj_context->ctp_type | driver_data->protected); |
| #endif |
| } |
| } |
| |
| if ((driver_data->protected & VA_RT_FORMAT_PROTECTED) && |
| !(obj_context->ctp_type & VA_RT_FORMAT_PROTECTED)) { |
| obj_context->ctp_type |= VA_RT_FORMAT_PROTECTED; |
| psb_update_context(driver_data, obj_context->ctp_type); |
| } |
| |
| /* if the surface is decode render target, and in displaying */ |
| if (obj_config && |
| (obj_config->entrypoint != VAEntrypointEncSlice) && |
| (driver_data->cur_displaying_surface == render_target)) |
| drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n"); |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| vaStatus = obj_context->format_vtable->beginPicture(obj_context); |
| } |
| |
| #ifdef ANDROID |
| /* want msvdx to do rotate |
| * but check per-context stream type: interlace or not |
| */ |
| if ((obj_config->entrypoint != VAEntrypointEncSlice) && |
| (obj_config->entrypoint != VAEntrypointEncPicture)) { |
| psb_RecalcAlternativeOutput(obj_context); |
| } |
| #endif |
| #ifdef PSBVIDEO_MRFL_VPP_ROTATE |
| if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) |
| driver_data->disable_msvdx_rotate = 0; |
| #endif |
| if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) { |
| int i = 0; |
| obj_context->msvdx_rotate = 0; |
| if (obj_context->num_render_targets > 0) { |
| for (i = 0; i < obj_context->num_render_targets; i++) { |
| object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]); |
| /*we invalidate all surfaces's rotate buffer share info here.*/ |
| if (obj_surface && obj_surface->share_info) { |
| obj_surface->share_info->surface_rotate = 0; |
| } |
| } |
| } |
| } |
| else |
| obj_context->msvdx_rotate = driver_data->msvdx_rotate_want; |
| |
| /* the main surface track current rotate information |
| * try to reuse the allocated rotate surfaces and don't destroy them |
| * thus the rotation info in obj_surface->out_loop_surface may not be updated |
| */ |
| |
| SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate); |
| |
| if (CONTEXT_SCALING(obj_context) && obj_config->entrypoint != VAEntrypointEncSlice) |
| if(VA_STATUS_SUCCESS != psb_CreateScalingSurface(obj_context, obj_surface)) { |
| obj_context->msvdx_scaling = 0; |
| ALOGE("%s: fail to allocate scaling surface", __func__); |
| } |
| |
| if (CONTEXT_ROTATE(obj_context)) { |
| #ifdef PSBVIDEO_MRFL_VPP_ROTATE |
| /* The VSP rotation is just for 1080P with tilling */ |
| if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) { |
| if (obj_config->entrypoint == VAEntrypointVideoProc) |
| vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate); |
| else { |
| SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0); |
| obj_context->msvdx_rotate = 0; |
| vaStatus = psb_DestroyRotateBuffer(obj_context, obj_surface); |
| } |
| } else |
| #endif |
| vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate); |
| if (VA_STATUS_SUCCESS !=vaStatus) |
| ALOGE("%s: fail to allocate out loop surface", __func__); |
| |
| } else { |
| if (obj_surface && obj_surface->share_info) { |
| obj_surface->share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate); |
| obj_surface->share_info->surface_rotate = VAROTATION2HAL(obj_context->msvdx_rotate); |
| } |
| } |
| |
| if (obj_surface && obj_surface->share_info && |
| obj_config->entrypoint == VAEntrypointVLD) { |
| obj_surface->share_info->crop_width = driver_data->render_rect.width; |
| obj_surface->share_info->crop_height = driver_data->render_rect.height; |
| } |
| |
| if (driver_data->is_oold && !obj_surface->psb_surface->in_loop_buf) { |
| psb_surface_p psb_surface = obj_surface->psb_surface; |
| |
| psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s)); |
| CHECK_ALLOCATION(psb_surface->in_loop_buf); |
| |
| /* FIXME: For RAR surface, need allocate RAR buffer */ |
| vaStatus = psb_buffer_create(obj_context->driver_data, |
| psb_surface->size, |
| psb_bt_surface, |
| psb_surface->in_loop_buf); |
| } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) { |
| psb_surface_p psb_surface = obj_surface->psb_surface; |
| |
| psb_buffer_destroy(psb_surface->in_loop_buf); |
| free(psb_surface->in_loop_buf); |
| psb_surface->in_loop_buf = NULL; |
| } |
| obj_context->is_oold = driver_data->is_oold; |
| |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n", |
| render_target, obj_context->frame_count); |
| psb__trace_message("------Trace frame %d------\n", obj_context->frame_count); |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_RenderPicture( |
| VADriverContextP ctx, |
| VAContextID context, |
| VABufferID *buffers, |
| int num_buffers |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_context_p obj_context; |
| object_buffer_p *buffer_list; |
| int i; |
| |
| obj_context = CONTEXT(context); |
| CHECK_CONTEXT(obj_context); |
| |
| CHECK_INVALID_PARAM(num_buffers <= 0); |
| /* Don't crash on NULL pointers */ |
| CHECK_BUFFER(buffers); |
| /* Must be within BeginPicture / EndPicture */ |
| ASSERT(obj_context->current_render_target != NULL); |
| |
| if (num_buffers > obj_context->num_buffers) { |
| free(obj_context->buffer_list); |
| |
| obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers); |
| if (obj_context->buffer_list == NULL) { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| obj_context->num_buffers = 0; |
| } |
| |
| obj_context->num_buffers = num_buffers; |
| } |
| buffer_list = obj_context->buffer_list; |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| /* Lookup buffer references */ |
| for (i = 0; i < num_buffers; i++) { |
| object_buffer_p obj_buffer = BUFFER(buffers[i]); |
| CHECK_BUFFER(obj_buffer); |
| |
| buffer_list[i] = obj_buffer; |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id, |
| buffer_type_to_string(obj_buffer->type)); |
| } |
| } |
| |
| if (VA_STATUS_SUCCESS == vaStatus) { |
| vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers); |
| } |
| |
| if (buffer_list) { |
| /* Release buffers */ |
| for (i = 0; i < num_buffers; i++) { |
| if (buffer_list[i]) { |
| psb__suspend_buffer(driver_data, buffer_list[i]); |
| } |
| } |
| } |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_EndPicture( |
| VADriverContextP ctx, |
| VAContextID context |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus; |
| object_context_p obj_context; |
| |
| obj_context = CONTEXT(context); |
| CHECK_CONTEXT(obj_context); |
| |
| vaStatus = obj_context->format_vtable->endPicture(obj_context); |
| |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count); |
| |
| obj_context->current_render_target = NULL; |
| obj_context->frame_count++; |
| |
| psb__trace_message("FrameCount = %03d\n", obj_context->frame_count); |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count); |
| psb__trace_message(NULL); |
| |
| |
| //psb_SyncSurface(ctx, obj_context->current_render_surface_id); |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| |
| static void psb__surface_usage( |
| psb_driver_data_p driver_data, |
| object_surface_p obj_surface, |
| int *decode, int *encode, int *rc_enable, int *proc |
| ) |
| { |
| object_context_p obj_context; |
| object_config_p obj_config; |
| VAEntrypoint tmp; |
| unsigned int eRCmode; |
| int i; |
| |
| |
| *decode = 0; |
| *encode = 0; |
| *rc_enable = 0; |
| *proc = 0; |
| |
| obj_context = CONTEXT(obj_surface->context_id); |
| if (NULL == obj_context) /* not associate with a context */ |
| return; |
| |
| obj_config = CONFIG(obj_context->config_id); |
| if (NULL == obj_config) /* not have a validate context */ |
| return; |
| |
| tmp = obj_config->entrypoint; |
| |
| *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture); |
| *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking); |
| #ifdef PSBVIDEO_MRFL_VPP |
| *proc = (VAEntrypointVideoProc == tmp); |
| #endif |
| |
| if (*encode) { |
| for (i = 0; i < obj_config->attrib_count; i++) { |
| if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) |
| break; |
| } |
| |
| if (i >= obj_config->attrib_count) |
| eRCmode = VA_RC_NONE; |
| else |
| eRCmode = obj_config->attrib_list[i].value; |
| |
| if (eRCmode == VA_RC_NONE) |
| *rc_enable = 0; |
| else |
| *rc_enable = 1; |
| } |
| } |
| |
| VAStatus psb_SyncSurface( |
| VADriverContextP ctx, |
| VASurfaceID render_target |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_surface_p obj_surface; |
| int decode = 0, encode = 0, rc_enable = 0, proc = 0; |
| object_context_p obj_context = NULL; |
| object_config_p obj_config = NULL; |
| |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target); |
| |
| obj_surface = SURFACE(render_target); |
| CHECK_SURFACE(obj_surface); |
| |
| obj_context = CONTEXT(obj_surface->context_id); |
| if (obj_context) { |
| obj_config = CONFIG(obj_context->config_id); |
| } |
| |
| /* The cur_displaying_surface indicates the surface being displayed by overlay. |
| * The diaplay_timestamp records the time point of put surface, which would |
| * be set to zero while using texture blit.*/ |
| |
| /* don't use mutex here for performance concern... */ |
| //pthread_mutex_lock(&output->output_mutex); |
| if (render_target == driver_data->cur_displaying_surface) |
| vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING; |
| else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */ |
| && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/ |
| object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface); |
| /* The flip operation on current displaying surface could be delayed to |
| * next VBlank and hadn't been finished yet. Then, the last displaying |
| * surface shouldn't be freed, because the hardware may not |
| * complete loading data of it. Any change of the last surface could |
| * have a impect on the scrren.*/ |
| if (NULL != cur_obj_surface) { |
| while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY) |
| usleep(PSB_MAX_FLIP_DELAY * 1000); |
| } |
| } |
| //pthread_mutex_unlock(&output->output_mutex); |
| |
| if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) { |
| #ifdef PSBVIDEO_MRFL_VPP_ROTATE |
| /* For VPP buffer, will sync the rotated buffer */ |
| if (obj_config && obj_config->entrypoint == VAEntrypointVideoProc) { |
| if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) && |
| (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) && |
| obj_surface->out_loop_surface) |
| vaStatus = psb_surface_sync(obj_surface->out_loop_surface); |
| else |
| vaStatus = psb_surface_sync(obj_surface->psb_surface); |
| } else |
| #endif |
| vaStatus = psb_surface_sync(obj_surface->psb_surface); |
| } |
| |
| /* report any error of decode for Android */ |
| psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc); |
| #if 0 |
| if (decode && IS_MRST(driver_data)) { |
| struct drm_lnc_video_getparam_arg arg; |
| uint32_t ret, handle, fw_status = 0; |
| handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf)); |
| arg.key = IMG_VIDEO_DECODE_STATUS; |
| arg.arg = (uint64_t)((unsigned long) & handle); |
| arg.value = (uint64_t)((unsigned long) & fw_status); |
| ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, |
| &arg, sizeof(arg)); |
| if (ret == 0) { |
| if (fw_status != 0) |
| vaStatus = VA_STATUS_ERROR_DECODING_ERROR; |
| } else { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n"); |
| vaStatus = VA_STATUS_ERROR_UNKNOWN; |
| } |
| } else if (proc && IS_MRFL(driver_data)) { |
| /* FIXME: does it need a new surface sync mechanism for FRC? */ |
| } |
| #endif |
| if (proc && IS_MRFL(driver_data)) { |
| /* FIXME: does it need a new surface sync mechanism for FRC? */ |
| } |
| |
| //psb__dump_NV_buffers(obj_surface->psb_surface, 0, 0, obj_surface->width, obj_surface->height); |
| //psb__dump_NV_buffers(obj_surface->psb_surface_rotate, 0, 0, obj_surface->height, ((obj_surface->width + 0x1f) & (~0x1f))); |
| if (obj_surface->scaling_surface) |
| psb__dump_NV12_buffers(obj_surface->scaling_surface, 0, 0, obj_surface->width_s, obj_surface->height_s); |
| DEBUG_FAILURE; |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| |
| VAStatus psb_QuerySurfaceStatus( |
| VADriverContextP ctx, |
| VASurfaceID render_target, |
| VASurfaceStatus *status /* out */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_surface_p obj_surface; |
| VASurfaceStatus surface_status; |
| int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0; |
| object_context_p obj_context = NULL; |
| |
| obj_surface = SURFACE(render_target); |
| CHECK_SURFACE(obj_surface); |
| |
| CHECK_INVALID_PARAM(status == NULL); |
| |
| psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc); |
| #ifdef PSBVIDEO_MRFL_VPP_ROTATE |
| /* For VPP 1080P, will query the rotated buffer */ |
| if (proc) { |
| obj_context = CONTEXT(obj_surface->context_id); |
| CHECK_CONTEXT(obj_context); |
| if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) && |
| (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) && |
| obj_surface->out_loop_surface) |
| vaStatus = psb_surface_query_status(obj_surface->out_loop_surface, &surface_status); |
| else |
| vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status); |
| } else |
| #endif |
| vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status); |
| |
| /* The cur_displaying_surface indicates the surface being displayed by overlay. |
| * The diaplay_timestamp records the time point of put surface, which would |
| * be set to zero while using texture blit.*/ |
| pthread_mutex_lock(&driver_data->output_mutex); |
| if (render_target == driver_data->cur_displaying_surface) |
| surface_status = VASurfaceDisplaying; |
| else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */ |
| && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/ |
| object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface); |
| /*The flip operation on current displaying surface could be delayed to |
| * next VBlank and hadn't been finished yet. Then, the last displaying |
| * surface shouldn't be freed, because the hardware may not |
| * complete loading data of it. Any change of the last surface could |
| * have a impect on the scrren.*/ |
| if ((NULL != cur_obj_surface) |
| && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) { |
| surface_status = VASurfaceDisplaying; |
| } |
| } |
| pthread_mutex_unlock(&driver_data->output_mutex); |
| |
| /* try to get frameskip flag for encode */ |
| #ifndef BAYTRAIL |
| if (!decode) { |
| /* The rendering surface may not be associated with any context. So driver should |
| check the frame skip flag even variable encode is 0 */ |
| #ifdef PSBVIDEO_MRFL |
| if (IS_MRFL(driver_data)) |
| tng_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); |
| else |
| #endif |
| pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); |
| |
| if (frame_skip == 1) { |
| surface_status = surface_status | VASurfaceSkipped; |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped", |
| __FUNCTION__, render_target); |
| } |
| } else |
| #endif |
| if (decode) { |
| #ifdef ANDROID |
| if (obj_surface->psb_surface->buf.handle) { |
| buffer_handle_t handle = obj_surface->psb_surface->buf.handle; |
| int display_status; |
| int err; |
| err = gralloc_getdisplaystatus(handle, &display_status); |
| if (!err) { |
| if (display_status) |
| surface_status = VASurfaceDisplaying; |
| else |
| surface_status = VASurfaceReady; |
| } else { |
| surface_status = VASurfaceReady; |
| } |
| |
| /* if not used by display, then check whether surface used by widi */ |
| if (surface_status == VASurfaceReady && obj_surface->share_info) { |
| if (obj_surface->share_info->renderStatus == 1) { |
| surface_status = VASurfaceDisplaying; |
| } |
| } |
| } |
| #endif |
| } else if (proc) { |
| /* FIXME: does it need a new surface sync mechanism for FRC? */ |
| } |
| |
| *status = surface_status; |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_QuerySurfaceError( |
| VADriverContextP ctx, |
| VASurfaceID render_target, |
| VAStatus error_status, |
| void **error_info /*out*/ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_surface_p obj_surface; |
| uint32_t i; |
| |
| obj_surface = SURFACE(render_target); |
| CHECK_SURFACE(obj_surface); |
| |
| #ifdef PSBVIDEO_MSVDX_EC |
| if (driver_data->ec_enabled == 0) { |
| #else |
| { |
| #endif |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n"); |
| error_info = NULL; |
| return VA_STATUS_ERROR_UNKNOWN; |
| } |
| |
| if (error_status == VA_STATUS_ERROR_DECODING_ERROR) { |
| drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status; |
| struct drm_lnc_video_getparam_arg arg; |
| uint32_t ret, handle; |
| handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf)); |
| |
| arg.key = IMG_VIDEO_MB_ERROR; |
| arg.arg = (uint64_t)((unsigned long) & handle); |
| arg.value = (uint64_t)((unsigned long)decode_status); |
| ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, |
| &arg, sizeof(arg)); |
| if (ret != 0) { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL,"return value is %d drmCommandWriteRead\n",ret); |
| return VA_STATUS_ERROR_UNKNOWN; |
| } |
| #ifndef _FOR_FPGA_ |
| if (decode_status->num_region > MAX_MB_ERRORS) { |
| drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n"); |
| return VA_STATUS_ERROR_UNKNOWN; |
| } |
| i = 0; |
| for (i = 0; i < decode_status->num_region; ++i) { |
| driver_data->surface_mb_error[i].status = 1; |
| driver_data->surface_mb_error[i].start_mb = decode_status->mb_regions[i].start; |
| driver_data->surface_mb_error[i].end_mb = decode_status->mb_regions[i].end; |
| //driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i]; |
| //driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i]; |
| //driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i]; |
| } |
| #endif |
| driver_data->surface_mb_error[i].status = -1; |
| *error_info = driver_data->surface_mb_error; |
| } else { |
| error_info = NULL; |
| return VA_STATUS_ERROR_UNKNOWN; |
| } |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| #define PSB_MAX_SURFACE_ATTRIBUTES 16 |
| |
| VAStatus psb_QuerySurfaceAttributes(VADriverContextP ctx, |
| VAConfigID config, |
| VASurfaceAttrib *attrib_list, |
| unsigned int *num_attribs) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| object_config_p obj_config; |
| unsigned int i = 0; |
| |
| CHECK_INVALID_PARAM(num_attribs == NULL); |
| |
| if (attrib_list == NULL) { |
| *num_attribs = PSB_MAX_SURFACE_ATTRIBUTES; |
| return VA_STATUS_SUCCESS; |
| } |
| |
| obj_config = CONFIG(config); |
| CHECK_CONFIG(obj_config); |
| |
| VASurfaceAttrib *attribs = NULL; |
| attribs = malloc(PSB_MAX_SURFACE_ATTRIBUTES *sizeof(VASurfaceAttrib)); |
| if (attribs == NULL) |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| |
| 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('N', 'V', '1', '2'); |
| i++; |
| |
| attribs[i].type = VASurfaceAttribMemoryType; |
| attribs[i].value.type = VAGenericValueTypeInteger; |
| attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE; |
| if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3) { |
| attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA | |
| VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM | |
| VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC | |
| VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION; |
| } else { |
| attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA | |
| VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM | |
| VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR | |
| VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC | |
| VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION; |
| } |
| i++; |
| |
| attribs[i].type = VASurfaceAttribExternalBufferDescriptor; |
| attribs[i].value.type = VAGenericValueTypePointer; |
| attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE; |
| attribs[i].value.value.p = NULL; |
| i++; |
| |
| //modules have speical formats to support |
| if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */ |
| |
| } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */ |
| obj_config->entrypoint == VAEntrypointEncPicture) { |
| #ifdef PSBVIDEO_MFLD |
| if (IS_MFLD(driver_data)) {} |
| #endif |
| #ifdef PSBVIDEO_MRFL |
| if (IS_MRFL(driver_data)) {} |
| #endif |
| #ifdef BAYTRAIL |
| if (IS_BAYTRAIL(driver_data)) {} |
| #endif |
| } |
| else if (obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */ |
| |
| } |
| |
| if (i > *num_attribs) { |
| *num_attribs = i; |
| if (attribs != NULL) |
| free(attribs); |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| |
| *num_attribs = i; |
| memcpy(attrib_list, attribs, i * sizeof(*attribs)); |
| free(attribs); |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_LockSurface( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| unsigned int *fourcc, /* following are output argument */ |
| unsigned int *luma_stride, |
| unsigned int *chroma_u_stride, |
| unsigned int *chroma_v_stride, |
| unsigned int *luma_offset, |
| unsigned int *chroma_u_offset, |
| unsigned int *chroma_v_offset, |
| unsigned int *buffer_name, |
| void **buffer |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| unsigned char *surface_data; |
| int ret; |
| |
| object_surface_p obj_surface = SURFACE(surface); |
| psb_surface_p psb_surface; |
| CHECK_SURFACE(obj_surface); |
| |
| psb_surface = obj_surface->psb_surface; |
| if (buffer_name) |
| *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); |
| |
| if (buffer) { /* map the surface buffer */ |
| uint32_t srf_buf_ofs = 0; |
| ret = psb_buffer_map(&psb_surface->buf, &surface_data); |
| if (ret) { |
| *buffer = NULL; |
| vaStatus = VA_STATUS_ERROR_UNKNOWN; |
| DEBUG_FAILURE; |
| return vaStatus; |
| } |
| srf_buf_ofs = psb_surface->buf.buffer_ofs; |
| *buffer = surface_data + srf_buf_ofs; |
| } |
| |
| *fourcc = VA_FOURCC_NV12; |
| *luma_stride = psb_surface->stride; |
| *chroma_u_stride = psb_surface->stride; |
| *chroma_v_stride = psb_surface->stride; |
| *luma_offset = 0; |
| *chroma_u_offset = obj_surface->height * psb_surface->stride; |
| *chroma_v_offset = obj_surface->height * psb_surface->stride + 1; |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| |
| VAStatus psb_UnlockSurface( |
| VADriverContextP ctx, |
| VASurfaceID surface |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| object_surface_p obj_surface = SURFACE(surface); |
| CHECK_SURFACE(obj_surface); |
| |
| psb_surface_p psb_surface = obj_surface->psb_surface; |
| |
| psb_buffer_unmap(&psb_surface->buf); |
| |
| DEBUG_FUNC_EXIT |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus psb_GetEGLClientBufferFromSurface( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| void **buffer |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| object_surface_p obj_surface = SURFACE(surface); |
| CHECK_SURFACE(obj_surface); |
| |
| psb_surface_p psb_surface = obj_surface->psb_surface; |
| *buffer = (unsigned char *)psb_surface->bc_buffer; |
| |
| DEBUG_FUNC_EXIT |
| return vaStatus; |
| } |
| |
| VAStatus psb_PutSurfaceBuf( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| unsigned char __maybe_unused * data, |
| int __maybe_unused * data_len, |
| short __maybe_unused srcx, |
| short __maybe_unused srcy, |
| unsigned short __maybe_unused srcw, |
| unsigned short __maybe_unused srch, |
| short __maybe_unused destx, |
| short __maybe_unused desty, |
| unsigned short __maybe_unused destw, |
| unsigned short __maybe_unused desth, |
| VARectangle __maybe_unused * cliprects, /* client supplied clip list */ |
| unsigned int __maybe_unused number_cliprects, /* number of clip rects in the clip list */ |
| unsigned int __maybe_unused flags /* de-interlacing flags */ |
| ) |
| { |
| DEBUG_FUNC_ENTER |
| INIT_DRIVER_DATA; |
| object_surface_p obj_surface = SURFACE(surface); |
| psb_surface_p psb_surface; |
| |
| obj_surface = SURFACE(surface); |
| if (obj_surface == NULL) |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| |
| psb_surface = obj_surface->psb_surface; |
| |
| #if 0 |
| psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */ |
| obj_surface->width, obj_surface->height, |
| psb_surface->stride |