mm-video: venc: Expose OMX_QTIIndexParamIframeSizeType

OMX_QTIIndexParamIframeSizeType allows clients to control the size of
I-frames.

Change-Id: I091f425a26c28207b208f1737904a0176f45bb0b
CRs-Fixed: 1082285
diff --git a/mm-core/inc/OMX_QCOMExtns.h b/mm-core/inc/OMX_QCOMExtns.h
index 39ea5e5..93da3b5 100644
--- a/mm-core/inc/OMX_QCOMExtns.h
+++ b/mm-core/inc/OMX_QCOMExtns.h
@@ -575,6 +575,9 @@
     OMX_QTIIndexParamVPXColorSpaceExtraData = 0x7F000066,
     /* Enable client extradata */
     OMX_QTIIndexParamVideoClientExtradata = 0x7F000060,
+
+    /* Suggest how big Iframe sizes should be */
+    OMX_QTIIndexParamIframeSizeType = 0x7F000070,
 };
 
 /**
@@ -1742,6 +1745,19 @@
    OMX_U32 nCabacInitIdc;
 } QOMX_VIDEO_H264ENTROPYCODINGTYPE;
 
+typedef enum QOMX_VIDEO_IFRAMESIZE_TYPE {
+    QOMX_IFRAMESIZE_DEFAULT,
+    QOMX_IFRAMESIZE_MEDIUM,
+    QOMX_IFRAMESIZE_HUGE,
+    QOMX_IFRAMESIZE_UNLIMITED,
+} QOMX_VIDEO_IFRAMESIZE_TYPE;
+
+typedef struct QOMX_VIDEO_IFRAMESIZE {
+   OMX_U32 nSize;
+   OMX_VERSIONTYPE nVersion;
+   QOMX_VIDEO_IFRAMESIZE_TYPE eType;
+} QOMX_VIDEO_IFRAMESIZE;
+
 /* VIDEO POSTPROCESSING CTRLS AND ENUMS */
 /* MUST KEEP SAME AS IN vpp.h */
 #define QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ 256
diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
index c65b789..7cf1909 100644
--- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -443,6 +443,7 @@
         void venc_clip_luma_chroma(int fd, OMX_U32 offset, OMX_U32 size);
         bool venc_set_layer_bitrates(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hpmode);
         bool venc_set_colorspace(OMX_U32 primaries, OMX_U32 range, OMX_U32 transfer_chars, OMX_U32 matrix_coeffs);
+        bool venc_set_iframesize_type(QOMX_VIDEO_IFRAMESIZE_TYPE type);
 
 #ifdef MAX_RES_1080P
         OMX_U32 pmem_free();
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 1104daf..54b1949 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -1606,6 +1606,16 @@
                 }
                 break;
             }
+        case OMX_QTIIndexParamIframeSizeType:
+            {
+                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_IFRAMESIZE);
+                if (!handle->venc_set_param(paramData,
+                            (OMX_INDEXTYPE)OMX_QTIIndexParamIframeSizeType)) {
+                    DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamIframeSizeType failed");
+                    return OMX_ErrorUnsupportedSetting;
+                }
+                break;
+            }
         case OMX_IndexParamVideoSliceFMO:
         default:
             {
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 25a0358..6f43692 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
@@ -1437,6 +1437,7 @@
     struct v4l2_format fmt;
     struct v4l2_requestbuffers bufreq;
     int ret;
+    bool isCBR;
 
     switch ((int)index) {
         case OMX_IndexParamPortDefinition:
@@ -2065,6 +2066,23 @@
                 }
                 break;
             }
+        case OMX_QTIIndexParamIframeSizeType:
+            {
+                QOMX_VIDEO_IFRAMESIZE* pParam =
+                    (QOMX_VIDEO_IFRAMESIZE *)paramData;
+                isCBR = rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR ||
+                    rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
+                if (!isCBR) {
+                    DEBUG_PRINT_ERROR("venc_set_param: OMX_QTIIndexParamIframeSizeType not allowed for this configuration isCBR(%d)",
+                        isCBR);
+                    return OMX_ErrorUnsupportedSetting;
+                }
+                if (!venc_set_iframesize_type(pParam->eType)) {
+                    DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamIframeSizeType failed");
+                    return OMX_ErrorUnsupportedSetting;
+                }
+                break;
+            }
         case OMX_IndexParamVideoSliceFMO:
         default:
             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
@@ -5344,6 +5362,37 @@
     return true;
 }
 
+bool venc_dev::venc_set_iframesize_type(QOMX_VIDEO_IFRAMESIZE_TYPE type)
+{
+    struct v4l2_control control;
+    control.id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE;
+
+    switch (type) {
+        case QOMX_IFRAMESIZE_DEFAULT:
+            control.value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT;
+            break;
+        case QOMX_IFRAMESIZE_MEDIUM:
+            control.value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM;
+            break;
+        case QOMX_IFRAMESIZE_HUGE:
+            control.value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE;
+            break;
+        case QOMX_IFRAMESIZE_UNLIMITED:
+            control.value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED;
+            break;
+        default:
+            DEBUG_PRINT_INFO("Unknown Iframe Size found setting it to default");
+            control.value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT;
+    }
+
+    if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+        DEBUG_PRINT_ERROR("Failed to set iframe size hint");
+        return false;
+    }
+
+    return true;
+}
+
 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
 {
     struct v4l2_control control;