mm-video-v4l2: Add support for AllocateNativeHandle extension

Add support for AllocateNativeHandle extension on
secure encoder's session output port.

Change-Id: Ie48a52dbc487634df9cf81d970c047cf1c930063
diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index b2e21af..2f4d0f9 100644
--- a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -691,6 +691,8 @@
         int pending_input_buffers;
         int pending_output_buffers;
 
+        bool allocate_native_handle;
+
         uint64_t m_out_bm_count;
         uint64_t m_inp_bm_count;
         uint64_t m_flags;
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index 2c94cc9..5175d99 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -2467,6 +2467,12 @@
         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
         return OMX_ErrorNone;
     }
+
+    if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
+        *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
+        return OMX_ErrorNone;
+    }
+
     return OMX_ErrorNotImplemented;
 }
 
@@ -3044,11 +3050,18 @@
                 munmap (m_pOutput_pmem[index].buffer,
                         m_pOutput_pmem[index].size);
             } else {
-                char *data = (char*) m_pOutput_pmem[index].buffer;
-                native_handle_t *handle = NULL;
-                memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
-                native_handle_delete(handle);
-                free(m_pOutput_pmem[index].buffer);
+                if (allocate_native_handle) {
+                    native_handle_t *handle = NULL;
+                    handle = (native_handle_t *)m_pOutput_pmem[index].buffer;
+                    native_handle_close(handle);
+                    native_handle_delete(handle);
+                } else {
+                    char *data = (char*) m_pOutput_pmem[index].buffer;
+                    native_handle_t *handle = NULL;
+                    memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
+                    native_handle_delete(handle);
+                    free(m_pOutput_pmem[index].buffer);
+                }
             }
             close (m_pOutput_pmem[index].fd);
 #ifdef USE_ION
@@ -3439,24 +3452,37 @@
             else {
                 //This should only be used for passing reference to source type and
                 //secure handle fd struct native_handle_t*
-                native_handle_t *handle = native_handle_create(1, 3); //fd, offset, size, alloc length
-                if (!handle) {
-                    DEBUG_PRINT_ERROR("ERROR: native handle creation failed");
-                    return OMX_ErrorInsufficientResources;
+                if (allocate_native_handle) {
+                    native_handle_t *nh = native_handle_create(1 /*numFds*/, 3 /*numInts*/);
+                    if (!nh) {
+                        DEBUG_PRINT_ERROR("Native handle create failed");
+                        return OMX_ErrorInsufficientResources;
+                    }
+                    nh->data[0] = m_pOutput_pmem[i].fd;
+                    nh->data[1] = 0;
+                    nh->data[2] = 0;
+                    nh->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
+                    m_pOutput_pmem[i].buffer = (OMX_U8 *)nh;
+                } else {
+                    native_handle_t *handle = native_handle_create(1, 3); //fd, offset, size, alloc length
+                    if (!handle) {
+                        DEBUG_PRINT_ERROR("ERROR: native handle creation failed");
+                        return OMX_ErrorInsufficientResources;
+                    }
+                    m_pOutput_pmem[i].buffer = malloc(sizeof(output_metabuffer));
+                    if (m_pOutput_pmem[i].buffer == NULL) {
+                        DEBUG_PRINT_ERROR("%s: Failed to allocate meta buffer", __func__);
+                        return OMX_ErrorInsufficientResources;
+                    }
+                    (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
+                    handle->data[0] = m_pOutput_pmem[i].fd;
+                    handle->data[1] = 0;
+                    handle->data[2] = 0;
+                    handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
+                    output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
+                    buffer->type = 1;
+                    buffer->nh = handle;
                 }
-                m_pOutput_pmem[i].buffer = malloc(sizeof(output_metabuffer));
-                if (m_pOutput_pmem[i].buffer == NULL) {
-                    DEBUG_PRINT_ERROR("%s: Failed to allocate meta buffer", __func__);
-                    return OMX_ErrorInsufficientResources;
-                }
-                (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
-                handle->data[0] = m_pOutput_pmem[i].fd;
-                handle->data[1] = 0;
-                handle->data[2] = 0;
-                handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
-                output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
-                buffer->type = 1;
-                buffer->nh = handle;
             }
 
             (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index a23218f..1598a93 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -1148,6 +1148,31 @@
                 break;
 
             }
+        case OMX_GoogleAndroidIndexAllocateNativeHandle:
+            {
+                VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
+
+                AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
+
+                if (!secure_session) {
+                    DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only in secure session");
+                    eRet = OMX_ErrorUnsupportedSetting;
+                    break;
+                } else if (allocateNativeHandleParams->nPortIndex != PORT_INDEX_OUT) {
+                    DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on Output port!");
+                    eRet = OMX_ErrorUnsupportedSetting;
+                    break;
+                } else if (m_out_mem_ptr) {
+                    DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Output port is not free !");
+                    eRet = OMX_ErrorInvalidState;
+                    break;
+                }
+
+                if (allocateNativeHandleParams != NULL) {
+                    allocate_native_handle = allocateNativeHandleParams->enable;
+                }
+                break;
+            }
         case OMX_IndexParamVideoQuantization:
             {
                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
@@ -1292,14 +1317,9 @@
                         }
                     }
                 } else if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session) {
-                    if (pParam->bStoreMetaData != meta_mode_enable) {
-                        if (!handle->venc_set_meta_mode(pParam->bStoreMetaData)) {
-                            DEBUG_PRINT_ERROR("\nERROR: set Metabuffer mode %d fail",
-                                    pParam->bStoreMetaData);
+                            DEBUG_PRINT_ERROR("set_parameter: metamode is "
+                            "valid for input port only in secure session");
                             return OMX_ErrorUnsupportedSetting;
-                        }
-                        meta_mode_enable = pParam->bStoreMetaData;
-                    }
                 } else {
                     DEBUG_PRINT_ERROR("set_parameter: metamode is "
                             "valid for input port only");
@@ -2622,13 +2642,22 @@
                                 m_sVenc_msg->buf.len);
                     }
                 } else if (omx->is_secure_session()) {
-                    output_metabuffer *meta_buf = (output_metabuffer *)(omxhdr->pBuffer);
-                    native_handle_t *nh = meta_buf->nh;
-                    nh->data[1] = m_sVenc_msg->buf.offset;
-                    nh->data[2] = m_sVenc_msg->buf.len;
-                    omxhdr->nFilledLen = sizeof(output_metabuffer);
-                    omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp;
-                    omxhdr->nFlags = m_sVenc_msg->buf.flags;
+                    if (omx->allocate_native_handle) {
+                        native_handle_t *nh = (native_handle_t *)(omxhdr->pBuffer);
+                        nh->data[1] = m_sVenc_msg->buf.offset;
+                        nh->data[2] = m_sVenc_msg->buf.len;
+                        omxhdr->nFilledLen = m_sVenc_msg->buf.len;
+                        omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp;
+                        omxhdr->nFlags = m_sVenc_msg->buf.flags;
+                    } else {
+                        output_metabuffer *meta_buf = (output_metabuffer *)(omxhdr->pBuffer);
+                        native_handle_t *nh = meta_buf->nh;
+                        nh->data[1] = m_sVenc_msg->buf.offset;
+                        nh->data[2] = m_sVenc_msg->buf.len;
+                        omxhdr->nFilledLen = sizeof(output_metabuffer);
+                        omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp;
+                        omxhdr->nFlags = m_sVenc_msg->buf.flags;
+                    }
                 } else {
                     omxhdr->nFilledLen = 0;
                 }
diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
index b9f634d..247d83d 100644
--- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -4251,9 +4251,14 @@
     buf.flags = 0;
 
     if (venc_handle->is_secure_session()) {
-        output_metabuffer *meta_buf = (output_metabuffer *)(bufhdr->pBuffer);
-        native_handle_t *handle_t = meta_buf->nh;
-        plane[0].length = handle_t->data[3];
+        if (venc_handle->allocate_native_handle) {
+            native_handle_t *handle_t = (native_handle_t *)(bufhdr->pBuffer);
+            plane[0].length = handle_t->data[3];
+        } else {
+            output_metabuffer *meta_buf = (output_metabuffer *)(bufhdr->pBuffer);
+            native_handle_t *handle_t = meta_buf->nh;
+            plane[0].length = handle_t->data[3];
+        }
     }
 
     if (mBatchSize) {