summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShalaj Jain <shalajj@codeaurora.org>2016-01-25 12:43:40 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-03-24 11:38:53 -0700
commitc1c9a542c7d1e6a6069b0519c64fdce9314f8d2e (patch)
treea089cff23f2020fb44c62af123297998d20c87b5
parent4c809c2302a7ad94d669d82549c802a6f8abfd46 (diff)
downloadandroid_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.h1
-rw-r--r--mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp107
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);
+ }
+}
+