64035ac463
Prepare for better device categorization by moving everything to testing subdir first. [skip-ci]: chicken-egg problem: passing pmaports CI depends on pmbootstrap MR depends on this MR Related: postmarketos#16
6547 lines
215 KiB
Diff
6547 lines
215 KiB
Diff
From e9eb0f878b6c2173654d6d7780fd1babc427ccea Mon Sep 17 00:00:00 2001
|
|
From: "elel@3wh.net" <elel@3wh.net>
|
|
Date: Thu, 27 Dec 2018 14:37:10 +0000
|
|
Subject: [PATCH 5/5] Use Samsung MFC from A810
|
|
|
|
---
|
|
drivers/media/platform/exynos/mfc/Kconfig | 0
|
|
drivers/media/platform/exynos/mfc/Makefile | 0
|
|
.../media/platform/exynos/mfc/regs-mfc-v5.h | 3 +
|
|
.../media/platform/exynos/mfc/regs-mfc-v6.h | 34 +-
|
|
.../media/platform/exynos/mfc/regs-mfc-v8.h | 32 +-
|
|
.../media/platform/exynos/mfc/regs-mfc-v9.h | 42 +-
|
|
drivers/media/platform/exynos/mfc/s5p_mfc.c | 509 +++--
|
|
.../media/platform/exynos/mfc/s5p_mfc_cmd.h | 0
|
|
.../platform/exynos/mfc/s5p_mfc_cmd_v5.c | 0
|
|
.../platform/exynos/mfc/s5p_mfc_cmd_v6.c | 0
|
|
.../platform/exynos/mfc/s5p_mfc_common.h | 145 +-
|
|
.../media/platform/exynos/mfc/s5p_mfc_ctrl.c | 42 +-
|
|
.../media/platform/exynos/mfc/s5p_mfc_ctrl.h | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_debug.h | 7 -
|
|
.../media/platform/exynos/mfc/s5p_mfc_dec.c | 170 +-
|
|
.../media/platform/exynos/mfc/s5p_mfc_dec.h | 2 +-
|
|
.../media/platform/exynos/mfc/s5p_mfc_enc.c | 1764 +++++++++++++----
|
|
.../media/platform/exynos/mfc/s5p_mfc_enc.h | 2 +-
|
|
.../media/platform/exynos/mfc/s5p_mfc_inst.c | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_inst.h | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_intr.c | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_intr.h | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_mem.c | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_mem.h | 0
|
|
.../platform/exynos/mfc/s5p_mfc_opr_v5.c | 4 +-
|
|
.../platform/exynos/mfc/s5p_mfc_opr_v5.h | 1 +
|
|
.../platform/exynos/mfc/s5p_mfc_opr_v6.c | 1154 ++++++-----
|
|
.../platform/exynos/mfc/s5p_mfc_opr_v6.h | 1 +
|
|
.../platform/exynos/mfc/s5p_mfc_opr_v8.h | 1 +
|
|
.../platform/exynos/mfc/s5p_mfc_opr_v9.h | 25 -
|
|
.../media/platform/exynos/mfc/s5p_mfc_pm.c | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_pm.h | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_qos.c | 15 +-
|
|
.../media/platform/exynos/mfc/s5p_mfc_reg.c | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_reg.h | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_shm.c | 0
|
|
.../media/platform/exynos/mfc/s5p_mfc_shm.h | 0
|
|
include/uapi/linux/v4l2-controls.h | 6 +-
|
|
include/uapi/linux/videodev2_exynos_media.h | 128 +-
|
|
39 files changed, 2820 insertions(+), 1267 deletions(-)
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/Kconfig
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/Makefile
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v5.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v6.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v8.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v9.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_cmd.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v5.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v6.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_common.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_inst.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_inst.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_intr.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_intr.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_mem.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_pm.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_pm.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_reg.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_reg.h
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_shm.c
|
|
mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_shm.h
|
|
mode change 100644 => 100755 include/uapi/linux/v4l2-controls.h
|
|
mode change 100644 => 100755 include/uapi/linux/videodev2_exynos_media.h
|
|
|
|
diff --git a/drivers/media/platform/exynos/mfc/Kconfig b/drivers/media/platform/exynos/mfc/Kconfig
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/Makefile b/drivers/media/platform/exynos/mfc/Makefile
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v5.h b/drivers/media/platform/exynos/mfc/regs-mfc-v5.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index d7a16b816b88..1e63a2f79548
|
|
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v5.h
|
|
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v5.h
|
|
@@ -128,6 +128,7 @@
|
|
#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1
|
|
#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2
|
|
#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
|
|
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH 5
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
|
|
#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */
|
|
@@ -398,6 +399,8 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_MFC_VERSION 0
|
|
#define S5P_FIMV_ERR_FRAME_CONCEAL -1
|
|
#define S5P_FIMV_R2H_CMD_DPB_FLUSH_RET -2
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0 -1
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1 -1
|
|
|
|
/* for compatibility */
|
|
#define S5P_FIMV_E_GOP_CONFIG2 -1
|
|
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v6.h b/drivers/media/platform/exynos/mfc/regs-mfc-v6.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index bce2f1571dc2..15f83e965b76
|
|
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v6.h
|
|
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v6.h
|
|
@@ -140,6 +140,8 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_RET_INSTANCE_ID 0xF070
|
|
|
|
#define S5P_FIMV_ERROR_CODE 0xF074
|
|
+#define S5P_FIMV_ERR_HEADER_NOT_FOUND 102
|
|
+#define S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED 190
|
|
#define S5P_FIMV_ERR_WARNINGS_START 160
|
|
#define S5P_FIMV_ERR_WARNINGS_END 222
|
|
#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
|
|
@@ -173,6 +175,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
|
|
#define S5P_FIMV_D_SEI_ENABLE 0xF0C4
|
|
#define S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT 1
|
|
+#define S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE 2
|
|
|
|
/* Buffer setting registers */
|
|
#define S5P_FIMV_D_MIN_NUM_DPB 0xF0F0
|
|
@@ -337,6 +340,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_ENC_PROFILE_H264_MAIN 1
|
|
#define S5P_FIMV_ENC_PROFILE_H264_HIGH 2
|
|
#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
|
|
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH 5
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
|
|
#define S5P_FIMV_E_FIXED_PICTURE_QP 0xF790
|
|
@@ -405,12 +409,15 @@ static inline unsigned int r2h_bits(int cmd)
|
|
|
|
#define S5P_FIMV_E_MPEG4_OPTIONS 0xFB10
|
|
#define S5P_FIMV_E_MPEG4_HEC_PERIOD 0xFB14
|
|
+
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0 0xFB44
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1 0xFB48
|
|
+#define S5P_FIMV_E_H264_OPTIONS_2 0xFB4C
|
|
#define S5P_FIMV_E_ASPECT_RATIO 0xFB50
|
|
#define S5P_FIMV_E_EXTENDED_SAR 0xFB54
|
|
|
|
#define S5P_FIMV_E_IDR_H264_IDR 0
|
|
#define S5P_FIMV_E_H264_OPTIONS 0xFB58
|
|
-#define S5P_FIMV_E_H264_OPTIONS_2 0xFB4C
|
|
#define S5P_FIMV_E_H264_LF_ALPHA_OFFSET 0xFB5C
|
|
#define S5P_FIMV_E_H264_LF_BETA_OFFSET 0xFB60
|
|
#define S5P_FIMV_E_H264_I_PERIOD 0xFB64
|
|
@@ -432,13 +439,10 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5 0xFB9C
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6 0xFBA0
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7 0xFBA4
|
|
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET 0xFBA8
|
|
|
|
#define S5P_FIMV_E_NUM_T_LAYER 0xFBAC
|
|
|
|
-/* For backward compatibility */
|
|
-#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET 0xFBA8
|
|
-#define S5P_FIMV_E_H264_NUM_T_LAYER S5P_FIMV_E_NUM_T_LAYER
|
|
-
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 0xFBB0
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1 0xFBB4
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2 0xFBB8
|
|
@@ -448,23 +452,8 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6 0xFBC8
|
|
|
|
/* For backward compatibility */
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1 S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2 S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3 S5P_FIMV_E_HIERARCHICAL_QP_LAYER3
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4 S5P_FIMV_E_HIERARCHICAL_QP_LAYER4
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5 S5P_FIMV_E_HIERARCHICAL_QP_LAYER5
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6 S5P_FIMV_E_HIERARCHICAL_QP_LAYER6
|
|
-
|
|
#define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO 0xFC4C
|
|
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER1 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER2 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER3 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER4 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER5 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER6 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 0xFD18
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1 0xFD1C
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2 0xFD20
|
|
@@ -828,11 +817,6 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_VP8_OPTION 0xFDB0
|
|
#define S5P_FIMV_E_VP8_FILTER_OPTIONS 0xFDB4
|
|
#define S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION 0xFDB8
|
|
-/* For backward compatibility */
|
|
-#define S5P_FIMV_E_VP8_NUM_T_LAYER S5P_FIMV_E_NUM_T_LAYER
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0 S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER1 S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER2 S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
|
|
/* for compatibility */
|
|
#define S5P_FIMV_E_HEVC_OPTIONS -1
|
|
#define S5P_FIMV_E_HEVC_REFRESH_PERIOD -1
|
|
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v8.h b/drivers/media/platform/exynos/mfc/regs-mfc-v8.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 53c38ba1f1ca..195df530aa8e
|
|
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v8.h
|
|
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v8.h
|
|
@@ -144,6 +144,8 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_RET_INSTANCE_ID 0xF070
|
|
#define S5P_FIMV_ERROR_CODE 0xF074
|
|
|
|
+#define S5P_FIMV_ERR_HEADER_NOT_FOUND 102
|
|
+#define S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED 190
|
|
#define S5P_FIMV_ERR_WARNINGS_START 160
|
|
#define S5P_FIMV_ERR_WARNINGS_END 222
|
|
#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
|
|
@@ -178,6 +180,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
|
|
#define S5P_FIMV_D_SEI_ENABLE 0xF0C4
|
|
#define S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT 1
|
|
+#define S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE 2
|
|
|
|
/* Buffer setting registers */
|
|
/* Session return */
|
|
@@ -372,6 +375,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_ENC_PROFILE_H264_MAIN 1
|
|
#define S5P_FIMV_ENC_PROFILE_H264_HIGH 2
|
|
#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
|
|
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH 5
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
|
|
#define S5P_FIMV_E_FIXED_PICTURE_QP 0xF794
|
|
@@ -453,6 +457,9 @@ static inline unsigned int r2h_bits(int cmd)
|
|
|
|
#define S5P_FIMV_E_MPEG4_OPTIONS 0xFB10
|
|
#define S5P_FIMV_E_MPEG4_HEC_PERIOD 0xFB14
|
|
+
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0 0xFB44
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1 0xFB48
|
|
#define S5P_FIMV_E_ASPECT_RATIO 0xFB4C
|
|
#define S5P_FIMV_E_EXTENDED_SAR 0xFB50
|
|
|
|
@@ -480,13 +487,10 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5 0xFB9C
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6 0xFBA0
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7 0xFBA4
|
|
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET 0xFBA8
|
|
|
|
#define S5P_FIMV_E_NUM_T_LAYER 0xFBAC
|
|
|
|
-/* For backward compatibility */
|
|
-#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET 0xFBA8
|
|
-#define S5P_FIMV_E_H264_NUM_T_LAYER S5P_FIMV_E_NUM_T_LAYER
|
|
-
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 0xFBB0
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1 0xFBB4
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2 0xFBB8
|
|
@@ -496,23 +500,8 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6 0xFBC8
|
|
|
|
/* For backward compatibility */
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1 S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2 S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3 S5P_FIMV_E_HIERARCHICAL_QP_LAYER3
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4 S5P_FIMV_E_HIERARCHICAL_QP_LAYER4
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5 S5P_FIMV_E_HIERARCHICAL_QP_LAYER5
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6 S5P_FIMV_E_HIERARCHICAL_QP_LAYER6
|
|
-
|
|
#define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO 0xFC4C
|
|
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER1 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER2 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER3 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER4 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER5 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER6 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 0xFD18
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1 0xFD1C
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2 0xFD20
|
|
@@ -531,11 +520,6 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_VP8_OPTION 0xFDB0
|
|
#define S5P_FIMV_E_VP8_FILTER_OPTIONS 0xFDB4
|
|
#define S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION 0xFDB8
|
|
-/* For backward compatibility */
|
|
-#define S5P_FIMV_E_VP8_NUM_T_LAYER S5P_FIMV_E_NUM_T_LAYER
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0 S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER1 S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER2 S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
|
|
/* for compatibility */
|
|
#define S5P_FIMV_E_HEVC_OPTIONS -1
|
|
#define S5P_FIMV_E_HEVC_REFRESH_PERIOD -1
|
|
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v9.h b/drivers/media/platform/exynos/mfc/regs-mfc-v9.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 5dab5fc9a45e..dbfb8933e42d
|
|
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v9.h
|
|
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v9.h
|
|
@@ -75,6 +75,7 @@
|
|
#define S5P_FIMV_R2H_CMD_FRAME_DONE_RET 13
|
|
#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET 14
|
|
#define S5P_FIMV_R2H_CMD_SLICE_DONE_RET 15
|
|
+#define S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET 16
|
|
#define S5P_FIMV_R2H_CMD_CACHE_FLUSH_RET 20
|
|
#define S5P_FIMV_R2H_CMD_ERR_RET 32
|
|
|
|
@@ -100,7 +101,8 @@ static inline unsigned int h2r_to_r2h_bits(int cmd)
|
|
case S5P_FIMV_CH_FRAME_START:
|
|
mask |= (R2H_BIT(S5P_FIMV_R2H_CMD_FRAME_DONE_RET) |
|
|
R2H_BIT(S5P_FIMV_R2H_CMD_FIELD_DONE_RET) |
|
|
- R2H_BIT(S5P_FIMV_R2H_CMD_SLICE_DONE_RET));
|
|
+ R2H_BIT(S5P_FIMV_R2H_CMD_SLICE_DONE_RET) |
|
|
+ R2H_BIT(S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET));
|
|
break;
|
|
case S5P_FIMV_CH_LAST_FRAME:
|
|
mask |= R2H_BIT(S5P_FIMV_R2H_CMD_FRAME_DONE_RET);
|
|
@@ -118,7 +120,8 @@ static inline unsigned int r2h_bits(int cmd)
|
|
mask |= (R2H_BIT(S5P_FIMV_R2H_CMD_FIELD_DONE_RET) |
|
|
R2H_BIT(S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET) |
|
|
R2H_BIT(S5P_FIMV_R2H_CMD_SLICE_DONE_RET) |
|
|
- R2H_BIT(S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET));
|
|
+ R2H_BIT(S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET) |
|
|
+ R2H_BIT(S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET));
|
|
/* FIXME: Temporal mask for S3D SEI processing */
|
|
else if (cmd == S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET)
|
|
mask |= (R2H_BIT(S5P_FIMV_R2H_CMD_FIELD_DONE_RET) |
|
|
@@ -150,6 +153,9 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_RET_INSTANCE_ID 0xF070
|
|
#define S5P_FIMV_ERROR_CODE 0xF074
|
|
|
|
+#define S5P_FIMV_ERR_HEADER_NOT_FOUND 102
|
|
+#define S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED 190
|
|
+#define S5P_FIMV_ERR_NON_PAIRED_FIELD 191
|
|
#define S5P_FIMV_ERR_WARNINGS_START 160
|
|
#define S5P_FIMV_ERR_WARNINGS_END 222
|
|
#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
|
|
@@ -176,6 +182,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_D_OPT_TILE_MODE_SHIFT 0
|
|
#define S5P_FIMV_D_OPT_DYNAMIC_DPB_SET_SHIFT 3
|
|
#define S5P_FIMV_D_OPT_NOT_CODED_SET_SHIFT 4
|
|
+#define S5P_FIMV_D_OPT_SPECIAL_PARSING_SHIFT 15
|
|
|
|
#define S5P_FIMV_D_DISPLAY_DELAY 0xF0B8
|
|
|
|
@@ -184,6 +191,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
|
|
#define S5P_FIMV_D_SEI_ENABLE 0xF0C4
|
|
#define S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT 1
|
|
+#define S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE 2
|
|
|
|
/* Buffer setting registers */
|
|
/* Session return */
|
|
@@ -367,6 +375,7 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_ENC_PROFILE_H264_MAIN 1
|
|
#define S5P_FIMV_ENC_PROFILE_H264_HIGH 2
|
|
#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
|
|
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH 5
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
|
|
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
|
|
#define S5P_FIMV_E_FIXED_PICTURE_QP 0xF794
|
|
@@ -457,6 +466,9 @@ static inline unsigned int r2h_bits(int cmd)
|
|
|
|
#define S5P_FIMV_E_MPEG4_OPTIONS 0xFB10
|
|
#define S5P_FIMV_E_MPEG4_HEC_PERIOD 0xFB14
|
|
+
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0 0xFB44
|
|
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1 0xFB48
|
|
#define S5P_FIMV_E_ASPECT_RATIO 0xFB4C
|
|
#define S5P_FIMV_E_EXTENDED_SAR 0xFB50
|
|
|
|
@@ -485,13 +497,10 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5 0xFB9C
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6 0xFBA0
|
|
#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7 0xFBA4
|
|
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET 0xFBA8
|
|
|
|
#define S5P_FIMV_E_NUM_T_LAYER 0xFBAC
|
|
|
|
-/* For backward compatibility */
|
|
-#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET 0xFBA8
|
|
-#define S5P_FIMV_E_H264_NUM_T_LAYER S5P_FIMV_E_NUM_T_LAYER
|
|
-
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 0xFBB0
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1 0xFBB4
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2 0xFBB8
|
|
@@ -501,24 +510,9 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6 0xFBC8
|
|
|
|
/* For backward compatibility */
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1 S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2 S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3 S5P_FIMV_E_HIERARCHICAL_QP_LAYER3
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4 S5P_FIMV_E_HIERARCHICAL_QP_LAYER4
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5 S5P_FIMV_E_HIERARCHICAL_QP_LAYER5
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6 S5P_FIMV_E_HIERARCHICAL_QP_LAYER6
|
|
-
|
|
#define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO 0xFC4C
|
|
|
|
#define S5P_FIMV_E_H264_NAL_CONTROL 0xFD14
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER1 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER2 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER3 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER4 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER5 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5
|
|
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER6 S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 0xFD18
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1 0xFD1C
|
|
#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2 0xFD20
|
|
@@ -538,12 +532,6 @@ static inline unsigned int r2h_bits(int cmd)
|
|
#define S5P_FIMV_E_VP8_FILTER_OPTIONS 0xFDB4
|
|
#define S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION 0xFDB8
|
|
|
|
-/* For backward compatibility */
|
|
-#define S5P_FIMV_E_VP8_NUM_T_LAYER S5P_FIMV_E_NUM_T_LAYER
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0 S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER1 S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
|
|
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER2 S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
|
|
-
|
|
#define S5P_FIMV_E_HEVC_OPTIONS 0xFDD4
|
|
#define S5P_FIMV_E_HEVC_REFRESH_PERIOD 0xFDD8
|
|
#define S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET 0xFDDC
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc.c b/drivers/media/platform/exynos/mfc/s5p_mfc.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index 5b07d11ec5b7..3ff3d4c7d0a3
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc.c
|
|
@@ -160,20 +160,21 @@ int exynos_mfc_sysmmu_fault_handler(struct iommu_domain *iodmn, struct device *d
|
|
/*
|
|
* A framerate table determines framerate by the interval(us) of each frame.
|
|
* Framerate is not accurate, just rough value to seperate overload section.
|
|
- * Base line of each section are selected from 25fps(40000us), 45fps(22222us)
|
|
- * and 100fps(10000us).
|
|
+ * Base line of each section are selected from 40fps(25000us), 80fps(12500us),
|
|
+ * 145fps(6940us) and 205fps(4860us).
|
|
*
|
|
- * interval(us) | 0 10000 22222 40000 |
|
|
- * framerate | 120fps | 60fps | 30fps | 25fps |
|
|
+ * interval(us) | 0 4860 6940 12500 25000 |
|
|
+ * framerate | 240fps | 180fps | 120fps | 60fps | 30fps |
|
|
*/
|
|
|
|
#define COL_FRAME_RATE 0
|
|
#define COL_FRAME_INTERVAL 1
|
|
static unsigned long framerate_table[][2] = {
|
|
- { 25000, 40000 },
|
|
- { 30000, 22222 },
|
|
- { 60000, 10000 },
|
|
- { 120000, 0 },
|
|
+ { 30000, 25000 },
|
|
+ { 60000, 12500 },
|
|
+ { 120000, 6940 },
|
|
+ { 180000, 4860 },
|
|
+ { 240000, 0 },
|
|
};
|
|
|
|
static inline unsigned long timeval_diff(struct timeval *to,
|
|
@@ -280,6 +281,7 @@ int get_framerate_by_timestamp(struct s5p_mfc_ctx *ctx, struct v4l2_buffer *buf)
|
|
|
|
if (list_empty(&ctx->ts_list)) {
|
|
dec_add_timestamp(ctx, buf, &ctx->ts_list);
|
|
+ return get_framerate_by_interval(0);
|
|
} else {
|
|
found = 0;
|
|
list_for_each_entry_reverse(temp_ts, &ctx->ts_list, list) {
|
|
@@ -324,6 +326,12 @@ int get_framerate_by_timestamp(struct s5p_mfc_ctx *ctx, struct v4l2_buffer *buf)
|
|
min_interval, max_framerate);
|
|
}
|
|
|
|
+ if (!ctx->ts_is_full) {
|
|
+ if (debug_ts == 1)
|
|
+ mfc_info_ctx("ts doesn't full, keep %d fps\n", ctx->framerate);
|
|
+ return ctx->framerate;
|
|
+ }
|
|
+
|
|
return max_framerate;
|
|
}
|
|
|
|
@@ -557,10 +565,8 @@ static int s5p_mfc_check_hw_state(struct s5p_mfc_dev *dev)
|
|
clk_state = mfc_check_clock_state(dev);
|
|
mfc_disp_dev_state(dev);
|
|
|
|
- if (!pwr_state || !clk_state)
|
|
- mfc_err("power or clock state is unstable\n");
|
|
-
|
|
- s5p_mfc_dump_regs(dev);
|
|
+ if (pwr_state && clk_state)
|
|
+ s5p_mfc_dump_regs(dev);
|
|
|
|
return 0;
|
|
}
|
|
@@ -725,7 +731,7 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
|
|
struct s5p_mfc_dev *dev;
|
|
struct s5p_mfc_buf *dst_buf;
|
|
int index, is_first = 1;
|
|
- unsigned int interlace_type, is_interlace = 0;
|
|
+ unsigned int interlace_type = 0, is_interlace = 0;
|
|
|
|
if (!ctx) {
|
|
mfc_err("no mfc context to run\n");
|
|
@@ -809,7 +815,9 @@ static void mfc_check_ref_frame(struct s5p_mfc_ctx *ctx,
|
|
{
|
|
struct s5p_mfc_dec *dec = ctx->dec_priv;
|
|
struct s5p_mfc_buf *ref_buf, *tmp_buf;
|
|
+ struct list_head *dst_list;
|
|
int index;
|
|
+ int found = 0;
|
|
|
|
list_for_each_entry_safe(ref_buf, tmp_buf, ref_list, list) {
|
|
index = ref_buf->vb.v4l2_buf.index;
|
|
@@ -825,9 +833,26 @@ static void mfc_check_ref_frame(struct s5p_mfc_ctx *ctx,
|
|
clear_bit(index, &dec->dpb_status);
|
|
mfc_debug(2, "Move buffer[%d], fd[%d] to dst queue\n",
|
|
index, dec->assigned_fd[index]);
|
|
+ found = 1;
|
|
break;
|
|
}
|
|
}
|
|
+
|
|
+ if (is_h264(ctx) && !found) {
|
|
+ dst_list = &ctx->dst_queue;
|
|
+ list_for_each_entry_safe(ref_buf, tmp_buf, dst_list, list) {
|
|
+ index = ref_buf->vb.v4l2_buf.index;
|
|
+ if (index == ref_index && ref_buf->already) {
|
|
+ dec->assigned_fd[index] =
|
|
+ ref_buf->vb.v4l2_planes[0].m.fd;
|
|
+ clear_bit(index, &dec->dpb_status);
|
|
+ mfc_debug(2, "re-assigned buffer[%d], fd[%d] for H264\n",
|
|
+ index, dec->assigned_fd[index]);
|
|
+ found = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/* Process the released reference information */
|
|
@@ -844,11 +869,17 @@ static void mfc_handle_released_info(struct s5p_mfc_ctx *ctx,
|
|
if (released_flag) {
|
|
for (t = 0; t < MFC_MAX_DPBS; t++) {
|
|
if (released_flag & (1 << t)) {
|
|
- mfc_debug(2, "Release FD[%d] = %03d !! ",
|
|
- t, dec->assigned_fd[t]);
|
|
- refBuf->dpb[ncount].fd[0] = dec->assigned_fd[t];
|
|
+ if (dec->err_sync_flag & (1 << t)) {
|
|
+ mfc_debug(2, "Released, but reuse. FD[%d] = %03d\n",
|
|
+ t, dec->assigned_fd[t]);
|
|
+ dec->err_sync_flag &= ~(1 << t);
|
|
+ } else {
|
|
+ mfc_debug(2, "Release FD[%d] = %03d\n",
|
|
+ t, dec->assigned_fd[t]);
|
|
+ refBuf->dpb[ncount].fd[0] = dec->assigned_fd[t];
|
|
+ ncount++;
|
|
+ }
|
|
dec->assigned_fd[t] = MFC_INFO_INIT_FD;
|
|
- ncount++;
|
|
mfc_check_ref_frame(ctx, dst_queue_addr, t);
|
|
}
|
|
}
|
|
@@ -906,7 +937,7 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
|
|
dma_addr_t dspl_y_addr;
|
|
unsigned int index;
|
|
unsigned int frame_type;
|
|
- unsigned int interlace_type, is_interlace = 0;
|
|
+ unsigned int interlace_type = 0, is_interlace = 0;
|
|
int mvc_view_id;
|
|
unsigned int dst_frame_status, last_frame_status;
|
|
struct list_head *dst_queue_addr;
|
|
@@ -994,6 +1025,24 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
|
|
if (s5p_mfc_mem_plane_addr(ctx, &dst_buf->vb, 0)
|
|
== dspl_y_addr) {
|
|
index = dst_buf->vb.v4l2_buf.index;
|
|
+ if (ctx->codec_mode == S5P_FIMV_CODEC_VC1RCV_DEC &&
|
|
+ s5p_mfc_err_dspl(err) == S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED) {
|
|
+ if (released_flag & (1 << index)) {
|
|
+ list_del(&dst_buf->list);
|
|
+ dec->ref_queue_cnt--;
|
|
+ list_add_tail(&dst_buf->list, &ctx->dst_queue);
|
|
+ ctx->dst_queue_cnt++;
|
|
+ dec->dpb_status &= ~(1 << index);
|
|
+ released_flag &= ~(1 << index);
|
|
+ mfc_debug(2, "SYNC_POINT_NOT_RECEIVED, released.\n");
|
|
+ } else {
|
|
+ dec->err_sync_flag |= 1 << index;
|
|
+ mfc_debug(2, "SYNC_POINT_NOT_RECEIVED, used.\n");
|
|
+ }
|
|
+ dec->dynamic_used |= released_flag;
|
|
+ break;
|
|
+ }
|
|
+
|
|
list_del(&dst_buf->list);
|
|
|
|
if (dec->is_dynamic_dpb)
|
|
@@ -1024,7 +1073,8 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
|
|
dst_buf->vb.v4l2_buf.flags &=
|
|
~(V4L2_BUF_FLAG_KEYFRAME |
|
|
V4L2_BUF_FLAG_PFRAME |
|
|
- V4L2_BUF_FLAG_BFRAME);
|
|
+ V4L2_BUF_FLAG_BFRAME |
|
|
+ V4L2_BUF_FLAG_ERROR);
|
|
|
|
switch (frame_type) {
|
|
case S5P_FIMV_DISPLAY_FRAME_I:
|
|
@@ -1043,9 +1093,12 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
|
|
break;
|
|
}
|
|
|
|
- if (s5p_mfc_err_dspl(err))
|
|
+ if (s5p_mfc_err_dspl(err)) {
|
|
mfc_err_ctx("Warning for displayed frame: %d\n",
|
|
s5p_mfc_err_dspl(err));
|
|
+ dst_buf->vb.v4l2_buf.flags |=
|
|
+ V4L2_BUF_FLAG_ERROR;
|
|
+ }
|
|
|
|
if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
|
|
mfc_err_ctx("failed in get_buf_ctrls_val\n");
|
|
@@ -1142,19 +1195,6 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
|
|
}
|
|
}
|
|
|
|
-static int s5p_mfc_find_start_code(unsigned char *src_mem, unsigned int remainSize)
|
|
-{
|
|
- unsigned int index = 0;
|
|
-
|
|
- for (index = 0; index < remainSize - 3; index++) {
|
|
- if ((src_mem[index] == 0x00) && (src_mem[index+1] == 0x00) &&
|
|
- (src_mem[index+2] == 0x01))
|
|
- return index;
|
|
- }
|
|
-
|
|
- return -1;
|
|
-}
|
|
-
|
|
static void s5p_mfc_handle_frame_error(struct s5p_mfc_ctx *ctx,
|
|
unsigned int reason, unsigned int err)
|
|
{
|
|
@@ -1306,6 +1346,52 @@ static void s5p_mfc_handle_ref_frame(struct s5p_mfc_ctx *ctx)
|
|
}
|
|
}
|
|
|
|
+static void s5p_mfc_move_reuse_buffer(struct s5p_mfc_ctx *ctx, int release_index)
|
|
+{
|
|
+ struct s5p_mfc_dec *dec = ctx->dec_priv;
|
|
+ struct s5p_mfc_buf *ref_mb, *tmp_mb;
|
|
+ int index;
|
|
+
|
|
+ list_for_each_entry_safe(ref_mb, tmp_mb, &dec->ref_queue, list) {
|
|
+ index = ref_mb->vb.v4l2_buf.index;
|
|
+ if (index == release_index) {
|
|
+ ref_mb->used = 0;
|
|
+
|
|
+ list_del(&ref_mb->list);
|
|
+ dec->ref_queue_cnt--;
|
|
+
|
|
+ list_add_tail(&ref_mb->list, &ctx->dst_queue);
|
|
+ ctx->dst_queue_cnt++;
|
|
+
|
|
+ clear_bit(index, &dec->dpb_status);
|
|
+ mfc_debug(2, "buffer[%d] is moved to dst queue for reuse\n", index);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void s5p_mfc_handle_reuse_buffer(struct s5p_mfc_ctx *ctx)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
+ struct s5p_mfc_dec *dec = ctx->dec_priv;
|
|
+ unsigned int prev_flag, released_flag = 0;
|
|
+ int i;
|
|
+
|
|
+ if (!dec->is_dynamic_dpb)
|
|
+ return;
|
|
+
|
|
+ prev_flag = dec->dynamic_used;
|
|
+ dec->dynamic_used = mfc_get_dec_used_flag();
|
|
+ released_flag = prev_flag & (~dec->dynamic_used);
|
|
+
|
|
+ if (!released_flag)
|
|
+ return;
|
|
+
|
|
+ /* reuse not referenced buf anymore */
|
|
+ for (i = 0; i < MFC_MAX_DPBS; i++)
|
|
+ if (released_flag & (1 << i))
|
|
+ s5p_mfc_move_reuse_buffer(ctx, i);
|
|
+}
|
|
+
|
|
/* Handle frame decoding interrupt */
|
|
static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
|
|
unsigned int reason, unsigned int err)
|
|
@@ -1399,9 +1485,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
|
|
/* All frames remaining in the buffer have been extracted */
|
|
if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) {
|
|
if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
|
|
+ struct mfc_timestamp *temp_ts = NULL;
|
|
+
|
|
mfc_debug(2, "Last frame received after resolution change.\n");
|
|
s5p_mfc_handle_frame_all_extracted(ctx);
|
|
ctx->state = MFCINST_RES_CHANGE_END;
|
|
+
|
|
+ /* empty the timestamp queue */
|
|
+ while (!list_empty(&ctx->ts_list)) {
|
|
+ temp_ts = list_entry((&ctx->ts_list)->next,
|
|
+ struct mfc_timestamp, list);
|
|
+ list_del(&temp_ts->list);
|
|
+ }
|
|
+ ctx->ts_count = 0;
|
|
+ ctx->ts_is_full = 0;
|
|
+ ctx->last_framerate = 0;
|
|
+ ctx->framerate = DEC_MAX_FPS;
|
|
+
|
|
goto leave_handle_frame;
|
|
} else {
|
|
s5p_mfc_handle_frame_all_extracted(ctx);
|
|
@@ -1410,12 +1510,18 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
|
|
|
|
if (dec->is_dynamic_dpb) {
|
|
switch (dst_frame_status) {
|
|
- case S5P_FIMV_DEC_STATUS_DECODING_ONLY:
|
|
- dec->dynamic_used |= mfc_get_dec_used_flag();
|
|
- /* Fall through */
|
|
case S5P_FIMV_DEC_STATUS_DECODING_DISPLAY:
|
|
s5p_mfc_handle_ref_frame(ctx);
|
|
break;
|
|
+ case S5P_FIMV_DEC_STATUS_DECODING_ONLY:
|
|
+ s5p_mfc_handle_ref_frame(ctx);
|
|
+ /*
|
|
+ * Some cases can have many decoding only frames like VP9
|
|
+ * alt-ref frame. So need handling release buffer
|
|
+ * because of DPB full.
|
|
+ */
|
|
+ s5p_mfc_handle_reuse_buffer(ctx);
|
|
+ break;
|
|
default:
|
|
break;
|
|
}
|
|
@@ -1444,52 +1550,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
|
|
dec->consumed += s5p_mfc_get_consumed_stream();
|
|
remained = (unsigned int)(src_buf->vb.v4l2_planes[0].bytesused - dec->consumed);
|
|
|
|
- if ((prev_offset == 0) && dec->is_packedpb && remained > STUFF_BYTE &&
|
|
- dec->consumed < src_buf->vb.v4l2_planes[0].bytesused &&
|
|
- s5p_mfc_get_dec_frame_type() ==
|
|
- S5P_FIMV_DECODED_FRAME_P) {
|
|
- unsigned char *stream_vir;
|
|
- int offset = 0;
|
|
-
|
|
+ if ((dec->consumed > 0) && (remained > STUFF_BYTE) && (err == 0) &&
|
|
+ (src_buf->vb.v4l2_planes[0].bytesused > dec->consumed)) {
|
|
/* Run MFC again on the same buffer */
|
|
mfc_debug(2, "Running again the same buffer.\n");
|
|
|
|
- if (IS_MFCv7X(dev) && dec->is_dual_dpb)
|
|
- dec->y_addr_for_pb = mfc_get_dec_first_addr();
|
|
- else
|
|
+ if (dec->is_packedpb)
|
|
dec->y_addr_for_pb = (dma_addr_t)MFC_GET_ADR(DEC_DECODED_Y);
|
|
|
|
- spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
- stream_vir = vb2_plane_vaddr(&src_buf->vb, 0);
|
|
- s5p_mfc_mem_inv_vb(&src_buf->vb, 1);
|
|
- spin_lock_irqsave(&dev->irqlock, flags);
|
|
-
|
|
- if (ctx->codec_mode != S5P_FIMV_CODEC_VP9_DEC) {
|
|
- offset = s5p_mfc_find_start_code(
|
|
- stream_vir + dec->consumed, remained);
|
|
- }
|
|
-
|
|
- if (offset > STUFF_BYTE)
|
|
- dec->consumed += offset;
|
|
-
|
|
-#if 0
|
|
- s5p_mfc_set_dec_stream_buffer(ctx,
|
|
- src_buf->planes.stream, dec->consumed,
|
|
- src_buf->vb.v4l2_planes[0].bytesused -
|
|
- dec->consumed);
|
|
- dev->curr_ctx = ctx->num;
|
|
- dev->curr_ctx_drm = ctx->is_drm;
|
|
- s5p_mfc_clean_ctx_int_flags(ctx);
|
|
- s5p_mfc_clear_int_flags();
|
|
- wake_up_ctx(ctx, reason, err);
|
|
- spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
- s5p_mfc_decode_one_frame(ctx, 0);
|
|
- return;
|
|
-#else
|
|
dec->remained_size = src_buf->vb.v4l2_planes[0].bytesused -
|
|
dec->consumed;
|
|
/* Do not move src buffer to done_list */
|
|
-#endif
|
|
+ } else if (s5p_mfc_err_dec(err) == S5P_FIMV_ERR_NON_PAIRED_FIELD) {
|
|
+ /*
|
|
+ * For non-paired field, the same buffer need to be
|
|
+ * resumitted and the consumed stream will be 0
|
|
+ */
|
|
+ mfc_debug(2, "Not paired field. Running again the same buffer.\n");
|
|
} else {
|
|
index = src_buf->vb.v4l2_buf.index;
|
|
if (call_cop(ctx, recover_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
|
|
@@ -1548,32 +1625,50 @@ static inline void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
|
|
|
|
mfc_err_ctx("Interrupt Error: %d\n", err);
|
|
s5p_mfc_clear_int_flags();
|
|
- wake_up_dev(dev, reason, err);
|
|
|
|
/* Error recovery is dependent on the state of context */
|
|
switch (ctx->state) {
|
|
- case MFCINST_INIT:
|
|
- /* This error had to happen while acquireing instance */
|
|
+ case MFCINST_RES_CHANGE_END:
|
|
case MFCINST_GOT_INST:
|
|
- /* This error had to happen while parsing vps only */
|
|
+ /* This error had to happen while parsing the header */
|
|
if (err == S5P_FIMV_VPS_ONLY_ERROR) {
|
|
ctx->state = MFCINST_VPS_PARSED_ONLY;
|
|
if (!list_empty(&ctx->src_queue)) {
|
|
- src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
|
|
- list);
|
|
+ src_buf = list_entry(ctx->src_queue.next,
|
|
+ struct s5p_mfc_buf, list);
|
|
list_del(&src_buf->list);
|
|
ctx->src_queue_cnt--;
|
|
vb2_buffer_done(&src_buf->vb, VB2_BUF_STATE_DONE);
|
|
}
|
|
+ } else if (!ctx->is_drm) {
|
|
+ unsigned char *stream_vir = NULL;
|
|
+ unsigned int strm_size = 0;
|
|
+ spin_lock_irqsave(&dev->irqlock, flags);
|
|
+ if (!list_empty(&ctx->src_queue)) {
|
|
+ src_buf = list_entry(ctx->src_queue.next,
|
|
+ struct s5p_mfc_buf, list);
|
|
+ stream_vir = src_buf->vir_addr;
|
|
+ strm_size = src_buf->vb.v4l2_planes[0].bytesused;
|
|
+ if (strm_size > 32)
|
|
+ strm_size = 32;
|
|
+ }
|
|
+ spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
+ if (stream_vir && strm_size)
|
|
+ print_hex_dump(KERN_ERR, "No header: ",
|
|
+ DUMP_PREFIX_ADDRESS, strm_size, 4,
|
|
+ stream_vir, strm_size, false);
|
|
}
|
|
- case MFCINST_RES_CHANGE_END:
|
|
- /* This error had to happen while parsing the header */
|
|
+ case MFCINST_INIT:
|
|
+ /* This error had to happen while acquireing instance */
|
|
case MFCINST_HEAD_PARSED:
|
|
/* This error had to happen while setting dst buffers */
|
|
case MFCINST_RETURN_INST:
|
|
/* This error had to happen while releasing instance */
|
|
case MFCINST_DPB_FLUSHING:
|
|
/* This error had to happen while flushing DPB */
|
|
+ case MFCINST_SPECIAL_PARSING:
|
|
+ case MFCINST_SPECIAL_PARSING_NAL:
|
|
+ /* this error had to happen while special parsing */
|
|
clear_work_bit(ctx);
|
|
if (clear_hw_bit(ctx) == 0)
|
|
BUG();
|
|
@@ -1611,9 +1706,31 @@ static inline void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
|
|
|
|
break;
|
|
}
|
|
+ wake_up_dev(dev, reason, err);
|
|
+
|
|
return;
|
|
}
|
|
|
|
+static irqreturn_t s5p_mfc_top_half_irq(int irq, void *priv)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = priv;
|
|
+ struct s5p_mfc_ctx *ctx;
|
|
+ unsigned int err;
|
|
+ unsigned int reason;
|
|
+
|
|
+ ctx = dev->ctx[dev->curr_ctx];
|
|
+ if (!ctx)
|
|
+ mfc_err("no mfc context to run\n");
|
|
+
|
|
+ reason = s5p_mfc_get_int_reason();
|
|
+ err = s5p_mfc_get_int_err();
|
|
+ mfc_debug(2, "[c:%d] Int reason: %d (err: %d)\n",
|
|
+ dev->curr_ctx, reason, err);
|
|
+ MFC_TRACE_DEV("<< Int reason(top): %d\n", reason);
|
|
+
|
|
+ return IRQ_WAKE_THREAD;
|
|
+}
|
|
+
|
|
/* Interrupt processing */
|
|
static irqreturn_t s5p_mfc_irq(int irq, void *priv)
|
|
{
|
|
@@ -1625,6 +1742,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
|
|
unsigned int reason;
|
|
unsigned int err;
|
|
unsigned long flags;
|
|
+ unsigned int reg = 0;
|
|
|
|
mfc_debug_enter();
|
|
|
|
@@ -1696,19 +1814,87 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
|
|
case S5P_FIMV_R2H_CMD_FIELD_DONE_RET:
|
|
case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
|
|
case S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET:
|
|
+ case S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET:
|
|
if (ctx->type == MFCINST_DECODER) {
|
|
+ if (ctx->state == MFCINST_SPECIAL_PARSING_NAL) {
|
|
+ s5p_mfc_clear_int_flags();
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ clear_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+ ctx->state = MFCINST_RUNNING;
|
|
+ if (clear_hw_bit(ctx) == 0)
|
|
+ BUG();
|
|
+ s5p_mfc_clock_off(dev);
|
|
+ wake_up_ctx(ctx, reason, err);
|
|
+ goto done;
|
|
+ }
|
|
s5p_mfc_handle_frame(ctx, reason, err);
|
|
} else if (ctx->type == MFCINST_ENCODER) {
|
|
if (reason == S5P_FIMV_R2H_CMD_SLICE_DONE_RET) {
|
|
dev->preempt_ctx = ctx->num;
|
|
+ enc->buf_full = 0;
|
|
enc->in_slice = 1;
|
|
+ } else if (reason == S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET) {
|
|
+ mfc_err_ctx("stream buffer size(%d) isn't enough\n",
|
|
+ s5p_mfc_get_enc_strm_size());
|
|
+ dev->preempt_ctx = ctx->num;
|
|
+ enc->buf_full = 1;
|
|
+ enc->in_slice = 0;
|
|
} else {
|
|
+ enc->buf_full = 0;
|
|
enc->in_slice = 0;
|
|
}
|
|
|
|
if (ctx->c_ops->post_frame_start) {
|
|
- if (ctx->c_ops->post_frame_start(ctx))
|
|
- mfc_err_ctx("post_frame_start() failed\n");
|
|
+ if (ctx->enc_res_change || ctx->enc_res_change_state) {
|
|
+ /* Right after the first NAL_START finished with the new resolution,
|
|
+ * We need to reset the fields
|
|
+ */
|
|
+ if (ctx->enc_res_change) {
|
|
+ reg = s5p_mfc_read_reg(dev, S5P_FIMV_E_PARAM_CHANGE);
|
|
+ reg &= ~(0x7 << 6); /* clear resolution change bits */
|
|
+ s5p_mfc_write_reg(dev, reg, S5P_FIMV_E_PARAM_CHANGE);
|
|
+
|
|
+ ctx->enc_res_change_state = ctx->enc_res_change;
|
|
+ ctx->enc_res_change = 0;
|
|
+ }
|
|
+
|
|
+ if (ctx->enc_res_change_state == 1) { /* resolution swap */
|
|
+ ctx->enc_res_change_state = 0;
|
|
+ } else if (ctx->enc_res_change_state == 2) { /* resolution change */
|
|
+ reg = s5p_mfc_read_reg(dev, S5P_FIMV_E_NAL_DONE_INFO);
|
|
+ reg = (reg & (0x3 << 4)) >> 4;
|
|
+
|
|
+ mfc_debug(2, "Encoding Resolution Status : %d\n", reg);
|
|
+
|
|
+ if (reg == 1) { /* Resolution Change for B-frame */
|
|
+ /* Encode with previous resolution */
|
|
+ /* NOTHING TO-DO */
|
|
+ } else if (reg == 2) { /* Resolution Change for B-frame */
|
|
+ s5p_mfc_release_codec_buffers(ctx);
|
|
+ ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
|
|
+
|
|
+ ctx->enc_res_change_state = 0;
|
|
+ ctx->min_scratch_buf_size = s5p_mfc_read_reg(dev, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE);
|
|
+ mfc_debug(2, "S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE = 0x%x\n",
|
|
+ (unsigned int)ctx->min_scratch_buf_size);
|
|
+ } else if (reg == 3) { /* Resolution Change for only P-frame */
|
|
+ s5p_mfc_release_codec_buffers(ctx);
|
|
+ ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
|
|
+
|
|
+ ctx->enc_res_change_state = 0;
|
|
+ ctx->min_scratch_buf_size = s5p_mfc_read_reg(dev, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE);
|
|
+ ctx->enc_res_change_re_input = 1;
|
|
+ mfc_debug(2, "S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE = 0x%x\n",
|
|
+ (unsigned int)ctx->min_scratch_buf_size);
|
|
+ }
|
|
+ }
|
|
+ if (ctx->c_ops->post_frame_start(ctx))
|
|
+ mfc_err_ctx("post_frame_start() failed\n");
|
|
+ } else {
|
|
+ if (ctx->c_ops->post_frame_start(ctx))
|
|
+ mfc_err_ctx("post_frame_start() failed\n");
|
|
+ }
|
|
|
|
s5p_mfc_clear_int_flags();
|
|
if (clear_hw_bit(ctx) == 0)
|
|
@@ -1797,8 +1983,18 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
|
|
goto irq_cleanup_hw;
|
|
break;
|
|
case S5P_FIMV_R2H_CMD_NAL_ABORT_RET:
|
|
- ctx->state = MFCINST_ABORT;
|
|
- clear_work_bit(ctx);
|
|
+ if (ctx->type == MFCINST_ENCODER) {
|
|
+ ctx->state = MFCINST_RUNNING_BUF_FULL;
|
|
+ enc->buf_full = 0;
|
|
+ if (ctx->codec_mode == S5P_FIMV_CODEC_VP8_ENC)
|
|
+ mfc_err_ctx("stream buffer size isn't enough\n");
|
|
+ if (ctx->c_ops->post_frame_start)
|
|
+ if (ctx->c_ops->post_frame_start(ctx))
|
|
+ mfc_err_ctx("post_frame_start() failed\n");
|
|
+ } else {
|
|
+ ctx->state = MFCINST_ABORT;
|
|
+ clear_work_bit(ctx);
|
|
+ }
|
|
if (clear_hw_bit(ctx) == 0)
|
|
BUG();
|
|
goto irq_cleanup_hw;
|
|
@@ -2197,8 +2393,8 @@ static int s5p_mfc_open(struct file *file)
|
|
}
|
|
}
|
|
|
|
- mfc_info_ctx("MFC open completed [%d:%d] dev = %p, ctx = %p\n",
|
|
- dev->num_drm_inst, dev->num_inst, dev, ctx);
|
|
+ mfc_info_ctx("MFC open completed [%d:%d] dev = %p, ctx = %p, version = %d\n",
|
|
+ dev->num_drm_inst, dev->num_inst, dev, ctx, MFC_DRIVER_INFO);
|
|
mutex_unlock(&dev->mfc_mutex);
|
|
return ret;
|
|
|
|
@@ -2270,19 +2466,14 @@ err_no_device:
|
|
return ret;
|
|
}
|
|
|
|
-#define need_to_wait_frame_start(ctx) \
|
|
- (((ctx->state == MFCINST_FINISHING) || \
|
|
- (ctx->state == MFCINST_RUNNING)) && \
|
|
- test_bit(ctx->num, &ctx->dev->hw_lock))
|
|
/* Release MFC context */
|
|
static int s5p_mfc_release(struct file *file)
|
|
{
|
|
struct s5p_mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
|
|
struct s5p_mfc_dev *dev = NULL;
|
|
struct s5p_mfc_enc *enc = NULL;
|
|
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
|
|
int ret = 0;
|
|
-#endif
|
|
+
|
|
dev = ctx->dev;
|
|
if (!dev) {
|
|
mfc_err("no mfc device to run\n");
|
|
@@ -2294,22 +2485,33 @@ static int s5p_mfc_release(struct file *file)
|
|
mfc_info_ctx("MFC driver release is called [%d:%d], is_drm(%d)\n",
|
|
dev->num_drm_inst, dev->num_inst, ctx->is_drm);
|
|
|
|
- if (need_to_wait_frame_start(ctx)) {
|
|
- ctx->state = MFCINST_ABORT;
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ set_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ clear_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
+ /* If a H/W operation is in progress, wait for it complete */
|
|
+ if (need_to_wait_nal_abort(ctx)) {
|
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
- S5P_FIMV_R2H_CMD_FRAME_DONE_RET))
|
|
+ S5P_FIMV_R2H_CMD_NAL_ABORT_RET))
|
|
s5p_mfc_cleanup_timeout(ctx);
|
|
+ } else if (test_bit(ctx->num, &dev->hw_lock)) {
|
|
+ ret = wait_event_timeout(ctx->queue,
|
|
+ (test_bit(ctx->num, &dev->hw_lock) == 0),
|
|
+ msecs_to_jiffies(MFC_INT_TIMEOUT));
|
|
+ if (ret == 0)
|
|
+ mfc_err_ctx("wait for event failed\n");
|
|
}
|
|
|
|
if (ctx->type == MFCINST_ENCODER) {
|
|
enc = ctx->enc_priv;
|
|
if (!enc) {
|
|
mfc_err_ctx("no mfc encoder to run\n");
|
|
- mutex_unlock(&dev->mfc_mutex);
|
|
- return -EINVAL;
|
|
+ ret = -EINVAL;
|
|
+ goto err_release;
|
|
}
|
|
|
|
- if (enc->in_slice) {
|
|
+ if (enc->in_slice || enc->buf_full) {
|
|
ctx->state = MFCINST_ABORT_INST;
|
|
spin_lock_irq(&dev->condlock);
|
|
set_bit(ctx->num, &dev->ctx_work_bits);
|
|
@@ -2320,6 +2522,7 @@ static int s5p_mfc_release(struct file *file)
|
|
s5p_mfc_cleanup_timeout(ctx);
|
|
|
|
enc->in_slice = 0;
|
|
+ enc->buf_full = 0;
|
|
}
|
|
}
|
|
|
|
@@ -2362,77 +2565,36 @@ static int s5p_mfc_release(struct file *file)
|
|
if (!atomic_read(&dev->watchdog_run) &&
|
|
(ctx->inst_no != MFC_NO_INSTANCE_SET)) {
|
|
/* Wait for hw_lock == 0 for this context */
|
|
- wait_event_timeout(ctx->queue,
|
|
- (test_bit(ctx->num, &dev->hw_lock) == 0),
|
|
+ ret = wait_event_timeout(ctx->queue,
|
|
+ (dev->hw_lock == 0),
|
|
msecs_to_jiffies(MFC_INT_SHORT_TIMEOUT));
|
|
+ if (ret == 0) {
|
|
+ mfc_err_ctx("Waiting for hardware to finish timed out\n");
|
|
+ ret = -EBUSY;
|
|
+ goto err_release;
|
|
+ }
|
|
|
|
+ s5p_mfc_clean_ctx_int_flags(ctx);
|
|
ctx->state = MFCINST_RETURN_INST;
|
|
spin_lock_irq(&dev->condlock);
|
|
set_bit(ctx->num, &dev->ctx_work_bits);
|
|
spin_unlock_irq(&dev->condlock);
|
|
|
|
/* To issue the command 'CLOSE_INSTANCE' */
|
|
- s5p_mfc_clean_ctx_int_flags(ctx);
|
|
s5p_mfc_try_run(dev);
|
|
|
|
/* Wait until instance is returned or timeout occured */
|
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
- S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET)) {
|
|
- dev->curr_ctx_drm = ctx->is_drm;
|
|
- set_bit(ctx->num, &dev->hw_lock);
|
|
- s5p_mfc_clock_on(dev);
|
|
- s5p_mfc_close_inst(ctx);
|
|
+ S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET) == 1) {
|
|
+ mfc_err_ctx("It was expired to wait for a CLOSE_INSTANCE\n");
|
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
- S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET)) {
|
|
- mfc_err_ctx("Abnormal h/w state.\n");
|
|
-
|
|
- /* cleanup for the next open */
|
|
- if (dev->curr_ctx == ctx->num)
|
|
- clear_bit(ctx->num, &dev->hw_lock);
|
|
- if (ctx->is_drm)
|
|
- dev->num_drm_inst--;
|
|
- dev->num_inst--;
|
|
-
|
|
- mfc_info_dev("Failed to release MFC inst[%d:%d]\n",
|
|
- dev->num_drm_inst, dev->num_inst);
|
|
-
|
|
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
|
|
- if (ctx->is_drm && dev->num_drm_inst == 0) {
|
|
- ret = s5p_mfc_secmem_isolate_and_protect(0);
|
|
- if (ret)
|
|
- mfc_err("Failed to unprotect secure memory\n");
|
|
- }
|
|
-#endif
|
|
- if (dev->num_inst == 0) {
|
|
- s5p_mfc_deinit_hw(dev);
|
|
- del_timer_sync(&dev->watchdog_timer);
|
|
-
|
|
- flush_workqueue(dev->sched_wq);
|
|
-
|
|
- s5p_mfc_clock_off(dev);
|
|
- mfc_debug(2, "power off\n");
|
|
- s5p_mfc_power_off(dev);
|
|
-
|
|
- s5p_mfc_release_dev_context_buffer(dev);
|
|
- dev->drm_fw_status = 0;
|
|
-
|
|
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
|
|
- if (dev->is_support_smc) {
|
|
- s5p_mfc_release_sec_pgtable(dev);
|
|
- dev->is_support_smc = 0;
|
|
- }
|
|
-#endif
|
|
- } else {
|
|
- s5p_mfc_clock_off(dev);
|
|
- }
|
|
-
|
|
-
|
|
- mutex_unlock(&dev->mfc_mutex);
|
|
-
|
|
- return -EIO;
|
|
+ S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET)) {
|
|
+ mfc_err_ctx("It was once more expired. stop H/W\n");
|
|
+ s5p_mfc_check_hw_state(dev);
|
|
+ /* Stop */
|
|
+ BUG();
|
|
}
|
|
}
|
|
-
|
|
ctx->inst_no = MFC_NO_INSTANCE_SET;
|
|
}
|
|
/* hardware locking scheme */
|
|
@@ -2490,6 +2652,11 @@ static int s5p_mfc_release(struct file *file)
|
|
enc_cleanup_user_shared_handle(ctx);
|
|
kfree(ctx->enc_priv);
|
|
}
|
|
+
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ clear_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
dev->ctx[ctx->num] = 0;
|
|
kfree(ctx);
|
|
|
|
@@ -2499,6 +2666,15 @@ static int s5p_mfc_release(struct file *file)
|
|
mutex_unlock(&dev->mfc_mutex);
|
|
|
|
return 0;
|
|
+
|
|
+err_release:
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ clear_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
+ mutex_unlock(&dev->mfc_mutex);
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
/* Poll */
|
|
@@ -2788,8 +2964,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
|
|
goto err_res_irq;
|
|
}
|
|
dev->irq = res->start;
|
|
- ret = request_threaded_irq(dev->irq, NULL, s5p_mfc_irq, IRQF_ONESHOT, pdev->name,
|
|
- dev);
|
|
+ ret = request_threaded_irq(dev->irq, s5p_mfc_top_half_irq, s5p_mfc_irq,
|
|
+ IRQF_ONESHOT, pdev->name, dev);
|
|
if (ret != 0) {
|
|
dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
|
|
goto err_req_irq;
|
|
@@ -3164,8 +3340,6 @@ static int s5p_mfc_suspend(struct device *dev)
|
|
{
|
|
struct s5p_mfc_dev *m_dev = platform_get_drvdata(to_platform_device(dev));
|
|
int ret;
|
|
- int i = 0;
|
|
- struct s5p_mfc_ctx *ctx = NULL;
|
|
|
|
if (!m_dev) {
|
|
mfc_err("no mfc device to run\n");
|
|
@@ -3175,20 +3349,6 @@ static int s5p_mfc_suspend(struct device *dev)
|
|
if (m_dev->num_inst == 0)
|
|
return 0;
|
|
|
|
- ctx = m_dev->ctx[m_dev->curr_ctx];
|
|
- if (!ctx) {//may be, we got the instance just after release
|
|
- for(i = 0; i < MFC_NUM_CONTEXTS; i++)
|
|
- {
|
|
- ctx = m_dev->ctx[i];
|
|
- if(ctx)
|
|
- {
|
|
- mfc_info_ctx("MFC Find a not null ctx, and the curr_ctx changed to %d\n",i);
|
|
- m_dev->curr_ctx = i;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
ret = s5p_mfc_sleep(m_dev);
|
|
|
|
return ret;
|
|
@@ -3365,6 +3525,7 @@ static struct platform_driver s5p_mfc_driver = {
|
|
.owner = THIS_MODULE,
|
|
.pm = &s5p_mfc_pm_ops,
|
|
.of_match_table = exynos_mfc_match,
|
|
+ .suppress_bind_attrs = true,
|
|
},
|
|
};
|
|
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.h b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v5.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v6.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 38797515a390..78ebff85a12d
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h
|
|
@@ -37,6 +37,8 @@
|
|
#include <linux/pm_qos.h>
|
|
#endif
|
|
|
|
+#define MFC_DRIVER_INFO 180315
|
|
+
|
|
#define MFC_MAX_BUFFERS 32
|
|
#define MFC_MAX_REF_BUFS 2
|
|
#define MFC_FRAME_PLANES 2
|
|
@@ -47,15 +49,15 @@
|
|
#define MFC_NUM_CONTEXTS 32
|
|
#define MFC_MAX_DRM_CTX 2
|
|
/* Interrupt timeout */
|
|
-#define MFC_INT_TIMEOUT 2000
|
|
+#define MFC_INT_TIMEOUT 15000
|
|
/* Interrupt short timeout */
|
|
-#define MFC_INT_SHORT_TIMEOUT 800
|
|
+#define MFC_INT_SHORT_TIMEOUT 3000
|
|
/* Busy wait timeout */
|
|
#define MFC_BW_TIMEOUT 500
|
|
/* Watchdog interval */
|
|
#define MFC_WATCHDOG_INTERVAL 1000
|
|
/* After how many executions watchdog should assume lock up */
|
|
-#define MFC_WATCHDOG_CNT 5
|
|
+#define MFC_WATCHDOG_CNT 15
|
|
|
|
#define MFC_NO_INSTANCE_SET -1
|
|
|
|
@@ -71,6 +73,7 @@
|
|
#define MFC_BASE_MASK ((1 << 17) - 1)
|
|
|
|
#define FLAG_LAST_FRAME 0x80000000
|
|
+#define FLAG_CSD 0x20000000
|
|
#define MFC_MAX_INTERVAL (2 * USEC_PER_SEC)
|
|
|
|
/* Maximum number of temporal layers */
|
|
@@ -125,7 +128,7 @@ enum s5p_mfc_inst_state {
|
|
MFCINST_INIT = 100,
|
|
MFCINST_GOT_INST,
|
|
MFCINST_HEAD_PARSED,
|
|
- MFCINST_BUFS_SET,
|
|
+ MFCINST_RUNNING_BUF_FULL,
|
|
MFCINST_RUNNING,
|
|
MFCINST_FINISHING,
|
|
MFCINST_FINISHED,
|
|
@@ -139,6 +142,8 @@ enum s5p_mfc_inst_state {
|
|
MFCINST_ABORT_INST,
|
|
MFCINST_DPB_FLUSHING,
|
|
MFCINST_VPS_PARSED_ONLY,
|
|
+ MFCINST_SPECIAL_PARSING,
|
|
+ MFCINST_SPECIAL_PARSING_NAL,
|
|
};
|
|
|
|
/**
|
|
@@ -182,15 +187,6 @@ enum mfc_buf_usage_type {
|
|
MFCBUF_DRM,
|
|
};
|
|
|
|
-enum mfc_buf_process_type {
|
|
- MFCBUFPROC_DEFAULT = 0x0,
|
|
- MFCBUFPROC_COPY = (1 << 0),
|
|
- MFCBUFPROC_SHARE = (1 << 1),
|
|
- MFCBUFPROC_META = (1 << 2),
|
|
- MFCBUFPROC_ANBSHARE = (1 << 3),
|
|
- MFCBUFPROC_ANBSHARE_NV12L = (1 << 4),
|
|
-};
|
|
-
|
|
struct s5p_mfc_ctx;
|
|
struct s5p_mfc_extra_buf;
|
|
struct s5p_mfc_dev;
|
|
@@ -237,6 +233,7 @@ struct s5p_mfc_buf {
|
|
int used;
|
|
int already;
|
|
int consumed;
|
|
+ unsigned char *vir_addr;
|
|
};
|
|
|
|
#define vb_to_mfc_buf(x) \
|
|
@@ -363,6 +360,7 @@ struct s5p_mfc_dev {
|
|
int curr_ctx;
|
|
int preempt_ctx;
|
|
unsigned long ctx_work_bits;
|
|
+ unsigned long ctx_stop_bits;
|
|
|
|
atomic_t watchdog_cnt;
|
|
atomic_t watchdog_run;
|
|
@@ -434,6 +432,10 @@ struct s5p_mfc_h264_enc_params {
|
|
u8 rc_frame_qp;
|
|
u8 rc_min_qp;
|
|
u8 rc_max_qp;
|
|
+ u8 rc_min_qp_p;
|
|
+ u8 rc_max_qp_p;
|
|
+ u8 rc_min_qp_b;
|
|
+ u8 rc_max_qp_b;
|
|
u8 rc_mb_dark;
|
|
u8 rc_mb_smooth;
|
|
u8 rc_mb_static;
|
|
@@ -446,11 +448,12 @@ struct s5p_mfc_h264_enc_params {
|
|
u16 ext_sar_height;
|
|
u8 open_gop;
|
|
u16 open_gop_size;
|
|
- u8 hier_qp;
|
|
+ u8 hier_qp_enable;
|
|
enum v4l2_mpeg_video_h264_hierarchical_coding_type hier_qp_type;
|
|
- u8 hier_qp_layer;
|
|
- u8 hier_qp_layer_qp[7];
|
|
- u32 hier_qp_layer_bit[7];
|
|
+ u8 num_hier_layer;
|
|
+ u8 hier_ref_type;
|
|
+ u8 hier_qp_layer[7];
|
|
+ u32 hier_bit_layer[7];
|
|
u8 sei_gen_enable;
|
|
u8 sei_fp_curr_frame_0;
|
|
enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_arrangement_type;
|
|
@@ -464,6 +467,11 @@ struct s5p_mfc_h264_enc_params {
|
|
u32 aso_slice_order[8];
|
|
|
|
u32 prepend_sps_pps_to_idr;
|
|
+ u8 enable_ltr;
|
|
+ u8 num_of_ltr;
|
|
+ u32 set_priority;
|
|
+ u32 base_priority;
|
|
+ u32 vui_enable;
|
|
};
|
|
|
|
/**
|
|
@@ -482,6 +490,10 @@ struct s5p_mfc_mpeg4_enc_params {
|
|
u8 rc_frame_qp;
|
|
u8 rc_min_qp;
|
|
u8 rc_max_qp;
|
|
+ u8 rc_min_qp_p;
|
|
+ u8 rc_max_qp_p;
|
|
+ u8 rc_min_qp_b;
|
|
+ u8 rc_max_qp_b;
|
|
u8 rc_p_frame_qp;
|
|
};
|
|
|
|
@@ -494,19 +506,21 @@ struct s5p_mfc_vp8_enc_params {
|
|
u8 vp8_version;
|
|
u8 rc_min_qp;
|
|
u8 rc_max_qp;
|
|
+ u8 rc_min_qp_p;
|
|
+ u8 rc_max_qp_p;
|
|
u8 rc_frame_qp;
|
|
u8 rc_p_frame_qp;
|
|
u8 vp8_numberofpartitions;
|
|
u8 vp8_filterlevel;
|
|
u8 vp8_filtersharpness;
|
|
u8 vp8_goldenframesel;
|
|
- u8 vp8_gfrefreshperiod;
|
|
- u8 hierarchy_qp_enable;
|
|
- u8 hier_qp_layer_qp[3];
|
|
- u32 hier_qp_layer_bit[3];
|
|
+ u16 vp8_gfrefreshperiod;
|
|
+ u8 hier_qp_enable;
|
|
+ u8 hier_qp_layer[3];
|
|
+ u32 hier_bit_layer[3];
|
|
u8 num_refs_for_p;
|
|
u8 intra_4x4mode_disable;
|
|
- u8 num_temporal_layer;
|
|
+ u8 num_hier_layer;
|
|
};
|
|
|
|
/**
|
|
@@ -519,6 +533,10 @@ struct s5p_mfc_hevc_enc_params {
|
|
u32 rc_framerate;
|
|
u8 rc_min_qp;
|
|
u8 rc_max_qp;
|
|
+ u8 rc_min_qp_p;
|
|
+ u8 rc_max_qp_p;
|
|
+ u8 rc_min_qp_b;
|
|
+ u8 rc_max_qp_b;
|
|
u8 rc_lcu_dark;
|
|
u8 rc_lcu_smooth;
|
|
u8 rc_lcu_static;
|
|
@@ -529,11 +547,9 @@ struct s5p_mfc_hevc_enc_params {
|
|
u8 max_partition_depth;
|
|
u8 num_refs_for_p;
|
|
u8 refreshtype;
|
|
- u8 refreshperiod;
|
|
- s8 croma_qp_offset_cr;
|
|
- s8 croma_qp_offset_cb;
|
|
- s8 lf_beta_offset_div2;
|
|
- s8 lf_tc_offset_div2;
|
|
+ u16 refreshperiod;
|
|
+ s32 lf_beta_offset_div2;
|
|
+ s32 lf_tc_offset_div2;
|
|
u8 loopfilter_disable;
|
|
u8 loopfilter_across;
|
|
u8 nal_control_length_filed;
|
|
@@ -542,12 +558,13 @@ struct s5p_mfc_hevc_enc_params {
|
|
u8 const_intra_period_enable;
|
|
u8 lossless_cu_enable;
|
|
u8 wavefront_enable;
|
|
- u8 longterm_ref_enable;
|
|
- u8 hier_qp;
|
|
- u8 hier_qp_type;
|
|
- u8 hier_qp_layer;
|
|
- u8 hier_qp_layer_qp;
|
|
- u8 hier_qp_layer_bit;
|
|
+ u8 enable_ltr;
|
|
+ u8 hier_qp_enable;
|
|
+ enum v4l2_mpeg_video_hevc_hierarchical_coding_type hier_qp_type;
|
|
+ u8 hier_ref_type;
|
|
+ u8 num_hier_layer;
|
|
+ u8 hier_qp_layer[7];
|
|
+ u32 hier_bit_layer[7];
|
|
u8 sign_data_hiding;
|
|
u8 general_pb_enable;
|
|
u8 temporal_id_enable;
|
|
@@ -560,6 +577,7 @@ struct s5p_mfc_hevc_enc_params {
|
|
u8 size_of_length_field;
|
|
u8 user_ref;
|
|
u8 store_ref;
|
|
+ u8 prepend_sps_pps_to_idr;
|
|
};
|
|
|
|
/**
|
|
@@ -571,9 +589,10 @@ struct s5p_mfc_enc_params {
|
|
|
|
u32 gop_size;
|
|
enum v4l2_mpeg_video_multi_slice_mode slice_mode;
|
|
- u16 slice_mb;
|
|
+ u32 slice_mb;
|
|
u32 slice_bit;
|
|
- u16 intra_refresh_mb;
|
|
+ u32 slice_mb_row;
|
|
+ u32 intra_refresh_mb;
|
|
u8 pad;
|
|
u8 pad_luma;
|
|
u8 pad_cb;
|
|
@@ -581,6 +600,8 @@ struct s5p_mfc_enc_params {
|
|
u8 rc_frame;
|
|
u32 rc_bitrate;
|
|
u16 rc_reaction_coeff;
|
|
+ u32 config_qp;
|
|
+ u32 dynamic_qp;
|
|
u8 frame_tag;
|
|
|
|
u8 num_b_frame; /* H.264/MPEG4 */
|
|
@@ -589,6 +610,7 @@ struct s5p_mfc_enc_params {
|
|
enum v4l2_mpeg_video_header_mode seq_hdr_mode;
|
|
enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
|
|
u8 fixed_target_bit;
|
|
+ u8 num_hier_max_layer;
|
|
|
|
u16 rc_frame_delta; /* MFC6.1 Only */
|
|
|
|
@@ -652,6 +674,7 @@ struct s5p_mfc_buf_ctrl {
|
|
int has_new;
|
|
int val;
|
|
unsigned int old_val; /* only for MFC_CTRL_TYPE_SET */
|
|
+ unsigned int old_val2; /* only for MFC_CTRL_TYPE_SET */
|
|
unsigned int is_volatile; /* only for MFC_CTRL_TYPE_SET */
|
|
unsigned int updated;
|
|
unsigned int mode;
|
|
@@ -740,7 +763,7 @@ struct s5p_mfc_raw_info {
|
|
int plane_size[3];
|
|
};
|
|
|
|
-#define MFC_TIME_INDEX 8
|
|
+#define MFC_TIME_INDEX 15
|
|
struct mfc_timestamp {
|
|
struct list_head list;
|
|
struct timeval timestamp;
|
|
@@ -805,6 +828,8 @@ struct s5p_mfc_dec {
|
|
struct mfc_user_shared_handle sh_handle;
|
|
|
|
int dynamic_ref_filled;
|
|
+
|
|
+ unsigned int err_sync_flag;
|
|
};
|
|
|
|
struct s5p_mfc_enc {
|
|
@@ -831,6 +856,7 @@ struct s5p_mfc_enc {
|
|
unsigned int bits;
|
|
} slice_size;
|
|
unsigned int in_slice;
|
|
+ unsigned int buf_full;
|
|
|
|
int stored_tag;
|
|
struct mfc_user_shared_handle sh_handle;
|
|
@@ -872,6 +898,15 @@ struct s5p_mfc_ctx {
|
|
int dpb_count;
|
|
int buf_stride;
|
|
|
|
+ int old_img_width;
|
|
+ int old_img_height;
|
|
+
|
|
+ unsigned int enc_drc_flag;
|
|
+ int enc_res_change;
|
|
+ int enc_res_change_state;
|
|
+ int enc_res_change_re_input;
|
|
+ size_t min_scratch_buf_size;
|
|
+
|
|
struct s5p_mfc_raw_info raw_buf;
|
|
int mv_size;
|
|
|
|
@@ -879,10 +914,12 @@ struct s5p_mfc_ctx {
|
|
void *port_a_buf;
|
|
size_t port_a_phys;
|
|
size_t port_a_size;
|
|
+ void *port_a_virt;
|
|
|
|
void *port_b_buf;
|
|
size_t port_b_phys;
|
|
size_t port_b_size;
|
|
+ void *port_b_virt;
|
|
|
|
enum s5p_mfc_queue_state capture_state;
|
|
enum s5p_mfc_queue_state output_state;
|
|
@@ -926,16 +963,15 @@ struct s5p_mfc_ctx {
|
|
struct list_head qos_list;
|
|
#endif
|
|
int qos_ratio;
|
|
+ int qos_changed;
|
|
int framerate;
|
|
int last_framerate;
|
|
int avg_framerate;
|
|
int frame_count;
|
|
struct timeval last_timestamp;
|
|
- int qp_min_change;
|
|
- int qp_max_change;
|
|
|
|
int is_max_fps;
|
|
- int buf_process_type;
|
|
+ int use_extra_qos;
|
|
|
|
struct mfc_timestamp ts_array[MFC_TIME_INDEX];
|
|
struct list_head ts_list;
|
|
@@ -1054,8 +1090,6 @@ static inline unsigned int mfc_version(struct s5p_mfc_dev *dev)
|
|
(dev->fw.date >= 0x121005)) || \
|
|
(IS_MFCv5X(dev) && \
|
|
(dev->fw.date >= 0x120823)))
|
|
-#define FW_HAS_VUI_PARAMS(dev) (IS_MFCV6(dev) && \
|
|
- (dev->fw.date >= 0x121214))
|
|
#define FW_HAS_ADV_RC_MODE(dev) (IS_MFCV6(dev) && \
|
|
(dev->fw.date >= 0x130329))
|
|
#define FW_HAS_I_LIMIT_RC_MODE(dev) ((IS_MFCv7X(dev) && \
|
|
@@ -1080,12 +1114,19 @@ static inline unsigned int mfc_version(struct s5p_mfc_dev *dev)
|
|
|
|
#define FW_NEED_SHARED_MEMORY(dev) (IS_MFCv5X(dev) || IS_MFCv6X(dev) || \
|
|
IS_MFCv7X(dev) || IS_MFCv78(dev))
|
|
+#if 0 /* Do not use last frame info */
|
|
#define FW_HAS_LAST_DISP_INFO(dev) (IS_MFCv9X(dev) && \
|
|
- (dev->fw.date >= 0x141205))
|
|
+ (dev->fw.date >= 0x141205))
|
|
+#else
|
|
+#define FW_HAS_LAST_DISP_INFO(dev) 0
|
|
+#endif
|
|
#define FW_HAS_GOP2(dev) (IS_MFCv9X(dev) && \
|
|
(dev->fw.date >= 0x150316))
|
|
#define FW_HAS_E_MIN_SCRATCH_BUF(dev) IS_MFCv9X(dev)
|
|
|
|
+#define FW_SUPPORT_SKYPE(dev) IS_MFCv9X(dev) && \
|
|
+ (dev->fw.date >= 0x150603)
|
|
+
|
|
#define HW_LOCK_CLEAR_MASK (0xFFFFFFFF)
|
|
|
|
#define is_h264(ctx) ((ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) ||\
|
|
@@ -1102,15 +1143,30 @@ static inline unsigned int mfc_version(struct s5p_mfc_dev *dev)
|
|
#define interlaced_cond(ctx) is_mpeg4vc1(ctx) || is_mpeg2(ctx) || is_h264(ctx)
|
|
#define on_res_change(ctx) ((ctx)->state >= MFCINST_RES_CHANGE_INIT && \
|
|
(ctx)->state <= MFCINST_RES_CHANGE_END)
|
|
+#define need_to_wait_frame_start(ctx) \
|
|
+ (((ctx->state == MFCINST_FINISHING) || \
|
|
+ (ctx->state == MFCINST_RUNNING)) && \
|
|
+ test_bit(ctx->num, &ctx->dev->hw_lock))
|
|
+#define need_to_wait_nal_abort(ctx) \
|
|
+ (ctx->state == MFCINST_ABORT_INST)
|
|
+#define need_to_special_parsing(ctx) \
|
|
+ ((ctx->state == MFCINST_GOT_INST) || \
|
|
+ (ctx->state == MFCINST_HEAD_PARSED))
|
|
+#define need_to_special_parsing_nal(ctx) \
|
|
+ ((ctx->state == MFCINST_RUNNING) || \
|
|
+ (ctx->state == MFCINST_ABORT))
|
|
|
|
/* Extra information for Decoder */
|
|
#define DEC_SET_DUAL_DPB (1 << 0)
|
|
#define DEC_SET_DYNAMIC_DPB (1 << 1)
|
|
#define DEC_SET_LAST_FRAME_INFO (1 << 2)
|
|
+#define DEC_SET_SKYPE_FLAG (1 << 3)
|
|
/* Extra information for Encoder */
|
|
#define ENC_SET_RGB_INPUT (1 << 0)
|
|
#define ENC_SET_SPARE_SIZE (1 << 1)
|
|
#define ENC_SET_TEMP_SVC_CH (1 << 2)
|
|
+#define ENC_SET_SKYPE_FLAG (1 << 3)
|
|
+#define ENC_SET_QP_BOUND_PB (1 << 5)
|
|
|
|
#define MFC_QOS_FLAG_NODATA 0xFFFFFFFF
|
|
|
|
@@ -1129,8 +1185,11 @@ static inline int clear_hw_bit(struct s5p_mfc_ctx *ctx)
|
|
struct s5p_mfc_dev *dev = ctx->dev;
|
|
int ret = -1;
|
|
|
|
- if (!atomic_read(&dev->watchdog_run))
|
|
+ if (!atomic_read(&dev->watchdog_run)) {
|
|
ret = test_and_clear_bit(ctx->num, &dev->hw_lock);
|
|
+ /* Reset the timeout watchdog */
|
|
+ atomic_set(&dev->watchdog_cnt, 0);
|
|
+ }
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c b/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index 53677ca4248d..e3bf79c1e8b5
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
|
|
@@ -512,7 +512,8 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
|
|
{
|
|
struct s5p_mfc_ctx *ctx;
|
|
int ret;
|
|
- int old_state;
|
|
+ int old_state, i;
|
|
+ int need_cache_flush = 0;
|
|
|
|
mfc_debug_enter();
|
|
|
|
@@ -523,8 +524,25 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
|
|
|
|
ctx = dev->ctx[dev->curr_ctx];
|
|
if (!ctx) {
|
|
- mfc_err("no mfc context to run\n");
|
|
- return -EINVAL;
|
|
+ for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
|
|
+ if (dev->ctx[i]) {
|
|
+ ctx = dev->ctx[i];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!ctx) {
|
|
+ mfc_err("no mfc context to run\n");
|
|
+ return -EINVAL;
|
|
+ } else {
|
|
+ mfc_info_dev("ctx is changed %d -> %d\n",
|
|
+ dev->curr_ctx, ctx->num);
|
|
+ dev->curr_ctx = ctx->num;
|
|
+ if (dev->curr_ctx_drm != ctx->is_drm) {
|
|
+ need_cache_flush = 1;
|
|
+ mfc_info_dev("DRM attribute is changed %d->%d\n",
|
|
+ dev->curr_ctx_drm, ctx->is_drm);
|
|
+ }
|
|
+ }
|
|
}
|
|
old_state = ctx->state;
|
|
ctx->state = MFCINST_ABORT;
|
|
@@ -545,6 +563,22 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
|
|
ctx->state = old_state;
|
|
s5p_mfc_clock_on(dev);
|
|
s5p_mfc_clean_dev_int_flags(dev);
|
|
+
|
|
+ if (need_cache_flush) {
|
|
+ s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_CACHE_FLUSH, NULL);
|
|
+ if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_CACHE_FLUSH_RET)) {
|
|
+ mfc_err_ctx("Failed to flush cache\n");
|
|
+ ret = -EINVAL;
|
|
+ goto err_mfc_sleep;
|
|
+ }
|
|
+
|
|
+ s5p_mfc_init_memctrl(dev, (ctx->is_drm ? MFCBUF_DRM : MFCBUF_NORMAL));
|
|
+ s5p_mfc_clock_off(dev);
|
|
+
|
|
+ dev->curr_ctx_drm = ctx->is_drm;
|
|
+ s5p_mfc_clock_on(dev);
|
|
+ }
|
|
+
|
|
ret = s5p_mfc_sleep_cmd(dev);
|
|
if (ret) {
|
|
mfc_err_dev("Failed to send command to MFC - timeout.\n");
|
|
@@ -584,7 +618,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
|
|
mfc_err("no mfc device to run\n");
|
|
return -EINVAL;
|
|
}
|
|
- mfc_info_dev("curr_ctx_drm:%d\n", dev->curr_ctx_drm);
|
|
+ mfc_info_dev("curr_ctx_drm:%d\n", dev->curr_ctx_drm);
|
|
dev->wakeup_status = 1;
|
|
/* Set clock source again after wake up */
|
|
s5p_mfc_set_clock_parent(dev);
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.h b/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index c41996e6f8ea..fbc065cbc7b9
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
|
|
@@ -67,11 +67,4 @@ extern int debug;
|
|
__func__, __LINE__, ##args); \
|
|
} while (0)
|
|
|
|
-#define mfc_dbg_ctx(fmt, args...) \
|
|
- do { \
|
|
- printk(KERN_DEBUG "[d:%d, c:%d] %s:%d: " fmt, \
|
|
- ctx->dev->id, ctx->num, \
|
|
- __func__, __LINE__, ##args); \
|
|
- } while (0)
|
|
-
|
|
#endif /* S5P_MFC_DEBUG_H_ */
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index db53120b7531..c9ea937bdfcd
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
|
|
@@ -392,7 +392,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_VIDEO_QOS_RATIO,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "QoS ratio value",
|
|
- .minimum = 20,
|
|
+ .minimum = 0,
|
|
.maximum = 1000,
|
|
.step = 10,
|
|
.default_value = 100,
|
|
@@ -424,15 +424,6 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
- {
|
|
- .id = V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "Set buffer process type",
|
|
- .minimum = INT_MIN,
|
|
- .maximum = INT_MAX,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
};
|
|
|
|
#define NUM_CTRLS ARRAY_SIZE(controls)
|
|
@@ -631,12 +622,21 @@ static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
|
|
/* Check whether a context should be run on hardware */
|
|
int s5p_mfc_dec_ctx_ready(struct s5p_mfc_ctx *ctx)
|
|
{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
struct s5p_mfc_dec *dec = ctx->dec_priv;
|
|
mfc_debug(2, "src=%d, dst=%d, ref=%d, state=%d capstat=%d\n",
|
|
ctx->src_queue_cnt, ctx->dst_queue_cnt, dec->ref_queue_cnt,
|
|
ctx->state, ctx->capture_state);
|
|
mfc_debug(2, "wait_state = %d\n", ctx->wait_state);
|
|
|
|
+ /* Skip ready check temprally */
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ if (test_bit(ctx->num, &dev->ctx_stop_bits)) {
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+ return 0;
|
|
+ }
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
/* Context is to parse header */
|
|
if (ctx->src_queue_cnt >= 1 && ctx->state == MFCINST_GOT_INST)
|
|
return 1;
|
|
@@ -1453,7 +1453,6 @@ static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
|
|
spin_lock_irq(&dev->condlock);
|
|
set_bit(ctx->num, &dev->ctx_work_bits);
|
|
spin_unlock_irq(&dev->condlock);
|
|
- s5p_mfc_clean_ctx_int_flags(ctx);
|
|
s5p_mfc_try_run(dev);
|
|
/* Wait until instance is returned or timeout occured */
|
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
@@ -1514,7 +1513,6 @@ static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
|
|
spin_lock_irq(&dev->condlock);
|
|
set_bit(ctx->num, &dev->ctx_work_bits);
|
|
spin_unlock_irq(&dev->condlock);
|
|
- s5p_mfc_clean_ctx_int_flags(ctx);
|
|
s5p_mfc_try_run(dev);
|
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET)) {
|
|
@@ -1729,6 +1727,11 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
|
|
return -EIO;
|
|
}
|
|
|
|
+ if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && !buf->length) {
|
|
+ mfc_err_ctx("multiplanar but length is zero\n");
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
|
if (buf->m.planes[0].bytesused > ctx->vq_src.plane_sizes[0]) {
|
|
mfc_err_ctx("data size (%d) must be less than "
|
|
@@ -1751,9 +1754,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
|
|
sizeof(struct timeval));
|
|
}
|
|
if (ctx->last_framerate != 0 &&
|
|
- ctx->last_framerate != ctx->framerate) {
|
|
- mfc_debug(2, "fps changed: %d -> %d\n",
|
|
- ctx->framerate, ctx->last_framerate);
|
|
+ ((ctx->last_framerate != ctx->framerate) || ctx->qos_changed)) {
|
|
+ mfc_debug(2, "fps changed: %d -> %d (%s)\n",
|
|
+ ctx->framerate, ctx->last_framerate,
|
|
+ ctx->use_extra_qos ? "extra" : "normal");
|
|
ctx->framerate = ctx->last_framerate;
|
|
s5p_mfc_qos_on(ctx);
|
|
}
|
|
@@ -1788,7 +1792,13 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
|
|
ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
|
|
} else {
|
|
ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
|
|
+
|
|
/* Memcpy from dec->ref_info to shared memory */
|
|
+ if (buf->index >= MFC_MAX_DPBS) {
|
|
+ mfc_err_ctx("buffer index[%d] range over\n", buf->index);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
srcBuf = &dec->ref_info[buf->index];
|
|
for (ncount = 0; ncount < MFC_MAX_DPBS; ncount++) {
|
|
if (srcBuf->dpb[ncount].fd[0] == MFC_INFO_INIT_FD)
|
|
@@ -1854,7 +1864,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
|
|
} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
|
ret = vb2_streamoff(&ctx->vq_dst, type);
|
|
if (!ret) {
|
|
- if (!(ctx->buf_process_type & MFCBUFPROC_COPY))
|
|
+ if (!ctx->use_extra_qos)
|
|
s5p_mfc_qos_off(ctx);
|
|
}
|
|
} else {
|
|
@@ -1891,6 +1901,8 @@ static int dec_ext_info(struct s5p_mfc_ctx *ctx)
|
|
val |= DEC_SET_DYNAMIC_DPB;
|
|
if (FW_HAS_LAST_DISP_INFO(dev))
|
|
val |= DEC_SET_LAST_FRAME_INFO;
|
|
+ if (FW_SUPPORT_SKYPE(dev))
|
|
+ val |= DEC_SET_SKYPE_FLAG;
|
|
|
|
return val;
|
|
}
|
|
@@ -2001,6 +2013,9 @@ static int get_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
|
|
ctrl->value = dec_ext_info(ctx);
|
|
break;
|
|
+ case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
|
|
+ ctrl->value = MFC_DRIVER_INFO;
|
|
+ break;
|
|
default:
|
|
list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
|
|
if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
|
|
@@ -2177,8 +2192,16 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
|
case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
|
|
if (ctrl->value > 150)
|
|
ctrl->value = 1000;
|
|
- mfc_info_ctx("set %d qos_ratio.\n", ctrl->value);
|
|
+ if (ctrl->value == 0) {
|
|
+ ctrl->value = 100;
|
|
+ ctx->use_extra_qos = 1;
|
|
+ mfc_info_ctx("QOS_RATIO is 0, use extra qos!\n");
|
|
+ } else {
|
|
+ ctx->use_extra_qos = 0;
|
|
+ mfc_info_ctx("QOS_RATIO is %d, use normal qos!\n", ctrl->value);
|
|
+ }
|
|
ctx->qos_ratio = ctrl->value;
|
|
+ ctx->qos_changed = 1;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE:
|
|
if (FW_HAS_DYNAMIC_DPB(dev))
|
|
@@ -2193,9 +2216,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
|
return -EINVAL;
|
|
}
|
|
break;
|
|
- case V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE:
|
|
- ctx->buf_process_type = ctrl->value;
|
|
- break;
|
|
default:
|
|
list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
|
|
if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
|
|
@@ -2736,8 +2756,8 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
struct s5p_mfc_ctx *ctx = q->drv_priv;
|
|
struct s5p_mfc_dec *dec;
|
|
struct s5p_mfc_dev *dev;
|
|
- int aborted = 0;
|
|
int index = 0;
|
|
+ int ret = 0;
|
|
int prev_state;
|
|
|
|
if (!ctx) {
|
|
@@ -2755,15 +2775,22 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
return -EINVAL;
|
|
}
|
|
|
|
- if (need_to_wait_frame_start(ctx)) {
|
|
- ctx->state = MFCINST_ABORT;
|
|
- if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
- S5P_FIMV_R2H_CMD_FRAME_DONE_RET))
|
|
- s5p_mfc_cleanup_timeout(ctx);
|
|
- if (on_res_change(ctx))
|
|
- mfc_debug(2, "stop on res change(state:%d)\n", ctx->state);
|
|
- else
|
|
- aborted = 1;
|
|
+ mfc_info_ctx("dec stop_streaming is called, hw_lock : %d, type : %d\n",
|
|
+ test_bit(ctx->num, &dev->hw_lock), q->type);
|
|
+ MFC_TRACE_CTX("** DEC streamoff(type:%d)\n", q->type);
|
|
+
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ set_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ clear_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
+ /* If a H/W operation is in progress, wait for it complete */
|
|
+ if (test_bit(ctx->num, &dev->hw_lock)) {
|
|
+ ret = wait_event_timeout(ctx->queue,
|
|
+ (test_bit(ctx->num, &dev->hw_lock) == 0),
|
|
+ msecs_to_jiffies(MFC_INT_TIMEOUT));
|
|
+ if (ret == 0)
|
|
+ mfc_err_ctx("wait for event failed\n");
|
|
}
|
|
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
@@ -2773,6 +2800,7 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
cleanup_assigned_fd(ctx);
|
|
cleanup_ref_queue(ctx);
|
|
dec->dynamic_used = 0;
|
|
+ dec->err_sync_flag = 0;
|
|
}
|
|
|
|
s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
|
|
@@ -2801,7 +2829,44 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
mfc_debug(2, "Decoding can be started now\n");
|
|
}
|
|
} else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
|
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
|
|
+ while (!list_empty(&ctx->src_queue)) {
|
|
+ struct s5p_mfc_buf *src_buf;
|
|
+ int csd, condition = 0;
|
|
+
|
|
+ src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
|
|
+ csd = src_buf->vb.v4l2_buf.reserved2 & FLAG_CSD ? 1 : 0;
|
|
+
|
|
+ if (csd) {
|
|
+ spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
+ s5p_mfc_clean_ctx_int_flags(ctx);
|
|
+ if (need_to_special_parsing(ctx)) {
|
|
+ ctx->state = MFCINST_SPECIAL_PARSING;
|
|
+ condition = S5P_FIMV_R2H_CMD_SEQ_DONE_RET;
|
|
+ mfc_info_ctx("try to special parsing! (before NAL_START)\n");
|
|
+ } else if (need_to_special_parsing_nal(ctx)) {
|
|
+ ctx->state = MFCINST_SPECIAL_PARSING_NAL;
|
|
+ condition = S5P_FIMV_R2H_CMD_FRAME_DONE_RET;
|
|
+ mfc_info_ctx("try to special parsing! (after NAL_START)\n");
|
|
+ } else {
|
|
+ mfc_info_ctx("can't parsing CSD!, state = %d\n", ctx->state);
|
|
+ }
|
|
+ if (condition) {
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ set_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+ s5p_mfc_try_run(dev);
|
|
+ if (s5p_mfc_wait_for_done_ctx(ctx, condition)) {
|
|
+ mfc_err_ctx("special parsing time out\n");
|
|
+ s5p_mfc_cleanup_timeout(ctx);
|
|
+ }
|
|
+ }
|
|
+ spin_lock_irqsave(&dev->irqlock, flags);
|
|
+ }
|
|
+ vb2_set_plane_payload(&src_buf->vb, 0, 0);
|
|
+ vb2_buffer_done(&src_buf->vb, VB2_BUF_STATE_ERROR);
|
|
+ list_del(&src_buf->list);
|
|
+ }
|
|
+
|
|
INIT_LIST_HEAD(&ctx->src_queue);
|
|
ctx->src_queue_cnt = 0;
|
|
|
|
@@ -2814,13 +2879,30 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
}
|
|
}
|
|
|
|
- if (aborted)
|
|
+ if (ctx->state == MFCINST_FINISHING)
|
|
ctx->state = MFCINST_RUNNING;
|
|
|
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
|
|
if (IS_MFCV6(dev) && q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
|
|
need_to_dpb_flush(ctx)) {
|
|
+ int ret = 0;
|
|
+
|
|
+ /* If a H/W operation is in progress, wait for it complete */
|
|
+ if (dev->hw_lock) {
|
|
+ struct s5p_mfc_ctx *wait_ctx;
|
|
+
|
|
+ index = find_first_bit(&dev->hw_lock, MFC_NUM_CONTEXTS);
|
|
+ wait_ctx = dev->ctx[index];
|
|
+ ret = wait_event_interruptible_timeout(wait_ctx->queue,
|
|
+ (dev->hw_lock == 0),
|
|
+ msecs_to_jiffies(MFC_INT_TIMEOUT));
|
|
+ if (ret == 0) {
|
|
+ mfc_err_dev("Waiting for hardware to finish timed out\n");
|
|
+ return -EIO;
|
|
+ }
|
|
+ }
|
|
+
|
|
prev_state = ctx->state;
|
|
ctx->state = MFCINST_DPB_FLUSHING;
|
|
spin_lock_irq(&dev->condlock);
|
|
@@ -2833,6 +2915,23 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
s5p_mfc_cleanup_timeout(ctx);
|
|
ctx->state = prev_state;
|
|
}
|
|
+
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ clear_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
+ mfc_debug(2, "buffer cleanup & flush is done in stop_streaming, type : %d\n", q->type);
|
|
+
|
|
+ if (s5p_mfc_dec_ctx_ready(ctx)) {
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ set_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+ }
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ if (dev->ctx_work_bits)
|
|
+ queue_work(dev->sched_wq, &dev->sched_work);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -2868,6 +2967,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
|
|
int remove_flag = 0;
|
|
int index;
|
|
int skip_add = 0;
|
|
+ unsigned char *stream_vir = NULL;
|
|
|
|
mfc_debug_enter();
|
|
if (!ctx) {
|
|
@@ -2892,9 +2992,14 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
|
|
mfc_debug(2, "Adding to src: %p (0x%08lx, 0x%08lx)\n", vb,
|
|
(unsigned long)s5p_mfc_mem_plane_addr(ctx, vb, 0),
|
|
(unsigned long)buf->planes.stream);
|
|
+ if (ctx->state < MFCINST_HEAD_PARSED && !ctx->is_drm) {
|
|
+ stream_vir = vb2_plane_vaddr(vb, 0);
|
|
+ s5p_mfc_mem_inv_vb(vb, 1);
|
|
+ }
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
list_add_tail(&buf->list, &ctx->src_queue);
|
|
ctx->src_queue_cnt++;
|
|
+ buf->vir_addr = stream_vir;
|
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
|
buf->used = 0;
|
|
@@ -3052,6 +3157,7 @@ int s5p_mfc_init_dec_ctx(struct s5p_mfc_ctx *ctx)
|
|
dec->is_dts_mode = 0;
|
|
dec->is_dual_dpb = 0;
|
|
dec->tiled_buf_cnt = 0;
|
|
+ dec->err_sync_flag = 0;
|
|
|
|
dec->is_dynamic_dpb = 0;
|
|
dec->dynamic_used = 0;
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 584b2a4117fb..14b436624e92
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
|
|
@@ -15,7 +15,7 @@
|
|
|
|
#define MAX_FRAME_SIZE (2*1024*1024)
|
|
#define DEFAULT_TAG (0xE05)
|
|
-#define DEC_MAX_FPS (60000)
|
|
+#define DEC_MAX_FPS (240000)
|
|
|
|
const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
|
|
int s5p_mfc_init_dec_ctx(struct s5p_mfc_ctx *ctx);
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index 72172a419903..145c32b74284
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
|
|
@@ -198,7 +198,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "The slice partitioning method",
|
|
.minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
|
|
- .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
|
|
+ .maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW,
|
|
.step = 1,
|
|
.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
|
|
},
|
|
@@ -207,7 +207,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "The number of MB in a slice",
|
|
.minimum = 1,
|
|
- .maximum = ENC_MULTI_SLICE_MB_MAX,
|
|
+ .maximum = INT_MAX,
|
|
.step = 1,
|
|
.default_value = 1,
|
|
},
|
|
@@ -215,17 +215,26 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "The maximum bits per slices",
|
|
- .minimum = ENC_MULTI_SLICE_BYTE_MIN,
|
|
- .maximum = (1 << 30) - 1,
|
|
+ .minimum = 350,
|
|
+ .maximum = INT_MAX / 8,
|
|
+ .step = 1,
|
|
+ .default_value = 350,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "The number of MB row in a slice",
|
|
+ .minimum = 1,
|
|
+ .maximum = INT_MAX / 256,
|
|
.step = 1,
|
|
- .default_value = ENC_MULTI_SLICE_BYTE_MIN,
|
|
+ .default_value = 1,
|
|
},
|
|
{
|
|
.id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "The number of intra refresh MBs",
|
|
.minimum = 0,
|
|
- .maximum = ENC_INTRA_REFRESH_MB_MAX,
|
|
+ .maximum = (1 << 18) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -243,7 +252,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "Padding Color YUV Value",
|
|
.minimum = 0,
|
|
- .maximum = (1 << 25) - 1,
|
|
+ .maximum = (1 << 24) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -261,7 +270,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "Target bit rate rate-control",
|
|
.minimum = 1,
|
|
- .maximum = (1 << 30) - 1,
|
|
+ .maximum = INT_MAX,
|
|
.step = 1,
|
|
.default_value = 1,
|
|
},
|
|
@@ -279,7 +288,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "Encoded stream size",
|
|
.minimum = 0,
|
|
- .maximum = (1 << 30) - 1,
|
|
+ .maximum = INT_MAX,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
.flags = V4L2_CTRL_FLAG_READ_ONLY,
|
|
@@ -289,7 +298,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "Encoded frame count",
|
|
.minimum = 0,
|
|
- .maximum = (1 << 30) - 1,
|
|
+ .maximum = INT_MAX,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
.flags = V4L2_CTRL_FLAG_READ_ONLY,
|
|
@@ -319,7 +328,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "VBV buffer size (1Kbits)",
|
|
.minimum = 0,
|
|
- .maximum = ENC_VBV_BUF_SIZE_MAX,
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -373,7 +382,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "H264 profile",
|
|
.minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
|
|
- .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
|
|
+ .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
|
|
.step = 1,
|
|
.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
|
|
},
|
|
@@ -408,8 +417,8 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "H264 loop filter alpha offset",
|
|
- .minimum = ENC_H264_LOOP_FILTER_AB_MIN,
|
|
- .maximum = ENC_H264_LOOP_FILTER_AB_MAX,
|
|
+ .minimum = -12,
|
|
+ .maximum = 12,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -417,8 +426,8 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "H264 loop filter beta offset",
|
|
- .minimum = ENC_H264_LOOP_FILTER_AB_MIN,
|
|
- .maximum = ENC_H264_LOOP_FILTER_AB_MAX,
|
|
+ .minimum = -12,
|
|
+ .maximum = 12,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -463,7 +472,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "H264 Frame rate",
|
|
.minimum = 1,
|
|
- .maximum = ENC_H264_RC_FRAME_RATE_MAX,
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 1,
|
|
},
|
|
@@ -476,25 +485,6 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "H264 Minimum QP value",
|
|
- .minimum = 0,
|
|
- .maximum = 51,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
- {
|
|
- /* MAX_QP must be greater than or equal to MIN_QP */
|
|
- .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "H264 Maximum QP value",
|
|
- .minimum = 0,
|
|
- .maximum = 51,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
{
|
|
.id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK,
|
|
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
@@ -619,7 +609,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.minimum = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
|
|
.maximum = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
|
|
.step = 1,
|
|
- .default_value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
|
|
+ .default_value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
|
|
},
|
|
{
|
|
.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER,
|
|
@@ -775,24 +765,6 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 1,
|
|
},
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "MPEG4 Minimum QP value",
|
|
- .minimum = 1,
|
|
- .maximum = 31,
|
|
- .step = 1,
|
|
- .default_value = 1,
|
|
- },
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "MPEG4 Maximum QP value",
|
|
- .minimum = 1,
|
|
- .maximum = 31,
|
|
- .step = 1,
|
|
- .default_value = 1,
|
|
- },
|
|
{ /* MFC5.x Only */
|
|
.id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
|
|
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
@@ -825,7 +797,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "MPEG4 vop time resolution",
|
|
.minimum = 0,
|
|
- .maximum = ENC_MPEG4_VOP_TIME_RES_MAX,
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -843,7 +815,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "H263 Frame rate",
|
|
.minimum = 1,
|
|
- .maximum = ENC_H263_RC_FRAME_RATE_MAX,
|
|
+ .maximum = (1 << 8) - 1,
|
|
.step = 1,
|
|
.default_value = 1,
|
|
},
|
|
@@ -856,24 +828,6 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 1,
|
|
},
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "H263 Minimum QP value",
|
|
- .minimum = 1,
|
|
- .maximum = 31,
|
|
- .step = 1,
|
|
- .default_value = 1,
|
|
- },
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "H263 Maximum QP value",
|
|
- .minimum = 1,
|
|
- .maximum = 31,
|
|
- .step = 1,
|
|
- .default_value = 1,
|
|
- },
|
|
{
|
|
.id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
@@ -905,8 +859,8 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_VIDEO_QOS_RATIO,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "QoS ratio value",
|
|
- .minimum = 20,
|
|
- .maximum = 200,
|
|
+ .minimum = 0,
|
|
+ .maximum = 1000,
|
|
.step = 10,
|
|
.default_value = 100,
|
|
},
|
|
@@ -937,30 +891,12 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "VP8 Frame QP MAX value",
|
|
- .minimum = 0,
|
|
- .maximum = 127,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "VP8 Frame QP MIN value",
|
|
- .minimum = 0,
|
|
- .maximum = 127,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
{
|
|
.id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "VP8 Frame rate",
|
|
.minimum = 1,
|
|
- .maximum = ENC_H264_RC_FRAME_RATE_MAX,
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -1005,7 +941,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "VP8 indication of golden frame",
|
|
.minimum = 0,
|
|
- .maximum = ((1 << 16) - 1),
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -1099,26 +1035,6 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
-
|
|
- {
|
|
- .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "HEVC Minimum QP value",
|
|
- .minimum = 0,
|
|
- .maximum = 51,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
- {
|
|
- /* MAX_QP must be greater than or equal to MIN_QP */
|
|
- .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "HEVC Maximum QP value",
|
|
- .minimum = 0,
|
|
- .maximum = 51,
|
|
- .step = 1,
|
|
- .default_value = 0,
|
|
- },
|
|
{
|
|
.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK,
|
|
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
@@ -1187,7 +1103,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "HEVC Frame rate",
|
|
.minimum = 1,
|
|
- .maximum = ENC_HEVC_RC_FRAME_RATE_MAX,
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
@@ -1285,8 +1201,8 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE,
|
|
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
.name = "Hierarchical Coding Type",
|
|
- .minimum = 0,
|
|
- .maximum = 1,
|
|
+ .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
|
|
+ .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
|
|
.step = 1,
|
|
.default_value = 0, /* need to check defualt value */
|
|
},
|
|
@@ -1309,13 +1225,76 @@ static struct v4l2_queryctrl controls[] = {
|
|
.default_value = 0, /* need to check defualt value */
|
|
},
|
|
{
|
|
- .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "Hierarchical Coding Layer BIT",
|
|
+ .name = "Hierarchical Coding Layer BIT0",
|
|
.minimum = INT_MIN,
|
|
.maximum = INT_MAX,
|
|
.step = 1,
|
|
- .default_value = 0, /* need to check defualt value */
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer BIT1",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer BIT2",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer BIT3",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer BIT4",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer BIT5",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer BIT6",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding Layer Change",
|
|
+ .minimum = INT_MIN,
|
|
+ .maximum = INT_MAX,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
},
|
|
{
|
|
.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING,
|
|
@@ -1394,25 +1373,7 @@ static struct v4l2_queryctrl controls[] = {
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "HEVC Number of reference picture",
|
|
.minimum = 0,
|
|
- .maximum = 10, /* need to check maximum size */
|
|
- .step = 1,
|
|
- .default_value = 0, /* need to check defualt value */
|
|
- },
|
|
- {
|
|
- .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CR,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "Chroma QP index offset Cr",
|
|
- .minimum = ENC_HEVC_QP_INDEX_MIN,
|
|
- .maximum = ENC_HEVC_QP_INDEX_MAX,
|
|
- .step = 1,
|
|
- .default_value = 0, /* need to check defualt value */
|
|
- },
|
|
- {
|
|
- .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CB,
|
|
- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
- .name = "Chroma QP index offset Cb",
|
|
- .minimum = ENC_HEVC_QP_INDEX_MIN,
|
|
- .maximum = ENC_HEVC_QP_INDEX_MAX,
|
|
+ .maximum = (1 << 16) - 1,
|
|
.step = 1,
|
|
.default_value = 0, /* need to check defualt value */
|
|
},
|
|
@@ -1420,8 +1381,8 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "HEVC loop filter beta offset",
|
|
- .minimum = ENC_HEVC_LOOP_FILTER_MIN,
|
|
- .maximum = ENC_HEVC_LOOP_FILTER_MAX,
|
|
+ .minimum = -6,
|
|
+ .maximum = 6,
|
|
.step = 1,
|
|
.default_value = 0, /* need to check defualt value */
|
|
},
|
|
@@ -1429,8 +1390,8 @@ static struct v4l2_queryctrl controls[] = {
|
|
.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2,
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
.name = "HEVC loop filter tc offset",
|
|
- .minimum = ENC_HEVC_LOOP_FILTER_MIN,
|
|
- .maximum = ENC_HEVC_LOOP_FILTER_MAX,
|
|
+ .minimum = -6,
|
|
+ .maximum = 6,
|
|
.step = 1,
|
|
.default_value = 0, /* need to check defualt value */
|
|
},
|
|
@@ -1596,90 +1557,422 @@ static struct v4l2_queryctrl controls[] = {
|
|
.step = 1,
|
|
.default_value = 0,
|
|
},
|
|
-};
|
|
-
|
|
-#define NUM_CTRLS ARRAY_SIZE(controls)
|
|
-
|
|
-static struct v4l2_queryctrl *get_ctrl(int id)
|
|
-{
|
|
- unsigned long i;
|
|
-
|
|
- for (i = 0; i < NUM_CTRLS; ++i)
|
|
- if (id == controls[i].id)
|
|
- return &controls[i];
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-static int check_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
-{
|
|
- struct s5p_mfc_dev *dev = ctx->dev;
|
|
- struct v4l2_queryctrl *c;
|
|
-
|
|
- c = get_ctrl(ctrl->id);
|
|
- if (!c)
|
|
- return -EINVAL;
|
|
- if (ctrl->id == V4L2_CID_MPEG_VIDEO_GOP_SIZE
|
|
- && ctrl->value > c->maximum) {
|
|
- mfc_info_ctx("GOP_SIZE is changed to max(%d -> %d)\n",
|
|
- ctrl->value, c->maximum);
|
|
- ctrl->value = c->maximum;
|
|
- }
|
|
-
|
|
- if (ctrl->value < c->minimum || ctrl->value > c->maximum
|
|
- || (c->step != 0 && ctrl->value % c->step != 0)) {
|
|
- v4l2_err(&dev->v4l2_dev, "Invalid control value\n");
|
|
- return -ERANGE;
|
|
- }
|
|
- if (!FW_HAS_ENC_SPSPPS_CTRL(dev) && ctrl->id == \
|
|
- V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR) {
|
|
- mfc_err_ctx("Not support feature(0x%x) for F/W\n", ctrl->id);
|
|
- return -ERANGE;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static int enc_ctrl_read_cst(struct s5p_mfc_ctx *ctx,
|
|
- struct s5p_mfc_buf_ctrl *buf_ctrl)
|
|
-{
|
|
- int ret;
|
|
- struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
-
|
|
- switch (buf_ctrl->id) {
|
|
- case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
|
|
- ret = !enc->in_slice;
|
|
- break;
|
|
- default:
|
|
- mfc_err_ctx("not support custom per-buffer control\n");
|
|
- ret = -EINVAL;
|
|
- break;
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
|
|
- { /* set frame tag */
|
|
- .type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
|
|
- .is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_SHARED_SET_E_FRAME_TAG,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_NONE,
|
|
- .flag_addr = 0,
|
|
- .flag_shft = 0,
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_ENABLE_LTR,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Enable LTR",
|
|
+ .minimum = 0,
|
|
+ .maximum = 1,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
},
|
|
- { /* get frame tag */
|
|
- .type = MFC_CTRL_TYPE_GET_DST,
|
|
- .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
|
|
- .is_volatile = 0,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_SHARED_GET_E_FRAME_TAG,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_NONE,
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Number of LTR",
|
|
+ .minimum = 0,
|
|
+ .maximum = 4,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Set the frame as a LTRP",
|
|
+ .minimum = 0,
|
|
+ .maximum = 4,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_USE_LTR,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Specify a LTRP for encoding",
|
|
+ .minimum = 0,
|
|
+ .maximum = 0xF,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Base Layer Priority",
|
|
+ .minimum = 0,
|
|
+ .maximum = (1 << 6) - 1 - 6,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_CONFIG_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "QP control per each frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = (1 << 7) - 1,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 vui generation enable",
|
|
+ .minimum = 0,
|
|
+ .maximum = 1,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Prepend SPS/PPS to every IDR",
|
|
+ .minimum = 0,
|
|
+ .maximum = 1,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "set dynamic qp control",
|
|
+ .minimum = 0,
|
|
+ .maximum = 1,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 Min QP value for I frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 Max QP value for I frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "HEVC Min QP value for I frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "HEVC Max QP value for I frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "MPEG4 Min QP value for I frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "MPEG4 Max QP value for I frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H263 Min QP value for I frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H263 Max QP value for I frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "VP8 Min QP value for I frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 127,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "VP8 Max QP value for I frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 127,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 Min QP value for P frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 Max QP value for P frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "HEVC Min QP value for P frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "HEVC Max QP value for P frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "MPEG4 Min QP value for P frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "MPEG4 Max QP value for P frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H263 Min QP value for P frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H263 Max QP value for P frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "VP8 Min QP value for P frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 127,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "VP8 Max QP value for P frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 127,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 Min QP value for B frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "H264 Max QP value for B frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "HEVC Min QP value for B frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "HEVC Max QP value for B frame",
|
|
+ .minimum = 0,
|
|
+ .maximum = 51,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "MPEG4 Min QP value for B frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "MPEG4 Max QP value for B frame",
|
|
+ .minimum = 1,
|
|
+ .maximum = 31,
|
|
+ .step = 1,
|
|
+ .default_value = 1,
|
|
+ },
|
|
+ {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER,
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .name = "Hierarchical Coding max layer",
|
|
+ .minimum = 0,
|
|
+ .maximum = 3,
|
|
+ .step = 1,
|
|
+ .default_value = 0,
|
|
+ },
|
|
+};
|
|
+
|
|
+#define NUM_CTRLS ARRAY_SIZE(controls)
|
|
+
|
|
+static struct v4l2_queryctrl *get_ctrl(int id)
|
|
+{
|
|
+ unsigned long i;
|
|
+
|
|
+ for (i = 0; i < NUM_CTRLS; ++i)
|
|
+ if (id == controls[i].id)
|
|
+ return &controls[i];
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static int check_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
+ struct v4l2_queryctrl *c;
|
|
+
|
|
+ c = get_ctrl(ctrl->id);
|
|
+ if (!c)
|
|
+ return -EINVAL;
|
|
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_GOP_SIZE
|
|
+ && ctrl->value > c->maximum) {
|
|
+ mfc_info_ctx("GOP_SIZE is changed to max(%d -> %d)\n",
|
|
+ ctrl->value, c->maximum);
|
|
+ ctrl->value = c->maximum;
|
|
+ }
|
|
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER) {
|
|
+ if ((ctrl->value & ~(1 << 16)) < c->minimum || (ctrl->value & ~(1 << 16)) > c->maximum
|
|
+ || (c->step != 0 && (ctrl->value & ~(1 << 16)) % c->step != 0)) {
|
|
+ v4l2_err(&dev->v4l2_dev, "Invalid control value\n");
|
|
+ return -ERANGE;
|
|
+ } else {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ if (ctrl->value < c->minimum || ctrl->value > c->maximum
|
|
+ || (c->step != 0 && ctrl->value % c->step != 0)) {
|
|
+ v4l2_err(&dev->v4l2_dev, "Invalid control value\n");
|
|
+ return -ERANGE;
|
|
+ }
|
|
+ if (!FW_HAS_ENC_SPSPPS_CTRL(dev) && ctrl->id == \
|
|
+ V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR) {
|
|
+ mfc_err_ctx("Not support feature(0x%x) for F/W\n", ctrl->id);
|
|
+ return -ERANGE;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int enc_ctrl_read_cst(struct s5p_mfc_ctx *ctx,
|
|
+ struct s5p_mfc_buf_ctrl *buf_ctrl)
|
|
+{
|
|
+ int ret;
|
|
+ struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
+
|
|
+ switch (buf_ctrl->id) {
|
|
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
|
|
+ ret = !enc->in_slice;
|
|
+ break;
|
|
+ default:
|
|
+ mfc_err_ctx("not support custom per-buffer control\n");
|
|
+ ret = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
|
|
+ { /* set frame tag */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_SHARED_SET_E_FRAME_TAG,
|
|
+ .mask = 0xFFFFFFFF,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_NONE,
|
|
+ .flag_addr = 0,
|
|
+ .flag_shft = 0,
|
|
+ },
|
|
+ { /* get frame tag */
|
|
+ .type = MFC_CTRL_TYPE_GET_DST,
|
|
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
|
|
+ .is_volatile = 0,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_SHARED_GET_E_FRAME_TAG,
|
|
+ .mask = 0xFFFFFFFF,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_NONE,
|
|
.flag_addr = 0,
|
|
.flag_shft = 0,
|
|
},
|
|
@@ -1769,149 +2062,426 @@ static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
|
|
.read_cst = enc_ctrl_read_cst,
|
|
.write_cst = NULL,
|
|
},
|
|
- { /* H.264 QP Max change */
|
|
+ { /* H.264 I frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.264 I frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.263 I frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.263 I frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* MPEG4 I frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* MPEG4 I frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* VP8 I frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* VP8 I frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* HEVC I frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* HEVC I frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.264 P frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.264 P frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.263 P frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.263 P frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* MPEG4 P frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* MPEG4 P frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* VP8 P frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* VP8 P frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* HEVC P frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* HEVC P frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 0,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.264 B frame QP Max change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 24,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* H.264 B frame QP Min change */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 16,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
+ .flag_shft = 4,
|
|
+ },
|
|
+ { /* MPEG4 B frame QP Max change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 24,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
.flag_shft = 4,
|
|
},
|
|
- { /* H.264 QP Min change */
|
|
+ { /* MPEG4 B frame QP Min change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 16,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
.flag_shft = 4,
|
|
},
|
|
- { /* H.263 QP Max change */
|
|
+ { /* HEVC B frame QP Max change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 24,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
.flag_shft = 4,
|
|
},
|
|
- { /* H.263 QP Min change */
|
|
+ { /* HEVC B frame QP Min change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_RC_QP_BOUND_PB,
|
|
+ .mask = 0x7F,
|
|
+ .shft = 16,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
+ .flag_addr = S5P_FIMV_E_PARAM_CHANGE,
|
|
.flag_shft = 4,
|
|
},
|
|
- { /* MPEG4 QP Max change */
|
|
+
|
|
+ { /* H.264 Dynamic Temporal Layer & bitrate change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
|
|
.is_volatile = 1,
|
|
.mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .addr = S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0,
|
|
.mask = 0xFFFFFFFF,
|
|
.shft = 0,
|
|
.flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 4,
|
|
+ .flag_shft = 10,
|
|
},
|
|
- { /* MPEG4 QP Min change */
|
|
+ { /* HEVC Dynamic Temporal Layer & bitrate change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
|
|
.is_volatile = 1,
|
|
.mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .addr = S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0,
|
|
.mask = 0xFFFFFFFF,
|
|
.shft = 0,
|
|
.flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 4,
|
|
+ .flag_shft = 10,
|
|
},
|
|
- { /* VP8 QP Max change */
|
|
+ { /* VP8 Dynamic Temporal Layer change */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
|
|
.is_volatile = 1,
|
|
.mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
+ .addr = S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0,
|
|
.mask = 0xFFFFFFFF,
|
|
.shft = 0,
|
|
.flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 4,
|
|
+ .flag_shft = 10,
|
|
},
|
|
- { /* VP8 QP Min change */
|
|
+ { /* set level */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
|
|
.is_volatile = 1,
|
|
.mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .addr = S5P_FIMV_E_PICTURE_PROFILE,
|
|
+ .mask = 0x000000FF,
|
|
+ .shft = 8,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 4,
|
|
+ .flag_shft = 5,
|
|
},
|
|
- { /* H.264 Dynamic Temporal Layer change */
|
|
+ { /* set profile */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
|
|
+ .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
|
|
.is_volatile = 1,
|
|
.mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0,
|
|
- .mask = 0xFFFFFFFF,
|
|
+ .addr = S5P_FIMV_E_PICTURE_PROFILE,
|
|
+ .mask = 0x0000000F,
|
|
.shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 10,
|
|
+ .flag_shft = 5,
|
|
},
|
|
- { /* HEVC QP Max change */
|
|
+ { /* set store LTR */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_H264_NAL_CONTROL,
|
|
+ .mask = 0x00000003,
|
|
.shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 4,
|
|
+ .flag_mode = MFC_CTRL_MODE_NONE,
|
|
+ .flag_addr = 0,
|
|
+ .flag_shft = 0,
|
|
},
|
|
- { /* HEVC QP Min change */
|
|
+ { /* set use LTR */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_USE_LTR,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_NEW_RC_QP_BOUND,
|
|
- .mask = 0xFFFFFFFF,
|
|
- .shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 4,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_H264_NAL_CONTROL,
|
|
+ .mask = 0x00000003,
|
|
+ .shft = 2,
|
|
+ .flag_mode = MFC_CTRL_MODE_NONE,
|
|
+ .flag_addr = 0,
|
|
+ .flag_shft = 0,
|
|
},
|
|
- { /* VP8 Dynamic Temporal Layer change */
|
|
+ { /* set base layer priority */
|
|
.type = MFC_CTRL_TYPE_SET,
|
|
- .id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
|
|
+ .id = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
|
|
.is_volatile = 1,
|
|
- .mode = MFC_CTRL_MODE_CUSTOM,
|
|
- .addr = S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0,
|
|
- .mask = 0xFFFFFFFF,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_H264_HD_SVC_EXTENSION_0,
|
|
+ .mask = 0x0000003F,
|
|
.shft = 0,
|
|
- .flag_mode = MFC_CTRL_MODE_CUSTOM,
|
|
+ .flag_mode = MFC_CTRL_MODE_SFR,
|
|
.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
|
|
- .flag_shft = 10,
|
|
+ .flag_shft = 12,
|
|
+ },
|
|
+ { /* set QP per each frame */
|
|
+ .type = MFC_CTRL_TYPE_SET,
|
|
+ .id = V4L2_CID_MPEG_MFC_CONFIG_QP,
|
|
+ .is_volatile = 1,
|
|
+ .mode = MFC_CTRL_MODE_SFR,
|
|
+ .addr = S5P_FIMV_E_FIXED_PICTURE_QP,
|
|
+ .mask = 0x0000007F,
|
|
+ .shft = 24,
|
|
+ .flag_mode = MFC_CTRL_MODE_NONE,
|
|
+ .flag_addr = 0,
|
|
+ .flag_shft = 0,
|
|
},
|
|
};
|
|
|
|
@@ -1919,12 +2489,21 @@ static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
|
|
|
|
int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx)
|
|
{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
struct s5p_mfc_enc_params *p = &enc->params;
|
|
|
|
mfc_debug(2, "src=%d, dst=%d, state=%d\n",
|
|
ctx->src_queue_cnt, ctx->dst_queue_cnt, ctx->state);
|
|
|
|
+ /* Skip ready check temporally */
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ if (test_bit(ctx->num, &dev->ctx_stop_bits)) {
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+ return 0;
|
|
+ }
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
/* context is ready to make header */
|
|
if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1) {
|
|
if (p->seq_hdr_mode == \
|
|
@@ -1946,6 +2525,10 @@ int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx)
|
|
if (ctx->state == MFCINST_RUNNING_NO_OUTPUT &&
|
|
ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
|
|
return 1;
|
|
+ /* context is ready to encode a frame for NAL_ABORT command */
|
|
+ if (ctx->state == MFCINST_ABORT_INST &&
|
|
+ ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
|
|
+ return 1;
|
|
/* context is ready to encode remain frames */
|
|
if (ctx->state == MFCINST_FINISHING &&
|
|
ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
|
|
@@ -1956,6 +2539,40 @@ int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx)
|
|
return 0;
|
|
}
|
|
|
|
+static inline int h264_profile(struct s5p_mfc_ctx *ctx, enum v4l2_mpeg_video_h264_profile profile)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
+ int ret = 0;
|
|
+
|
|
+ switch (profile) {
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
|
+ ret = S5P_FIMV_ENC_PROFILE_H264_MAIN;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
|
+ ret = S5P_FIMV_ENC_PROFILE_H264_HIGH;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
|
|
+ ret =S5P_FIMV_ENC_PROFILE_H264_BASELINE;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
|
+ if (IS_MFCV6(dev))
|
|
+ ret = S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
|
|
+ else
|
|
+ ret = -EINVAL;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
|
|
+ if (IS_MFCV6(dev))
|
|
+ ret = S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH;
|
|
+ else
|
|
+ ret = -EINVAL;
|
|
+ break;
|
|
+ default:
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int enc_cleanup_ctx_ctrls(struct s5p_mfc_ctx *ctx)
|
|
{
|
|
struct s5p_mfc_ctx_ctrl *ctx_ctrl;
|
|
@@ -2265,9 +2882,10 @@ static int enc_set_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_head *head
|
|
struct s5p_mfc_buf_ctrl *buf_ctrl;
|
|
struct s5p_mfc_dev *dev = ctx->dev;
|
|
struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
- unsigned int value = 0;
|
|
+ unsigned int value = 0, value2 = 0;
|
|
struct temporal_layer_info temporal_LC;
|
|
unsigned int i;
|
|
+ struct s5p_mfc_enc_params *p = &enc->params;
|
|
|
|
list_for_each_entry(buf_ctrl, head, list) {
|
|
if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
|
|
@@ -2312,44 +2930,91 @@ static int enc_set_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_head *head
|
|
if (buf_ctrl->id
|
|
== V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH ||
|
|
buf_ctrl->id
|
|
- == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH) {
|
|
+ == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
|
|
+ buf_ctrl->id
|
|
+ == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
|
|
memcpy(&temporal_LC,
|
|
enc->sh_handle.virt, sizeof(struct temporal_layer_info));
|
|
|
|
- if((temporal_LC.temporal_layer_count < 1) ||
|
|
- ((temporal_LC.temporal_layer_count > 7) &&
|
|
- (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)) ||
|
|
+ if(((temporal_LC.temporal_layer_count & 0x7) < 1) ||
|
|
((temporal_LC.temporal_layer_count > 3) &&
|
|
(ctx->codec_mode == S5P_FIMV_CODEC_VP8_ENC))) {
|
|
+ /* claer NUM_T_LAYER_CHANGE */
|
|
value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
|
|
value &= ~(1 << 10);
|
|
s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
|
|
- mfc_err_ctx("temporal layer count is invalid : %d\n"
|
|
- , temporal_LC.temporal_layer_count);
|
|
+ mfc_err_ctx("Temporal SVC: layer count is invalid : %d\n",
|
|
+ temporal_LC.temporal_layer_count);
|
|
goto invalid_layer_count;
|
|
}
|
|
|
|
- value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
|
|
+ if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
|
|
+ p->codec.h264.num_hier_layer = temporal_LC.temporal_layer_count & 0x7;
|
|
+
|
|
/* enable RC_BIT_RATE_CHANGE */
|
|
- value |= (1 << 2);
|
|
+ value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
|
|
+ if (temporal_LC.temporal_layer_bitrate[0] > 0)
|
|
+ /* set RC_BIT_RATE_CHANGE */
|
|
+ value |= (1 << 2);
|
|
+ else
|
|
+ /* claer RC_BIT_RATE_CHANGE */
|
|
+ value &= ~(1 << 2);
|
|
s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
|
|
|
|
- mfc_debug(2, "temporal layer count : %d\n", temporal_LC.temporal_layer_count);
|
|
- if(ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
|
|
- s5p_mfc_write_reg(dev,
|
|
- temporal_LC.temporal_layer_count, S5P_FIMV_E_H264_NUM_T_LAYER);
|
|
- else if(ctx->codec_mode == S5P_FIMV_CODEC_VP8_ENC)
|
|
- s5p_mfc_write_reg(dev,
|
|
- temporal_LC.temporal_layer_count, S5P_FIMV_E_VP8_NUM_T_LAYER);
|
|
- for(i = 0; i < temporal_LC.temporal_layer_count; i++) {
|
|
- mfc_debug(2, "temporal layer bitrate[%d] : %d\n",
|
|
+ mfc_debug(3, "Temporal SVC: layer count %d, E_PARAM_CHANGE %#x\n",
|
|
+ temporal_LC.temporal_layer_count & 0x7, value);
|
|
+
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_NUM_T_LAYER);
|
|
+ buf_ctrl->old_val2 = value;
|
|
+ value &= ~(0x7);
|
|
+ value |= (temporal_LC.temporal_layer_count & 0x7);
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_NUM_T_LAYER);
|
|
+ mfc_debug(3, "Temporal SVC: E_NUM_T_LAYER %#x\n", value);
|
|
+ for(i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
|
|
+ mfc_debug(3, "Temporal SVC: layer bitrate[%d] %d\n",
|
|
i, temporal_LC.temporal_layer_bitrate[i]);
|
|
s5p_mfc_write_reg(dev,
|
|
temporal_LC.temporal_layer_bitrate[i], buf_ctrl->addr + i * 4);
|
|
}
|
|
+
|
|
+ /* priority change */
|
|
+ if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
|
|
+ value = 0;
|
|
+ value2 = 0;
|
|
+ for (i = 0; i < (p->codec.h264.num_hier_layer & 0x07); i++) {
|
|
+ if (i <= 4)
|
|
+ value |= ((p->codec.h264.base_priority & 0x3F) + i) << (6 * i);
|
|
+ else
|
|
+ value2 |= ((p->codec.h264.base_priority & 0x3F) + i) << (6 * (i - 5));
|
|
+ }
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
|
|
+ s5p_mfc_write_reg(dev, value2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
|
|
+ mfc_debug(3, "Temporal SVC: EXTENSION0 %#x, EXTENSION1 %#x\n",
|
|
+ value, value2);
|
|
+
|
|
+ value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
|
|
+ value |= (1 << 12);
|
|
+ s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
|
|
+ mfc_debug(3, "Temporal SVC: E_PARAM_CHANGE %#x\n", value);
|
|
+ }
|
|
}
|
|
+
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ buf_ctrl->old_val2 = (value >> 8) & 0x7;
|
|
+ value &= ~(0x7 << 8);
|
|
+ value |= (buf_ctrl->val & 0x7) << 8;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ }
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ buf_ctrl->old_val2 = (value >> 11) & 0xF;
|
|
+ value &= ~(0xF << 11);
|
|
+ value |= (buf_ctrl->val & 0xF) << 11;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ }
|
|
+
|
|
if ((buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH) && FW_HAS_GOP2(dev)) {
|
|
- value = 0;
|
|
value = s5p_mfc_read_reg(dev, S5P_FIMV_E_GOP_CONFIG2);
|
|
buf_ctrl->old_val |= (value << 16) & 0x3FFF0000;
|
|
value &= ~(0x3FFF);
|
|
@@ -2357,12 +3022,61 @@ static int enc_set_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_head *head
|
|
s5p_mfc_write_reg(dev, value, S5P_FIMV_E_GOP_CONFIG2);
|
|
}
|
|
|
|
+ /* PROFILE & LEVEL have to be set up together */
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ buf_ctrl->old_val |= (value & 0x000F) << 8;
|
|
+ value &= ~(0x000F);
|
|
+ value |= p->codec.h264.profile & 0x000F;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ p->codec.h264.level = buf_ctrl->val;
|
|
+ }
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ buf_ctrl->old_val |= value & 0xFF00;
|
|
+ value &= ~(0x00FF << 8);
|
|
+ value |= (p->codec.h264.level << 8) & 0xFF00;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ p->codec.h264.profile = buf_ctrl->val;
|
|
+ }
|
|
+
|
|
+ /* temproral layer priority */
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
|
|
+ buf_ctrl->old_val |= value & 0x3FFFFFC0;
|
|
+ value &= ~(0x3FFFFFC0);
|
|
+ value2 = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
|
|
+ buf_ctrl->old_val2 = value2 & 0x0FFF;
|
|
+ value2 &= ~(0x0FFF);
|
|
+ for (i = 0; i < (p->codec.h264.num_hier_layer & 0x07); i++) {
|
|
+ if (i <= 4)
|
|
+ value |= ((buf_ctrl->val & 0x3F) + i) << (6 * i);
|
|
+ else
|
|
+ value2 |= ((buf_ctrl->val & 0x3F) + i) << (6 * (i - 5));
|
|
+ }
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
|
|
+ s5p_mfc_write_reg(dev, value2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
|
|
+ p->codec.h264.base_priority = buf_ctrl->val;
|
|
+ mfc_debug(3, "Temporal SVC: EXTENSION0 %#x, EXTENSION1 %#x\n",
|
|
+ value, value2);
|
|
+ }
|
|
+ /* per buffer QP setting change */
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_CONFIG_QP)
|
|
+ p->config_qp = buf_ctrl->val;
|
|
+
|
|
invalid_layer_count:
|
|
mfc_debug(8, "Set buffer control "\
|
|
"id: 0x%08x val: %d\n",
|
|
buf_ctrl->id, buf_ctrl->val);
|
|
}
|
|
|
|
+ if (!p->rc_frame && !p->rc_mb && p->dynamic_qp) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ value &= ~(0xFF000000);
|
|
+ value |= (p->config_qp & 0xFF) << 24;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -2438,12 +3152,51 @@ static int enc_recover_buf_ctrls_val(struct s5p_mfc_ctx *ctx,
|
|
"id: 0x%08x old val: %d\n",
|
|
buf_ctrl->id, buf_ctrl->old_val);
|
|
if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH && FW_HAS_GOP2(dev)) {
|
|
- value = 0;
|
|
value = s5p_mfc_read_reg(dev, S5P_FIMV_E_GOP_CONFIG2);
|
|
value &= ~(0x3FFF);
|
|
value |= (buf_ctrl->old_val >> 16) & 0x3FFF;
|
|
s5p_mfc_write_reg(dev, value, S5P_FIMV_E_GOP_CONFIG2);
|
|
}
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ value &= ~(0x000F);
|
|
+ value |= (buf_ctrl->old_val >> 8) & 0x000F;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ }
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ value &= ~(0xFF00);
|
|
+ value |= buf_ctrl->old_val & 0xFF00;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
|
|
+ }
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
|
|
+ s5p_mfc_write_reg(dev, buf_ctrl->old_val, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
|
|
+ s5p_mfc_write_reg(dev, buf_ctrl->old_val2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
|
|
+ }
|
|
+ if (buf_ctrl->id
|
|
+ == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH ||
|
|
+ buf_ctrl->id
|
|
+ == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
|
|
+ buf_ctrl->id
|
|
+ == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
|
|
+ s5p_mfc_write_reg(dev, buf_ctrl->old_val2, S5P_FIMV_E_NUM_T_LAYER);
|
|
+ /* clear RC_BIT_RATE_CHANGE */
|
|
+ value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
|
|
+ value &= ~(1 << 2);
|
|
+ s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
|
|
+ }
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ value &= ~(0x7 << 8);
|
|
+ value |= (buf_ctrl->old_val2 & 0x7) << 8;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ }
|
|
+ if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
|
|
+ value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ value &= ~(0xF << 11);
|
|
+ value |= (buf_ctrl->old_val2 & 0xF) << 11;
|
|
+ s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
|
|
+ }
|
|
}
|
|
|
|
return 0;
|
|
@@ -2597,9 +3350,14 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
|
|
strm_size = s5p_mfc_get_enc_strm_size();
|
|
pic_count = s5p_mfc_get_enc_pic_count();
|
|
|
|
- mfc_debug(2, "encoded slice type: %d", slice_type);
|
|
- mfc_debug(2, "encoded stream size: %d", strm_size);
|
|
- mfc_debug(2, "display order: %d", pic_count);
|
|
+ mfc_debug(2, "encoded slice type: %d\n", slice_type);
|
|
+ mfc_debug(2, "encoded stream size: %d\n", strm_size);
|
|
+ mfc_debug(2, "display order: %d\n", pic_count);
|
|
+
|
|
+ if (enc->buf_full) {
|
|
+ ctx->state = MFCINST_ABORT_INST;
|
|
+ return 0;
|
|
+ }
|
|
|
|
/* set encoded frame type */
|
|
enc->frame_type = slice_type;
|
|
@@ -2608,7 +3366,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
|
|
ctx->sequence++;
|
|
- if (strm_size > 0 || ctx->state == MFCINST_FINISHING) {
|
|
+ if (strm_size > 0 || ctx->state == MFCINST_FINISHING
|
|
+ || ctx->state == MFCINST_RUNNING_BUF_FULL) {
|
|
/* at least one more dest. buffers exist always */
|
|
mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
|
|
|
|
@@ -2666,9 +3425,10 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
|
|
return 0;
|
|
}
|
|
|
|
- if (slice_type >= 0 &&
|
|
+ if (!ctx->enc_res_change_re_input && slice_type >= 0 &&
|
|
ctx->state != MFCINST_FINISHING) {
|
|
- if (ctx->state == MFCINST_RUNNING_NO_OUTPUT)
|
|
+ if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
|
|
+ ctx->state == MFCINST_RUNNING_BUF_FULL)
|
|
ctx->state = MFCINST_RUNNING;
|
|
|
|
s5p_mfc_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes);
|
|
@@ -2725,9 +3485,13 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
|
|
vb2_buffer_done(&mb_entry->vb, VB2_BUF_STATE_DONE);
|
|
}
|
|
|
|
+ if (ctx->enc_res_change_re_input)
|
|
+ ctx->enc_res_change_re_input = 0;
|
|
+
|
|
if ((ctx->src_queue_cnt > 0) &&
|
|
((ctx->state == MFCINST_RUNNING) ||
|
|
- (ctx->state == MFCINST_RUNNING_NO_OUTPUT))) {
|
|
+ (ctx->state == MFCINST_RUNNING_NO_OUTPUT) ||
|
|
+ (ctx->state == MFCINST_RUNNING_BUF_FULL))) {
|
|
mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
|
|
|
|
if (mb_entry->used) {
|
|
@@ -2946,10 +3710,18 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|
if (ret)
|
|
return ret;
|
|
|
|
- if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
|
|
- v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
|
|
- ret = -EBUSY;
|
|
- goto out;
|
|
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
|
+ if (ctx->vq_dst.streaming) {
|
|
+ v4l2_err(&dev->v4l2_dev, "%s dst queue busy\n", __func__);
|
|
+ ret = -EBUSY;
|
|
+ goto out;
|
|
+ }
|
|
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
|
+ if (ctx->vq_src.streaming) {
|
|
+ v4l2_err(&dev->v4l2_dev, "%s src queue busy\n", __func__);
|
|
+ ret = -EBUSY;
|
|
+ goto out;
|
|
+ }
|
|
}
|
|
|
|
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
|
@@ -3014,6 +3786,12 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|
ctx->img_height = pix_fmt_mp->height;
|
|
ctx->buf_stride = pix_fmt_mp->plane_fmt[0].bytesperline;
|
|
|
|
+ if ((ctx->state == MFCINST_RUNNING)
|
|
+ && (((ctx->old_img_width != 0) && (ctx->old_img_width != ctx->img_width))
|
|
+ || ((ctx->old_img_height != 0) && (ctx->old_img_height != ctx->img_height)))) {
|
|
+ ctx->enc_drc_flag = 1;
|
|
+ }
|
|
+
|
|
mfc_info_ctx("Enc input pixelformat : %s\n", ctx->src_fmt->name);
|
|
mfc_info_ctx("fmt - w: %d, h: %d, stride: %d\n",
|
|
pix_fmt_mp->width, pix_fmt_mp->height, ctx->buf_stride);
|
|
@@ -3184,11 +3962,18 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
|
|
int ret = -EINVAL;
|
|
|
|
mfc_debug_enter();
|
|
+
|
|
mfc_debug(2, "Enqueued buf: %d (type = %d)\n", buf->index, buf->type);
|
|
if (ctx->state == MFCINST_ERROR) {
|
|
mfc_err_ctx("Call on QBUF after unrecoverable error.\n");
|
|
return -EIO;
|
|
}
|
|
+
|
|
+ if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && !buf->length) {
|
|
+ mfc_err_ctx("multiplanar but length is zero\n");
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
|
ret = vb2_qbuf(&ctx->vq_src, buf);
|
|
if (!ret) {
|
|
@@ -3236,9 +4021,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
|
|
calc_again:
|
|
#endif
|
|
if (ctx->last_framerate != 0 &&
|
|
- ctx->last_framerate != ctx->framerate) {
|
|
- mfc_debug(2, "fps changed: %d -> %d\n",
|
|
- ctx->framerate, ctx->last_framerate);
|
|
+ ((ctx->last_framerate != ctx->framerate) || ctx->qos_changed)) {
|
|
+ mfc_debug(2, "fps changed: %d -> %d (%s)\n",
|
|
+ ctx->framerate, ctx->last_framerate,
|
|
+ ctx->use_extra_qos ? "extra" : "normal");
|
|
ctx->framerate = ctx->last_framerate;
|
|
s5p_mfc_qos_on(ctx);
|
|
}
|
|
@@ -3313,6 +4099,13 @@ static int vidioc_streamoff(struct file *file, void *priv,
|
|
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
|
ctx->last_framerate = 0;
|
|
memset(&ctx->last_timestamp, 0, sizeof(struct timeval));
|
|
+
|
|
+ ctx->old_img_width = ctx->img_width;
|
|
+ ctx->old_img_height = ctx->img_height;
|
|
+
|
|
+ mfc_debug(2, "vidioc_streamoff ctx->old_img_width = %d\n", ctx->old_img_width);
|
|
+ mfc_debug(2, "vidioc_streamoff ctx->old_img_height = %d\n", ctx->old_img_height);
|
|
+
|
|
ret = vb2_streamoff(&ctx->vq_src, type);
|
|
if (!ret)
|
|
s5p_mfc_qos_off(ctx);
|
|
@@ -3351,6 +4144,11 @@ static int enc_ext_info(struct s5p_mfc_ctx *ctx)
|
|
if (FW_HAS_TEMPORAL_SVC_CH(dev))
|
|
val |= ENC_SET_TEMP_SVC_CH;
|
|
|
|
+ if (FW_SUPPORT_SKYPE(dev))
|
|
+ val |= ENC_SET_SKYPE_FLAG;
|
|
+
|
|
+ val |= ENC_SET_QP_BOUND_PB;
|
|
+
|
|
return val;
|
|
}
|
|
|
|
@@ -3414,6 +4212,9 @@ static int get_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
|
|
ctrl->value = mfc_version(dev);
|
|
break;
|
|
+ case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
|
|
+ ctrl->value = MFC_DRIVER_INFO;
|
|
+ break;
|
|
case V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE:
|
|
ctrl->value = mfc_linear_buf_size(mfc_version(dev));
|
|
break;
|
|
@@ -3530,6 +4331,9 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
|
|
p->slice_bit = ctrl->value * 8;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW:
|
|
+ p->slice_mb_row = ctrl->value;
|
|
+ break;
|
|
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
|
|
p->intra_refresh_mb = ctrl->value;
|
|
break;
|
|
@@ -3572,29 +4376,8 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
p->num_b_frame = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
|
|
- switch ((enum v4l2_mpeg_video_h264_profile)(ctrl->value)) {
|
|
- case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
|
- p->codec.h264.profile =
|
|
- S5P_FIMV_ENC_PROFILE_H264_MAIN;
|
|
- break;
|
|
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
|
- p->codec.h264.profile =
|
|
- S5P_FIMV_ENC_PROFILE_H264_HIGH;
|
|
- break;
|
|
- case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
|
|
- p->codec.h264.profile =
|
|
- S5P_FIMV_ENC_PROFILE_H264_BASELINE;
|
|
- break;
|
|
- case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
|
- if (IS_MFCV6(dev))
|
|
- p->codec.h264.profile =
|
|
- S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
|
|
- else
|
|
- ret = -EINVAL;
|
|
- break;
|
|
- default:
|
|
- ret = -EINVAL;
|
|
- }
|
|
+ p->codec.h264.profile =
|
|
+ h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
|
|
p->codec.h264.level =
|
|
@@ -3638,6 +4421,18 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
|
|
p->codec.h264.rc_max_qp = ctrl->value;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
|
|
+ p->codec.h264.rc_min_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
|
|
+ p->codec.h264.rc_max_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
|
|
+ p->codec.h264.rc_min_qp_b = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
|
|
+ p->codec.h264.rc_max_qp_b = ctrl->value;
|
|
+ break;
|
|
case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:
|
|
p->codec.h264.rc_mb_dark = ctrl->value;
|
|
break;
|
|
@@ -3676,39 +4471,40 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
p->codec.h264.open_gop_size = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
|
|
- p->codec.h264.hier_qp = ctrl->value;
|
|
+ p->codec.h264.hier_qp_enable = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
|
|
p->codec.h264.hier_qp_type =
|
|
(enum v4l2_mpeg_video_h264_hierarchical_coding_type)(ctrl->value);
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
|
|
- p->codec.h264.hier_qp_layer = ctrl->value;
|
|
+ p->codec.h264.num_hier_layer = ctrl->value & 0x7;
|
|
+ p->codec.h264.hier_ref_type = (ctrl->value >> 16) & 0x1;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
|
|
- p->codec.h264.hier_qp_layer_qp[(ctrl->value >> 16) & 0x7]
|
|
+ p->codec.h264.hier_qp_layer[(ctrl->value >> 16) & 0x7]
|
|
= ctrl->value & 0xFF;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0:
|
|
- p->codec.h264.hier_qp_layer_bit[0] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[0] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1:
|
|
- p->codec.h264.hier_qp_layer_bit[1] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[1] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2:
|
|
- p->codec.h264.hier_qp_layer_bit[2] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[2] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3:
|
|
- p->codec.h264.hier_qp_layer_bit[3] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[3] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4:
|
|
- p->codec.h264.hier_qp_layer_bit[4] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[4] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5:
|
|
- p->codec.h264.hier_qp_layer_bit[5] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[5] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6:
|
|
- p->codec.h264.hier_qp_layer_bit[6] = ctrl->value;
|
|
+ p->codec.h264.hier_bit_layer[6] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
|
|
p->codec.h264.sei_gen_enable = ctrl->value;
|
|
@@ -3760,6 +4556,16 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR:
|
|
p->codec.h264.prepend_sps_pps_to_idr = ctrl->value ? 1 : 0;
|
|
break;
|
|
+ case V4L2_CID_MPEG_MFC_H264_ENABLE_LTR:
|
|
+ p->codec.h264.enable_ltr = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR:
|
|
+ p->codec.h264.num_of_ltr = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
|
|
+ p->codec.h264.base_priority = ctrl->value;
|
|
+ p->codec.h264.set_priority = 1;
|
|
+ break;
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
|
|
switch ((enum v4l2_mpeg_video_mpeg4_profile)(ctrl->value)) {
|
|
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
|
|
@@ -3787,6 +4593,18 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
|
|
p->codec.mpeg4.rc_max_qp = ctrl->value;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
|
|
+ p->codec.mpeg4.rc_min_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
|
|
+ p->codec.mpeg4.rc_max_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
|
|
+ p->codec.mpeg4.rc_min_qp_b = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
|
|
+ p->codec.mpeg4.rc_max_qp_b = ctrl->value;
|
|
+ break;
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
|
|
p->codec.mpeg4.quarter_pixel = ctrl->value;
|
|
break;
|
|
@@ -3814,6 +4632,12 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
|
|
p->codec.mpeg4.rc_max_qp = ctrl->value;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
|
|
+ p->codec.mpeg4.rc_min_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
|
|
+ p->codec.mpeg4.rc_max_qp_p = ctrl->value;
|
|
+ break;
|
|
case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
|
|
p->codec.mpeg4.rc_p_frame_qp = ctrl->value;
|
|
break;
|
|
@@ -3829,6 +4653,12 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
|
|
p->codec.vp8.rc_max_qp = ctrl->value;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
|
|
+ p->codec.vp8.rc_min_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
|
|
+ p->codec.vp8.rc_max_qp_p = ctrl->value;
|
|
+ break;
|
|
case V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP:
|
|
p->codec.vp8.rc_frame_qp = ctrl->value;
|
|
break;
|
|
@@ -3851,28 +4681,28 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
p->codec.vp8.vp8_gfrefreshperiod = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE:
|
|
- p->codec.vp8.hierarchy_qp_enable = ctrl->value;
|
|
+ p->codec.vp8.hier_qp_enable = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0:
|
|
- p->codec.vp8.hier_qp_layer_qp[(ctrl->value >> 16) & 0x3]
|
|
+ p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
|
|
= ctrl->value & 0xFF;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1:
|
|
- p->codec.vp8.hier_qp_layer_qp[(ctrl->value >> 16) & 0x3]
|
|
+ p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
|
|
= ctrl->value & 0xFF;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2:
|
|
- p->codec.vp8.hier_qp_layer_qp[(ctrl->value >> 16) & 0x3]
|
|
+ p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
|
|
= ctrl->value & 0xFF;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0:
|
|
- p->codec.vp8.hier_qp_layer_bit[0] = ctrl->value;
|
|
+ p->codec.vp8.hier_bit_layer[0] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1:
|
|
- p->codec.vp8.hier_qp_layer_bit[1] = ctrl->value;
|
|
+ p->codec.vp8.hier_bit_layer[1] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2:
|
|
- p->codec.vp8.hier_qp_layer_bit[2] = ctrl->value;
|
|
+ p->codec.vp8.hier_bit_layer[2] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES:
|
|
p->codec.vp8.num_refs_for_p = ctrl->value;
|
|
@@ -3881,7 +4711,7 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
p->codec.vp8.intra_4x4mode_disable = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER:
|
|
- p->codec.vp8.num_temporal_layer = ctrl->value;
|
|
+ p->codec.vp8.num_hier_layer = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
|
|
p->codec.hevc.rc_frame_qp = ctrl->value;
|
|
@@ -3901,6 +4731,18 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
|
|
p->codec.hevc.rc_max_qp = ctrl->value;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
|
|
+ p->codec.hevc.rc_min_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
|
|
+ p->codec.hevc.rc_max_qp_p = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
|
|
+ p->codec.hevc.rc_min_qp_b = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
|
|
+ p->codec.hevc.rc_max_qp_b = ctrl->value;
|
|
+ break;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
|
|
p->codec.hevc.level = ctrl->value;
|
|
break;
|
|
@@ -3943,25 +4785,46 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
p->codec.hevc.loopfilter_disable = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY:
|
|
- p->codec.hevc.loopfilter_disable = ctrl->value;
|
|
+ p->codec.hevc.loopfilter_across = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE:
|
|
- p->codec.hevc.longterm_ref_enable = ctrl->value;
|
|
+ p->codec.hevc.enable_ltr = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE:
|
|
- p->codec.hevc.hier_qp = ctrl->value;
|
|
+ p->codec.hevc.hier_qp_enable = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE:
|
|
- p->codec.hevc.hier_qp_type = ctrl->value;
|
|
+ p->codec.hevc.hier_qp_type =
|
|
+ (enum v4l2_mpeg_video_hevc_hierarchical_coding_type)(ctrl->value);
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER:
|
|
- p->codec.hevc.hier_qp_layer = ctrl->value;
|
|
+ p->codec.hevc.num_hier_layer = ctrl->value & 0x7;
|
|
+ p->codec.hevc.hier_ref_type = (ctrl->value >> 16) & 0x1;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP:
|
|
- p->codec.hevc.hier_qp_layer_qp = ctrl->value & 0xFF;
|
|
+ p->codec.hevc.hier_qp_layer[(ctrl->value >> 16) & 0x7]
|
|
+ = ctrl->value & 0xFF;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0:
|
|
+ p->codec.hevc.hier_bit_layer[0] = ctrl->value;
|
|
break;
|
|
- case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT:
|
|
- p->codec.hevc.hier_qp_layer_bit = ctrl->value & 0xFF;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1:
|
|
+ p->codec.hevc.hier_bit_layer[1] = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2:
|
|
+ p->codec.hevc.hier_bit_layer[2] = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3:
|
|
+ p->codec.hevc.hier_bit_layer[3] = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4:
|
|
+ p->codec.hevc.hier_bit_layer[4] = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5:
|
|
+ p->codec.hevc.hier_bit_layer[5] = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6:
|
|
+ p->codec.hevc.hier_bit_layer[6] = ctrl->value;
|
|
break;
|
|
case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING:
|
|
p->codec.hevc.sign_data_hiding = ctrl->value;
|
|
@@ -3990,12 +4853,6 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD:
|
|
p->codec.hevc.refreshperiod = ctrl->value;
|
|
break;
|
|
- case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CR:
|
|
- p->codec.hevc.croma_qp_offset_cr = ctrl->value;
|
|
- break;
|
|
- case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CB:
|
|
- p->codec.hevc.croma_qp_offset_cb = ctrl->value;
|
|
- break;
|
|
case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:
|
|
p->codec.hevc.lf_beta_offset_div2 = ctrl->value;
|
|
break;
|
|
@@ -4011,6 +4868,21 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF:
|
|
p->codec.hevc.store_ref = ctrl->value;
|
|
break;
|
|
+ case V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE:
|
|
+ p->codec.h264.vui_enable = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR:
|
|
+ p->codec.hevc.prepend_sps_pps_to_idr = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE:
|
|
+ p->dynamic_qp = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_MFC_CONFIG_QP:
|
|
+ p->config_qp = ctrl->value;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER:
|
|
+ p->num_hier_max_layer = ctrl->value;
|
|
+ break;
|
|
default:
|
|
v4l2_err(&dev->v4l2_dev, "Invalid control\n");
|
|
ret = -EINVAL;
|
|
@@ -4090,23 +4962,45 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
ctx->cacheable = 0;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
|
|
+ if (ctrl->value > 150)
|
|
+ ctrl->value = 1000;
|
|
+ if (ctrl->value == 0) {
|
|
+ ctrl->value = 100;
|
|
+ ctx->use_extra_qos = 1;
|
|
+ mfc_info_ctx("QOS_RATIO is 0, use extra qos!\n");
|
|
+ } else {
|
|
+ ctx->use_extra_qos = 0;
|
|
+ mfc_info_ctx("QOS_RATIO is %d, use extra qos!\n", ctrl->value);
|
|
+ }
|
|
ctx->qos_ratio = ctrl->value;
|
|
+ ctx->qos_changed = 1;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
|
|
case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
|
|
case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
|
|
- ctx->qp_max_change = ctrl->value;
|
|
- break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
|
|
case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
|
|
case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
|
|
- ctx->qp_min_change = ctrl->value;
|
|
- ctrl->value = ((ctx->qp_max_change << 8)
|
|
- | (ctx->qp_min_change));
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
|
|
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
|
|
case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
|
|
case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
|
|
case V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH:
|
|
@@ -4114,6 +5008,13 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
case V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH:
|
|
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
|
|
case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH:
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
|
|
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
|
|
+ case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
|
|
+ case V4L2_CID_MPEG_MFC_H264_USE_LTR:
|
|
+ case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
|
|
+ case V4L2_CID_MPEG_MFC_CONFIG_QP:
|
|
list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
|
|
if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
|
|
continue;
|
|
@@ -4128,7 +5029,9 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
if (((ctx_ctrl->id == \
|
|
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH) ||
|
|
(ctx_ctrl->id == \
|
|
- V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH)) &&
|
|
+ V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH) ||
|
|
+ (ctx_ctrl->id == \
|
|
+ V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH)) &&
|
|
(enc->sh_handle.fd == -1)) {
|
|
enc->sh_handle.fd = ctrl->value;
|
|
if (process_user_shared_handle_enc(ctx)) {
|
|
@@ -4136,6 +5039,10 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
+ if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL)
|
|
+ ctx_ctrl->val = h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
|
|
+ if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE)
|
|
+ ctx_ctrl->val = h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
|
|
found = 1;
|
|
break;
|
|
}
|
|
@@ -4582,10 +5489,6 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
return 0;
|
|
}
|
|
|
|
-#define need_to_wait_frame_start(ctx) \
|
|
- (((ctx->state == MFCINST_FINISHING) || \
|
|
- (ctx->state == MFCINST_RUNNING)) && \
|
|
- test_bit(ctx->num, &ctx->dev->hw_lock))
|
|
static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
{
|
|
unsigned long flags;
|
|
@@ -4594,16 +5497,32 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
int index = 0;
|
|
int aborted = 0;
|
|
+ int ret = 0;
|
|
+
|
|
+ mfc_info_ctx("enc stop_streaming is called, hw_lock : %d, type : %d\n",
|
|
+ test_bit(ctx->num, &dev->hw_lock), q->type);
|
|
+ MFC_TRACE_CTX("** ENC streamoff(type:%d)\n", q->type);
|
|
|
|
- if (need_to_wait_frame_start(ctx)) {
|
|
- ctx->state = MFCINST_ABORT;
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ set_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ clear_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
+ /* If a H/W operation is in progress, wait for it complete */
|
|
+ if (need_to_wait_nal_abort(ctx)) {
|
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
|
- S5P_FIMV_R2H_CMD_FRAME_DONE_RET))
|
|
+ S5P_FIMV_R2H_CMD_NAL_ABORT_RET))
|
|
s5p_mfc_cleanup_timeout(ctx);
|
|
aborted = 1;
|
|
+ } else if (test_bit(ctx->num, &dev->hw_lock)) {
|
|
+ ret = wait_event_timeout(ctx->queue,
|
|
+ (test_bit(ctx->num, &dev->hw_lock) == 0),
|
|
+ msecs_to_jiffies(MFC_INT_TIMEOUT));
|
|
+ if (ret == 0)
|
|
+ mfc_err_ctx("wait for event failed\n");
|
|
}
|
|
|
|
- if (enc->in_slice) {
|
|
+ if (enc->in_slice || enc->buf_full) {
|
|
ctx->state = MFCINST_ABORT_INST;
|
|
spin_lock_irq(&dev->condlock);
|
|
set_bit(ctx->num, &dev->ctx_work_bits);
|
|
@@ -4614,6 +5533,7 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
s5p_mfc_cleanup_timeout(ctx);
|
|
|
|
enc->in_slice = 0;
|
|
+ enc->buf_full = 0;
|
|
aborted = 1;
|
|
}
|
|
|
|
@@ -4649,9 +5569,25 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|
|
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
|
|
- if (aborted)
|
|
+ if (aborted || ctx->state == MFCINST_FINISHING)
|
|
ctx->state = MFCINST_RUNNING;
|
|
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ clear_bit(ctx->num, &dev->ctx_stop_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
+ mfc_debug(2, "buffer cleanup is done in stop_streaming, type : %d\n", q->type);
|
|
+
|
|
+ if (s5p_mfc_enc_ctx_ready(ctx)) {
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ set_bit(ctx->num, &dev->ctx_work_bits);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+ }
|
|
+ spin_lock_irq(&dev->condlock);
|
|
+ if (dev->ctx_work_bits)
|
|
+ queue_work(dev->sched_wq, &dev->sched_work);
|
|
+ spin_unlock_irq(&dev->condlock);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 541a61de1158..9fb31c764da3
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
|
|
@@ -16,7 +16,7 @@
|
|
#define MFC_ENC_AVG_FPS_MODE
|
|
|
|
#define ENC_HIGH_FPS (70000)
|
|
-#define ENC_MAX_FPS (120000)
|
|
+#define ENC_MAX_FPS (240000)
|
|
#define ENC_AVG_FRAMES (10)
|
|
|
|
const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.h b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_intr.c b/drivers/media/platform/exynos/mfc/s5p_mfc_intr.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_intr.h b/drivers/media/platform/exynos/mfc/s5p_mfc_intr.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.h b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index 1a3cf0b99e5d..fadfa7edd5b5
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
|
|
@@ -881,10 +881,10 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
|
|
/* multi-slice control */
|
|
/* multi-slice MB number or bit size */
|
|
- if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
|
|
+ if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
|
|
WRITEL(((0x0 << 1) | 0x1), S5P_FIMV_ENC_MSLICE_CTRL);
|
|
WRITEL(p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);
|
|
- } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
|
|
+ } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
|
|
WRITEL(((0x1 << 1) | 0x1), S5P_FIMV_ENC_MSLICE_CTRL);
|
|
WRITEL(p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);
|
|
} else {
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 8ad06de595f2..e851e179e17c
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
|
|
@@ -144,6 +144,7 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
|
|
#define ENC_MULTI_SLICE_MB_MAX ((1 << 16) - 1)
|
|
#define ENC_MULTI_SLICE_BIT_MIN 1900
|
|
#define ENC_MULTI_SLICE_BYTE_MIN 238
|
|
+#define ENC_MULTI_SLICE_MB_ROW_MAX 100
|
|
#define ENC_INTRA_REFRESH_MB_MAX ((1 << 16) - 1)
|
|
#define ENC_VBV_BUF_SIZE_MAX ((1 << 16) - 1)
|
|
#define ENC_H264_LOOP_FILTER_AB_MIN -6
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index 04ced6aa052f..c9b11c116d65
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
|
|
@@ -333,6 +333,9 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
|
|
(ctx->dpb_count * (enc->luma_dpb_size +
|
|
enc->chroma_dpb_size + enc->me_buffer_size));
|
|
ctx->port_b_size = 0;
|
|
+
|
|
+ ctx->scratch_buf_size = max(ctx->scratch_buf_size, ctx->min_scratch_buf_size);
|
|
+ ctx->min_scratch_buf_size = 0;
|
|
break;
|
|
case S5P_FIMV_CODEC_MPEG4_ENC:
|
|
case S5P_FIMV_CODEC_H263_ENC:
|
|
@@ -399,6 +402,15 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
|
|
return -ENOMEM;
|
|
}
|
|
ctx->port_a_phys = s5p_mfc_mem_daddr_priv(ctx->port_a_buf);
|
|
+ ctx->port_a_virt = s5p_mfc_mem_vaddr_priv(ctx->port_a_buf);
|
|
+ if (!ctx->port_a_virt) {
|
|
+ s5p_mfc_mem_free_priv(ctx->port_a_buf);
|
|
+ ctx->port_a_buf = NULL;
|
|
+ ctx->port_a_phys = 0;
|
|
+
|
|
+ mfc_err_ctx("Get vaddr for codec buffer failed.\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
}
|
|
|
|
mfc_debug_leave();
|
|
@@ -982,7 +994,7 @@ int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, dma_addr_t buf_addr,
|
|
if (cpb_buf_size < strm_size + 4)
|
|
mfc_info_ctx("cpb_buf_size(%zu) < strm_size(0x%08x) + 4 bytes\n",
|
|
cpb_buf_size, strm_size);
|
|
- if (ctx->state == MFCINST_GOT_INST && strm_size == 0)
|
|
+ if (strm_size == 0)
|
|
mfc_info_ctx("stream size is 0\n");
|
|
|
|
WRITEL(strm_size, S5P_FIMV_D_STREAM_DATA_SIZE);
|
|
@@ -1283,6 +1295,8 @@ int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
|
|
{
|
|
struct s5p_mfc_dev *dev = ctx->dev;
|
|
|
|
+ size = ALIGN(size, 512);
|
|
+
|
|
WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR); /* 16B align */
|
|
WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE);
|
|
|
|
@@ -1390,16 +1404,18 @@ static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
|
|
struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
|
|
/* multi-slice control */
|
|
- if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES)
|
|
+ if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
|
|
WRITEL((enc->slice_mode + 0x4), S5P_FIMV_E_MSLICE_MODE);
|
|
+ else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW)
|
|
+ WRITEL((enc->slice_mode - 0x2), S5P_FIMV_E_MSLICE_MODE);
|
|
else
|
|
WRITEL(enc->slice_mode, S5P_FIMV_E_MSLICE_MODE);
|
|
|
|
/* multi-slice MB number or bit size */
|
|
- if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
|
|
+ if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB || \
|
|
+ enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW) {
|
|
WRITEL(enc->slice_size.mb, S5P_FIMV_E_MSLICE_SIZE_MB);
|
|
- } else if (enc->slice_mode == \
|
|
- V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
|
|
+ } else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
|
|
WRITEL(enc->slice_size.bits, S5P_FIMV_E_MSLICE_SIZE_BITS);
|
|
} else {
|
|
WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_MB);
|
|
@@ -1410,6 +1426,77 @@ static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
|
|
|
|
}
|
|
|
|
+void s5p_mfc_set_default_params(struct s5p_mfc_ctx *ctx)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
+
|
|
+ /* Default setting for quality */
|
|
+ /* Common Registers */
|
|
+ WRITEL(0x0, S5P_FIMV_E_ENC_OPTIONS);
|
|
+ WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ WRITEL(0x80, S5P_FIMV_E_MV_HOR_RANGE);
|
|
+ WRITEL(0x80, S5P_FIMV_E_MV_VER_RANGE);
|
|
+ WRITEL(0x0, S5P_FIMV_E_IR_SIZE);
|
|
+ WRITEL(0x0, S5P_FIMV_E_AIR_THRESHOLD);
|
|
+ WRITEL(0x1E, S5P_FIMV_E_GOP_CONFIG); /* I frame period: 30 */
|
|
+ WRITEL(0x0, S5P_FIMV_E_GOP_CONFIG2);
|
|
+ WRITEL(0x0, S5P_FIMV_E_MSLICE_MODE);
|
|
+
|
|
+ /* Hierarchical Coding */
|
|
+ WRITEL(0x8, S5P_FIMV_E_NUM_T_LAYER);
|
|
+
|
|
+ /* Rate Control */
|
|
+ WRITEL(0x4000, S5P_FIMV_E_RC_CONFIG);
|
|
+ WRITEL(0x0, S5P_FIMV_E_RC_QP_BOUND);
|
|
+ WRITEL(0x0, S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+ WRITEL(0x2, S5P_FIMV_E_RC_MODE);
|
|
+ WRITEL(0xF, S5P_FIMV_E_MB_RC_CONFIG);
|
|
+ WRITEL(0x1E0001, S5P_FIMV_E_RC_FRAME_RATE); /* framerate: 30 fps */
|
|
+ WRITEL(0xF4240, S5P_FIMV_E_RC_BIT_RATE); /* bitrate: 1000000 */
|
|
+ WRITEL(0x3FD00, S5P_FIMV_E_RC_ROI_CTRL);
|
|
+ WRITEL(0x0, S5P_FIMV_E_VBV_BUFFER_SIZE);
|
|
+ WRITEL(0x0, S5P_FIMV_E_VBV_INIT_DELAY);
|
|
+ WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE);
|
|
+ WRITEL(0x2710, S5P_FIMV_E_MAX_BIT_COUNT); /* max bit count: 10000 */
|
|
+ WRITEL(0x3E8, S5P_FIMV_E_MIN_BIT_COUNT); /* min bit count: 1000 */
|
|
+
|
|
+ /* HEVC */
|
|
+ WRITEL(0x50F215, S5P_FIMV_E_HEVC_OPTIONS);
|
|
+ WRITEL(0x1E, S5P_FIMV_E_HEVC_REFRESH_PERIOD);
|
|
+ WRITEL(0x0, S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET);
|
|
+ WRITEL(0x0, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2);
|
|
+ WRITEL(0x0, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2);
|
|
+
|
|
+ /* H.264 */
|
|
+ WRITEL(0x3011, S5P_FIMV_E_H264_OPTIONS);
|
|
+ WRITEL(0x0, S5P_FIMV_E_H264_OPTIONS_2);
|
|
+ WRITEL(0x0, S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
|
|
+ WRITEL(0x0, S5P_FIMV_E_H264_LF_BETA_OFFSET);
|
|
+ WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD);
|
|
+ WRITEL(0x0, S5P_FIMV_E_H264_CHROMA_QP_OFFSET);
|
|
+
|
|
+ /* VP8 */
|
|
+ WRITEL(0x0, S5P_FIMV_E_VP8_OPTION);
|
|
+ WRITEL(0x0, S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION);
|
|
+
|
|
+ /* MVC */
|
|
+ WRITEL(0x1D, S5P_FIMV_E_MVC_FRAME_QP_VIEW1); /* QP: 29 */
|
|
+ WRITEL(0xF4240, S5P_FIMV_E_MVC_RC_BIT_RATE_VIEW1); /* bitrate: 1000000 */
|
|
+ WRITEL(0x33003300, S5P_FIMV_E_MVC_RC_QBOUND_VIEW1); /* max I, P QP: 51 */
|
|
+ WRITEL(0x2, S5P_FIMV_E_MVC_RC_MODE_VIEW1);
|
|
+ WRITEL(0x1, S5P_FIMV_E_MVC_INTER_VIEW_PREDICTION_ON);
|
|
+
|
|
+ /* Additional initialization: NAL start only */
|
|
+ WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION);
|
|
+ WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR);
|
|
+ WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE);
|
|
+ WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG);
|
|
+ WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR);
|
|
+ WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE);
|
|
+
|
|
+ return;
|
|
+}
|
|
+
|
|
static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
{
|
|
struct s5p_mfc_dev *dev = ctx->dev;
|
|
@@ -1419,6 +1506,8 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
|
|
mfc_debug_enter();
|
|
|
|
+ s5p_mfc_set_default_params(ctx);
|
|
+
|
|
/* width */
|
|
WRITEL(ctx->img_width, S5P_FIMV_E_FRAME_WIDTH); /* 16 align */
|
|
/* height */
|
|
@@ -1432,12 +1521,14 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET);
|
|
|
|
/* pictype : IDR period */
|
|
- reg = 0;
|
|
+ reg = READL(S5P_FIMV_E_GOP_CONFIG);
|
|
+ reg &= ~(0xFFFF);
|
|
reg |= p->gop_size & 0xFFFF;
|
|
WRITEL(reg, S5P_FIMV_E_GOP_CONFIG);
|
|
|
|
if(FW_HAS_GOP2(dev)) {
|
|
- reg = 0;
|
|
+ reg = READL(S5P_FIMV_E_GOP_CONFIG2);
|
|
+ reg &= ~(0x3FFF);
|
|
reg |= (p->gop_size >> 16) & 0x3FFF;
|
|
WRITEL(reg, S5P_FIMV_E_GOP_CONFIG2);
|
|
}
|
|
@@ -1446,12 +1537,12 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
/* multi-slice MB number or bit size */
|
|
enc->slice_mode = p->slice_mode;
|
|
|
|
- WRITEL(0, S5P_FIMV_E_ENC_OPTIONS);
|
|
-
|
|
- if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
|
|
+ if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
|
|
enc->slice_size.mb = p->slice_mb;
|
|
- } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
|
|
+ } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
|
|
enc->slice_size.bits = p->slice_bit;
|
|
+ } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW) {
|
|
+ enc->slice_size.mb = p->slice_mb_row * ((ctx->img_width + 15) / 16);
|
|
} else {
|
|
enc->slice_size.mb = 0;
|
|
enc->slice_size.bits = 0;
|
|
@@ -1461,31 +1552,22 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
|
|
/* cyclic intra refresh */
|
|
WRITEL(p->intra_refresh_mb, S5P_FIMV_E_IR_SIZE);
|
|
+
|
|
reg = READL(S5P_FIMV_E_ENC_OPTIONS);
|
|
- if (p->intra_refresh_mb == 0)
|
|
- reg &= ~(0x1 << 4);
|
|
- else
|
|
+ /* frame skip mode */
|
|
+ reg &= ~(0x3);
|
|
+ reg |= (p->frame_skip_mode & 0x3);
|
|
+ /* seq header ctrl */
|
|
+ reg &= ~(0x1 << 2);
|
|
+ reg |= ((p->seq_hdr_mode & 0x1) << 2);
|
|
+ /* cyclic intra refresh */
|
|
+ reg &= ~(0x1 << 4);
|
|
+ if (p->intra_refresh_mb)
|
|
reg |= (0x1 << 4);
|
|
- WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
|
|
-
|
|
/* 'NON_REFERENCE_STORE_ENABLE' for debugging */
|
|
- reg = READL(S5P_FIMV_E_ENC_OPTIONS);
|
|
reg &= ~(0x1 << 9);
|
|
WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
|
|
|
|
- /* memory structure cur. frame */
|
|
- if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
|
|
- /* 0: Linear, 1: 2D tiled*/
|
|
- reg = READL(S5P_FIMV_E_ENC_OPTIONS);
|
|
- reg |= (0x1 << 7);
|
|
- WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
|
|
- } else {
|
|
- /* 0: Linear, 1: 2D tiled*/
|
|
- reg = READL(S5P_FIMV_E_ENC_OPTIONS);
|
|
- reg &= ~(0x1 << 7);
|
|
- WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
|
|
- }
|
|
-
|
|
switch (ctx->src_fmt->fourcc) {
|
|
case V4L2_PIX_FMT_NV12M:
|
|
case V4L2_PIX_FMT_NV12MT_16X16:
|
|
@@ -1521,12 +1603,6 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
}
|
|
WRITEL(pix_val, S5P_FIMV_PIXEL_FORMAT);
|
|
|
|
- /* memory structure recon. frame */
|
|
- /* 0: Linear, 1: 2D tiled */
|
|
- reg = READL(S5P_FIMV_E_ENC_OPTIONS);
|
|
- reg |= (0x1 << 8);
|
|
- WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
|
|
-
|
|
/* padding control & value */
|
|
WRITEL(0x0, S5P_FIMV_E_PADDING_CTRL);
|
|
if (p->pad) {
|
|
@@ -1546,18 +1622,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
}
|
|
|
|
/* rate control config. */
|
|
- reg = 0;
|
|
- /** frame-level rate control */
|
|
+ reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
+ /* macroblock level rate control */
|
|
+ reg &= ~(0x1 << 8);
|
|
+ reg |= ((p->rc_mb & 0x1) << 8);
|
|
+ /* framelevel rate control */
|
|
reg &= ~(0x1 << 9);
|
|
- reg |= (p->rc_frame << 9);
|
|
+ reg |= ((p->rc_frame & 0x1) << 9);
|
|
+ /* 'DROP_CONTROL_ENABLE', disable */
|
|
+ reg &= ~(0x1 << 10);
|
|
WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
|
|
/* bit rate */
|
|
- if (p->rc_frame)
|
|
- WRITEL(p->rc_bitrate,
|
|
- S5P_FIMV_E_RC_BIT_RATE);
|
|
- else
|
|
- WRITEL(1, S5P_FIMV_E_RC_BIT_RATE);
|
|
+ if (p->rc_bitrate)
|
|
+ WRITEL(p->rc_bitrate, S5P_FIMV_E_RC_BIT_RATE);
|
|
|
|
if (p->rc_frame) {
|
|
if (FW_HAS_ADV_RC_MODE(dev)) {
|
|
@@ -1580,48 +1658,12 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
|
|
|
|
/* extended encoder ctrl */
|
|
/** vbv buffer size */
|
|
- if (p->frame_skip_mode == V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT)
|
|
- WRITEL(p->vbv_buf_size, S5P_FIMV_E_VBV_BUFFER_SIZE);
|
|
-
|
|
- /** seq header ctrl */
|
|
- reg = READL(S5P_FIMV_E_ENC_OPTIONS);
|
|
- reg &= ~(0x1 << 2);
|
|
- reg |= (p->seq_hdr_mode << 2);
|
|
- /** frame skip mode */
|
|
- reg &= ~(0x3);
|
|
- reg |= (p->frame_skip_mode);
|
|
- WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
|
|
-
|
|
- /* 'DROP_CONTROL_ENABLE', disable */
|
|
- reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
- reg &= ~(0x1 << 10);
|
|
- WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
-
|
|
- /* setting for MV range [16, 256] */
|
|
- if (mfc_version(dev) == 0x61)
|
|
- reg = ENC_V61_MV_RANGE;
|
|
- else if (mfc_version(dev) == 0x78)
|
|
- reg = ENC_V78_MV_RANGE;
|
|
- else
|
|
- reg = ENC_V65_MV_RANGE;
|
|
- WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE);
|
|
- WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE);
|
|
-
|
|
- WRITEL(0x0, S5P_FIMV_E_VBV_INIT_DELAY); /* SEQ_start Only */
|
|
-
|
|
- /* initialize for '0' only setting */
|
|
- WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_RC_ROI_CTRL); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG); /* NAL_start Only */
|
|
-
|
|
- WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_MAX_BIT_COUNT); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_MIN_BIT_COUNT); /* NAL_start Only */
|
|
-
|
|
- WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR); /* NAL_start Only */
|
|
- WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE); /* NAL_start Only */
|
|
+ if (p->frame_skip_mode == V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
|
|
+ reg = READL(S5P_FIMV_E_VBV_BUFFER_SIZE);
|
|
+ reg &= ~(0xFF);
|
|
+ reg |= p->vbv_buf_size & 0xFF;
|
|
+ WRITEL(reg, S5P_FIMV_E_VBV_BUFFER_SIZE);
|
|
+ }
|
|
|
|
mfc_debug_leave();
|
|
|
|
@@ -1634,7 +1676,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
|
|
struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
struct s5p_mfc_enc_params *p = &enc->params;
|
|
struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
|
|
- unsigned int reg = 0;
|
|
+ unsigned int reg = 0, reg2 = 0;
|
|
int i;
|
|
|
|
mfc_debug_enter();
|
|
@@ -1682,10 +1724,52 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
|
|
reg |= p_264->profile;
|
|
WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
|
|
|
|
+ reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
+ /* entropy coding mode */
|
|
+ reg &= ~(0x1);
|
|
+ reg |= (p_264->entropy_mode & 0x1);
|
|
+ /* loop filter ctrl */
|
|
+ reg &= ~(0x3 << 1);
|
|
+ reg |= ((p_264->loop_filter_mode & 0x3) << 1);
|
|
/* interlace */
|
|
- reg = 0;
|
|
reg &= ~(0x1 << 3);
|
|
- reg |= (p_264->interlace << 3);
|
|
+ reg |= ((p_264->interlace & 0x1) << 3);
|
|
+ /* intra picture period for H.264 open GOP
|
|
+ * from 9.0 Version changed register meaning
|
|
+ */
|
|
+ reg &= ~(0x1 << 4);
|
|
+ p_264->open_gop ^= S5P_FIMV_E_IDR_H264_IDR;
|
|
+ reg |= ((p_264->open_gop & 0x1) << 4);
|
|
+ /* extended encoder ctrl */
|
|
+ reg &= ~(0x1 << 5);
|
|
+ reg |= ((p_264->ar_vui & 0x1) << 5);
|
|
+ /* ASO enable */
|
|
+ reg &= ~(0x1 << 6);
|
|
+ reg |= ((p_264->aso_enable & 0x1) << 6);
|
|
+ /* number of ref. picture */
|
|
+ reg &= ~(0x1 << 7);
|
|
+ reg |= (((p_264->num_ref_pic_4p - 1) & 0x1) << 7);
|
|
+ /* Temporal SVC - hier qp enable */
|
|
+ reg &= ~(0x1 << 8);
|
|
+ reg |= ((p_264->hier_qp_enable & 0x1) << 8);
|
|
+ /* 8x8 transform enable */
|
|
+ reg &= ~(0x1 << 12);
|
|
+ reg &= ~(0x1 << 13);
|
|
+ reg |= ((p_264->_8x8_transform & 0x1) << 12);
|
|
+ reg |= ((p_264->_8x8_transform & 0x1) << 13);
|
|
+ /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
|
|
+ reg &= ~(0x1 << 14);
|
|
+ /*
|
|
+ * CONSTRAINT_SET0_FLAG: all constraints specified in
|
|
+ * Baseline Profile
|
|
+ */
|
|
+ reg |= (0x1 << 26);
|
|
+ /* sps pps control */
|
|
+ reg &= ~(0x1 << 29);
|
|
+ reg |= ((p_264->prepend_sps_pps_to_idr & 0x1) << 29);
|
|
+ /* VUI parameter disable */
|
|
+ reg &= ~(0x1 << 30);
|
|
+ reg |= ((p_264->vui_enable & 0x1) << 30);
|
|
WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
|
|
/** height */
|
|
@@ -1695,134 +1779,90 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
|
|
WRITEL(ctx->img_height >> 1, S5P_FIMV_E_CROPPED_FRAME_HEIGHT);
|
|
}
|
|
|
|
- /* loop filter ctrl */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x3 << 1);
|
|
- reg |= (p_264->loop_filter_mode << 1);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
-
|
|
/* loopfilter alpha offset */
|
|
- if (p_264->loop_filter_alpha < 0) {
|
|
- reg = 0x10;
|
|
- reg |= (0xFF - p_264->loop_filter_alpha) + 1;
|
|
- } else {
|
|
- reg = 0x00;
|
|
- reg |= (p_264->loop_filter_alpha & 0xF);
|
|
- }
|
|
+ reg = READL(S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
|
|
+ reg &= ~(0x1F);
|
|
+ reg |= (p_264->loop_filter_alpha & 0x1F);
|
|
WRITEL(reg, S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
|
|
|
|
/* loopfilter beta offset */
|
|
- if (p_264->loop_filter_beta < 0) {
|
|
- reg = 0x10;
|
|
- reg |= (0xFF - p_264->loop_filter_beta) + 1;
|
|
- } else {
|
|
- reg = 0x00;
|
|
- reg |= (p_264->loop_filter_beta & 0xF);
|
|
- }
|
|
+ reg = READL(S5P_FIMV_E_H264_LF_BETA_OFFSET);
|
|
+ reg &= ~(0x1F);
|
|
+ reg |= (p_264->loop_filter_beta & 0x1F);
|
|
WRITEL(reg, S5P_FIMV_E_H264_LF_BETA_OFFSET);
|
|
|
|
- /* entropy coding mode */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1);
|
|
- reg |= (p_264->entropy_mode);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
-
|
|
- /* number of ref. picture */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1 << 7);
|
|
- if (!IS_MFCv78(dev))
|
|
- reg |= ((p_264->num_ref_pic_4p-1) << 7);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
-
|
|
- /* 8x8 transform enable */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x3 << 12);
|
|
- reg |= (p_264->_8x8_transform << 12);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
-
|
|
/* rate control config. */
|
|
reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
- /** macroblock level rate control */
|
|
- reg &= ~(0x1 << 8);
|
|
- reg |= (p->rc_mb << 8);
|
|
- WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
/** frame QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_264->rc_frame_qp;
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_264->rc_frame_qp & 0x7F);
|
|
+ if (!p->rc_frame && !p->rc_mb && p->dynamic_qp)
|
|
+ reg |= (0x1 << 11);
|
|
WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
|
|
/* frame rate */
|
|
/* Fix value for H.264, H.263 in the driver */
|
|
p->rc_frame_delta = FRAME_DELTA_DEFAULT;
|
|
if (p->rc_frame) {
|
|
- reg = 0;
|
|
- reg &= ~(0xffff << 16);
|
|
- reg |= ((p_264->rc_framerate * p->rc_frame_delta) << 16);
|
|
- reg &= ~(0xffff);
|
|
- reg |= p->rc_frame_delta;
|
|
+ reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
|
|
+ reg &= ~(0xFFFF << 16);
|
|
+ reg |= (p_264->rc_framerate * p->rc_frame_delta) << 16;
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= p->rc_frame_delta & 0xFFFF;
|
|
WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
|
|
}
|
|
-
|
|
- /* max & min value of QP */
|
|
- reg = 0;
|
|
- /** max QP */
|
|
- reg &= ~(0x3F << 8);
|
|
- reg |= (p_264->rc_max_qp << 8);
|
|
- /** min QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_264->rc_min_qp;
|
|
+ /* max & min value of QP for I frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND);
|
|
+ /** max I frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_264->rc_max_qp & 0x7F) << 8);
|
|
+ /** min I frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_264->rc_min_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
|
|
|
|
- /* macroblock adaptive scaling features */
|
|
- WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG);
|
|
- if (p->rc_mb) {
|
|
- reg = 0;
|
|
- /** dark region */
|
|
- reg &= ~(0x1 << 3);
|
|
- reg |= (p_264->rc_mb_dark << 3);
|
|
- /** smooth region */
|
|
- reg &= ~(0x1 << 2);
|
|
- reg |= (p_264->rc_mb_smooth << 2);
|
|
- /** static region */
|
|
- reg &= ~(0x1 << 1);
|
|
- reg |= (p_264->rc_mb_static << 1);
|
|
- /** high activity region */
|
|
- reg &= ~(0x1);
|
|
- reg |= p_264->rc_mb_activity;
|
|
- WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
|
|
- }
|
|
-
|
|
- WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- if (!p->rc_frame && !p->rc_mb) {
|
|
- reg = 0;
|
|
- reg &= ~(0x3f << 16);
|
|
- reg |= (p_264->rc_b_frame_qp << 16);
|
|
- reg &= ~(0x3f << 8);
|
|
- reg |= (p_264->rc_p_frame_qp << 8);
|
|
- reg &= ~(0x3f);
|
|
- reg |= p_264->rc_frame_qp;
|
|
- WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- }
|
|
-
|
|
- /* sps pps control */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1 << 29);
|
|
- reg |= (p_264->prepend_sps_pps_to_idr << 29);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
+ /* max & min value of QP for P/B frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+ /** max B frame QP */
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p_264->rc_max_qp_b & 0x7F) << 24);
|
|
+ /** min B frame QP */
|
|
+ reg &= ~(0x7F << 16);
|
|
+ reg |= ((p_264->rc_min_qp_b & 0x7F) << 16);
|
|
+ /** max P frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_264->rc_max_qp_p & 0x7F) << 8);
|
|
+ /** min P frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= p_264->rc_min_qp_p & 0x7F;
|
|
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
|
|
- /*
|
|
- * CONSTRAINT_SET0_FLAG: all constraints specified in
|
|
- * Baseline Profile
|
|
- */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg |= (0x1 << 26);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
+ /* macroblock adaptive scaling features */
|
|
+ reg = READL(S5P_FIMV_E_MB_RC_CONFIG);
|
|
+ /* dark region */
|
|
+ reg &= ~(0x1 << 3);
|
|
+ reg |= ((p_264->rc_mb_dark & 0x1) << 3);
|
|
+ /* smooth region */
|
|
+ reg &= ~(0x1 << 2);
|
|
+ reg |= ((p_264->rc_mb_smooth & 0x1) << 2);
|
|
+ /* static region */
|
|
+ reg &= ~(0x1 << 1);
|
|
+ reg |= ((p_264->rc_mb_static & 0x1) << 1);
|
|
+ /* high activity region */
|
|
+ reg &= ~(0x1);
|
|
+ reg |= (p_264->rc_mb_activity & 0x1);
|
|
+ WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
|
|
|
|
- /* extended encoder ctrl */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1 << 5);
|
|
- reg |= (p_264->ar_vui << 5);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
+ reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p->config_qp & 0x7F) << 24);
|
|
+ reg &= ~(0x7F << 16);
|
|
+ reg |= ((p_264->rc_b_frame_qp & 0x7F) << 16);
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_264->rc_p_frame_qp & 0x7F) << 8);
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_264->rc_frame_qp & 0x7F);
|
|
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
|
|
WRITEL(0x0, S5P_FIMV_E_ASPECT_RATIO);
|
|
WRITEL(0x0, S5P_FIMV_E_EXTENDED_SAR);
|
|
@@ -1841,87 +1881,72 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
|
|
WRITEL(reg, S5P_FIMV_E_EXTENDED_SAR);
|
|
}
|
|
}
|
|
-
|
|
- /* intra picture period for H.264 open GOP */
|
|
- /** control */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- /* from 9.0 Version changed register meaning*/
|
|
- reg &= ~(0x1 << 4);
|
|
- p_264->open_gop ^= S5P_FIMV_E_IDR_H264_IDR;
|
|
- reg |= (p_264->open_gop << 4);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
- /** value */
|
|
- WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD);
|
|
+ /* intra picture period for H.264 open GOP, value */
|
|
if (p_264->open_gop) {
|
|
- reg = 0;
|
|
- reg &= ~(0xffff);
|
|
- reg |= p_264->open_gop_size;
|
|
+ reg = READL(S5P_FIMV_E_H264_I_PERIOD);
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= (p_264->open_gop_size & 0xFFFF);
|
|
WRITEL(reg, S5P_FIMV_E_H264_I_PERIOD);
|
|
}
|
|
|
|
- /* 'WEIGHTED_BI_PREDICTION' for B is disable */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x3 << 9);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
-
|
|
- /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1 << 14);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
-
|
|
- /* ASO enable */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- if (p_264->aso_enable)
|
|
- reg |= (0x1 << 6);
|
|
- else
|
|
- reg &= ~(0x1 << 6);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_2);
|
|
+ /* pic_order_cnt_type = 0 for backward compatibilities */
|
|
+ if (FW_HAS_POC_TYPE_CTRL(dev))
|
|
+ reg &= ~(0x3);
|
|
+ /* Enable LTR */
|
|
+ reg &= ~(0x1 << 2);
|
|
+ if ((p_264->enable_ltr & 0x1) || (p_264->num_of_ltr > 0))
|
|
+ reg |= (0x1 << 2);
|
|
+ /* Number of LTR */
|
|
+ reg &= ~(0x3 << 7);
|
|
+ if (p_264->num_of_ltr > 2)
|
|
+ reg |= (((p_264->num_of_ltr - 2) & 0x3) << 7);
|
|
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_2);
|
|
|
|
- /* VUI parameter disable */
|
|
- if (FW_HAS_VUI_PARAMS(dev)) {
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1 << 30);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
+ /* Temporal SVC - qp type, layer number */
|
|
+ reg = READL(S5P_FIMV_E_NUM_T_LAYER);
|
|
+ reg &= ~(0x1 << 3);
|
|
+ reg |= (p_264->hier_qp_type & 0x1) << 3;
|
|
+ reg &= ~(0x7);
|
|
+ reg |= p_264->num_hier_layer & 0x7;
|
|
+ reg &= ~(0x7 << 4);
|
|
+ if (p_264->hier_ref_type) {
|
|
+ reg |= 0x1 << 7;
|
|
+ reg |= (p->num_hier_max_layer & 0x7) << 4;
|
|
+ } else {
|
|
+ reg |= 0x7 << 4;
|
|
}
|
|
+ WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
|
|
+ mfc_debug(3, "Temporal SVC: hier_qp_enable %d, enable_ltr %d, "
|
|
+ "num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
|
|
+ p_264->hier_qp_enable, p_264->enable_ltr, p_264->num_hier_layer,
|
|
+ p->num_hier_max_layer, p_264->hier_ref_type, reg);
|
|
|
|
- /* pic_order_cnt_type = 0 for backward compatibilities */
|
|
- if (FW_HAS_POC_TYPE_CTRL(dev)) {
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS_2);
|
|
- reg &= ~(0x3 << 0);
|
|
- reg |= (0x0 << 0); /* TODO: add new CID for this */
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_2);
|
|
+ /* QP & Bitrate for each layer */
|
|
+ for (i = 0; i < 7; i++) {
|
|
+ WRITEL(p_264->hier_qp_layer[i],
|
|
+ S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
|
|
+ WRITEL(p_264->hier_bit_layer[i],
|
|
+ S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
|
|
+ mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
|
|
+ i, p_264->hier_qp_layer[i],
|
|
+ p_264->hier_bit_layer[i]);
|
|
}
|
|
|
|
-#if defined(CONFIG_SOC_EXYNOS5422) || defined(CONFIG_SOC_EXYNOS5433)
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS_2);
|
|
- reg |= (0x1 << 3); /* Enable ECO MODE */
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_2);
|
|
-#endif
|
|
-
|
|
- /* hier qp enable */
|
|
- reg = READL(S5P_FIMV_E_H264_OPTIONS);
|
|
- reg &= ~(0x1 << 8);
|
|
- reg |= ((p_264->hier_qp & 0x1) << 8);
|
|
- WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
|
|
- reg = 0;
|
|
- if (p_264->hier_qp_layer) {
|
|
- reg |= 0x7 << 0x4;
|
|
- reg |= (p_264->hier_qp_type & 0x1) << 0x3;
|
|
- reg |= p_264->hier_qp_layer & 0x7;
|
|
- WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER);
|
|
- /* QP value for each layer */
|
|
- if (p_264->hier_qp) {
|
|
- for (i = 0; i < (p_264->hier_qp_layer & 0x7); i++)
|
|
- WRITEL(p_264->hier_qp_layer_qp[i],
|
|
- S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 + i * 4);
|
|
- } else {
|
|
- for (i = 0; i < (p_264->hier_qp_layer & 0x7); i++)
|
|
- WRITEL(p_264->hier_qp_layer_bit[i],
|
|
- S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
|
|
+ if (p_264->set_priority) {
|
|
+ reg = 0;
|
|
+ reg2 = 0;
|
|
+ for (i = 0; i < (p_264->num_hier_layer & 0x7); i++) {
|
|
+ if (i <= 4)
|
|
+ reg |= ((p_264->base_priority & 0x3F) + i) << (6 * i);
|
|
+ else
|
|
+ reg2 |= ((p_264->base_priority & 0x3F) + i) << (6 * (i - 5));
|
|
}
|
|
+ WRITEL(reg, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
|
|
+ WRITEL(reg2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
|
|
+ mfc_debug(3, "Temporal SVC: priority EXTENSION0: %#x, EXTENSION1: %#x\n",
|
|
+ reg, reg2);
|
|
}
|
|
- /* number of coding layer should be zero when hierarchical is disable */
|
|
- WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER);
|
|
|
|
/* set frame pack sei generation */
|
|
if (p_264->sei_gen_enable) {
|
|
@@ -2015,26 +2040,25 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
|
|
/* WRITEL(p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL); */
|
|
|
|
/* qp */
|
|
- WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- if (!p->rc_frame && !p->rc_mb) {
|
|
- reg = 0;
|
|
- reg &= ~(0x3f << 16);
|
|
- reg |= (p_mpeg4->rc_b_frame_qp << 16);
|
|
- reg &= ~(0x3f << 8);
|
|
- reg |= (p_mpeg4->rc_p_frame_qp << 8);
|
|
- reg &= ~(0x3f);
|
|
- reg |= p_mpeg4->rc_frame_qp;
|
|
- WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- }
|
|
+ reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p->config_qp & 0x7F) << 24);
|
|
+ reg &= ~(0x7F << 16);
|
|
+ reg |= ((p_mpeg4->rc_b_frame_qp & 0x7F) << 16);
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_mpeg4->rc_p_frame_qp & 0x7F) << 8);
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_mpeg4->rc_frame_qp & 0x7F);
|
|
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
|
|
/* frame rate */
|
|
if (p->rc_frame) {
|
|
p->rc_frame_delta = p_mpeg4->vop_frm_delta;
|
|
- reg = 0;
|
|
- reg &= ~(0xffff << 16);
|
|
+ reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
|
|
+ reg &= ~(0xFFFF << 16);
|
|
reg |= (p_mpeg4->vop_time_res << 16);
|
|
- reg &= ~(0xffff);
|
|
- reg |= p_mpeg4->vop_frm_delta;
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= (p_mpeg4->vop_frm_delta & 0xFFFF);
|
|
WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
|
|
} else {
|
|
p->rc_frame_delta = FRAME_DELTA_DEFAULT;
|
|
@@ -2042,25 +2066,37 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
|
|
|
|
/* rate control config. */
|
|
reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
- /** macroblock level rate control */
|
|
- reg &= ~(0x1 << 8);
|
|
- reg |= (p->rc_mb << 8);
|
|
- WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
/** frame QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_mpeg4->rc_frame_qp;
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_mpeg4->rc_frame_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
|
|
- /* max & min value of QP */
|
|
- reg = 0;
|
|
- /** max QP */
|
|
- reg &= ~(0x3F << 8);
|
|
- reg |= (p_mpeg4->rc_max_qp << 8);
|
|
- /** min QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_mpeg4->rc_min_qp;
|
|
+ /* max & min value of QP for I frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND);
|
|
+ /** max I frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_mpeg4->rc_max_qp & 0x7F) << 8);
|
|
+ /** min I frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_mpeg4->rc_min_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
|
|
|
|
+ /* max & min value of QP for P/B frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+ /** max B frame QP */
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p_mpeg4->rc_max_qp_b & 0x7F) << 24);
|
|
+ /** min B frame QP */
|
|
+ reg &= ~(0x7F << 16);
|
|
+ reg |= ((p_mpeg4->rc_min_qp_b & 0x7F) << 16);
|
|
+ /** max P frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_mpeg4->rc_max_qp_p & 0x7F) << 8);
|
|
+ /** min P frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= p_mpeg4->rc_min_qp_p & 0x7F;
|
|
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+
|
|
/* initialize for '0' only setting*/
|
|
WRITEL(0x0, S5P_FIMV_E_MPEG4_OPTIONS); /* SEQ_start only */
|
|
WRITEL(0x0, S5P_FIMV_E_MPEG4_HEC_PERIOD); /* SEQ_start only */
|
|
@@ -2089,49 +2125,54 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
|
|
WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
|
|
|
|
/* qp */
|
|
- WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- if (!p->rc_frame && !p->rc_mb) {
|
|
- reg = 0;
|
|
- reg &= ~(0x3f << 8);
|
|
- reg |= (p_mpeg4->rc_p_frame_qp << 8);
|
|
- reg &= ~(0x3f);
|
|
- reg |= p_mpeg4->rc_frame_qp;
|
|
- WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- }
|
|
+ reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p->config_qp & 0x7F) << 24);
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_mpeg4->rc_p_frame_qp & 0x7F) << 8);
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_mpeg4->rc_frame_qp & 0x7F);
|
|
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
|
|
/* frame rate */
|
|
/* Fix value for H.264, H.263 in the driver */
|
|
p->rc_frame_delta = FRAME_DELTA_DEFAULT;
|
|
if (p->rc_frame) {
|
|
- reg = 0;
|
|
- reg &= ~(0xffff << 16);
|
|
+ reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
|
|
+ reg &= ~(0xFFFF << 16);
|
|
reg |= ((p_mpeg4->rc_framerate * p->rc_frame_delta) << 16);
|
|
- reg &= ~(0xffff);
|
|
- reg |= p->rc_frame_delta;
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= (p->rc_frame_delta & 0xFFFF);
|
|
WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
|
|
}
|
|
|
|
/* rate control config. */
|
|
reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
- /** macroblock level rate control */
|
|
- reg &= ~(0x1 << 8);
|
|
- reg |= (p->rc_mb << 8);
|
|
- WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
/** frame QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_mpeg4->rc_frame_qp;
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_mpeg4->rc_frame_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
|
|
- /* max & min value of QP */
|
|
- reg = 0;
|
|
- /** max QP */
|
|
- reg &= ~(0x3F << 8);
|
|
- reg |= (p_mpeg4->rc_max_qp << 8);
|
|
- /** min QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_mpeg4->rc_min_qp;
|
|
+ /* max & min value of QP for I frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND);
|
|
+ /** max I frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_mpeg4->rc_max_qp & 0x7F) << 8);
|
|
+ /** min I frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_mpeg4->rc_min_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
|
|
|
|
+ /* max & min value of QP for P/B frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+ /** max P frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_mpeg4->rc_max_qp_p & 0x7F) << 8);
|
|
+ /** min P frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= p_mpeg4->rc_min_qp_p & 0x7F;
|
|
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+
|
|
mfc_debug_leave();
|
|
|
|
return 0;
|
|
@@ -2155,42 +2196,47 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
|
|
reg |= (p_vp8->vp8_version) ;
|
|
WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
|
|
|
|
- reg = 0;
|
|
+ reg = READL(S5P_FIMV_E_VP8_OPTION);
|
|
+ reg &= ~(0x1);
|
|
+ reg |= (p_vp8->num_refs_for_p - 1) & 0x1;
|
|
+ reg &= ~(0xF << 3);
|
|
+ reg |= (p_vp8->vp8_numberofpartitions & 0xF) << 3;
|
|
+ reg &= ~(0x1 << 10);
|
|
+ reg |= (p_vp8->intra_4x4mode_disable & 0x1) << 10;
|
|
+ /* Temporal SVC - hier qp enable */
|
|
+ reg &= ~(0x1 << 11);
|
|
+ reg |= (p_vp8->hier_qp_enable & 0x1) << 11;
|
|
/* Disable IVF header */
|
|
reg |= (0x1 << 12);
|
|
- reg |= (p_vp8->intra_4x4mode_disable & 0x1) << 10;
|
|
- reg |= (p_vp8->vp8_numberofpartitions & 0xF) << 3;
|
|
- reg |= (p_vp8->num_refs_for_p - 1) & 0x1;
|
|
WRITEL(reg, S5P_FIMV_E_VP8_OPTION);
|
|
|
|
- reg = 0;
|
|
+ reg = READL(S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION);
|
|
+ reg &= ~(0x1);
|
|
reg |= (p_vp8->vp8_goldenframesel & 0x1);
|
|
- reg |= (p_vp8->vp8_gfrefreshperiod & 0xffff) << 1;
|
|
+ reg &= ~(0xFFFF << 1);
|
|
+ reg |= (p_vp8->vp8_gfrefreshperiod & 0xFFFF) << 1;
|
|
WRITEL(reg, S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION);
|
|
|
|
- /* hier qp enable */
|
|
- reg = READL(S5P_FIMV_E_VP8_OPTION);
|
|
- reg &= ~(0x1 << 11);
|
|
- reg |= ((p_vp8->hierarchy_qp_enable & 0x1) << 11);
|
|
- WRITEL(reg, S5P_FIMV_E_VP8_OPTION);
|
|
- reg = 0;
|
|
- if (p_vp8->num_temporal_layer) {
|
|
- reg |= p_vp8->num_temporal_layer & 0x3;
|
|
- WRITEL(reg, S5P_FIMV_E_VP8_NUM_T_LAYER);
|
|
- /* QP value for each layer */
|
|
- if (p_vp8->hierarchy_qp_enable) {
|
|
- for (i = 0; i < (p_vp8->num_temporal_layer & 0x3); i++)
|
|
- WRITEL(p_vp8->hier_qp_layer_qp[i],
|
|
- S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0 + i * 4);
|
|
- } else {
|
|
- for (i = 0; i < (p_vp8->num_temporal_layer & 0x3); i++)
|
|
- WRITEL(p_vp8->hier_qp_layer_bit[i],
|
|
- S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
|
|
- }
|
|
+ /* Temporal SVC - layer number */
|
|
+ reg = READL(S5P_FIMV_E_NUM_T_LAYER);
|
|
+ reg &= ~(0x7);
|
|
+ reg |= p_vp8->num_hier_layer & 0x3;
|
|
+ reg &= ~(0x7 << 4);
|
|
+ reg |= 0x3 << 4;
|
|
+ WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
|
|
+ mfc_debug(3, "Temporal SVC: hier_qp_enable %d, num_hier_layer %d, NUM_T_LAYER 0x%x\n",
|
|
+ p_vp8->hier_qp_enable, p_vp8->num_hier_layer, reg);
|
|
+
|
|
+ /* QP & Bitrate for each layer */
|
|
+ for (i = 0; i < 3; i++) {
|
|
+ WRITEL(p_vp8->hier_qp_layer[i],
|
|
+ S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
|
|
+ WRITEL(p_vp8->hier_bit_layer[i],
|
|
+ S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
|
|
+ mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
|
|
+ i, p_vp8->hier_qp_layer[i],
|
|
+ p_vp8->hier_bit_layer[i]);
|
|
}
|
|
- /* number of coding layer should be zero when hierarchical is disable */
|
|
- reg |= p_vp8->num_temporal_layer;
|
|
- WRITEL(reg, S5P_FIMV_E_VP8_NUM_T_LAYER);
|
|
|
|
reg = 0;
|
|
reg |= (p_vp8->vp8_filtersharpness & 0x7);
|
|
@@ -2198,51 +2244,52 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
|
|
WRITEL(reg , S5P_FIMV_E_VP8_FILTER_OPTIONS);
|
|
|
|
/* qp */
|
|
- WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- if (!p->rc_frame && !p->rc_mb) {
|
|
- reg = 0;
|
|
- reg &= ~(0x3f << 8);
|
|
- reg |= (p_vp8->rc_p_frame_qp << 8);
|
|
- reg &= ~(0x3f);
|
|
- reg |= p_vp8->rc_frame_qp;
|
|
- WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- }
|
|
+ reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p->config_qp & 0x7F) << 24);
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8);
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_vp8->rc_frame_qp & 0x7F);
|
|
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
|
|
/* frame rate */
|
|
p->rc_frame_delta = FRAME_DELTA_DEFAULT;
|
|
-
|
|
if (p->rc_frame) {
|
|
- reg = 0;
|
|
- reg &= ~(0xffff << 16);
|
|
+ reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
|
|
+ reg &= ~(0xFFFF << 16);
|
|
reg |= ((p_vp8->rc_framerate * p->rc_frame_delta) << 16);
|
|
- reg &= ~(0xffff);
|
|
- reg |= p->rc_frame_delta;
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= (p->rc_frame_delta & 0xFFFF);
|
|
WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
|
|
}
|
|
|
|
/* rate control config. */
|
|
reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
- /** macroblock level rate control */
|
|
- reg &= ~(0x1 << 8);
|
|
- reg |= (p->rc_mb << 8);
|
|
/** frame QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_vp8->rc_frame_qp;
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_vp8->rc_frame_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
|
|
- /* max & min value of QP */
|
|
- reg = 0;
|
|
- /** max QP */
|
|
- reg &= ~(0x3F << 8);
|
|
- reg |= (p_vp8->rc_max_qp << 8);
|
|
- /** min QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_vp8->rc_min_qp;
|
|
+ /* max & min value of QP for I frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND);
|
|
+ /** max I frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_vp8->rc_max_qp & 0x7F) << 8);
|
|
+ /** min I frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_vp8->rc_min_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
|
|
|
|
- /* Disable all macroblock adaptive scaling features */
|
|
- reg = 0xF;
|
|
- WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
|
|
+ /* max & min value of QP for P/B frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+ /** max P frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_vp8->rc_max_qp_p & 0x7F) << 8);
|
|
+ /** min P frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= p_vp8->rc_min_qp_p & 0x7F;
|
|
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
|
|
mfc_debug_leave();
|
|
|
|
@@ -2286,129 +2333,165 @@ static int s5p_mfc_set_enc_params_hevc(struct s5p_mfc_ctx *ctx)
|
|
WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
|
|
|
|
/* max partition depth */
|
|
- reg = 0;
|
|
+ reg = READL(S5P_FIMV_E_HEVC_OPTIONS);
|
|
+ reg &= ~(0x3);
|
|
reg |= (p_hevc->max_partition_depth & 0x1);
|
|
- reg |= (p_hevc->num_refs_for_p-1) << 2;
|
|
- reg |= (2 << 3); /* always set IDR encoding */
|
|
+ reg &= ~(0x1 << 2);
|
|
+ reg |= (p_hevc->num_refs_for_p - 1) << 2;
|
|
+ reg &= ~(0x1 << 5);
|
|
reg |= (p_hevc->const_intra_period_enable & 0x1) << 5;
|
|
+ reg &= ~(0x1 << 6);
|
|
reg |= (p_hevc->lossless_cu_enable & 0x1) << 6;
|
|
+ reg &= ~(0x1 << 7);
|
|
reg |= (p_hevc->wavefront_enable & 0x1) << 7;
|
|
+ reg &= ~(0x1 << 8);
|
|
reg |= (p_hevc->loopfilter_disable & 0x1) << 8;
|
|
- reg |= (p_hevc->longterm_ref_enable & 0x1) << 10;
|
|
- reg |= (p_hevc->hier_qp & 0x1) << 11;
|
|
+ reg &= ~(0x1 << 9);
|
|
+ reg |= (p_hevc->loopfilter_across & 0x1) << 9;
|
|
+ reg &= ~(0x1 << 10);
|
|
+ reg |= (p_hevc->enable_ltr & 0x1) << 10;
|
|
+ reg &= ~(0x1 << 11);
|
|
+ reg |= (p_hevc->hier_qp_enable & 0x1) << 11;
|
|
+ reg &= ~(0x1 << 12);
|
|
reg |= (p_hevc->sign_data_hiding & 0x1) << 12;
|
|
+ reg &= ~(0x1 << 13);
|
|
reg |= (p_hevc->general_pb_enable & 0x1) << 13;
|
|
+ reg &= ~(0x1 << 14);
|
|
reg |= (p_hevc->temporal_id_enable & 0x1) << 14;
|
|
+ reg &= ~(0x1 << 15);
|
|
reg |= (p_hevc->strong_intra_smooth & 0x1) << 15;
|
|
+ reg &= ~(0x1 << 16);
|
|
reg |= (p_hevc->intra_pu_split_disable & 0x1) << 16;
|
|
+ reg &= ~(0x1 << 17);
|
|
reg |= (p_hevc->tmv_prediction_disable & 0x1) << 17;
|
|
+ reg &= ~(0x7 << 18);
|
|
reg |= (p_hevc->max_num_merge_mv & 0x7) << 18;
|
|
- /* reg |= (1 << 21); always eco mode disable */
|
|
+ reg &= ~(0x1 << 22);
|
|
reg |= (p_hevc->encoding_nostartcode_enable & 0x1) << 22;
|
|
+ reg &= ~(0x1 << 26);
|
|
+ reg |= (p_hevc->prepend_sps_pps_to_idr & 0x1) << 26;
|
|
WRITEL(reg, S5P_FIMV_E_HEVC_OPTIONS);
|
|
/* refresh period */
|
|
- if (p_hevc->refreshtype) {
|
|
- reg = 0;
|
|
- reg |= (p_hevc->refreshperiod & 0x1);
|
|
- WRITEL(reg, S5P_FIMV_E_HEVC_REFRESH_PERIOD);
|
|
- }
|
|
+ reg = READL(S5P_FIMV_E_HEVC_REFRESH_PERIOD);
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= (p_hevc->refreshperiod & 0xFFFF);
|
|
+ WRITEL(reg, S5P_FIMV_E_HEVC_REFRESH_PERIOD);
|
|
/* loop filter setting */
|
|
- reg |= (p_hevc->loopfilter_disable & 0x01) << 8;
|
|
if (!p_hevc->loopfilter_disable) {
|
|
- reg = 0;
|
|
- reg |= (p_hevc->lf_beta_offset_div2 & 0x1);
|
|
- WRITEL(reg, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2);
|
|
- reg = 0;
|
|
- reg |= (p_hevc->lf_tc_offset_div2 & 0x1);
|
|
- WRITEL(reg, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2);
|
|
- reg = READL(S5P_FIMV_E_HEVC_OPTIONS);
|
|
- reg &= ~(0x1 << 9);
|
|
- reg |= (p_hevc->loopfilter_across & 0x1) << 9;
|
|
+ WRITEL(p_hevc->lf_beta_offset_div2, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2);
|
|
+ WRITEL(p_hevc->lf_tc_offset_div2, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2);
|
|
}
|
|
/* long term reference */
|
|
- if (p_hevc->longterm_ref_enable) {
|
|
+ if (p_hevc->enable_ltr) {
|
|
reg = 0;
|
|
reg |= (p_hevc->store_ref & 0x3);
|
|
reg &= ~(0x3 << 2);
|
|
reg |= (p_hevc->user_ref & 0x3) << 2;
|
|
WRITEL(reg, S5P_FIMV_E_HEVC_NAL_CONTROL);
|
|
}
|
|
- /* hier qp enable */
|
|
- if (p_hevc->hier_qp && p_hevc->hier_qp_layer) {
|
|
- reg |= (p_hevc->hier_qp_type & 0x1) << 0x3;
|
|
- reg |= p_hevc->hier_qp_layer & 0x7;
|
|
- /* number of coding layer should be zero when hierarchical is disable */
|
|
- WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
|
|
- /* QP value for each layer */
|
|
- for (i = 0; i < (p_hevc->hier_qp_layer & 0x7); i++)
|
|
- WRITEL(p_hevc->hier_qp_layer_qp,
|
|
- S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
|
|
- WRITEL(p_hevc->hier_qp_layer_bit,
|
|
- S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
|
|
+
|
|
+ /* Temporal SVC - qp type, layer number */
|
|
+ reg = READL(S5P_FIMV_E_NUM_T_LAYER);
|
|
+ reg &= ~(0x1 << 3);
|
|
+ reg |= (p_hevc->hier_qp_type & 0x1) << 3;
|
|
+ reg &= ~(0x7);
|
|
+ reg |= p_hevc->num_hier_layer & 0x7;
|
|
+ reg &= ~(0x7 << 4);
|
|
+ if (p_hevc->hier_ref_type) {
|
|
+ reg |= 0x1 << 7;
|
|
+ reg |= (p->num_hier_max_layer & 0x7) << 4;
|
|
+ } else {
|
|
+ reg |= 0x7 << 4;
|
|
+ }
|
|
+ WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
|
|
+ mfc_debug(2, "Temporal SVC: hier_qp_enable %d, enable_ltr %d, "
|
|
+ "num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
|
|
+ p_hevc->hier_qp_enable, p_hevc->enable_ltr, p_hevc->num_hier_layer,
|
|
+ p->num_hier_max_layer, p_hevc->hier_ref_type, reg);
|
|
+
|
|
+ /* QP & Bitrate for each layer */
|
|
+ for (i = 0; i < 7; i++) {
|
|
+ WRITEL(p_hevc->hier_qp_layer[i],
|
|
+ S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
|
|
+ WRITEL(p_hevc->hier_bit_layer[i],
|
|
+ S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
|
|
+ mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
|
|
+ i, p_hevc->hier_qp_layer[i],
|
|
+ p_hevc->hier_bit_layer[i]);
|
|
}
|
|
+
|
|
/* rate control config. */
|
|
reg = READL(S5P_FIMV_E_RC_CONFIG);
|
|
- /** macroblock level rate control */
|
|
- reg &= ~(0x1 << 8);
|
|
- reg |= (p->rc_mb << 8);
|
|
- WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
/** frame QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_hevc->rc_frame_qp;
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_hevc->rc_frame_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
|
|
|
|
/* frame rate */
|
|
-
|
|
p->rc_frame_delta = FRAME_DELTA_DEFAULT;
|
|
if (p->rc_frame) {
|
|
- reg = 0;
|
|
- reg &= ~(0xffff << 16);
|
|
+ reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
|
|
+ reg &= ~(0xFFFF << 16);
|
|
reg |= ((p_hevc->rc_framerate * p->rc_frame_delta) << 16);
|
|
- reg &= ~(0xffff);
|
|
- reg |= p->rc_frame_delta;
|
|
+ reg &= ~(0xFFFF);
|
|
+ reg |= (p->rc_frame_delta & 0xFFFF);
|
|
WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
|
|
}
|
|
|
|
- /* max & min value of QP */
|
|
- reg = 0;
|
|
- /** max QP */
|
|
- reg &= ~(0x3F << 8);
|
|
- reg |= (p_hevc->rc_max_qp << 8);
|
|
- /** min QP */
|
|
- reg &= ~(0x3F);
|
|
- reg |= p_hevc->rc_min_qp;
|
|
+ /* max & min value of QP for I frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND);
|
|
+ /** max I frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_hevc->rc_max_qp & 0x7F) << 8);
|
|
+ /** min I frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_hevc->rc_min_qp & 0x7F);
|
|
WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
|
|
|
|
+ /* max & min value of QP for P/B frame */
|
|
+ reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+ /** max B frame QP */
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p_hevc->rc_max_qp_b & 0x7F) << 24);
|
|
+ /** min B frame QP */
|
|
+ reg &= ~(0x7F << 16);
|
|
+ reg |= ((p_hevc->rc_min_qp_b & 0x7F) << 16);
|
|
+ /** max P frame QP */
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_hevc->rc_max_qp_p & 0x7F) << 8);
|
|
+ /** min P frame QP */
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= p_hevc->rc_min_qp_p & 0x7F;
|
|
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
|
|
+
|
|
/* macroblock adaptive scaling features */
|
|
- WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG);
|
|
- if (p->rc_mb) {
|
|
- reg = 0;
|
|
- /** dark region */
|
|
- reg &= ~(0x1 << 3);
|
|
- reg |= (p_hevc->rc_lcu_dark << 3);
|
|
- /** smooth region */
|
|
- reg &= ~(0x1 << 2);
|
|
- reg |= (p_hevc->rc_lcu_smooth << 2);
|
|
- /** static region */
|
|
- reg &= ~(0x1 << 1);
|
|
- reg |= (p_hevc->rc_lcu_static << 1);
|
|
- /** high activity region */
|
|
- reg &= ~(0x1);
|
|
- reg |= p_hevc->rc_lcu_activity;
|
|
- WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
|
|
- }
|
|
- WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- if (!p->rc_frame && !p->rc_mb) {
|
|
- reg = 0;
|
|
- reg &= ~(0x3f << 16);
|
|
- reg |= (p_hevc->rc_b_frame_qp << 16);
|
|
- reg &= ~(0x3f << 8);
|
|
- reg |= (p_hevc->rc_p_frame_qp << 8);
|
|
- reg &= ~(0x3f);
|
|
- reg |= p_hevc->rc_frame_qp;
|
|
- WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
- }
|
|
- mfc_debug_leave();
|
|
+ reg = READL(S5P_FIMV_E_MB_RC_CONFIG);
|
|
+ /* dark region */
|
|
+ reg &= ~(0x1 << 3);
|
|
+ reg |= ((p_hevc->rc_lcu_dark & 0x1) << 3);
|
|
+ /* smooth region */
|
|
+ reg &= ~(0x1 << 2);
|
|
+ reg |= ((p_hevc->rc_lcu_smooth & 0x1) << 2);
|
|
+ /* static region */
|
|
+ reg &= ~(0x1 << 1);
|
|
+ reg |= ((p_hevc->rc_lcu_static & 0x1) << 1);
|
|
+ /* high activity region */
|
|
+ reg &= ~(0x1);
|
|
+ reg |= (p_hevc->rc_lcu_activity & 0x1);
|
|
+ WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
|
|
+
|
|
+ reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+ reg &= ~(0x7F << 24);
|
|
+ reg |= ((p->config_qp & 0x7F) << 24);
|
|
+ reg &= ~(0x7F << 16);
|
|
+ reg |= ((p_hevc->rc_b_frame_qp & 0x7F) << 16);
|
|
+ reg &= ~(0x7F << 8);
|
|
+ reg |= ((p_hevc->rc_p_frame_qp & 0x7F) << 8);
|
|
+ reg &= ~(0x7F);
|
|
+ reg |= (p_hevc->rc_frame_qp & 0x7F);
|
|
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
|
|
+
|
|
+ mfc_debug_leave();
|
|
|
|
return 0;
|
|
}
|
|
@@ -2471,6 +2554,9 @@ static int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
|
|
if (dec->is_dual_dpb)
|
|
reg |= (0x1 << S5P_FIMV_D_OPT_DISPLAY_LINEAR_EN);
|
|
|
|
+ /* Parsing all including PPS */
|
|
+ reg |= (0x1 << S5P_FIMV_D_OPT_SPECIAL_PARSING_SHIFT);
|
|
+
|
|
WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS);
|
|
|
|
if (ctx->codec_mode == S5P_FIMV_CODEC_FIMV1_DEC) {
|
|
@@ -2515,6 +2601,10 @@ static int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
|
|
/* Enable realloc interface if SEI is enabled */
|
|
if (dec->sei_parse && FW_HAS_SEI_S3D_REALLOC(dev))
|
|
reg |= (0x1 << S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT);
|
|
+
|
|
+ /* Enable recovery SEI parsing */
|
|
+ reg |= (0x1 << S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE);
|
|
+
|
|
WRITEL(reg, S5P_FIMV_D_SEI_ENABLE);
|
|
|
|
WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
|
|
@@ -2632,6 +2722,109 @@ static int s5p_mfc_h264_set_aso_slice_order(struct s5p_mfc_ctx *ctx)
|
|
return 0;
|
|
}
|
|
|
|
+static inline void s5p_mfc_set_stride_enc(struct s5p_mfc_ctx *ctx)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
+ int i;
|
|
+
|
|
+ if (IS_MFCv7X(dev) || IS_MFCV8(dev)) {
|
|
+ for (i = 0; i < ctx->raw_buf.num_planes; i++) {
|
|
+ WRITEL(ctx->raw_buf.stride[i],
|
|
+ S5P_FIMV_E_SOURCE_FIRST_STRIDE + (i * 4));
|
|
+ mfc_debug(2, "enc src[%d] stride: 0x%08lx",
|
|
+ i, (unsigned long)ctx->raw_buf.stride[i]);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ When the resolution is changed,
|
|
+ s5p_mfc_start_change_resol_enc() should be called right before NAL_START.
|
|
+ return value
|
|
+ 0: no resolution change
|
|
+ 1: resolution swap
|
|
+ 2: resolution change
|
|
+*/
|
|
+int s5p_mfc_start_change_resol_enc(struct s5p_mfc_ctx *ctx)
|
|
+{
|
|
+ struct s5p_mfc_dev *dev = ctx->dev;
|
|
+ struct s5p_mfc_enc *enc = ctx->enc_priv;
|
|
+ struct s5p_mfc_enc_params *p = &enc->params;
|
|
+ unsigned int reg = 0;
|
|
+ int old_img_width;
|
|
+ int old_img_height;
|
|
+ int new_img_width;
|
|
+ int new_img_height;
|
|
+ int ret = 0;
|
|
+
|
|
+ if ((ctx->img_width == 0) || (ctx->img_height == 0)) {
|
|
+ mfc_err("new_img_width = %d, new_img_height = %d\n",
|
|
+ ctx->img_width, ctx->img_height);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ old_img_width = ctx->old_img_width;
|
|
+ old_img_height = ctx->old_img_height;
|
|
+
|
|
+ new_img_width = ctx->img_width;
|
|
+ new_img_height = ctx->img_height;
|
|
+
|
|
+ if ((old_img_width == new_img_width) && (old_img_height == new_img_height)) {
|
|
+ mfc_err("Resolution is not changed. new_img_width = %d, new_img_height = %d\n",
|
|
+ new_img_width, new_img_height);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ mfc_info_ctx("Resolution Change : (%d x %d) -> (%d x %d)\n",
|
|
+ old_img_width, old_img_height, new_img_width, new_img_height);
|
|
+
|
|
+ if (ctx->img_width) {
|
|
+ ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);
|
|
+ }
|
|
+
|
|
+ if ((old_img_width == new_img_height) && (old_img_height == new_img_width)) {
|
|
+ reg = READL(S5P_FIMV_E_PARAM_CHANGE);
|
|
+ reg &= ~(0x1 << 6);
|
|
+ reg |= (0x1 << 6); /* resolution swap */
|
|
+ WRITEL(reg, S5P_FIMV_E_PARAM_CHANGE);
|
|
+ ret = 1;
|
|
+ } else {
|
|
+ reg = READL(S5P_FIMV_E_PARAM_CHANGE);
|
|
+ reg &= ~(0x3 << 7);
|
|
+ /* For now, FW does not care S5P_FIMV_E_PARAM_CHANGE is 1 or 2.
|
|
+ * It cares S5P_FIMV_E_PARAM_CHANGE is NOT zero.
|
|
+ */
|
|
+ if ((old_img_width*old_img_height) < (new_img_width*new_img_height)) {
|
|
+ reg |= (0x1 << 7); /* resolution increased */
|
|
+ mfc_info_ctx("Resolution Increased\n");
|
|
+ } else {
|
|
+ reg |= (0x2 << 7); /* resolution decreased */
|
|
+ mfc_info_ctx("Resolution Decreased\n");
|
|
+ }
|
|
+ WRITEL(reg, S5P_FIMV_E_PARAM_CHANGE);
|
|
+
|
|
+ /** set cropped width */
|
|
+ WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH);
|
|
+ /** set cropped height */
|
|
+ WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT);
|
|
+
|
|
+ /* bit rate */
|
|
+ if (p->rc_frame)
|
|
+ WRITEL(p->rc_bitrate, S5P_FIMV_E_RC_BIT_RATE);
|
|
+ else
|
|
+ WRITEL(1000000, S5P_FIMV_E_RC_BIT_RATE);
|
|
+ ret = 2;
|
|
+ }
|
|
+
|
|
+ /** set new stride */
|
|
+ s5p_mfc_set_stride_enc(ctx);
|
|
+
|
|
+ /** set cropped offset */
|
|
+ WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/* Encode a single frame */
|
|
int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame)
|
|
{
|
|
@@ -2644,6 +2837,11 @@ int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame)
|
|
|
|
s5p_mfc_set_slice_mode(ctx);
|
|
|
|
+ if (ctx->enc_drc_flag) {
|
|
+ ctx->enc_res_change = s5p_mfc_start_change_resol_enc(ctx);
|
|
+ ctx->enc_drc_flag = 0;
|
|
+ }
|
|
+
|
|
WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
|
|
/* Issue different commands to instance basing on whether it
|
|
* is the last frame or not. */
|
|
@@ -2768,8 +2966,13 @@ static inline int s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx)
|
|
temp_vb = list_entry(ctx->src_queue.next,
|
|
struct s5p_mfc_buf, list);
|
|
temp_vb->used = 1;
|
|
- s5p_mfc_set_dec_stream_buffer(ctx,
|
|
- s5p_mfc_mem_plane_addr(ctx, &temp_vb->vb, 0), 0, 0);
|
|
+ if (dec->consumed)
|
|
+ s5p_mfc_set_dec_stream_buffer(ctx,
|
|
+ s5p_mfc_mem_plane_addr(ctx, &temp_vb->vb, 0),
|
|
+ dec->consumed, dec->remained_size);
|
|
+ else
|
|
+ s5p_mfc_set_dec_stream_buffer(ctx,
|
|
+ s5p_mfc_mem_plane_addr(ctx, &temp_vb->vb, 0), 0, 0);
|
|
}
|
|
|
|
if (dec->is_dynamic_dpb) {
|
|
@@ -3130,21 +3333,6 @@ static inline int s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
|
|
return 0;
|
|
}
|
|
|
|
-static inline void s5p_mfc_set_stride_enc(struct s5p_mfc_ctx *ctx)
|
|
-{
|
|
- struct s5p_mfc_dev *dev = ctx->dev;
|
|
- int i;
|
|
-
|
|
- if (IS_MFCv7X(dev) || IS_MFCV8(dev)) {
|
|
- for (i = 0; i < ctx->raw_buf.num_planes; i++) {
|
|
- WRITEL(ctx->raw_buf.stride[i],
|
|
- S5P_FIMV_E_SOURCE_FIRST_STRIDE + (i * 4));
|
|
- mfc_debug(2, "enc src[%d] stride: 0x%08lx",
|
|
- i, (unsigned long)ctx->raw_buf.stride[i]);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
static inline int s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
|
|
{
|
|
struct s5p_mfc_dev *dev = ctx->dev;
|
|
@@ -3156,6 +3344,12 @@ static inline int s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
|
|
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
|
|
+ if (list_empty(&ctx->dst_queue)) {
|
|
+ mfc_debug(2, "no dst buffers.\n");
|
|
+ spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
+ return -EAGAIN;
|
|
+ }
|
|
+
|
|
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
|
|
dst_addr = s5p_mfc_mem_plane_addr(ctx, &dst_mb->vb, 0);
|
|
dst_size = (unsigned int)vb2_plane_size(&dst_mb->vb, 0);
|
|
@@ -3386,6 +3580,7 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
|
|
ret = s5p_mfc_run_dec_last_frames(ctx);
|
|
break;
|
|
case MFCINST_RUNNING:
|
|
+ case MFCINST_SPECIAL_PARSING_NAL:
|
|
ret = s5p_mfc_run_dec_frame(ctx);
|
|
break;
|
|
case MFCINST_INIT:
|
|
@@ -3395,6 +3590,7 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
|
|
ret = s5p_mfc_close_inst(ctx);
|
|
break;
|
|
case MFCINST_GOT_INST:
|
|
+ case MFCINST_SPECIAL_PARSING:
|
|
ret = s5p_mfc_run_init_dec(ctx);
|
|
break;
|
|
case MFCINST_HEAD_PARSED:
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index b20f72fe2647..6a94096d89e4
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
|
|
@@ -152,6 +152,7 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
|
|
#define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1)
|
|
#define ENC_MULTI_SLICE_BIT_MIN 2800
|
|
#define ENC_MULTI_SLICE_BYTE_MIN 350
|
|
+#define ENC_MULTI_SLICE_MB_ROW_MAX 255
|
|
#define ENC_INTRA_REFRESH_MB_MAX ((1 << 18) - 1)
|
|
#define ENC_VBV_BUF_SIZE_MAX ((1 << 30) - 1)
|
|
#define ENC_H264_LOOP_FILTER_AB_MIN -12
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index ac0ac5b78663..1933c1bbef58
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
|
|
@@ -151,6 +151,7 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
|
|
#define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1)
|
|
#define ENC_MULTI_SLICE_BIT_MIN 2800
|
|
#define ENC_MULTI_SLICE_BYTE_MIN 350
|
|
+#define ENC_MULTI_SLICE_MB_ROW_MAX 255
|
|
#define ENC_INTRA_REFRESH_MB_MAX ((1 << 18) - 1)
|
|
#define ENC_VBV_BUF_SIZE_MAX ((1 << 30) - 1)
|
|
#define ENC_H264_LOOP_FILTER_AB_MIN -12
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 7644451748d1..9c47ba8fcc3c
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
|
|
@@ -148,28 +148,9 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
|
|
} while (0)
|
|
|
|
/* Definition */
|
|
-#define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1)
|
|
-#define ENC_MULTI_SLICE_BIT_MIN 2800
|
|
-#define ENC_MULTI_SLICE_BYTE_MIN 350
|
|
-#define ENC_INTRA_REFRESH_MB_MAX ((1 << 18) - 1)
|
|
-#define ENC_VBV_BUF_SIZE_MAX ((1 << 30) - 1)
|
|
-#define ENC_H264_LOOP_FILTER_AB_MIN -12
|
|
-#define ENC_H264_LOOP_FILTER_AB_MAX 12
|
|
-#define ENC_H264_RC_FRAME_RATE_MAX ((1 << 16) - 1)
|
|
-#define ENC_H263_RC_FRAME_RATE_MAX ((1 << 16) - 1)
|
|
-#define ENC_H264_PROFILE_MAX 3
|
|
-#define ENC_H264_LEVEL_MAX 42
|
|
-#define ENC_MPEG4_VOP_TIME_RES_MAX ((1 << 16) - 1)
|
|
#define FRAME_DELTA_DEFAULT 1
|
|
#define TIGHT_CBR_MAX 10
|
|
#define I_LIMIT_CBR_MAX 5
|
|
-#define ENC_HEVC_RC_FRAME_RATE_MAX ((1 << 16) - 1)
|
|
-#define ENC_HEVC_QP_INDEX_MIN -12
|
|
-#define ENC_HEVC_QP_INDEX_MAX 12
|
|
-#define ENC_HEVC_LOOP_FILTER_MIN -12
|
|
-#define ENC_HEVC_LOOP_FILTER_MAX 12
|
|
-#define ENC_HEVC_RC_FRAME_RATE_MAX ((1 << 16) - 1)
|
|
-#define ENC_HEVC_LEVEL_MAX 62
|
|
|
|
/* Definitions for shared memory compatibility */
|
|
#define PIC_TIME_TOP S5P_FIMV_D_RET_PICTURE_TAG_TOP
|
|
@@ -233,12 +214,6 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
|
|
#define ENC_HEVC_ME_SIZE(x, y) \
|
|
((((x * 32 / 8 + 63) / 64 * 64) * ((y * 8) + 64)) + (x * y * 32))
|
|
|
|
-/* MV range is [16,256] for v6.1, [16,128] for v6.5 */
|
|
-#define ENC_V61_MV_RANGE 256
|
|
-#define ENC_V65_MV_RANGE 128
|
|
-/* MV range is [16,32] for v7.8 */
|
|
-#define ENC_V78_MV_RANGE 32
|
|
-
|
|
#define NUM_MPEG4_LF_BUF 2
|
|
|
|
/* Scratch buffer size for MFC v8.0 */
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_pm.c b/drivers/media/platform/exynos/mfc/s5p_mfc_pm.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_pm.h b/drivers/media/platform/exynos/mfc/s5p_mfc_pm.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index cce9e2f0d831..7ad9a83a7e8e
|
|
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
|
|
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
|
|
@@ -36,7 +36,9 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
|
|
struct s5p_mfc_platdata *pdata = dev->pdata;
|
|
struct s5p_mfc_qos *qos_table = pdata->qos_table;
|
|
|
|
- if (ctx->buf_process_type & MFCBUFPROC_COPY) {
|
|
+ if (ctx->qos_changed)
|
|
+ ctx->qos_changed = 0;
|
|
+ if (ctx->use_extra_qos) {
|
|
if (pdata->qos_extra[idx].thrd_mb != MFC_QOS_FLAG_NODATA) {
|
|
qos_table = pdata->qos_extra;
|
|
#ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
|
|
@@ -85,7 +87,7 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
|
|
qos_table[idx].freq_kfc);
|
|
#endif
|
|
atomic_set(&dev->qos_req_cur, idx + 1);
|
|
- mfc_dbg_ctx("QoS request: %d\n", idx + 1);
|
|
+ mfc_info_ctx("QoS request: %d\n", idx + 1);
|
|
break;
|
|
case MFC_QOS_UPDATE:
|
|
if (dev->curr_rate < qos_table[idx].freq_mfc) {
|
|
@@ -131,7 +133,7 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
|
|
qos_table[idx].freq_kfc);
|
|
#endif
|
|
atomic_set(&dev->qos_req_cur, idx + 1);
|
|
- mfc_dbg_ctx("QoS update: %d\n", idx + 1);
|
|
+ mfc_info_ctx("QoS update: %d\n", idx + 1);
|
|
break;
|
|
case MFC_QOS_REMOVE:
|
|
MFC_TRACE_CTX("++ QOS remove(prev mfc:%d)\n",
|
|
@@ -154,7 +156,7 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
|
|
pm_qos_remove_request(&dev->qos_req_cluster0);
|
|
#endif
|
|
atomic_set(&dev->qos_req_cur, 0);
|
|
- mfc_dbg_ctx("QoS remove\n");
|
|
+ mfc_info_ctx("QoS remove\n");
|
|
break;
|
|
default:
|
|
mfc_err_ctx("Unknown request for opr [%d]\n", opr_type);
|
|
@@ -173,7 +175,7 @@ static void mfc_qos_print(struct s5p_mfc_ctx *ctx,
|
|
qos_table[index].freq_cpu);
|
|
#endif
|
|
#ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
|
|
- mfc_dbg_ctx("\tint: %d(%d), mif: %d, cpu: %d, kfc: %d\n",
|
|
+ mfc_info_ctx("\tint: %d(%d), mif: %d, cpu: %d, kfc: %d\n",
|
|
qos_table[index].freq_int,
|
|
qos_table[index].freq_mfc,
|
|
qos_table[index].freq_mif,
|
|
@@ -211,6 +213,9 @@ static void mfc_qos_add_or_update(struct s5p_mfc_ctx *ctx, int total_mb)
|
|
} else if (atomic_read(&dev->qos_req_cur) != (i + 1)) {
|
|
mfc_qos_print(ctx, qos_table, i);
|
|
mfc_qos_operate(ctx, MFC_QOS_UPDATE, i);
|
|
+ } else if (atomic_read(&dev->qos_req_cur) == (i + 1) &&
|
|
+ ctx->qos_changed) {
|
|
+ mfc_qos_operate(ctx, MFC_QOS_UPDATE, i);
|
|
}
|
|
break;
|
|
}
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_shm.c b/drivers/media/platform/exynos/mfc/s5p_mfc_shm.c
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_shm.h b/drivers/media/platform/exynos/mfc/s5p_mfc_shm.h
|
|
old mode 100644
|
|
new mode 100755
|
|
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 69bd5bb0d5af..90c6ccfd97d6
|
|
--- a/include/uapi/linux/v4l2-controls.h
|
|
+++ b/include/uapi/linux/v4l2-controls.h
|
|
@@ -358,8 +358,9 @@ enum v4l2_mpeg_video_header_mode {
|
|
#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221)
|
|
enum v4l2_mpeg_video_multi_slice_mode {
|
|
V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0,
|
|
- V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1,
|
|
- V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2,
|
|
+ V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB = 1,
|
|
+ V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES = 2,
|
|
+ V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW = 3,
|
|
};
|
|
#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222)
|
|
#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223)
|
|
@@ -431,6 +432,7 @@ enum v4l2_mpeg_video_h264_profile {
|
|
V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14,
|
|
V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15,
|
|
V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16,
|
|
+ V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH = 17,
|
|
};
|
|
#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364)
|
|
#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365)
|
|
diff --git a/include/uapi/linux/videodev2_exynos_media.h b/include/uapi/linux/videodev2_exynos_media.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index abb64fdc078f..21927206676a
|
|
--- a/include/uapi/linux/videodev2_exynos_media.h
|
|
+++ b/include/uapi/linux/videodev2_exynos_media.h
|
|
@@ -322,6 +322,26 @@ enum v4l2_mpeg_mfc51_video_frame_type {
|
|
(V4L2_CID_MPEG_MFC_BASE + 97)
|
|
#define V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE \
|
|
(V4L2_CID_MPEG_MFC_BASE + 98)
|
|
+#define V4L2_CID_MPEG_MFC_GET_10BIT_INFO \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 99)
|
|
+#define V4L2_CID_MPEG_MFC_H264_ENABLE_LTR \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 100)
|
|
+#define V4L2_CID_MPEG_MFC_H264_MARK_LTR \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 101)
|
|
+#define V4L2_CID_MPEG_MFC_H264_USE_LTR \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 102)
|
|
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 103)
|
|
+#define V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 104)
|
|
+#define V4L2_CID_MPEG_MFC_CONFIG_QP \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 105)
|
|
+#define V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 106)
|
|
+#define V4L2_CID_MPEG_MFC_GET_DRIVER_INFO \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 107)
|
|
+#define V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 108)
|
|
|
|
/* CIDs for HEVC encoding. Number gaps are for compatibility */
|
|
|
|
@@ -339,12 +359,14 @@ enum v4l2_mpeg_mfc51_video_frame_type {
|
|
(V4L2_CID_MPEG_MFC_BASE + 115)
|
|
#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE \
|
|
(V4L2_CID_MPEG_MFC_BASE + 116)
|
|
+enum v4l2_mpeg_video_hevc_hierarchical_coding_type {
|
|
+ V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B = 0,
|
|
+ V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P = 1,
|
|
+};
|
|
#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER \
|
|
(V4L2_CID_MPEG_MFC_BASE + 117)
|
|
#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP \
|
|
(V4L2_CID_MPEG_MFC_BASE + 118)
|
|
-#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT \
|
|
- (V4L2_CID_MPEG_MFC_BASE + 119)
|
|
#define V4L2_CID_MPEG_VIDEO_HEVC_PROFILE \
|
|
(V4L2_CID_MPEG_MFC_BASE + 120)
|
|
#define V4L2_CID_MPEG_VIDEO_HEVC_LEVEL \
|
|
@@ -411,4 +433,106 @@ enum v4l2_mpeg_mfc51_video_frame_type {
|
|
(V4L2_CID_MPEG_MFC_BASE + 151)
|
|
#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD \
|
|
(V4L2_CID_MPEG_MFC_BASE + 152)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 153)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 154)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 155)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 156)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 157)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 158)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 159)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 160)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 161)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_VERSION \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 163)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 164)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_MIN_QP \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 165)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_QP \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 166)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 167)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 168)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 169)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 170)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 171)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 172)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 173)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 174)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 175)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 176)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 177)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2 \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 178)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 179)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 180)
|
|
+#define V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 181)
|
|
+
|
|
+/* CIDs for new common interface */
|
|
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 193)
|
|
+#define V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 194)
|
|
+#define V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 195)
|
|
+
|
|
+/* QP BOUND interface */
|
|
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 201)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 202)
|
|
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 203)
|
|
+#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 204)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 205)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 206)
|
|
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 207)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 208)
|
|
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 209)
|
|
+#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 210)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 211)
|
|
+#define V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 212)
|
|
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 213)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 214)
|
|
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 215)
|
|
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 216)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 217)
|
|
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B \
|
|
+ (V4L2_CID_MPEG_MFC_BASE + 218)
|
|
#endif /* __LINUX_VIDEODEV2_EXYNOS_MEDIA_H */
|
|
--
|
|
2.20.1
|
|
|