aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Hu <austin.hu@intel.com>2016-11-14 13:57:40 +0800
committerNick Desaulniers <ndesaulniers@google.com>2016-11-23 15:04:25 -0800
commit06e002d2cd1c3698b9ce4c96363a67e60e62707b (patch)
treed67c54f2268514d7b971114d1728e0a90ef8cdc4
parenta805f1c63455a00883e066119fb0c5d533d3a116 (diff)
downloadpsb_video-06e002d2cd1c3698b9ce4c96363a67e60e62707b.tar.gz
Bug: 32721372 BZ: IMINAN-51199 During the decoding process, there're >= 2 threads (such as ISV and MediaCodec) which may share the same gralloc buffer (obj_surface->share_info), although their allocated surfaces belong to each corresponding decoding context. So fixed the random issue by registering (referencing) the gralloc buffer before locking it (for read/write), to avoid its potential free by other processes/threads. And the gralloc HAL would defer to free the buffer once all of the registered processes or threads have unregistered it. Change-Id: Ied970b0e9a9de512cec9e0841a591cc4d98e327d Signed-off-by: Austin Hu <austin.hu@intel.com>
-rw-r--r--src/android/psb_gralloc.cpp48
-rw-r--r--src/android/psb_gralloc.h4
-rw-r--r--src/android/psb_surface_gralloc.c171
3 files changed, 141 insertions, 82 deletions
diff --git a/src/android/psb_gralloc.cpp b/src/android/psb_gralloc.cpp
index ff21242..a920fd5 100644
--- a/src/android/psb_gralloc.cpp
+++ b/src/android/psb_gralloc.cpp
@@ -129,6 +129,54 @@ int gralloc_unlock(buffer_handle_t handle)
return err;
}
+int gralloc_register(buffer_handle_t handle)
+{
+ int err = 0;
+
+ if (!mAllocMod) {
+ ALOGW("%s: gralloc module has not been initialized.", __func__);
+ if (gralloc_init()) {
+ ALOGE("%s: can't find the %s module", __func__,
+ GRALLOC_HARDWARE_MODULE_ID);
+ return -1;
+ }
+ }
+
+ err = mAllocMod->registerBuffer(mAllocMod, handle);
+ if (err) {
+ ALOGE("%s failed with %d (%s).\n", __func__, err, strerror(-err));
+ return -1;
+ } else {
+ ALOGV("registered buffer %p successfully\n", handle);
+ }
+
+ return err;
+}
+
+int gralloc_unregister(buffer_handle_t handle)
+{
+ int err = 0;
+
+ if (!mAllocMod) {
+ ALOGW("%s: gralloc module has not been initialized.", __func__);
+ if (gralloc_init()) {
+ ALOGE("%s: can't find the %s module", __func__,
+ GRALLOC_HARDWARE_MODULE_ID);
+ return -1;
+ }
+ }
+
+ err = mAllocMod->unregisterBuffer(mAllocMod, handle);
+ if (err) {
+ ALOGE("%s failed with %d (%s).\n", __func__, err, strerror(-err));
+ return -1;
+ } else {
+ ALOGV("unregistered buffer %p successfully\n", handle);
+ }
+
+ return err;
+}
+
int gralloc_init(void)
{
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
diff --git a/src/android/psb_gralloc.h b/src/android/psb_gralloc.h
index 461070d..678e0ca 100644
--- a/src/android/psb_gralloc.h
+++ b/src/android/psb_gralloc.h
@@ -41,6 +41,10 @@ int gralloc_lock(buffer_handle_t handle, int usage,
int gralloc_unlock(buffer_handle_t handle);
+int gralloc_register(buffer_handle_t handle);
+
+int gralloc_unregister(buffer_handle_t handle);
+
int gralloc_init(void);
int gralloc_getdisplaystatus(buffer_handle_t handle, int* status);
diff --git a/src/android/psb_surface_gralloc.c b/src/android/psb_surface_gralloc.c
index bc3dc29..5f994ee 100644
--- a/src/android/psb_surface_gralloc.c
+++ b/src/android/psb_surface_gralloc.c
@@ -60,6 +60,7 @@ VAStatus psb_DestroySurfaceGralloc(object_surface_p obj_surface)
void *vaddr[GRALLOC_SUB_BUFFER_MAX];
int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER;
buffer_handle_t handle = obj_surface->psb_surface->buf.handle;
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
#ifdef PSBVIDEO_MRFL
usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
@@ -82,10 +83,13 @@ VAStatus psb_DestroySurfaceGralloc(object_surface_p obj_surface)
obj_surface->share_info->bob_deinterlace = bob_deinterlace;
}
gralloc_unlock(handle);
+
+ if (gralloc_unregister(handle))
+ vaStatus = VA_STATUS_ERROR_UNKNOWN;
}
pthread_mutex_unlock(&gralloc_mutex);
- return VA_STATUS_SUCCESS;
+ return vaStatus;
}
#ifdef BAYTRAIL
@@ -364,100 +368,103 @@ VAStatus psb_CreateSurfacesFromGralloc(
handle = (unsigned long)external_buffers->buffers[i];
pthread_mutex_lock(&gralloc_mutex);
- if (gralloc_lock((buffer_handle_t)handle, usage, 0, 0, width, height, (void **)&vaddr[GRALLOC_SUB_BUFFER0])) {
- vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ if (gralloc_register((buffer_handle_t)handle)) {
+ vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
} else {
- int cache_flag = PSB_USER_BUFFER_UNCACHED;
- int buf_fd = gralloc_getbuffd((buffer_handle_t)handle);
+ if (gralloc_lock((buffer_handle_t)handle, usage, 0, 0, width, height, (void **)&vaddr[GRALLOC_SUB_BUFFER0])) {
+ vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ gralloc_unregister((buffer_handle_t)handle);
+ } else {
+ int cache_flag = PSB_USER_BUFFER_UNCACHED;
+ int buf_fd = gralloc_getbuffd((buffer_handle_t)handle);
#ifdef PSBVIDEO_MRFL
- //cache_flag = 0;
+ //cache_flag = 0;
#endif
- vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
- (VASurfaceAttributeTPI *)external_buffers, psb_surface,
- vaddr[GRALLOC_SUB_BUFFER0], buf_fd, cache_flag);
- psb_surface->buf.handle = (void *)handle;
- obj_surface->share_info = NULL;
-
- if ((gfx_colorformat != HAL_PIXEL_FORMAT_NV12) &&
- (gfx_colorformat != HAL_PIXEL_FORMAT_YV12) &&
- (format != VA_RT_FORMAT_RGB32)) {
-
- unsigned int decoder_share_info = (unsigned int)external_buffers->reserved[2];
- drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : Create graphic buffer initialized share info %d",__FUNCTION__, decoder_share_info);
- obj_surface->share_info = (psb_surface_share_info_t *)vaddr[GRALLOC_SUB_BUFFER1];
-
- if (obj_surface->share_info->initialized != SHARE_INFO_INIT_VALUE) {
- memset(obj_surface->share_info, 0, sizeof(struct psb_surface_share_info_s));
- // Set clear video the default output method as OUTPUT_FORCE_OVERLAY_FOR_SW_DECODE
- // if the video can be decoded by HW, will reset the output method as 0 in psb_BeginPicture
+ vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
+ (VASurfaceAttributeTPI *)external_buffers, psb_surface,
+ vaddr[GRALLOC_SUB_BUFFER0], buf_fd, cache_flag);
+ psb_surface->buf.handle = (void *)handle;
+ obj_surface->share_info = NULL;
+
+ if ((gfx_colorformat != HAL_PIXEL_FORMAT_NV12) &&
+ (gfx_colorformat != HAL_PIXEL_FORMAT_YV12) &&
+ (format != VA_RT_FORMAT_RGB32)) {
+ unsigned int decoder_share_info = (unsigned int)external_buffers->reserved[2];
+ drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : Create graphic buffer initialized share info %d", __FUNCTION__, decoder_share_info);
+ obj_surface->share_info = (psb_surface_share_info_t *)vaddr[GRALLOC_SUB_BUFFER1];
+
+ if (obj_surface->share_info->initialized != SHARE_INFO_INIT_VALUE) {
+ memset(obj_surface->share_info, 0, sizeof(struct psb_surface_share_info_s));
+ // Set clear video the default output method as OUTPUT_FORCE_OVERLAY_FOR_SW_DECODE
+ // if the video can be decoded by HW, will reset the output method as 0 in psb_BeginPicture
#ifdef PSBVIDEO_MSVDX_DEC_TILING
- obj_surface->share_info->tiling = external_buffers->tiling;
+ obj_surface->share_info->tiling = external_buffers->tiling;
#endif
- obj_surface->share_info->width = obj_surface->width;
- obj_surface->share_info->height = obj_surface->height_origin;
+ obj_surface->share_info->width = obj_surface->width;
+ obj_surface->share_info->height = obj_surface->height_origin;
- obj_surface->share_info->luma_stride = psb_surface->stride;
- obj_surface->share_info->chroma_u_stride = psb_surface->stride;
- obj_surface->share_info->chroma_v_stride = psb_surface->stride;
- obj_surface->share_info->format = VA_FOURCC_NV12;
+ obj_surface->share_info->luma_stride = psb_surface->stride;
+ obj_surface->share_info->chroma_u_stride = psb_surface->stride;
+ obj_surface->share_info->chroma_v_stride = psb_surface->stride;
+ obj_surface->share_info->format = VA_FOURCC_NV12;
- obj_surface->share_info->khandle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
+ obj_surface->share_info->khandle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
- obj_surface->share_info->initialized = SHARE_INFO_INIT_VALUE;
- }
-
- if (decoder_share_info) {
- obj_surface->share_info->force_output_method = protected ? OUTPUT_FORCE_OVERLAY : OUTPUT_FORCE_OVERLAY_FOR_SW_DECODE;
- obj_surface->share_info->native_window = (void *)external_buffers->reserved[0];
-
- attribute_tpi->reserved[1] = (unsigned long)obj_surface->share_info;
-
- if (vaddr[GRALLOC_SUB_BUFFER0] == NULL) {
- drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to lock graphic buffer in psb_video");
- }
- else {
- size = psb_surface->chroma_offset;
- // the following memset was used to work-around Bug 19197299 on L.
- // on DDK-1.5 we didn't observe the problem so comment it out.
- // memset((char *)vaddr[GRALLOC_SUB_BUFFER0], 0, size);
- // memset((char *)vaddr[GRALLOC_SUB_BUFFER0] + size, 0x80, psb_surface->size - size);
- }
- // overlay only support BT.601 and BT.709
- if (driver_data->load_csc_matrix == 1) {
- obj_surface->share_info->csc_mode = (driver_data->is_BT601 == 1) ? 0 : 1;
- } else {
- // if csc matrix is not set, use BT601 by default
- obj_surface->share_info->csc_mode = 0;
+ obj_surface->share_info->initialized = SHARE_INFO_INIT_VALUE;
}
- if (driver_data->set_video_range == 1) {
- obj_surface->share_info->video_range = driver_data->video_range;
- } else {
- // if video range is not set, use limited range by default
- obj_surface->share_info->video_range = 0;
+ if (decoder_share_info) {
+ obj_surface->share_info->force_output_method = protected ? OUTPUT_FORCE_OVERLAY : OUTPUT_FORCE_OVERLAY_FOR_SW_DECODE;
+ obj_surface->share_info->native_window = (void *)external_buffers->reserved[0];
+
+ attribute_tpi->reserved[1] = (unsigned long)obj_surface->share_info;
+
+ if (vaddr[GRALLOC_SUB_BUFFER0] == NULL) {
+ drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to lock graphic buffer in psb_video");
+ } else {
+ size = psb_surface->chroma_offset;
+ // the following memset was used to work-around Bug 19197299 on L.
+ // on DDK-1.5 we didn't observe the problem so comment it out.
+ // memset((char *)vaddr[GRALLOC_SUB_BUFFER0], 0, size);
+ // memset((char *)vaddr[GRALLOC_SUB_BUFFER0] + size, 0x80, psb_surface->size - size);
+ }
+ // overlay only support BT.601 and BT.709
+ if (driver_data->load_csc_matrix == 1) {
+ obj_surface->share_info->csc_mode = (driver_data->is_BT601 == 1) ? 0 : 1;
+ } else {
+ // if csc matrix is not set, use BT601 by default
+ obj_surface->share_info->csc_mode = 0;
+ }
+
+ if (driver_data->set_video_range == 1) {
+ obj_surface->share_info->video_range = driver_data->video_range;
+ } else {
+ // if video range is not set, use limited range by default
+ obj_surface->share_info->video_range = 0;
+ }
+
+ obj_surface->share_info->surface_protected = driver_data->protected;
+ if (driver_data->render_rect.width == 0 || driver_data->render_rect.height == 0) {
+ obj_surface->share_info->crop_width = obj_surface->share_info->width;
+ obj_surface->share_info->crop_height = obj_surface->share_info->height;
+ } else {
+ obj_surface->share_info->crop_width = driver_data->render_rect.width;
+ obj_surface->share_info->crop_height = driver_data->render_rect.height;
+ }
+
+ if (obj_surface->share_info->coded_width == 0 || obj_surface->share_info->coded_height == 0) {
+ obj_surface->share_info->coded_width = (obj_surface->share_info->width + 0xf) & ~0xf;
+ obj_surface->share_info->coded_height = (obj_surface->share_info->height + 0xf) & ~0xf;
+ }
+
+ drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : Create graphic buffer success"
+ "surface_id= 0x%x, vaddr[0] (0x%x), vaddr[1] (0x%x)\n",
+ __FUNCTION__, surfaceID, vaddr[GRALLOC_SUB_BUFFER0], vaddr[GRALLOC_SUB_BUFFER1]);
}
-
- obj_surface->share_info->surface_protected = driver_data->protected;
- if (driver_data->render_rect.width == 0 || driver_data->render_rect.height == 0) {
- obj_surface->share_info->crop_width = obj_surface->share_info->width;
- obj_surface->share_info->crop_height = obj_surface->share_info->height;
- } else {
- obj_surface->share_info->crop_width = driver_data->render_rect.width;
- obj_surface->share_info->crop_height = driver_data->render_rect.height;
- }
-
- if (obj_surface->share_info->coded_width == 0 || obj_surface->share_info->coded_height == 0) {
- obj_surface->share_info->coded_width = (obj_surface->share_info->width + 0xf) & ~0xf;
- obj_surface->share_info->coded_height = (obj_surface->share_info->height + 0xf) & ~0xf;
- }
-
- drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : Create graphic buffer success"
- "surface_id= 0x%x, vaddr[0] (0x%x), vaddr[1] (0x%x)\n",
- __FUNCTION__, surfaceID, vaddr[GRALLOC_SUB_BUFFER0], vaddr[GRALLOC_SUB_BUFFER1]);
}
+ gralloc_unlock((buffer_handle_t)handle);
+ psb_surface->buf.user_ptr = NULL;
}
- gralloc_unlock((buffer_handle_t)handle);
- psb_surface->buf.user_ptr = NULL;
}
pthread_mutex_unlock(&gralloc_mutex);