[go: nahoru, domu]

Merge "mm-core: Add support for qcs605 target"
diff --git a/conf_files/sdm845/system_properties.xml b/conf_files/sdm845/system_properties.xml
index 31f1fea..a6edc62 100644
--- a/conf_files/sdm845/system_properties.xml
+++ b/conf_files/sdm845/system_properties.xml
@@ -30,6 +30,7 @@
 <configs>
         <property name="vidc_dec_log_in" value="0"/>
         <property name="vidc_dec_log_out" value="0"/>
+        <property name="vidc_dec_hfr_fps" value="0"/>
         <property name="vidc_enc_log_in" value="0"/>
         <property name="vidc_enc_log_out" value="0"/>
         <property name="vidc_enc_csc_custom_matrix" value="0"/>
diff --git a/libc2dcolorconvert/C2DColorConverter.h b/libc2dcolorconvert/C2DColorConverter.h
old mode 100644
new mode 100755
index 228bd35..aa8fa1e
--- a/libc2dcolorconvert/C2DColorConverter.h
+++ b/libc2dcolorconvert/C2DColorConverter.h
@@ -108,6 +108,7 @@
     NV12_128m,
     NV12_UBWC,
     TP10_UBWC,
+    YCbCr420_VENUS_P010,
     NO_COLOR_FORMAT
 };
 
diff --git a/libplatformconfig/PlatformConfig.h b/libplatformconfig/PlatformConfig.h
index 7cfcc60..a205e12 100644
--- a/libplatformconfig/PlatformConfig.h
+++ b/libplatformconfig/PlatformConfig.h
@@ -52,6 +52,7 @@
 typedef enum {
     vidc_dec_log_in = 0,
     vidc_dec_log_out,
+    vidc_dec_hfr_fps,
     vidc_enc_log_in,
     vidc_enc_log_out,
     vidc_dec_conceal_color_8bit,
@@ -67,6 +68,7 @@
 static const struct configStr configStrMap[] = {
     {vidc_dec_log_in, "vidc_dec_log_in"},
     {vidc_dec_log_out, "vidc_dec_log_out"},
+    {vidc_dec_hfr_fps, "vidc_dec_hfr_fps"},
     {vidc_enc_log_in, "vidc_enc_log_in"},
     {vidc_enc_log_out, "vidc_enc_log_out"},
     {vidc_dec_conceal_color_8bit, "vidc_dec_conceal_color_8bit"},
diff --git a/mm-core/inc/OMX_QCOMExtns.h b/mm-core/inc/OMX_QCOMExtns.h
old mode 100644
new mode 100755
index 745df32..a7571a7
--- a/mm-core/inc/OMX_QCOMExtns.h
+++ b/mm-core/inc/OMX_QCOMExtns.h
@@ -327,6 +327,7 @@
     QOMX_COLOR_Format32bitRGBA8888,
     QOMX_COLOR_Format32bitRGBA8888Compressed,
     QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed,
+    QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus,
     QOMX_COLOR_FormatAndroidOpaque = (OMX_COLOR_FORMATTYPE) OMX_COLOR_FormatVendorStartUnused  + 0x789,
 };
 
diff --git a/mm-core/inc/OMX_Video.h b/mm-core/inc/OMX_Video.h
index 64dbe87..f89f62f 100644
--- a/mm-core/inc/OMX_Video.h
+++ b/mm-core/inc/OMX_Video.h
@@ -614,14 +614,15 @@
  * sizes, bit rates, decoder frame rates.  No need 
  */
 typedef enum OMX_VIDEO_MPEG4LEVELTYPE {
-    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */   
-    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */   
-    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */ 
-    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */ 
-    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */ 
-    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */  
-    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */  
-    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */  
+    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */
+    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */
+    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */
+    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */
+    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */
+    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */
+    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */
+    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */
+    OMX_VIDEO_MPEG4Level6  = 0x100,  /**< Level 6 */
     OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
     OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF  
diff --git a/mm-video-v4l2/vidc/common/src/vidc_common.cpp b/mm-video-v4l2/vidc/common/src/vidc_common.cpp
index 1ea2343..f787b90 100644
--- a/mm-video-v4l2/vidc/common/src/vidc_common.cpp
+++ b/mm-video-v4l2/vidc/common/src/vidc_common.cpp
@@ -310,6 +310,7 @@
     version(),
     size(32),
     fourCC{'V','P','8','0'},
+    frameCount(0),
     unused()
 {
 }
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
old mode 100644
new mode 100755
index 9f363b0..56a7db2
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -246,6 +246,7 @@
 #define VDEC_MSG_EVT_MAX_CLIENTS	(VDEC_MSG_BASE + 15)
 #define VDEC_MSG_EVT_HW_UNSUPPORTED	(VDEC_MSG_BASE + 16)
 
+
 //  Define next macro with required values to enable default extradata,
 //    VDEC_EXTRADATA_MB_ERROR_MAP
 //    OMX_INTERLACE_EXTRADATA
@@ -308,7 +309,8 @@
 	VDEC_YUV_FORMAT_NV12 = 0x1,
 	VDEC_YUV_FORMAT_TILE_4x2 = 0x2,
 	VDEC_YUV_FORMAT_NV12_UBWC = 0x3,
-	VDEC_YUV_FORMAT_NV12_TP10_UBWC = 0x4
+	VDEC_YUV_FORMAT_NV12_TP10_UBWC = 0x4,
+	VDEC_YUV_FORMAT_P010_VENUS = 0x5,
 };
 
 enum vdec_interlaced_format {
@@ -664,6 +666,8 @@
         OMX_ERRORTYPE set_dpb(bool is_split_mode, int dpb_color_format);
         OMX_ERRORTYPE decide_dpb_buffer_mode(bool is_downscalar_enabled);
         int dpb_bit_depth;
+        bool check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format);
+        bool is_flexible_format;//To save status if required format is flexible color formats
         bool async_thread_force_stop;
         volatile bool message_thread_stop;
         struct extradata_info m_extradata_info;
@@ -1277,6 +1281,7 @@
         int log_cc_output_buffers(OMX_BUFFERHEADERTYPE *);
         void send_codec_config();
         OMX_TICKS m_last_rendered_TS;
+        int32_t m_dec_hfr_fps;
         volatile int32_t m_queued_codec_config_count;
         OMX_U32 current_perf_level;
         bool secure_scaling_to_non_secure_opb;
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp b/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp
index b7a3d79..47bc07a 100644
--- a/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp
@@ -3140,9 +3140,9 @@
         if (p_profilelevel->nProfileIndex == 0)
         {
             p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
-            p_profilelevel->eLevel   = OMX_VIDEO_MPEG4Level5;
+            p_profilelevel->eLevel   = OMX_VIDEO_MPEG4Level6;
 
-            OMX_SWVDEC_LOG_HIGH("MPEG-4 simple profile, level 5");
+            OMX_SWVDEC_LOG_HIGH("MPEG-4 simple profile, level 6");
         }
         else if (p_profilelevel->nProfileIndex == 1)
         {
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
old mode 100644
new mode 100755
index e606be7..2aa3fc2
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -717,7 +717,8 @@
     m_profile(0),
     client_set_fps(false),
     stereo_output_mode(HAL_NO_3D),
-    m_last_rendered_TS(-1),
+    m_last_rendered_TS(0),
+    m_dec_hfr_fps(0),
     m_queued_codec_config_count(0),
     secure_scaling_to_non_secure_opb(false),
     m_force_compressed_for_dpb(true),
@@ -752,6 +753,11 @@
     Platform::Config::getInt32(Platform::vidc_dec_log_out,
             (int32_t *)&m_debug.out_buffer_log, 0);
 
+    Platform::Config::getInt32(Platform::vidc_dec_hfr_fps,
+            (int32_t *)&m_dec_hfr_fps, 0);
+
+    DEBUG_PRINT_HIGH("HFR fps value = %d", m_dec_hfr_fps);
+
     property_value[0] = '\0';
     property_get("vendor.vidc.dec.log.in", property_value, "0");
     m_debug.in_buffer_log |= atoi(property_value);
@@ -1008,6 +1014,7 @@
          capture_capability == V4L2_PIX_FMT_NV12 ? "nv12":
          capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc":
          capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC ? "nv12_10bit_ubwc":
+         capture_capability == V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010 ? "P010":
          "unknown");
 
     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
@@ -1048,13 +1055,6 @@
     bool dither_enable = false;
     bool capability_changed = false;
 
-    // Check the component for its valid current state
-    if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
-        !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
-        DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
-        return OMX_ErrorNone;
-    }
-
     // Downscalar is not supported
     is_downscalar_enabled = false;
 
@@ -1080,6 +1080,11 @@
         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
             enable_split = true;
             dpb_color_format = V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC;
+            if(is_flexible_format){ // if flexible formats are expected, P010 is set for 10bit cases here
+                 drv_ctx.output_format = VDEC_YUV_FORMAT_P010_VENUS;
+                 capture_capability = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010;
+                 capability_changed = true;
+            }
         } else  if (m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE) {
             enable_split = true;
             dpb_color_format = V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC;
@@ -1097,6 +1102,9 @@
 
             if (dither_enable) {
                 dpb_color_format = V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC;
+                capture_capability = m_disable_ubwc_mode ?
+                            V4L2_PIX_FMT_NV12 : V4L2_PIX_FMT_NV12_UBWC;
+                capability_changed = true;
             } else {
                 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC;
                 capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC;
@@ -1125,7 +1133,12 @@
             return OMX_ErrorUnsupportedSetting;
         }
     }
-
+    // Check the component for its valid current state
+    if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
+        !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
+        DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
+        return OMX_ErrorNone;
+    }
     eRet = set_dpb(enable_split, dpb_color_format);
     if (eRet) {
         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
@@ -1134,6 +1147,19 @@
     return eRet;
 }
 
+bool omx_vdec::check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format)
+{
+    if(required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
+         required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus) {
+         //for now, the flexible formats should be NV12 by default for 8bit cases
+         //it will change to P010 after 10bit port-reconfig accordingly
+       return TRUE;
+    }
+    else {
+       return FALSE;
+    }
+}
+
 int omx_vdec::enable_downscalar()
 {
     int rc = 0;
@@ -1985,6 +2011,7 @@
 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
     int buf_index = 0;
     char *temp = NULL;
+    char *bufaddr = NULL;
 
     if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen)
         return 0;
@@ -2018,7 +2045,18 @@
     }
 
     buf_index = buffer - m_out_mem_ptr;
-    temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
+    bufaddr = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
+    if (dynamic_buf_mode && !secure_mode) {
+        bufaddr = (char*)mmap(0, drv_ctx.ptr_outputbuffer[buf_index].buffer_len,
+                                 PROT_READ|PROT_WRITE, MAP_SHARED,
+                                 drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, 0);
+        //mmap returns (void *)-1 on failure and sets error code in errno.
+        if (bufaddr == MAP_FAILED) {
+            DEBUG_PRINT_ERROR("mmap failed - errno: %d", errno);
+            return -1;
+        }
+    }
+    temp = bufaddr;
 
     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC ||
             drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
@@ -2050,13 +2088,12 @@
             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
 
-            temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
             for (i = 0; i < y_meta_scanlines; i++) {
                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
                  temp += y_meta_stride;
             }
 
-            temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane;
+            temp = bufaddr + y_meta_plane + y_plane;
             for(i = 0; i < uv_meta_scanlines; i++) {
                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
                 temp += uv_meta_stride;
@@ -2080,12 +2117,40 @@
              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
              temp += stride;
         }
-        temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
+        temp = bufaddr + stride * scanlines;
         int stride_c = stride;
         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
             temp += stride_c;
         }
+    } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
+        int stride = drv_ctx.video_resolution.stride;
+        int scanlines = drv_ctx.video_resolution.scan_lines;
+        if (m_smoothstreaming_mode) {
+            stride = drv_ctx.video_resolution.frame_width * 2;
+            scanlines = drv_ctx.video_resolution.frame_height;
+            stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
+            scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
+        }
+        unsigned i;
+        DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
+            drv_ctx.video_resolution.frame_width,
+            drv_ctx.video_resolution.frame_height, stride, scanlines);
+        int bytes_written = 0;
+        for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
+             bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
+             temp += stride;
+        }
+        temp = bufaddr + stride * scanlines;
+        int stride_c = stride;
+        for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
+            bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
+            temp += stride_c;
+        }
+    }
+
+    if (dynamic_buf_mode && !secure_mode) {
+        munmap(bufaddr, drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
     }
     return 0;
 }
@@ -2157,6 +2222,7 @@
     struct v4l2_requestbuffers bufreq;
     struct v4l2_control control;
     struct v4l2_frmsizeenum frmsize;
+    struct v4l2_queryctrl query;
     unsigned int   alignment = 0,buffer_size = 0, nBufCount = 0;
     int fds[2];
     int r,ret=0;
@@ -2306,6 +2372,7 @@
 
         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
         m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
+        is_flexible_format = FALSE;
 
         if (m_disable_ubwc_mode) {
             capture_capability = V4L2_PIX_FMT_NV12;
@@ -2461,6 +2528,17 @@
             DEBUG_PRINT_HIGH("Failed to set OUTPUT Buffer count Err = %d Count = %d",
                 ret, nBufCount);
 
+        if (m_dec_hfr_fps) {
+            memset(&query, 0, sizeof(struct v4l2_queryctrl));
+
+            query.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
+            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &query);
+            if (!ret)
+                m_dec_hfr_fps = MIN(query.maximum, m_dec_hfr_fps);
+
+            DEBUG_PRINT_HIGH("Updated HFR fps value = %d", m_dec_hfr_fps);
+        }
+
 #endif
         m_state = OMX_StateLoaded;
 #ifdef DEFAULT_EXTRADATA
@@ -3912,9 +3990,14 @@
                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
                                //been called.
-                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
+                               DEBUG_PRINT_LOW(
+                                       "set_parameter: OMX_IndexParamPortDefinition: dir %d port %d wxh %dx%d count: min %d actual %d size %d",
+                                       (int)portDefn->eDir, (int)portDefn->nPortIndex,
+                                       (int)portDefn->format.video.nFrameWidth,
                                        (int)portDefn->format.video.nFrameHeight,
-                                       (int)portDefn->format.video.nFrameWidth);
+                                       (int)portDefn->nBufferCountMin,
+                                       (int)portDefn->nBufferCountActual,
+                                       (int)portDefn->nBufferSize);
 
                                if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
@@ -4206,11 +4289,15 @@
                                         portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
                                         op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12;
                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
+                                        //check if the required color format is a supported flexible format
+                                        is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
                                                    QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
                                                portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) {
                                         op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12_UBWC;
                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
+                                        //check if the required color format is a supported flexible format
+                                        is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
                                     } else {
                                         eRet = OMX_ErrorBadParameter;
                                     }
@@ -6256,8 +6343,6 @@
         int nPlatformEntrySize = 0;
         int nPlatformListSize  = 0;
         int nPMEMInfoSize = 0;
-        int pmem_fd = -1;
-        unsigned char *pmem_baseaddress = NULL;
 
         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
@@ -6333,76 +6418,13 @@
                 // Keep pBuffer NULL till vdec is opened
                 bufHdr->pBuffer            = NULL;
                 bufHdr->nOffset            = 0;
-
-#ifdef USE_ION
-                // Allocate output buffers as cached to improve performance of software-reading
-                // of the YUVs. Output buffers are cache-invalidated in driver.
-                // If color-conversion is involved, Only the C2D output buffers are cached, no
-                // need to cache the decoder's output buffers
-                int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
-                ion_device_fd = alloc_map_ion_memory(drv_ctx.op_buf.buffer_size,
-                        secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
-                        &ion_alloc_data, &fd_ion_data,
-                        (secure_mode && !secure_scaling_to_non_secure_opb) ?
-                        SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
-                if (ion_device_fd < 0) {
-                    return OMX_ErrorInsufficientResources;
-                }
-                pmem_fd = fd_ion_data.fd;
-#else
-                pmem_fd = open (MEM_DEVICE,O_RDWR);
-                if (pmem_fd < 0) {
-                    DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
-                            drv_ctx.op_buf.buffer_size);
-                    return OMX_ErrorInsufficientResources;
-                }
-                if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size,
-                            drv_ctx.op_buf.alignment)) {
-                    DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
-                    close(pmem_fd);
-                    return OMX_ErrorInsufficientResources;
-                }
-#endif
-                if (!secure_mode) {
-                    pmem_baseaddress = (unsigned char *)mmap(NULL,
-                            drv_ctx.op_buf.buffer_size,
-                            PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
-                    if (pmem_baseaddress == MAP_FAILED) {
-                        DEBUG_PRINT_ERROR("MMAP failed for Size %u",
-                                (unsigned int)drv_ctx.op_buf.buffer_size);
-                        close(pmem_fd);
-#ifdef USE_ION
-                        free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
-#endif
-                        return OMX_ErrorInsufficientResources;
-                    }
-                }
                 pPMEMInfo->offset = 0;
                 pPMEMInfo->pmem_fd = -1;
                 bufHdr->pPlatformPrivate = pPlatformList;
-
-                drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
-                m_pmem_info[i].pmem_fd = pmem_fd;
-#ifdef USE_ION
-                drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
-                drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
-                drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
-#endif
-
                 /*Create a mapping between buffers*/
                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
                                     &drv_ctx.ptr_outputbuffer[i];
-                drv_ctx.ptr_outputbuffer[i].offset = 0;
-                drv_ctx.ptr_outputbuffer[i].bufferaddr = pmem_baseaddress;
-                drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
-                m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
-                m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
-                m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
-
-                DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
-                        pmem_fd, (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
-                        drv_ctx.ptr_outputbuffer[i].bufferaddr);
                 // Move the buffer and buffer header pointers
                 bufHdr++;
                 pPMEMInfo++;
@@ -6450,10 +6472,65 @@
     if (eRet == OMX_ErrorNone) {
         if (i < drv_ctx.op_buf.actualcount) {
             int rc;
-            m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
+            int pmem_fd = -1;
+            unsigned char *pmem_baseaddress = NULL;
 
-            drv_ctx.ptr_outputbuffer[i].buffer_len =
-                drv_ctx.op_buf.buffer_size;
+#ifdef USE_ION
+            // Allocate output buffers as cached to improve performance of software-reading
+            // of the YUVs. Output buffers are cache-invalidated in driver.
+            // If color-conversion is involved, Only the C2D output buffers are cached, no
+            // need to cache the decoder's output buffers
+            int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
+            ion_device_fd = alloc_map_ion_memory(drv_ctx.op_buf.buffer_size,
+                    secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
+                    &ion_alloc_data, &fd_ion_data,
+                    (secure_mode && !secure_scaling_to_non_secure_opb) ?
+                    SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
+            if (ion_device_fd < 0) {
+                return OMX_ErrorInsufficientResources;
+            }
+            pmem_fd = fd_ion_data.fd;
+            drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
+            drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
+            drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
+#else
+            pmem_fd = open (MEM_DEVICE,O_RDWR);
+            if (pmem_fd < 0) {
+                DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
+                        drv_ctx.op_buf.buffer_size);
+                return OMX_ErrorInsufficientResources;
+            }
+            if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size,
+                        drv_ctx.op_buf.alignment)) {
+                DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
+                close(pmem_fd);
+                return OMX_ErrorInsufficientResources;
+            }
+#endif
+            if (!secure_mode) {
+                pmem_baseaddress = (unsigned char *)mmap(NULL,
+                        drv_ctx.op_buf.buffer_size,
+                        PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
+                if (pmem_baseaddress == MAP_FAILED) {
+                    DEBUG_PRINT_ERROR("MMAP failed for Size %u",
+                            (unsigned int)drv_ctx.op_buf.buffer_size);
+                    close(pmem_fd);
+#ifdef USE_ION
+                    free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
+#endif
+                    return OMX_ErrorInsufficientResources;
+                }
+            }
+            drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
+            drv_ctx.ptr_outputbuffer[i].offset = 0;
+            drv_ctx.ptr_outputbuffer[i].bufferaddr = pmem_baseaddress;
+            drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
+            drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
+            m_pmem_info[i].pmem_fd = pmem_fd;
+            m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
+            m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
+            m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
+            m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
 
             *bufferHdr = (m_out_mem_ptr + i );
             if (secure_mode) {
@@ -6464,8 +6541,6 @@
                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
 #endif
             }
-            drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
-
             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
                 enum v4l2_buf_type buf_type;
 
@@ -6473,6 +6548,7 @@
                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
                 if (rc) {
+                    DEBUG_PRINT_ERROR("STREAMON(CAPTURE_MPLANE) Failed");
                     return OMX_ErrorInsufficientResources;
                 } else {
                     streaming[CAPTURE_PORT] = true;
@@ -7951,8 +8027,10 @@
         il_buffer = client_buffers.get_il_buf_hdr(buffer);
         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
 
-        if (il_buffer && m_last_rendered_TS >= 0) {
+        if (il_buffer && m_dec_hfr_fps > 0) {
             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
+            // Convert fps into ms value. 1 sec = 1000000 ms.
+            OMX_U64 target_ts_delta = m_dec_hfr_fps ? 1000000 / m_dec_hfr_fps : ts_delta;
 
             // Current frame can be send for rendering if
             // (a) current FPS is <=  60
@@ -7962,8 +8040,8 @@
             // (e) its TS is equal to previous frame TS
             // (f) if marked EOS
 
-            if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
-               il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
+            if(current_framerate <= (OMX_U32)m_dec_hfr_fps || m_last_rendered_TS == 0 ||
+               il_buffer->nTimeStamp == 0 || ts_delta >= (OMX_TICKS)target_ts_delta||
                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
                m_last_rendered_TS = il_buffer->nTimeStamp;
             } else {
@@ -7977,8 +8055,8 @@
 
             //above code makes sure that delta b\w two consecutive frames is not
             //greater than 16ms, slow-mo feature, so cap fps to max 60
-            if (current_framerate > 60 ) {
-                current_framerate = 60;
+            if (current_framerate > (OMX_U32)m_dec_hfr_fps ) {
+                current_framerate = m_dec_hfr_fps;
             }
         }
 
@@ -8001,8 +8079,8 @@
                     }
                 }
             }
-            if (refresh_rate > 60) {
-                refresh_rate = 60;
+            if (refresh_rate > m_dec_hfr_fps) {
+                refresh_rate = m_dec_hfr_fps;
             }
             DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms);
             OMX_U32 buf_index = buffer - m_out_mem_ptr;
@@ -8393,6 +8471,12 @@
                            omx->drv_ctx.video_resolution.scan_lines =
                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height);
                         }
+                        else if(omx->drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
+                           omx->drv_ctx.video_resolution.stride =
+                               VENUS_Y_STRIDE(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_width);
+                           omx->drv_ctx.video_resolution.scan_lines =
+                               VENUS_Y_SCANLINES(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_height);
+                        }
 
                        if(!reconfig_event_sent) {
                            omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
@@ -8779,7 +8863,6 @@
     unsigned buf_size = 0;
     struct v4l2_format fmt, c_fmt;
     struct v4l2_requestbuffers bufreq;
-    struct v4l2_control control;
     int ret = 0;
     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
@@ -8796,23 +8879,25 @@
         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
 
         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
-            control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
             fmt.fmt.pix_mp.pixelformat = output_capability;
+            DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
+                fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
+                fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.fmt.pix_mp.pixelformat);
             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
-            control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
             c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
             c_fmt.fmt.pix_mp.pixelformat = capture_capability;
             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
             c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
+            DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
+                c_fmt.type, c_fmt.fmt.pix_mp.width, c_fmt.fmt.pix_mp.height,
+                c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage, c_fmt.fmt.pix_mp.pixelformat);
             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
         } else {
             eRet = OMX_ErrorBadParameter;
         }
-
         if (ret) {
-            /*TODO: How to handle this case */
             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
             eRet = OMX_ErrorInsufficientResources;
         }
@@ -8827,15 +8912,8 @@
             eRet = OMX_ErrorBadParameter;
         }
 
-        control.value = buffer_prop->mincount;
         if (eRet == OMX_ErrorNone) {
-            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control);
-            if (ret)
-                eRet = OMX_ErrorUndefined;
-        }
-
-        if (eRet == OMX_ErrorNone &&
-                        buffer_prop->actualcount >= (uint32_t)control.value) {
+            DEBUG_PRINT_LOW("REQBUFS: type %d count %d", bufreq.type, bufreq.count);
             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
         }
 
@@ -8945,19 +9023,36 @@
         portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
         portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
         portDefn->eDir =  OMX_DirOutput;
+        portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
+        portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
+        portDefn->format.video.nStride  = drv_ctx.video_resolution.stride;
+        portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
+        portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+        portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
+        DEBUG_PRINT_LOW(" get_parameter: Port idx %d nBufSize %u nBufCnt %u",
+                (int)portDefn->nPortIndex,
+                (unsigned int)portDefn->nBufferSize,
+                (unsigned int)portDefn->nBufferCountActual);
+        return eRet;
     } else {
         portDefn->eDir = OMX_DirMax;
         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
                 (int)portDefn->nPortIndex);
         eRet = OMX_ErrorBadPortIndex;
     }
+    if (in_reconfig) {
+        m_extradata_info.output_crop_rect.nLeft = 0;
+        m_extradata_info.output_crop_rect.nTop = 0;
+        m_extradata_info.output_crop_rect.nWidth = fmt.fmt.pix_mp.width;
+        m_extradata_info.output_crop_rect.nHeight = fmt.fmt.pix_mp.height;
+    }
     update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
         fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
 
-        portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
-        portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
-        portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
-        portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
+    portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
+    portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
+    portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
+    portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
 
     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
@@ -10948,11 +11043,14 @@
                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_TP10_UBWC][-1] =
                      QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
+    mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_P010_VENUS][-1] =
+                     QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus;
 
     mMapOutput2Convert.insert( {
             {VDEC_YUV_FORMAT_NV12, NV12_128m},
             {VDEC_YUV_FORMAT_NV12_UBWC, NV12_UBWC},
             {VDEC_YUV_FORMAT_NV12_TP10_UBWC, TP10_UBWC},
+            {VDEC_YUV_FORMAT_P010_VENUS, YCbCr420_VENUS_P010},
         });
 }
 
@@ -11098,7 +11196,9 @@
         (drv_color_format != (OMX_COLOR_FORMATTYPE)
                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) &&
         (drv_color_format != (OMX_COLOR_FORMATTYPE)
-                QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
+                QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed) &&
+        (drv_color_format != (OMX_COLOR_FORMATTYPE)
+                QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus);
 
     dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE)
             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
@@ -11681,6 +11781,9 @@
     case VDEC_YUV_FORMAT_NV12_TP10_UBWC:
         color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
         break;
+    case VDEC_YUV_FORMAT_P010_VENUS:
+        color_fmt = COLOR_FMT_P010;
+        break;
     default:
         color_fmt = -1;
         DEBUG_PRINT_HIGH("Color format : %x not supported for secure memory prefetching\n", drv_ctx.output_format);
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 ff8a3ea..48c0d90 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
@@ -465,6 +465,7 @@
         msm_venc_temporal_layers            temporal_layers_config;
         OMX_BOOL                            downscalar_enabled;
         bool client_req_disable_bframe;
+        bool bframe_implicitly_enabled;
         bool client_req_disable_temporal_layers;
         bool client_req_turbo_mode;
 
diff --git a/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp b/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp
index e10ef99..ade82a4 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp
@@ -892,10 +892,32 @@
                  __FUNCTION__, Ret);
                RETURN(OMX_ErrorUnsupportedSetting);
             }
+            else
+            {
+                m_sIntraperiod.nPFrames = pParam->nPFrames;
+                m_sIntraperiod.nBFrames = pParam->nBFrames;
+            }
 
-            memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
-            m_sIntraperiod.nPFrames = m_sParamMPEG4.nPFrames;
-            m_sIntraperiod.nBFrames = m_sParamMPEG4.nBFrames;
+            /* set profile/level */
+            if (pParam->eProfile && pParam->eLevel)
+            {
+                DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel);
+                Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel);
+                if (Ret != SWVENC_S_SUCCESS)
+                {
+                    DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)",
+                            __FUNCTION__, Ret);
+                    RETURN(OMX_ErrorUnsupportedSetting);
+                }
+                else
+                {
+                    m_sParamProfileLevel.eProfile = pParam->eProfile;
+                    m_sParamProfileLevel.eLevel = pParam->eLevel;
+                }
+            }
+
+            // NOTE: m_sParamMPEG4.eProfile/eLevel may be overwritten to 0 if client didn't set them
+            memcpy(&m_sParamMPEG4, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
             break;
         }
 
@@ -913,10 +935,32 @@
                  __FUNCTION__, Ret);
                RETURN(OMX_ErrorUnsupportedSetting);
             }
+            else
+            {
+                m_sIntraperiod.nPFrames = pParam->nPFrames;
+                m_sIntraperiod.nBFrames = pParam->nBFrames;
+            }
 
+            /* set profile/level */
+            if (pParam->eProfile && pParam->eLevel)
+            {
+                DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel);
+                Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel);
+                if (Ret != SWVENC_S_SUCCESS)
+                {
+                    DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)",
+                            __FUNCTION__, Ret);
+                    RETURN(OMX_ErrorUnsupportedSetting);
+                }
+                else
+                {
+                    m_sParamProfileLevel.eProfile = pParam->eProfile;
+                    m_sParamProfileLevel.eLevel = pParam->eLevel;
+                }
+            }
+
+            // NOTE: m_sParamH263.eProfile/eLevel may be overwritten to 0 if client didn't set them
             memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE));
-            m_sIntraperiod.nPFrames = m_sParamH263.nPFrames;
-            m_sIntraperiod.nBFrames = m_sParamH263.nBFrames;
             break;
         }
 
@@ -2492,9 +2536,9 @@
             if (profileLevelType->nProfileIndex == 0)
             {
                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
-                profileLevelType->eLevel   = OMX_VIDEO_H263Level40;
+                profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
 
-                DEBUG_PRINT_HIGH("H.263 baseline profile, level 40");
+                DEBUG_PRINT_HIGH("H.263 baseline profile, level 70");
             }
             else
             {
@@ -2508,9 +2552,9 @@
             if (profileLevelType->nProfileIndex == 0)
             {
                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
-                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
+                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level6;
 
-                DEBUG_PRINT_LOW("MPEG-4 simple profile, level 5");
+                DEBUG_PRINT_LOW("MPEG-4 simple profile, level 6");
             }
             else
             {
@@ -3254,6 +3298,9 @@
           case OMX_VIDEO_MPEG4Level5:
              Level.mpeg4 = SWVENC_LEVEL_MPEG4_5;
              break;
+          case OMX_VIDEO_MPEG4Level6:
+             Level.mpeg4 = SWVENC_LEVEL_MPEG4_6;
+             break;
           default:
              DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
              Ret = SWVENC_S_FAILURE;
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 3943677..ed6c41c 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -1920,7 +1920,9 @@
                 QOMX_EXTRADATA_ENABLE *pParam =
                     (QOMX_EXTRADATA_ENABLE *)paramData;
                 if (pParam->nPortIndex == PORT_INDEX_EXTRADATA_OUT) {
-                    pParam->bEnable = m_sExtraData ? OMX_TRUE : OMX_FALSE;
+                    OMX_U32 output_extradata_mask = VENC_EXTRADATA_SLICEINFO | VENC_EXTRADATA_LTRINFO |
+                                                    VENC_EXTRADATA_MBINFO;
+                    pParam->bEnable = (m_sExtraData & output_extradata_mask) ? OMX_TRUE : OMX_FALSE;
                     eRet = OMX_ErrorNone;
                 } else {
                     DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)",
@@ -4031,6 +4033,16 @@
             DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
                     Input_pmem_info.fd, Input_pmem_info.offset,
                     Input_pmem_info.size);
+            // if input buffer dimensions is different from what is configured,
+            // reject the buffer
+            if ((int)m_sInPortDef.format.video.nFrameWidth != handle->unaligned_width ||
+                    (int)m_sInPortDef.format.video.nFrameHeight != handle->unaligned_height) {
+                ALOGE("Graphic buf size(%dx%d) does not match configured size(%ux%u)",
+                        handle->unaligned_width, handle->unaligned_height,
+                        m_sInPortDef.format.video.nFrameWidth, m_sInPortDef.format.video.nFrameHeight);
+                post_event ((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
+                return OMX_ErrorNone;
+            }
         }
         if (dev_use_buf(PORT_INDEX_IN) != true) {
             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp b/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp
index 574585b..abdc9fc 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp
@@ -37,10 +37,15 @@
     ADD_EXTENSION("qti-ext-enc-preprocess-mirror", OMX_IndexConfigCommonMirror, OMX_DirOutput)
     ADD_PARAM_END("flip", OMX_AndroidVendorValueInt32)
 
-    ADD_EXTENSION("qti-ext-enc-avc-intra-period", OMX_IndexConfigVideoAVCIntraPeriod, OMX_DirOutput)
+    ADD_EXTENSION("qti-ext-enc-avc-intra-period", QOMX_IndexConfigVideoIntraperiod, OMX_DirOutput)
     ADD_PARAM    ("n-pframes",    OMX_AndroidVendorValueInt32)
     ADD_PARAM_END("n-idr-period", OMX_AndroidVendorValueInt32)
 
+    ADD_EXTENSION("qti-ext-enc-intra-period", QOMX_IndexConfigVideoIntraperiod, OMX_DirOutput)
+    ADD_PARAM    ("n-pframes",    OMX_AndroidVendorValueInt32)
+    ADD_PARAM    ("n-bframes",    OMX_AndroidVendorValueInt32)
+    ADD_PARAM_END("n-idr-period", OMX_AndroidVendorValueInt32)
+
     ADD_EXTENSION("qti-ext-enc-error-correction", OMX_QcomIndexParamVideoSliceSpacing, OMX_DirOutput)
     ADD_PARAM_END("resync-marker-spacing-bits", OMX_AndroidVendorValueInt32)
 
@@ -139,10 +144,16 @@
             setStatus &= vExt.setParamInt32(ext, "flip", m_sConfigFrameMirror.eMirror);
             break;
         }
-        case OMX_IndexConfigVideoAVCIntraPeriod:
+        case QOMX_IndexConfigVideoIntraperiod:
         {
-            setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sConfigAVCIDRPeriod.nPFrames);
-            setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sConfigAVCIDRPeriod.nIDRPeriod);
+            if (vExt.isConfigKey(ext, "qti-ext-enc-avc-intra-period")) {
+                setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sIntraperiod.nPFrames);
+                setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sIntraperiod.nIDRPeriod);
+            } else if (vExt.isConfigKey(ext, "qti-ext-enc-intra-period")) {
+                setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sIntraperiod.nPFrames);
+                setStatus &= vExt.setParamInt32(ext, "n-bframes",  m_sIntraperiod.nBFrames);
+                setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sIntraperiod.nIDRPeriod);
+            }
             break;
         }
         case OMX_QcomIndexParamVideoSliceSpacing:
@@ -354,23 +365,33 @@
             }
             break;
         }
-        case OMX_IndexConfigVideoAVCIntraPeriod:
+        case QOMX_IndexConfigVideoIntraperiod:
         {
-            OMX_VIDEO_CONFIG_AVCINTRAPERIOD idrConfig;
-            memcpy(&idrConfig, &m_sConfigAVCIDRPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD));
-            valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(idrConfig.nPFrames));
-            valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(idrConfig.nIDRPeriod));
+            QOMX_VIDEO_INTRAPERIODTYPE intraPeriodConfig;
+            memcpy(&intraPeriodConfig, &m_sIntraperiod, sizeof(QOMX_VIDEO_INTRAPERIODTYPE));
+
+            if (vExt.isConfigKey(ext, "qti-ext-enc-avc-intra-period")) {
+                valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(intraPeriodConfig.nPFrames));
+                valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(intraPeriodConfig.nIDRPeriod));
+
+                DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: AVC-intra-period : nP=%d, nIDR=%d",
+                    intraPeriodConfig.nPFrames, intraPeriodConfig.nIDRPeriod);
+            } else if (vExt.isConfigKey(ext, "qti-ext-enc-intra-period")) {
+                valueSet |= vExt.readParamInt32(ext, "n-bframes", (OMX_S32 *)&(intraPeriodConfig.nBFrames));
+                valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(intraPeriodConfig.nPFrames));
+                valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(intraPeriodConfig.nIDRPeriod));
+
+                DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: intra-period : nIDR=%d, nP=%d, nB=%d",
+                intraPeriodConfig.nIDRPeriod, intraPeriodConfig.nPFrames, intraPeriodConfig.nBFrames);
+            }
             if (!valueSet) {
                 break;
             }
 
-            DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: AVC-intra-period : nP=%d, nIDR=%d",
-                    idrConfig.nPFrames, idrConfig.nIDRPeriod);
-
             err = set_config(
-                    NULL, OMX_IndexConfigVideoAVCIntraPeriod, &idrConfig);
+                    NULL, (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod, &intraPeriodConfig);
             if (err != OMX_ErrorNone) {
-                DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigVideoAVCIntraPeriod failed !");
+                DEBUG_PRINT_ERROR("set_config: QOMX_IndexConfigVideoIntraperiod failed !");
             }
             break;
         }
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 89543d4..383f20b 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
@@ -148,6 +148,7 @@
     memset(&color_space, 0x0, sizeof(color_space));
     memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
     client_req_disable_bframe   = false;
+    bframe_implicitly_enabled = false;
     client_req_disable_temporal_layers  = false;
     client_req_turbo_mode  = false;
     intra_period.num_pframes = 29;
@@ -756,6 +757,11 @@
         data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) +
             sizeof(struct msm_vidc_roi_qp_payload) +
             roi.info.nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
+        if (data->nSize > input_extradata_info.buffer_size  - consumed_len) {
+           DEBUG_PRINT_ERROR("Buffer size (%lu) is less than ROI extradata size (%u)",
+                             (input_extradata_info.buffer_size - consumed_len) ,data->nSize);
+           return false;
+        }
         data->nVersion.nVersion = OMX_SPEC_VERSION;
         data->nPortIndex = 0;
         data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
@@ -769,6 +775,7 @@
         DEBUG_PRINT_HIGH("Using ROI QP map: Enable = %d", roiData->b_roi_info);
         memcpy(roiData->data, roi.info.pRoiMBInfo, roi.info.nRoiMBInfoSize);
         data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+        consumed_len += data->nSize;
     }
 
     if (m_roi_enabled) {
@@ -2773,6 +2780,11 @@
                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
                         return false;
                     }
+
+                    if (venc_set_idr_period(intraperiod->nIDRPeriod) == false) {
+                        DEBUG_PRINT_ERROR("ERROR: Setting idr period failed");
+                        return false;
+                    }
                 }
                 client_req_disable_bframe = (intraperiod->nBFrames == 0) ? true : false;
 
@@ -3856,7 +3868,7 @@
                                 } else {
                                     DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
                                     fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
-                                    venc_set_colorspace(MSM_VIDC_BT709_5, 1,
+                                    venc_set_colorspace(MSM_VIDC_BT709_5, 0,
                                             MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
                                 }
                             } else {
@@ -4115,13 +4127,26 @@
         }
     }
 
+    if (!streaming[OUTPUT_PORT] &&
+        (m_sVenc_cfg.inputformat != V4L2_PIX_FMT_NV12_TP10_UBWC &&
+         m_sVenc_cfg.inputformat != V4L2_PIX_FMT_NV12_P010_UBWC &&
+         m_sVenc_cfg.inputformat != V4L2_PIX_FMT_NV12_UBWC)) {
+        if (bframe_implicitly_enabled) {
+            DEBUG_PRINT_HIGH("Disabling implicitly enabled B-frames");
+            if (!venc_set_intra_period(intra_period.num_pframes, 0)) {
+                DEBUG_PRINT_ERROR("Failed to set nPframes/nBframes");
+                return OMX_ErrorUndefined;
+            }
+        }
+    }
+
     extra_idx = EXTRADATA_IDX(num_input_planes);
 
     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
         int extradata_index = venc_get_index_from_fd(input_extradata_info.m_ion_dev,fd);
         if (extradata_index < 0 ) {
                 DEBUG_PRINT_ERROR("Extradata index calculation went wrong for fd = %d", fd);
-                return OMX_ErrorBadParameter;
+                return false;
             }
 
         plane[extra_idx].bytesused = 0;
@@ -5025,6 +5050,7 @@
     if (enableBframes && intra_period.num_bframes == 0) {
         intra_period.num_bframes = VENC_BFRAME_MAX_COUNT;
         intra_period.num_pframes = intra_period.num_pframes / (1 + intra_period.num_bframes);
+        bframe_implicitly_enabled = true;
     } else if (!enableBframes && intra_period.num_bframes > 0) {
         intra_period.num_pframes = intra_period.num_pframes + (intra_period.num_pframes * intra_period.num_bframes);
         intra_period.num_bframes = 0;
@@ -5098,7 +5124,7 @@
         (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN)        &&
         (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10)      &&
         (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
-        nBFrames=0;
+        nBFrames = 0;
     }
 
     if (temporal_layers_config.nPLayers > 1 && nBFrames) {
@@ -7304,10 +7330,10 @@
     for (int i = 0; i < 3; i++) {
         int first_idx = 2*i+1;
         int second_idx = 2*i+2;
-        ctrl[first_idx].id = RGB_PRIMARY_TABLE[first_idx];
+        ctrl[first_idx].id = RGB_PRIMARY_TABLE[first_idx-1];
         ctrl[first_idx].value = mastering_disp_info.primaries.rgbPrimaries[i][0];
 
-        ctrl[second_idx].id = RGB_PRIMARY_TABLE[second_idx];
+        ctrl[second_idx].id = RGB_PRIMARY_TABLE[second_idx-1];
         ctrl[second_idx].value = mastering_disp_info.primaries.rgbPrimaries[i][1];
     }