Merge "Fix for the flicker while changing the resolution in DashPlayer"
diff --git a/mm-video/vidc/common/inc/extra_data_handler.h b/mm-video/vidc/common/inc/extra_data_handler.h
index 42fc3ea..c7b6e7b 100644
--- a/mm-video/vidc/common/inc/extra_data_handler.h
+++ b/mm-video/vidc/common/inc/extra_data_handler.h
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -43,22 +43,31 @@
 #include<utils/Log.h>
 }
 #ifdef ENABLE_DEBUG_LOW
+#undef DEBUG_PRINT_LOW
 #define DEBUG_PRINT_LOW ALOGE
 #else
+#undef DEBUG_PRINT_LOW
 #define DEBUG_PRINT_LOW
 #endif
 #ifdef ENABLE_DEBUG_HIGH
+#undef DEBUG_PRINT_HIGH
 #define DEBUG_PRINT_HIGH ALOGE
 #else
+#undef DEBUG_PRINT_HIGH
 #define DEBUG_PRINT_HIGH
 #endif
 #ifdef ENABLE_DEBUG_ERROR
+#undef DEBUG_PRINT_ERROR
 #define DEBUG_PRINT_ERROR ALOGE
 #else
+#undef DEBUG_PRINT_ERROR
 #define DEBUG_PRINT_ERROR
 #endif
 
 #else //_ANDROID_
+#undef DEBUG_PRINT_LOW
+#undef DEBUG_PRINT_HIGH
+#undef DEBUG_PRINT_ERROR
 #define DEBUG_PRINT_LOW printf
 #define DEBUG_PRINT_HIGH printf
 #define DEBUG_PRINT_ERROR printf
diff --git a/mm-video/vidc/vdec/inc/omx_vdec.h b/mm-video/vidc/vdec/inc/omx_vdec.h
index bab8167..2ef2cfe 100644
--- a/mm-video/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video/vidc/vdec/inc/omx_vdec.h
@@ -609,6 +609,7 @@
     OMX_ERRORTYPE update_picture_resolution();
     int stream_off(OMX_U32 port);
     void adjust_timestamp(OMX_S64 &act_timestamp);
+    void enableAdditionalCores(int frm_int);
     void set_frame_rate(OMX_S64 act_timestamp);
     void handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr);
     void handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr);
@@ -871,6 +872,7 @@
     bool external_meta_buffer_iommu;
     OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata;
     bool codec_config_flag;
+    void* opt_handle;
 #ifdef _MSM8974_
     int capture_capability;
     int output_capability;
@@ -884,6 +886,11 @@
     bool async_thread_created;
 
     unsigned int m_fill_output_msg;
+
+    int (*perf_lock_acq)(int handle, int duration, int list[], int numArgs);
+    int (*perf_lock_rel)(int handle);
+    void (*perf_cpu_boost)(int ntasks);
+    int perf_lock_handle;
     class allocate_color_convert_buf {
     public:
         allocate_color_convert_buf();
diff --git a/mm-video/vidc/vdec/src/h264_utils.cpp b/mm-video/vidc/vdec/src/h264_utils.cpp
index 2cd40c3..651bb6b 100644
--- a/mm-video/vidc/vdec/src/h264_utils.cpp
+++ b/mm-video/vidc/vdec/src/h264_utils.cpp
@@ -1071,15 +1071,17 @@
     uev(); //bit_depth_luma_minus8
     uev(); //bit_depth_chroma_minus8
     extract_bits(1); //qpprime_y_zero_transform_bypass_flag
-    if (extract_bits(1)) //seq_scaling_matrix_present_flag
-      for (int i = 0; i < scaling_matrix_limit && more_bits(); i++)
+    if (extract_bits(1)) { //seq_scaling_matrix_present_flag
+      for (unsigned int i = 0; i < scaling_matrix_limit && more_bits(); i++)
       {
-        if (extract_bits(1)) ////seq_scaling_list_present_flag[ i ]
+        if (extract_bits(1)) { ////seq_scaling_list_present_flag[ i ]
           if (i < 6)
             scaling_list(16);
           else
             scaling_list(64);
+        }
       }
+    }
   }
   uev(); //log2_max_frame_num_minus4
   value = uev(); //pic_order_cnt_type
@@ -1091,7 +1093,7 @@
     sev(); //offset_for_non_ref_pic
     sev(); //offset_for_top_to_bottom_field
     value = uev(); // num_ref_frames_in_pic_order_cnt_cycle
-    for (int i = 0; i < value; i++)
+    for (unsigned int i = 0; i < value; i++)
       sev(); //offset_for_ref_frame[ i ]
   }
   uev(); //max_num_ref_frames
@@ -1116,7 +1118,7 @@
 void h264_stream_parser::scaling_list(OMX_U32 size_of_scaling_list)
 {
   OMX_S32 last_scale = 8, next_scale = 8, delta_scale;
-  for (int j = 0; j < size_of_scaling_list; j++)
+  for (unsigned int j = 0; j < size_of_scaling_list; j++)
   {
     if (next_scale != 0)
     {
@@ -1437,12 +1439,12 @@
 #else
   h264_pan_scan *pan_scan_param = &panscan_param;
 #endif
-  if (pan_scan_param)
+  if (pan_scan_param) {
     if (!(pan_scan_param->rect_id & NO_PAN_SCAN_BIT))
     {
       PRINT_PANSCAN_PARAM(*pan_scan_param);
       dest_pan_scan->numWindows = pan_scan_param->cnt;
-      for (int i = 0; i < dest_pan_scan->numWindows; i++)
+      for (unsigned int i = 0; i < dest_pan_scan->numWindows; i++)
       {
         dest_pan_scan->window[i].x = pan_scan_param->rect_left_offset[i];
         dest_pan_scan->window[i].y = pan_scan_param->rect_top_offset[i];
@@ -1460,6 +1462,7 @@
     }
     else
       pan_scan_param->rect_repetition_period = 0;
+  }
 }
 
 OMX_S64 h264_stream_parser::process_ts_with_sei_vui(OMX_S64 timestamp)
@@ -1594,11 +1597,12 @@
       panscan_node->active = true;
     }
   }
-  if (data)
+  if (data) {
     if (data->rect_repetition_period == 0)
       panscan_free.add_last(panscan_used.remove_first());
     else if (data->rect_repetition_period > 1)
       data->rect_repetition_period -= 2;
+  }
   PRINT_PANSCAN_DATA(panscan_node);
   return data;
 }
diff --git a/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp
index e41e9f9..69f33a7 100644
--- a/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp
+++ b/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp
@@ -560,7 +560,11 @@
 	iDivXDrmDecrypt(NULL),
 #endif
 	m_desc_buffer_ptr(NULL),
-	secure_mode(false)
+	secure_mode(false),
+	opt_handle(NULL),
+	perf_lock_acq(NULL),
+	perf_lock_rel(NULL),
+	perf_lock_handle(-1)
 {
   /* Assumption is that , to begin with , we have all the frames with decoder */
   DEBUG_PRINT_HIGH("In OMX vdec Constructor");
@@ -720,6 +724,15 @@
   pthread_mutex_destroy(&m_lock);
   pthread_mutex_destroy(&c_lock);
   sem_destroy(&m_cmd_lock);
+  if (perf_lock_handle >= 0 && perf_lock_rel) {
+    DEBUG_PRINT_LOW("Lock released");
+    perf_lock_rel(perf_lock_handle);
+    perf_lock_handle = -1;
+  }
+  if (opt_handle) {
+    dlclose(opt_handle);
+    opt_handle = NULL;
+  }
   if (perf_flag)
   {
     DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
@@ -2632,7 +2645,7 @@
       }
       else
       {
-        DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
+        DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
             profileLevelType->nProfileIndex);
         eRet = OMX_ErrorNoMore;
       }
@@ -3083,9 +3096,10 @@
               drv_ctx.frame_rate.fps_denominator = 1;
             frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
                       drv_ctx.frame_rate.fps_numerator;
-            DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
+            DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
                              frm_int, drv_ctx.frame_rate.fps_numerator /
                              (float)drv_ctx.frame_rate.fps_denominator);
+            enableAdditionalCores(frm_int);
         }
          DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
          if(drv_ctx.video_resolution.frame_height !=
@@ -3093,7 +3107,7 @@
              drv_ctx.video_resolution.frame_width  !=
                portDefn->format.video.nFrameWidth)
          {
-             DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n",
+             DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
                            portDefn->format.video.nFrameWidth,
                            portDefn->format.video.nFrameHeight);
              if (portDefn->format.video.nFrameHeight != 0x0 &&
@@ -3197,7 +3211,7 @@
     {
         OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
             (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
-        DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n",
+        DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
             portFmt->nFramePackingFormat);
 
         /* Input port */
@@ -3366,10 +3380,10 @@
                return OMX_ErrorIncorrectStateOperation;
             }
             OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
-            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
+            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
               priorityMgmtype->nGroupID);
 
-            DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
+            DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
              priorityMgmtype->nGroupPriority);
 
             m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
@@ -3788,7 +3802,7 @@
       // case where SPS+PPS is sent as part of set_config
       pDestBuf = m_vendor_config.pData;
 
-      DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
+      DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
            m_vendor_config.nPortIndex,
            m_vendor_config.nDataSize,
            m_vendor_config.pData);
@@ -4202,7 +4216,7 @@
         }
         pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
                     pmem_list->entryList->entry;
-        DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x",
+        DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
                           pmem_info->pmem_fd);
         drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
         drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
@@ -4250,8 +4264,6 @@
      buf.m.planes = plane;
      buf.length = drv_ctx.num_planes;
 
-     DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
-
      if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
        DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
 	   /*TODO: How to handle this case */	
@@ -4393,7 +4405,7 @@
     DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
     error = OMX_ErrorBadPortIndex;
   }
-  DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error);
+  DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
   if(error == OMX_ErrorNone)
   {
     if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
@@ -4459,7 +4471,7 @@
           sizeof (vdec_bufferpayload));
        DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
                     drv_ctx.ptr_inputbuffer[index].pmem_fd);
-       DEBUG_PRINT_LOW("\n unmap the input buffer size=%d  address = %d",
+       DEBUG_PRINT_LOW("\n unmap the input buffer size=%d  address = %p",
                     drv_ctx.ptr_inputbuffer[index].mmaped_size,
                     drv_ctx.ptr_inputbuffer[index].bufferaddr);
        munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
@@ -4496,7 +4508,7 @@
   if (index < drv_ctx.op_buf.actualcount
       && drv_ctx.ptr_outputbuffer)
   {
-    DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
+    DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
                     drv_ctx.ptr_outputbuffer[index].bufferaddr);
 
     struct vdec_setbuffer_cmd setbuffers;
@@ -4516,7 +4528,7 @@
         {
             DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
                     drv_ctx.ptr_outputbuffer[0].pmem_fd);
-            DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d  address = %d",
+            DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d  address = %p",
                     drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
                     drv_ctx.ptr_outputbuffer[0].bufferaddr);
             munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
@@ -4653,7 +4665,7 @@
 
   if(bytes != drv_ctx.ip_buf.buffer_size)
   {
-    DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",
+    DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
       bytes, drv_ctx.ip_buf.buffer_size);
     return OMX_ErrorBadParameter;
   }
@@ -4788,7 +4800,8 @@
     buf.m.planes = &plane;
     buf.length = 1;
 
-     DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_inputbuffer[i]);
+     DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
+             drv_ctx.ptr_inputbuffer[i].bufferaddr);
 
      rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
     
@@ -6106,14 +6119,16 @@
     DEBUG_PRINT_HIGH("\n Close the driver instance");
    
 #ifdef INPUT_BUFFER_LOG
-    fclose (inputBufferFile1);
+    if (inputBufferFile1)
+        fclose (inputBufferFile1);
 #endif
 #ifdef OUTPUT_BUFFER_LOG
     if (outputBufferFile1)
-		fclose (outputBufferFile1);
+        fclose (outputBufferFile1);
 #endif
 #ifdef OUTPUT_EXTRADATA_LOG
-    fclose (outputExtradataFile);
+    if (outputExtradataFile)
+        fclose (outputExtradataFile);
 #endif
   DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
   return OMX_ErrorNone;
@@ -6607,7 +6622,7 @@
       int stride = drv_ctx.video_resolution.stride;
       int scanlines = drv_ctx.video_resolution.scan_lines;
       char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
-	  int i;
+	  unsigned i;
 	  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, 1, outputBufferFile1);
@@ -8259,6 +8274,7 @@
         DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
                          frm_int, drv_ctx.frame_rate.fps_numerator /
                          (float)drv_ctx.frame_rate.fps_denominator);
+        enableAdditionalCores(frm_int);
       }
     }
   }
@@ -9229,3 +9245,39 @@
   }
   return status;
 }
+
+void omx_vdec::enableAdditionalCores(int frame_interval)
+{
+  DEBUG_PRINT_LOW("Setting frame rate to 1/(%dusec)", frame_interval);
+  if (frame_interval < 33000)
+  {
+    DEBUG_PRINT_HIGH("Turning on additional CPU cores");
+    if (NULL == opt_handle) {
+      char opt_lib_path[PATH_MAX] = {0};
+
+      if (property_get("ro.vendor.extension_library", opt_lib_path, NULL) != 0) {
+        if ((opt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
+          DEBUG_PRINT_ERROR("Unable to open %s: %s\n", opt_lib_path, dlerror());
+        } else {
+          perf_lock_acq = (int(*)(int, int, int*,int))dlsym(opt_handle, "perf_lock_acq");
+          if (perf_lock_acq == NULL) {
+            DEBUG_PRINT_ERROR("failed to get lock_acq sym");
+          }
+
+          perf_lock_rel = (int(*)(int))dlsym(opt_handle, "perf_lock_rel");
+          if (perf_lock_rel == NULL) {
+            DEBUG_PRINT_ERROR("failed to get lock_rel sym");
+          }
+        }
+      } else {
+        DEBUG_PRINT_ERROR("Property ro.vendor.extension_library does not exist.");
+      }
+    }
+
+    int decode_opts[1] = {0x704}; //value of last nibble == # of cores
+    if (perf_lock_acq && perf_lock_handle < 0) {
+      DEBUG_PRINT_LOW("Lock acquired");
+      perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, decode_opts, 1);
+    }
+  }
+}
diff --git a/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h
index aba6029..739cc2c 100644
--- a/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -41,7 +41,6 @@
 
 #define TIMEOUT 5*60*1000
 
-void* async_venc_message_thread (void *);
 
 struct msm_venc_switch{
 	unsigned char	status;
@@ -182,6 +181,7 @@
   venc_dev(class omx_venc *venc_class); //constructor
   ~venc_dev(); //des
 
+  static void* async_venc_message_thread (void *);
   bool venc_open(OMX_U32);
   void venc_close();
   unsigned venc_stop(void);
@@ -293,6 +293,10 @@
   bool streaming[MAX_PORT];
   bool extradata;
   struct extradata_buffer_info extradata_info;
+
+  pthread_mutex_t pause_resume_mlock;
+  pthread_cond_t pause_resume_cond;
+  bool paused;
 };
 
 enum instance_state {
diff --git a/mm-video/vidc/venc/src/omx_video_encoder.cpp b/mm-video/vidc/venc/src/omx_video_encoder.cpp
index 9bba0fc..6441585 100644
--- a/mm-video/vidc/venc/src/omx_video_encoder.cpp
+++ b/mm-video/vidc/venc/src/omx_video_encoder.cpp
@@ -435,7 +435,7 @@
         m_pipe_out = fds[1];
       }
     }
-    r = pthread_create(&msg_thread_id,0,message_thread,this);
+    r = pthread_create(&msg_thread_id,0, message_thread, this);
 
     if(r < 0)
     {
@@ -443,7 +443,7 @@
     }
     else
     {
-      r = pthread_create(&async_thread_id,0,async_venc_message_thread,this);
+    r = pthread_create(&async_thread_id,0, venc_dev::async_venc_message_thread, this);
       dev_set_message_thread_id(async_thread_id);
       if(r < 0)
       {
diff --git a/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp
index 92ef1b4..b07bb03 100644
--- a/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -48,7 +48,7 @@
 #define H264_BP_START 0
 #define H264_HP_START (H264_BP_START + 13)
 #define H264_MP_START (H264_BP_START + 26)
-#define POLL_TIMEOUT 0x7fffffff
+#define POLL_TIMEOUT 1000
 
 /* MPEG4 profile and level table*/
 static const unsigned int mpeg4_profile_level_table[][5]=
@@ -174,6 +174,10 @@
 	etb_count=0;
 	for (i = 0; i < MAX_PORT; i++)
 		streaming[i] = false;
+
+	paused = false;
+	pthread_mutex_init(&pause_resume_mlock, NULL);
+	pthread_cond_init(&pause_resume_cond, NULL);
 }
 
 venc_dev::~venc_dev()
@@ -181,9 +185,8 @@
   //nothing to do
 }
 
-void* async_venc_message_thread (void *input)
+void* venc_dev::async_venc_message_thread (void *input)
 {
-  struct venc_timeout timeout;
   struct venc_msg venc_msg;
   omx_video* omx_venc_base = NULL;
   omx_venc *omx = reinterpret_cast<omx_venc*>(input);
@@ -191,7 +194,6 @@
   OMX_BUFFERHEADERTYPE* omxhdr = NULL;
 
   prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
-  timeout.millisec = VEN_TIMEOUT_INFINITE;
   struct v4l2_plane plane[VIDEO_MAX_PLANES];
   struct pollfd pfd;
   struct v4l2_buffer v4l2_buf;
@@ -203,10 +205,36 @@
   memset(&v4l2_buf, 0, sizeof(v4l2_buf));
   while(1)
   {
+	  pthread_mutex_lock(&omx->handle->pause_resume_mlock);
+	  if (omx->handle->paused) {
+		  venc_msg.msgcode = VEN_MSG_PAUSE;
+		  venc_msg.statuscode = VEN_S_SUCCESS;
+		  if(omx->async_message_process(input, &venc_msg) < 0)
+		  {
+			  DEBUG_PRINT_ERROR("\nERROR: Failed to process pause msg");
+			  pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
+			  break;
+		  }
+
+		  /* Block here until the IL client resumes us again */
+		  pthread_cond_wait(&omx->handle->pause_resume_cond,
+				  &omx->handle->pause_resume_mlock);
+
+		  venc_msg.msgcode = VEN_MSG_RESUME;
+		  venc_msg.statuscode = VEN_S_SUCCESS;
+		  if(omx->async_message_process(input, &venc_msg) < 0)
+		  {
+			  DEBUG_PRINT_ERROR("\nERROR: Failed to process resume msg");
+			  pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
+			  break;
+		  }
+	  }
+	  pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
+
 	  rc = poll(&pfd, 1, POLL_TIMEOUT);
 		if (!rc) {
-			DEBUG_PRINT_ERROR("Poll timedout\n");
-			break;
+			DEBUG_PRINT_HIGH("Poll timedout\n");
+			continue;
 		} else if (rc < 0) {
 			DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
 			break;
@@ -1302,12 +1330,19 @@
 
 unsigned venc_dev::venc_pause(void)
 {
-  return 0;
+	pthread_mutex_lock(&pause_resume_mlock);
+	paused = true;
+	pthread_mutex_unlock(&pause_resume_mlock);
+	return 0;
 }
 
 unsigned venc_dev::venc_resume(void)
 {
-  return 0;
+	pthread_mutex_lock(&pause_resume_mlock);
+	paused = false;
+	pthread_mutex_unlock(&pause_resume_mlock);
+
+	return pthread_cond_signal(&pause_resume_cond);
 }
 
 unsigned venc_dev::venc_start_done(void)
@@ -1692,9 +1727,17 @@
 	control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
 	control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
 	DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
-	if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
-		DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
-		return false;
+	if(multislice.mslice_mode && multislice.mslice_mode != V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
+	{
+		if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+			DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
+			return false;
+		}
+	}
+	else
+	{
+		DEBUG_PRINT_ERROR("Failed to set slice extradata, slice_mode "
+						  "is set to [%lu]", multislice.mslice_mode);
 	}
 	return true;
 }