Merge "mm-video-v4l2: add support for AVC and HEVC secure encoding"
diff --git a/conf_files/kona/media_codecs_performance.xml b/conf_files/kona/media_codecs_performance.xml
index 4766953..795dd6f 100644
--- a/conf_files/kona/media_codecs_performance.xml
+++ b/conf_files/kona/media_codecs_performance.xml
@@ -183,7 +183,7 @@
             <Limit name="measured-frame-rate-1920x1080" range="36-49" />
         </MediaCodec>
         <MediaCodec name="c2.android.mpeg4.decoder" type="video/mp4v-es" update="true">
-            <Limit name="measured-frame-rate-176x144" range="401-545" />
+            <Limit name="measured-frame-rate-176x144" range="550-1200" />
         </MediaCodec>
         <MediaCodec name="c2.android.h263.decoder" type="video/3gpp" update="true">
             <Limit name="measured-frame-rate-176x144" range="483-663" />
diff --git a/conf_files/kona/media_codecs_vendor_audio.xml b/conf_files/kona/media_codecs_vendor_audio.xml
index aae3e59..0cd3294 100644
--- a/conf_files/kona/media_codecs_vendor_audio.xml
+++ b/conf_files/kona/media_codecs_vendor_audio.xml
@@ -16,19 +16,11 @@
      limitations under the License.
 -->
 <Included>
-    <Encoders>
-        <MediaCodec name="OMX.qcom.audio.encoder.mpegh" type="audio/mhas" rank="0">
-            <Limit name="concurrent-instances" max="1" />
-        </MediaCodec>
-    </Encoders>
     <Decoders>
         <MediaCodec name="OMX.google.opus.decoder" type="audio/opus" update="true" rank="100"/>
         <!-- SimpleOMXComponet based software decoder-->
         <MediaCodec name="OMX.qti.audio.decoder.flac" type="audio/flac" rank="0">
             <Limit name="concurrent-instances" max="10" />
         </MediaCodec>
-        <MediaCodec name="OMX.qti.audio.decoder.mpegh" type="audio/mhas" rank="0">
-            <Limit name="concurrent-instances" max="1" />
-        </MediaCodec>
     </Decoders>
 </Included>
diff --git a/conf_files/kona/media_profiles.xml b/conf_files/kona/media_profiles.xml
index 924afcd..bb9cd1f 100644
--- a/conf_files/kona/media_profiles.xml
+++ b/conf_files/kona/media_profiles.xml
@@ -476,88 +476,6 @@
         <ImageEncoding quality="70" />
         <ImageDecoding memCap="20000000" />
 
-    <EncoderProfile quality="highspeedlow" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="6400000"
-             width="640"
-             height="480"
-             frameRate="240" />
-
-      <Audio codec="aac"
-             bitRate="156000"
-             sampleRate="48000"
-             channels="2" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeedhigh" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="120000000"
-             width="3840"
-             height="2160"
-             frameRate="120" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed2160p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="120000000"
-             width="3840"
-             height="2160"
-             frameRate="120" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed1080p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="50000000"
-             width="1920"
-             height="1080"
-             frameRate="120" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed720p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="88000000"
-             width="1280"
-             height="720"
-             frameRate="480" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed480p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="6400000"
-             width="640"
-             height="480"
-             frameRate="240" />
-
-      <Audio codec="aac"
-             bitRate="156000"
-             sampleRate="48000"
-             channels="2" />
-    </EncoderProfile>
-
     </CamcorderProfiles>
     <!-- Front Camera -->
     <CamcorderProfiles cameraId="1">
@@ -938,88 +856,6 @@
             channels="2" />
     </EncoderProfile>
 
-    <EncoderProfile quality="highspeedlow" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="6400000"
-             width="640"
-             height="480"
-             frameRate="240" />
-
-      <Audio codec="aac"
-             bitRate="156000"
-             sampleRate="48000"
-             channels="2" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeedhigh" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="120000000"
-             width="3840"
-             height="2160"
-             frameRate="120" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed2160p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="120000000"
-             width="3840"
-             height="2160"
-             frameRate="120" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed1080p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="50000000"
-             width="1920"
-             height="1080"
-             frameRate="120" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed720p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="88000000"
-             width="1280"
-             height="720"
-             frameRate="480" />
-
-      <!-- audio setting is ignored -->
-      <Audio codec="aac"
-             bitRate="96000"
-             sampleRate="48000"
-             channels="1" />
-    </EncoderProfile>
-
-    <EncoderProfile quality="highspeed480p" fileFormat="mp4" duration="30">
-      <Video codec="h264"
-             bitRate="6400000"
-             width="640"
-             height="480"
-             frameRate="240" />
-
-      <Audio codec="aac"
-             bitRate="156000"
-             sampleRate="48000"
-             channels="2" />
-    </EncoderProfile>
-
         <ImageEncoding quality="95" />
         <ImageEncoding quality="80" />
         <ImageEncoding quality="70" />
diff --git a/conf_files/lito/media_codecs_vendor.xml b/conf_files/lito/media_codecs_vendor.xml
index 8e2bdf0..531a84b 100644
--- a/conf_files/lito/media_codecs_vendor.xml
+++ b/conf_files/lito/media_codecs_vendor.xml
@@ -215,6 +215,8 @@
             <Limit name="concurrent-instances" max="6" />
             <Limit name="quality" range="0-100" default="80" />
             <Feature name="bitrate-modes" value="CQ" />
+            <Limit name="performance-point-8192x4320" value="3" />
+            <Limit name="performance-point-1920x1080" value="6" />
         </MediaCodec>
         <!-- Video Software -->
         <MediaCodec name="OMX.qcom.video.encoder.h263sw" type="video/3gpp" >
diff --git a/conf_files/lito/media_codecs_vendor_v1.xml b/conf_files/lito/media_codecs_vendor_v1.xml
index 86b9599..7a49364 100644
--- a/conf_files/lito/media_codecs_vendor_v1.xml
+++ b/conf_files/lito/media_codecs_vendor_v1.xml
@@ -210,6 +210,8 @@
             <Limit name="concurrent-instances" max="6" />
             <Limit name="quality" range="0-100" default="80" />
             <Feature name="bitrate-modes" value="CQ" />
+            <Limit name="performance-point-8192x4320" value="3" />
+            <Limit name="performance-point-1920x1080" value="6" />
         </MediaCodec>
         <!-- Video Software -->
         <MediaCodec name="OMX.qcom.video.encoder.h263sw" type="video/3gpp" >
diff --git a/mm-core/inc/OMX_Core.h b/mm-core/inc/OMX_Core.h
index 4a2f5db..6fa88c2 100644
--- a/mm-core/inc/OMX_Core.h
+++ b/mm-core/inc/OMX_Core.h
@@ -534,6 +534,20 @@
      *  fool-proof way to do that for video encoders.
      */
     OMX_EventDataSpaceChanged,
+
+    /**
+     * Event when a component has an updated configuration on output for the client to retrieve.
+     * |arg1| contains the port index (currently only output port is valid). |arg2| contains the
+     * index of the updated config.
+     *
+     * For config updates that's associated with one frame, the update should be applied to the
+     * next output frame that comes in EmptyBufferDone callback.
+     *
+     * Upon receiving this event, the client must call the corresponding OMX_GetConfig to retrieve
+     * the config update.
+     */
+    OMX_EventConfigUpdate,
+
     OMX_EventMax = 0x7FFFFFFF
 } OMX_EVENTTYPE;
 
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index dce07cb..72de01c 100644
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -150,7 +150,7 @@
         (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp)
 
 #define DEFAULT_FPS 30
-#define MAX_SUPPORTED_FPS 240
+#define MAX_SUPPORTED_FPS 960
 #define DEFAULT_WIDTH_ALIGNMENT 128
 #define DEFAULT_HEIGHT_ALIGNMENT 32
 
@@ -1309,6 +1309,7 @@
         void convert_hdr10plusinfo_to_metadata(OMX_PTR cookie, ColorMetaData &colorData);
         void remove_hdr10plusinfo_using_cookie(OMX_PTR cookie);
         void clear_hdr10plusinfo();
+        void get_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata);
 public:
         bool m_buffer_error;
         OMX_VIDEO_PARAM_PROFILELEVELTYPE get_clientSet_profile_level() {
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 ce7b0be..9b5260b 100644
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -129,6 +129,16 @@
 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
 
+/*
+To enable sending vp9 hdr10plus metadata via private gralloc
+handle to display, define VP9_HDR10PLUS_GRALLOC_PATH_ENABLE
+as 1. This disables sending metadata via framework.
+To enable sending vp9 hdr10plus metadata via framework, define
+VP9_HDR10PLUS_GRALLOC_PATH_ENABLE as 0. This disables sending
+metadata via gralloc handle.
+*/
+#define VP9HDR10PLUS_SETMETADATA_ENABLE 1
+
 using namespace android;
 
 void* async_message_thread (void *input)
@@ -1063,11 +1073,36 @@
                                         if (p2 != VDEC_S_SUCCESS) {
                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
                                             pThis->omx_report_error ();
-                                        } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
+                                            break;
+                                        }
+                                        if (pThis->fill_buffer_done(&pThis->m_cmp,
                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
                                             pThis->omx_report_error ();
+                                            break;
                                         }
+#if !VP9HDR10PLUS_SETMETADATA_ENABLE
+                                        if (pThis->output_capability != V4L2_PIX_FMT_VP9)
+                                            break;
+
+                                        if (!pThis->m_cb.EventHandler) {
+                                            DEBUG_PRINT_ERROR("fill_buffer_done: null event handler");
+                                            break;
+                                        }
+                                        bool is_list_empty;
+                                        is_list_empty = false;
+                                        pthread_mutex_lock(&pThis->m_hdr10pluslock);
+                                        is_list_empty = pThis->m_hdr10pluslist.empty();
+                                        pthread_mutex_unlock(&pThis->m_hdr10pluslock);
+                                        if (!is_list_empty) {
+                                            DEBUG_PRINT_LOW("fill_buffer_done: event config update");
+                                            pThis->m_cb.EventHandler(&pThis->m_cmp,
+                                                    pThis->m_app_data,
+                                                    OMX_EventConfigUpdate,
+                                                    OMX_CORE_OUTPUT_PORT_INDEX,
+                                                    OMX_QTIIndexConfigDescribeHDR10PlusInfo, NULL);
+                                        }
+#endif
                                         break;
 
                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
@@ -3081,7 +3116,8 @@
         case OMX_QTIIndexConfigDescribeHDR10PlusInfo:
         {
             VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
-            //TODO
+            DescribeHDR10PlusInfoParams *params = (DescribeHDR10PlusInfoParams *)configData;
+            get_hdr10plusinfo(params);
             break;
         }
         case OMX_IndexConfigAndroidVendorExtension:
@@ -7118,6 +7154,7 @@
 {
     OMX_ERRORTYPE eRet = OMX_ErrorNone;
     struct v4l2_format fmt;
+    struct v4l2_control control;
     if (!portDefn) {
         DEBUG_PRINT_ERROR("update_portdef: invalid params");
         return OMX_ErrorBadParameter;
@@ -7136,6 +7173,17 @@
             return OMX_ErrorHardware;
         }
         drv_ctx.ip_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+
+        control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
+        ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control);
+        if (ret) {
+            DEBUG_PRINT_ERROR("Get input buffer count failed");
+            return OMX_ErrorHardware;
+        }
+        drv_ctx.ip_buf.mincount = control.value;
+        if (drv_ctx.ip_buf.actualcount < control.value)
+            drv_ctx.ip_buf.actualcount = control.value;
+
         portDefn->eDir =  OMX_DirInput;
         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
@@ -8156,8 +8204,10 @@
                 get_preferred_hdr_info(final_hdr_info);
                 convert_color_aspects_to_metadata(final_color_aspects, color_mdata);
                 convert_hdr_info_to_metadata(final_hdr_info, color_mdata);
+#if VP9HDR10PLUS_SETMETADATA_ENABLE
                 convert_hdr10plusinfo_to_metadata(p_buf_hdr->pMarkData, color_mdata);
                 remove_hdr10plusinfo_using_cookie(p_buf_hdr->pMarkData);
+#endif
                 print_debug_hdr_color_info_mdata(&color_mdata);
                 print_debug_hdr10plus_metadata(color_mdata);
                 setMetaData(private_handle, COLOR_METADATA, (void*)&color_mdata);
@@ -9034,15 +9084,19 @@
     std::list<hdr10plusInfo>::reverse_iterator iter;
     unsigned int found = 0;
     unsigned int cookie = (unsigned int)(unsigned long)markdata;
+    bool is_list_empty = false;
 
     if (output_capability != V4L2_PIX_FMT_VP9)
         return;
 
-    if (m_hdr10pluslist.empty()) {
+    pthread_mutex_lock(&m_hdr10pluslock);
+    is_list_empty = m_hdr10pluslist.empty();
+    pthread_mutex_unlock(&m_hdr10pluslock);
+
+    if (is_list_empty) {
         DEBUG_PRINT_HIGH("update_hdr10plusinfo_cookie_using_timestamp: hdr10plusinfo list is empty!");
         return;
     }
-
     /*
      * look for the hdr10plus data which has timestamp nearest and
      * lower than the etb timestamp, we should not take the
@@ -9072,12 +9126,17 @@
 {
     std::list<hdr10plusInfo>::iterator iter;
     unsigned int cookie = (unsigned int)(unsigned long)markdata;
+    bool is_list_empty = false;
 
     if (output_capability != V4L2_PIX_FMT_VP9)
         return;
 
-    if (m_hdr10pluslist.empty()) {
-        DEBUG_PRINT_HIGH("convert_hdr10plusinfo_to_metadata: hdr10plus list is empty!");
+    pthread_mutex_lock(&m_hdr10pluslock);
+    is_list_empty = m_hdr10pluslist.empty();
+    pthread_mutex_unlock(&m_hdr10pluslock);
+
+    if (is_list_empty) {
+        DEBUG_PRINT_HIGH("convert_hdr10plusinfo_to_metadata: hdr10plusinfo list is empty!");
         return;
     }
 
@@ -9102,12 +9161,17 @@
 {
     std::list<hdr10plusInfo>::iterator iter;
     unsigned int cookie = (unsigned int)(unsigned long)markdata;
+    bool is_list_empty = false;
 
     if (output_capability != V4L2_PIX_FMT_VP9)
         return;
 
-    if (m_hdr10pluslist.empty()) {
-        DEBUG_PRINT_HIGH("remove_hdr10plusinfo_using_cookie: hdr10plus list is empty!");
+    pthread_mutex_lock(&m_hdr10pluslock);
+    is_list_empty = m_hdr10pluslist.empty();
+    pthread_mutex_unlock(&m_hdr10pluslock);
+
+    if (is_list_empty) {
+        DEBUG_PRINT_HIGH("remove_hdr10plusinfo_using_cookie: hdr10plusinfo list is empty!");
         return;
     }
 
@@ -9126,14 +9190,59 @@
 
 void omx_vdec::clear_hdr10plusinfo()
 {
-    if (m_hdr10pluslist.empty() || output_capability != V4L2_PIX_FMT_VP9)
+    bool is_list_empty = false;
+
+    if (output_capability != V4L2_PIX_FMT_VP9)
         return;
 
     pthread_mutex_lock(&m_hdr10pluslock);
+    is_list_empty = m_hdr10pluslist.empty();
+    pthread_mutex_unlock(&m_hdr10pluslock);
+
+    if (is_list_empty) {
+        DEBUG_PRINT_HIGH("clear_hdr10plusinfo: hdr10plusinfo list is empty!");
+        return;
+    }
+
+    pthread_mutex_lock(&m_hdr10pluslock);
     m_hdr10pluslist.clear();
     pthread_mutex_unlock(&m_hdr10pluslock);
 }
 
+void omx_vdec::get_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
+{
+    std::list<hdr10plusInfo>::iterator iter;
+    bool is_list_empty = false;
+
+    if (output_capability != V4L2_PIX_FMT_VP9)
+        return;
+
+    pthread_mutex_lock(&m_hdr10pluslock);
+    is_list_empty = m_hdr10pluslist.empty();
+    pthread_mutex_unlock(&m_hdr10pluslock);
+
+    if (is_list_empty) {
+        DEBUG_PRINT_HIGH("get_hdr10plusinfo: hdr10plusinfo list is empty!");
+        return;
+    }
+
+    pthread_mutex_lock(&m_hdr10pluslock);
+    iter = m_hdr10pluslist.begin();
+    while (iter != m_hdr10pluslist.end()) {
+        if (!iter->is_new) {
+            hdr10plusdata->nParamSizeUsed = iter->nParamSizeUsed;
+            memcpy(hdr10plusdata->nValue, iter->payload,
+                iter->nParamSizeUsed);
+            DEBUG_PRINT_LOW("found hdr10plus metadata with timestamp %lld, size %u",
+                iter->timestamp, iter->nParamSizeUsed);
+            iter = m_hdr10pluslist.erase(iter);
+            break;
+        }
+        iter++;
+    }
+    pthread_mutex_unlock(&m_hdr10pluslock);
+}
+
 void perf_metrics::start()
 {
     if (!active) {
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 5759b72..0967944 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -455,6 +455,7 @@
                 &m_sOutPortDef.nBufferSize,
                 m_sOutPortDef.nPortIndex) != true) {
         eRet = OMX_ErrorUndefined;
+        goto init_error;
     }
 
     // Initialize the video color format for input port