diff options
author | Shalaj Jain <shalajj@codeaurora.org> | 2016-01-25 12:43:40 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-03-24 11:38:53 -0700 |
commit | c1c9a542c7d1e6a6069b0519c64fdce9314f8d2e (patch) | |
tree | a089cff23f2020fb44c62af123297998d20c87b5 | |
parent | 4c809c2302a7ad94d669d82549c802a6f8abfd46 (diff) | |
download | android_hardware_qcom_media-c1c9a542c7d1e6a6069b0519c64fdce9314f8d2e.tar.gz android_hardware_qcom_media-c1c9a542c7d1e6a6069b0519c64fdce9314f8d2e.tar.bz2 android_hardware_qcom_media-c1c9a542c7d1e6a6069b0519c64fdce9314f8d2e.zip |
mm-video-v4l2: vdec: Add support for prefetching secure memory
Call an ioctl to ION to prefetch memory required for next resolution
when a resolution change is detetced. This is done to reduce
allocation times and avoid glitches.
Change-Id: I0b787f6f2b5c5ed497ae5643e2a21c4eb25ee411
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 1 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp | 107 |
2 files changed, 108 insertions, 0 deletions
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 7b29ac72..23b8d329 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -1157,6 +1157,7 @@ class omx_vdec: public qc_omx_component } static OMX_ERRORTYPE describeColorFormat(OMX_PTR params); + void prefetchNewBuffers(); }; diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp index 9d25d97d..b44adb21 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp @@ -1664,6 +1664,10 @@ void omx_vdec::process_event_cb(void *ctxt, unsigned char id) pThis->m_debug.out_uvmeta_file = NULL; } + if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) { + pThis->prefetchNewBuffers(); + } + if (pThis->m_cb.EventHandler) { uint32_t frame_data[2]; frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ? @@ -7189,6 +7193,7 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, //We'll restore this size later on, so that it's transparent to client buffer->nFilledLen = 0; buffer->nAllocLen = handle->size; + drv_ctx.op_buf.buffer_size = handle->size; } @@ -11851,3 +11856,105 @@ OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) { #endif //FLEXYUV_SUPPORTED } +void omx_vdec::prefetchNewBuffers() { + + struct v4l2_decoder_cmd dec; + uint32_t prefetch_count; + uint32_t prefetch_size; + uint32_t want_size; + uint32_t have_size; + int color_fmt; + uint32_t new_calculated_size; + uint32_t new_buffer_size; + uint32_t new_buffer_count; + uint32_t old_buffer_size; + uint32_t old_buffer_count; + + memset((void *)&dec, 0 , sizeof(dec)); + DEBUG_PRINT_LOW("Old size : %d, count : %d, width : %u, height : %u\n", + drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount, + drv_ctx.video_resolution.frame_width, + drv_ctx.video_resolution.frame_height); + dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT; + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { + DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno); + } else { + DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n", + dec.raw.data[0], dec.raw.data[1]); + } + + switch ((int)drv_ctx.output_format) { + case VDEC_YUV_FORMAT_NV12: + color_fmt = COLOR_FMT_NV12; + break; + case VDEC_YUV_FORMAT_NV12_UBWC: + color_fmt = COLOR_FMT_NV12_UBWC; + break; + default: + color_fmt = -1; + } + + new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height); + DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n", + m_reconfig_width, m_reconfig_height, new_calculated_size); + new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size; + new_buffer_count = dec.raw.data[1]; + old_buffer_size = drv_ctx.op_buf.buffer_size; + old_buffer_count = drv_ctx.op_buf.actualcount; + + /* + if (new_buffer_count == old_buffer_count) { + prefetch_size = new_buffer_size - old_buffer_size; + DEBUG_PRINT_LOW("Got same count!"); + } else { + prefetch_size = (want_size - have_size) / prefetch_count; + }*/ + new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count; + + prefetch_count = new_buffer_count; + prefetch_size = new_buffer_size - old_buffer_size; + want_size = new_buffer_size * new_buffer_count; + have_size = old_buffer_size * old_buffer_count; + + if (want_size > have_size) { + DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size); + DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size); + + int ion_fd = open(MEM_DEVICE, O_RDONLY); + if (ion_fd < 0) { + DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd); + } + + struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data)); + struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data)); + struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions) * 1); + size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count); + + for (uint32_t i = 0; i < prefetch_count; i++) { + sizes[i] = prefetch_size; + } + + regions[0].nr_sizes = prefetch_count; + regions[0].sizes = sizes; + regions[0].vmid = ION_FLAG_CP_PIXEL; + + prefetch_data->nr_regions = 1; + prefetch_data->regions = regions; + prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID); + + custom_data->cmd = ION_IOC_PREFETCH; + custom_data->arg = (unsigned long )prefetch_data; + + int rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data); + if (rc) { + DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno); + } + + close(ion_fd); + free(sizes); + free(regions); + free(prefetch_data); + free(custom_data); + } +} + |