msm: vidc: Add support for Picture Order Count Type

This patch adds POC type support for video core that
enables low-latency encoding.

Signed-off-by: Shiju Mathew <shijum@codeaurora.org>

Conflicts:
	drivers/video/msm/vidc/common/enc/venc.c
	include/media/msm/vcd_property.h

Change-Id: I1fe8ea38c7ed8d203a3ef99febb4001165a856fe
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index e0a4609..aa30ec3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -347,6 +347,7 @@
 	u32 avc_delimiter_enable;
 	u32 vui_timinginfo_enable;
 	u32 bitstream_restrict_enable;
+	u32 pic_order_cnt_type;
 };
 struct ddl_decoder_data {
 	struct ddl_codec_data_hdr  hdr;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 738bd82..1c1d6c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1226,6 +1226,27 @@
 		}
 		break;
 	}
+	case VCD_I_PIC_ORDER_CNT_TYPE:
+	{
+		struct vcd_property_pic_order_cnt_type *poc =
+			(struct vcd_property_pic_order_cnt_type *)
+				property_value;
+		if (sizeof(struct vcd_property_pic_order_cnt_type) ==
+			property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_H264 &&
+			(poc->poc_type == 0 || poc->poc_type == 2)) {
+			if (encoder->i_period.b_frames &&
+				poc->poc_type) {
+				DDL_MSG_HIGH("bframes = %d. Setting poc to 0",
+					encoder->i_period.b_frames);
+				encoder->pic_order_cnt_type = 0;
+			} else {
+				encoder->pic_order_cnt_type = poc->poc_type;
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
+	}
 	default:
 		DDL_MSG_ERROR("%s: INVALID ID 0x%x\n", __func__,
 			(int)property_hdr->prop_id);
@@ -1826,6 +1847,15 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 	break;
+	case VCD_I_PIC_ORDER_CNT_TYPE:
+		if (sizeof(struct vcd_property_pic_order_cnt_type) ==
+			property_hdr->sz) {
+			((struct vcd_property_pic_order_cnt_type *)
+				property_value)->poc_type
+					= encoder->pic_order_cnt_type;
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
 	default:
 		DDL_MSG_ERROR("%s: unknown prop_id = 0x%x", __func__,
 			property_hdr->prop_id);
@@ -1873,6 +1903,12 @@
 			property_hdr->sz) {
 			encoder->i_period = *i_period;
 			dynamic_prop_change = DDL_ENC_CHANGE_IPERIOD;
+			if (encoder->i_period.b_frames &&
+				encoder->pic_order_cnt_type) {
+				DDL_MSG_HIGH("bframes = %d. Setting poc to 0",
+					encoder->i_period.b_frames);
+				encoder->pic_order_cnt_type = 0;
+			}
 			vcd_status = VCD_S_SUCCESS;
 		}
 	}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 11cc1f4..21f3d90 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -600,7 +600,6 @@
 	const u32 recon_bufs = 4;
 	u32 h263_cpfc_enable = false;
 	u32 scaled_frame_rate, ltr_enable;
-	u32 pic_order_count = false;
 
 	ddl_vidc_encode_set_profile_level(ddl);
 	vidc_1080p_set_encode_frame_size(encoder->frame_size.width,
@@ -621,8 +620,6 @@
 		(DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE)
 		 != scaled_frame_rate))
 		h263_cpfc_enable = true;
-	if (encoder->codec.codec == VCD_CODEC_H264)
-		pic_order_count = true;
 
 	ltr_enable = DDL_IS_LTR_ENABLED(encoder);
 	DDL_MSG_HIGH("ltr_enable = %u", ltr_enable);
@@ -630,7 +627,7 @@
 		[ddl->command_channel], hdr_ext_control,
 		r_cframe_skip, false, 0,
 		h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
-		pic_order_count, encoder->closed_gop, encoder->
+		encoder->pic_order_cnt_type, encoder->closed_gop, encoder->
 		avc_delimiter_enable, encoder->vui_timinginfo_enable,
 		encoder->bitstream_restrict_enable, ltr_enable);
 	if (encoder->vui_timinginfo_enable) {
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index e6c0691..4a32016 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 2015, Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2003,6 +2003,48 @@
 		}
 		break;
 	}
+	case VEN_IOCTL_SET_PIC_ORDER_CNT_TYPE:
+	case VEN_IOCTL_GET_PIC_ORDER_CNT_TYPE:
+	{
+		struct vcd_property_hdr vcd_property_hdr;
+		struct vcd_property_pic_order_cnt_type vcd_property_val;
+		struct venc_poctype poc;
+
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		if (cmd == VEN_IOCTL_SET_PIC_ORDER_CNT_TYPE) {
+			if (copy_from_user(&poc, venc_msg.in, sizeof(poc)))
+				return -EFAULT;
+
+			vcd_property_hdr.prop_id = VCD_I_PIC_ORDER_CNT_TYPE;
+			vcd_property_hdr.sz = sizeof(struct
+					vcd_property_pic_order_cnt_type);
+
+			vcd_property_val.poc_type = poc.poc_type;
+
+			result = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_val);
+		} else {
+			vcd_property_hdr.prop_id = VCD_I_PIC_ORDER_CNT_TYPE;
+			vcd_property_hdr.sz = sizeof(struct
+					vcd_property_pic_order_cnt_type);
+
+			result = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_property_val);
+			if (!result) {
+				poc.poc_type = vcd_property_val.poc_type;
+				if (copy_to_user(venc_msg.out, &poc,
+					sizeof(poc)))
+					return -EFAULT;
+			}
+		}
+		if (result) {
+			ERR("VEN_IOCTL_(G)SET_PIC_ORDER_CNT_TYPE failed\n");
+			return -EIO;
+		}
+		break;
+	}
 	case VEN_IOCTL_SET_AC_PREDICTION:
 	case VEN_IOCTL_GET_AC_PREDICTION:
 	case VEN_IOCTL_SET_RVLC:
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index e4f973f..9aaf480 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -515,6 +515,12 @@
 /*IOCTL params:GET: InputData - NULL, OutputData - venc_ltrmark.*/
 #define VEN_IOCTL_GET_LTRMARK \
 	_IOR(VEN_IOCTLBASE_ENC, 65, struct venc_ioctl_msg)
+/*IOCTL params:SET: InputData - venc_poctype, OutputData - NULL.*/
+#define VEN_IOCTL_SET_PIC_ORDER_CNT_TYPE \
+	_IOW(VEN_IOCTLBASE_ENC, 66, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_poctype.*/
+#define VEN_IOCTL_GET_PIC_ORDER_CNT_TYPE \
+	_IOR(VEN_IOCTLBASE_ENC, 67, struct venc_ioctl_msg)
 
 struct venc_range {
 	unsigned long        max;
@@ -698,4 +704,8 @@
 	unsigned long ltr_frames;
 };
 
+struct venc_poctype {
+	unsigned long poc_type;
+};
+
 #endif /* _MSM_VIDC_ENC_H_ */
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 3852f5f..cbb3c0c 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -70,6 +70,7 @@
 #define VCD_I_LTR_USE (VCD_START_BASE + 0x34)
 #define VCD_I_CAPABILITY_LTR_COUNT (VCD_START_BASE + 0x35)
 #define VCD_I_LTR_MARK (VCD_START_BASE + 0x36)
+#define VCD_I_PIC_ORDER_CNT_TYPE (VCD_START_BASE + 0x37)
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
 #define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)
@@ -449,4 +450,8 @@
 	u32 ltr_frames;
 };
 
+struct vcd_property_pic_order_cnt_type {
+	u32 poc_type;
+};
+
 #endif