From 13c5034a859bd548c64b44a7f64e95b6d71016ff Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 9 Jun 2020 21:33:13 +0800 Subject: [PATCH] gralloc_gbm: add .lock_ycbcr to support video playback use case The .lock_ycbcr function hook is currently missing from gralloc driver, and that stops video playback from working. Add a .lock_ycbcr function implementation to get SW video playback test start working, where HAL_PIXEL_FORMAT_YV12 format is used/tested. Signed-off-by: Shawn Guo [AmitP: Verified by playing a mp4 format file using s/w codec (medaswcodec) on db845c running AOSP.] Signed-off-by: Amit Pundir --- gralloc.cpp | 14 ++++++++++++++ gralloc_gbm.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ gralloc_gbm_priv.h | 2 ++ 3 files changed, 63 insertions(+) diff --git a/gralloc.cpp b/gralloc.cpp index 538f908..1cc9f55 100644 --- a/gralloc.cpp +++ b/gralloc.cpp @@ -150,6 +150,19 @@ static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle) return err; } +static int gbm_mod_lock_ycbcr(gralloc_module_t const *mod, buffer_handle_t handle, + int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr) +{ + struct gbm_module_t *dmod = (struct gbm_module_t *) mod; + int err; + + pthread_mutex_lock(&dmod->mutex); + err = gralloc_gbm_bo_lock_ycbcr(handle, usage, x, y, w, h, ycbcr); + pthread_mutex_unlock(&dmod->mutex); + + return err; +} + static int gbm_mod_close_gpu0(struct hw_device_t *dev) { struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module; @@ -251,6 +264,7 @@ struct gbm_module_t HAL_MODULE_INFO_SYM = { .unregisterBuffer = gbm_mod_unregister_buffer, .lock = gbm_mod_lock, .unlock = gbm_mod_unlock, + .lock_ycbcr = gbm_mod_lock_ycbcr, .perform = gbm_mod_perform }, diff --git a/gralloc_gbm.cpp b/gralloc_gbm.cpp index 52ca974..f5729b9 100644 --- a/gralloc_gbm.cpp +++ b/gralloc_gbm.cpp @@ -482,3 +482,50 @@ int gralloc_gbm_bo_unlock(buffer_handle_t handle) return 0; } + +#define GRALLOC_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1)) + +int gralloc_gbm_bo_lock_ycbcr(buffer_handle_t handle, + int usage, int x, int y, int w, int h, + struct android_ycbcr *ycbcr) +{ + struct gralloc_handle_t *hnd = gralloc_handle(handle); + int ystride, cstride; + void *addr; + int err; + + ALOGD("handle %p, hnd %p, usage 0x%x", handle, hnd, usage); + + err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, &addr); + if (err) + return err; + + memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); + + switch (hnd->format) { + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + ystride = cstride = GRALLOC_ALIGN(hnd->width, 16); + ycbcr->y = addr; + ycbcr->cr = (unsigned char *)addr + ystride * hnd->height; + ycbcr->cb = (unsigned char *)addr + ystride * hnd->height + 1; + ycbcr->ystride = ystride; + ycbcr->cstride = cstride; + ycbcr->chroma_step = 2; + break; + case HAL_PIXEL_FORMAT_YV12: + ystride = hnd->width; + cstride = GRALLOC_ALIGN(ystride / 2, 16); + ycbcr->y = addr; + ycbcr->cr = (unsigned char *)addr + ystride * hnd->height; + ycbcr->cb = (unsigned char *)addr + ystride * hnd->height + cstride * hnd->height / 2; + ycbcr->ystride = ystride; + ycbcr->cstride = cstride; + ycbcr->chroma_step = 1; + break; + default: + ALOGE("Can not lock buffer, invalid format: 0x%x", hnd->format); + return -EINVAL; + } + + return 0; +} diff --git a/gralloc_gbm_priv.h b/gralloc_gbm_priv.h index d0326c5..cbe9256 100644 --- a/gralloc_gbm_priv.h +++ b/gralloc_gbm_priv.h @@ -45,6 +45,8 @@ int gralloc_gbm_get_gem_handle(buffer_handle_t handle); int gralloc_gbm_bo_lock(buffer_handle_t handle, int usage, int x, int y, int w, int h, void **addr); int gralloc_gbm_bo_unlock(buffer_handle_t handle); +int gralloc_gbm_bo_lock_ycbcr(buffer_handle_t handle, int usage, + int x, int y, int w, int h, struct android_ycbcr *ycbcr); struct gbm_device *gbm_dev_create(void); void gbm_dev_destroy(struct gbm_device *gbm);