mjpeg: CF1 mjpeg unsupport yuv422 && uv1:1 stream [1/1]

PD#SWPL-187606

Problem:
mjpeg unsupport yuv422 && uv1:1 stream

Solution:
decoder reports unsupported information to player,
player quits decoding.

Verify:
ohm

SourceCode:
ucode:
0.4.167-g72c72fe
I66376
I6f63f
Idbdf0
I33830
I3f33a

Change-Id: I4722f985cb999fa9fc3d5e5de06970624393e4a6
Signed-off-by: xing.xu <xing.xu@amlogic.com>
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index 7b68c08..3c6daad 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -117,6 +117,11 @@
 #define INVALID_IDX -1
 #define DEMUX_ES_MAGIC_NUM 0x5a5a5a5a
 
+/*
+ *MJPEG only supports streams with 1:1 horizontal and vertical sampling.
+*/
+#define MJPEG_SUPPORTS_HV_SAMPLE	0x11
+
 #define call_void_memop(vb, op, args...)				\
 	do {								\
 		if ((vb)->vb2_queue->mem_ops->op)			\
@@ -3706,6 +3711,14 @@
 				"The width or height of the stream is less than 16\n");
 			return -EPERM;
 		}
+
+		if ((ctx->picinfo.profile_idc != MJPEG_SUPPORTS_HV_SAMPLE) &&
+			ctx->output_pix_fmt == V4L2_PIX_FMT_MJPEG) {
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+				"amvdec_mmjpeg: unsupport uv %d:%d\n",
+				ctx->picinfo.profile_idc >> 4, ctx->picinfo.profile_idc & 0xf);
+			return -EPERM;
+		}
 	}
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index 9e0301f..08d7236 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -515,6 +515,7 @@
  * E.g. suppose picture size is 176x144,
  *      buffer size will be aligned to 176x160.
  * @profile_idc: source profile level
+ *      MJPEG profile_idc stores data for YUV horizontal and vertical sampling
  * @field: frame/field information.
  * @dpb_frames: used for DPB size of calculation.
  * @dpb_margin: extra buffers for decoder.
diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
index 6bd4851..f8eb70e 100644
--- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -555,6 +555,7 @@
 	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
+	pic->profile_idc	= ps->profile;
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
index a14daa0..cb295cd 100644
--- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
+++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
@@ -81,6 +81,11 @@
 #define DECODE_BUFFER_NUM_DEF		1
 #define MAX_BMMU_BUFFER_NUM		(DECODE_BUFFER_NUM_MAX + 1)
 
+/*
+ *MJPEG only supports streams with 1:1 horizontal and vertical sampling.
+*/
+#define MJPEG_SUPPORTS_HV_SAMPLE	0x11
+
 #define DEFAULT_MEM_SIZE	(32*SZ_1M)
 #define RP_WORKAROUND_SIZE  SZ_4K
 static int debug_enable;
@@ -160,6 +165,7 @@
 #define DEC_RESULT_ERROR            3
 #define DEC_RESULT_FORCE_EXIT       4
 #define DEC_RESULT_EOS              5
+#define DEC_RESULT_ERROR_DATA       6
 #define DEC_DECODE_TIMEOUT         0x21
 
 /*Send by DEC_STATUS_REG*/
@@ -245,6 +251,7 @@
 	char new_q_name[32];
 	char disp_q_name[32];
 	bool run_flag;
+	int unsupport_flag;
 };
 
 static void reset_process_time(struct vdec_mjpeg_hw_s *hw);
@@ -322,6 +329,18 @@
 	}
 
 	if (dec_status == MJPEG_CONFIG_REQUEST) {
+		int comps_spec_cb = READ_VREG(AV_SCRATCH_M) & 0xff;
+
+		if (comps_spec_cb != MJPEG_SUPPORTS_HV_SAMPLE) {
+			hw->dec_result = DEC_RESULT_ERROR_DATA;
+			mmjpeg_debug_print(DECODE_ID(hw), 0,
+				"amvdec_mmjpeg: unsupport uv %d:%d\n", comps_spec_cb >> 4, comps_spec_cb&0xf);
+			hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
+			vdec_schedule_work(&hw->work);
+			hw->run_flag = 0;
+			hw->unsupport_flag = 1;
+			return IRQ_HANDLED;
+		}
 		WRITE_VREG(DEC_STATUS_REG, 0);
 		return IRQ_HANDLED;
 	} else if (dec_status == MJPEG_DATA_EMPTY) {
@@ -1105,6 +1124,7 @@
 	hw->input_empty = 0;
 	hw->peek_num = 0;
 	hw->get_num = 0;
+	hw->unsupport_flag = 0;
 	for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
 		hw->vfbuf_use[i] = 0;
 
@@ -1152,6 +1172,10 @@
 	hw->not_run_ready++;
 	if (hw->eos)
 		return 0;
+
+	if (hw->unsupport_flag)
+		return 0;
+
 	if (vdec_stream_based(vdec) && (hw->init_flag == 0)
 		&& pre_decode_buf_level != 0) {
 		u32 rp, wp, level;
@@ -1380,6 +1404,10 @@
 		vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
 		hw->chunk = NULL;
 		vdec_clean_input(hw_to_vdec(hw));
+	} else if (hw->dec_result == DEC_RESULT_ERROR_DATA) {
+		amvdec_stop();
+		vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+		hw->chunk = NULL;
 	}
 	if (hw->stat & STAT_VDEC_RUN) {
 		amvdec_stop();
diff --git a/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c
index eb7de8d..2d6fd7b 100644
--- a/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c
+++ b/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c
@@ -342,7 +342,7 @@
 	return IRQ_WAKE_THREAD;
 }
 
-static int vmjpeg_get_ps_info(struct vdec_mjpeg_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps)
+static int vmjpeg_get_ps_info(struct vdec_mjpeg_hw_s *hw, int width, int height, int hv_subsample, struct aml_vdec_ps_infos *ps)
 {
 	ps->visible_width	= width;
 	ps->visible_height	= height;
@@ -351,12 +351,13 @@
 	ps->dpb_size 		= hw->buf_num;
 	ps->dpb_frames		= DECODE_BUFFER_NUM_DEF;
 	ps->dpb_margin		= hw->dynamic_buf_num_margin;
-	ps->field = V4L2_FIELD_NONE;
+	ps->field		= V4L2_FIELD_NONE;
+	ps->profile		= hv_subsample;
 
 	return 0;
 }
 
-static int v4l_res_change(struct vdec_mjpeg_hw_s *hw, int width, int height)
+static int v4l_res_change(struct vdec_mjpeg_hw_s *hw, int width, int height, int hv_subsample)
 {
 	struct aml_vcodec_ctx *ctx =
 			(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
@@ -375,7 +376,7 @@
 				hw->frame_width, hw->frame_height,
 				width,
 				height);
-			vmjpeg_get_ps_info(hw, width, height, &ps);
+			vmjpeg_get_ps_info(hw, width, height, hv_subsample, &ps);
 			vdec_v4l_set_ps_infos(ctx, &ps);
 			vdec_v4l_res_ch_event(ctx);
 			hw->v4l_params_parsed = false;
@@ -415,14 +416,15 @@
 	if (dec_status == MJPEG_CONFIG_REQUEST) {
 		int frame_width = READ_VREG(MREG_PIC_WIDTH);
 		int frame_height = READ_VREG(MREG_PIC_HEIGHT);
+		int hv_subsample = READ_VREG(AV_SCRATCH_M)  & 0xff;
 
-		if (!v4l_res_change(hw, frame_width, frame_height)) {
+		if (!v4l_res_change(hw, frame_width, frame_height, hv_subsample)) {
 			struct aml_vcodec_ctx *ctx =
 				(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
 			if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
 				struct aml_vdec_ps_infos ps;
 
-				vmjpeg_get_ps_info(hw, frame_width, frame_height, &ps);
+				vmjpeg_get_ps_info(hw, frame_width, frame_height, hv_subsample, &ps);
 				hw->v4l_params_parsed = true;
 				vdec_v4l_set_ps_infos(ctx, &ps);
 				ctx->decoder_status_info.frame_height = ps.visible_height;
diff --git a/firmware/A311D2/video_ucode.bin b/firmware/A311D2/video_ucode.bin
index d6c83e5..f6451fa 100644
--- a/firmware/A311D2/video_ucode.bin
+++ b/firmware/A311D2/video_ucode.bin
Binary files differ
diff --git a/firmware/A311D2J/video_ucode.bin b/firmware/A311D2J/video_ucode.bin
index 0f2c0ce..c086cd8 100644
--- a/firmware/A311D2J/video_ucode.bin
+++ b/firmware/A311D2J/video_ucode.bin
Binary files differ
diff --git a/firmware/POP1/video_ucode.bin b/firmware/POP1/video_ucode.bin
index edff5e3..38f88c5 100644
--- a/firmware/POP1/video_ucode.bin
+++ b/firmware/POP1/video_ucode.bin
Binary files differ
diff --git a/firmware/S805C1/video_ucode.bin b/firmware/S805C1/video_ucode.bin
index f473c87..0ff3025 100644
--- a/firmware/S805C1/video_ucode.bin
+++ b/firmware/S805C1/video_ucode.bin
Binary files differ
diff --git a/firmware/S805C1A/video_ucode.bin b/firmware/S805C1A/video_ucode.bin
index d5aa7eb..36fa746 100644
--- a/firmware/S805C1A/video_ucode.bin
+++ b/firmware/S805C1A/video_ucode.bin
Binary files differ
diff --git a/firmware/S805C1ENG/video_ucode.bin b/firmware/S805C1ENG/video_ucode.bin
index f473c87..0ff3025 100644
--- a/firmware/S805C1ENG/video_ucode.bin
+++ b/firmware/S805C1ENG/video_ucode.bin
Binary files differ
diff --git a/firmware/S805C3/video_ucode.bin b/firmware/S805C3/video_ucode.bin
index 36d54c3..122c7df 100644
--- a/firmware/S805C3/video_ucode.bin
+++ b/firmware/S805C3/video_ucode.bin
Binary files differ
diff --git a/firmware/S805C3L/video_ucode.bin b/firmware/S805C3L/video_ucode.bin
index bba4fcd..f0ebdd6 100644
--- a/firmware/S805C3L/video_ucode.bin
+++ b/firmware/S805C3L/video_ucode.bin
Binary files differ
diff --git a/firmware/S805X2/video_ucode.bin b/firmware/S805X2/video_ucode.bin
index ee0e226..be406ee 100644
--- a/firmware/S805X2/video_ucode.bin
+++ b/firmware/S805X2/video_ucode.bin
Binary files differ
diff --git a/firmware/S805X2G/video_ucode.bin b/firmware/S805X2G/video_ucode.bin
index b4cfbce..270cd47 100644
--- a/firmware/S805X2G/video_ucode.bin
+++ b/firmware/S805X2G/video_ucode.bin
Binary files differ
diff --git a/firmware/S805X3/video_ucode.bin b/firmware/S805X3/video_ucode.bin
index d872ac2..fbe9555 100644
--- a/firmware/S805X3/video_ucode.bin
+++ b/firmware/S805X3/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C2/video_ucode.bin b/firmware/S905C2/video_ucode.bin
index e3f6ef5..41d94fe 100644
--- a/firmware/S905C2/video_ucode.bin
+++ b/firmware/S905C2/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C2ENG/video_ucode.bin b/firmware/S905C2ENG/video_ucode.bin
index 0ca0ef8..e5c6aaa 100644
--- a/firmware/S905C2ENG/video_ucode.bin
+++ b/firmware/S905C2ENG/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C2L/video_ucode.bin b/firmware/S905C2L/video_ucode.bin
index ef32449..c273c4f 100644
--- a/firmware/S905C2L/video_ucode.bin
+++ b/firmware/S905C2L/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C3/video_ucode.bin b/firmware/S905C3/video_ucode.bin
index 5764620..8b4285b 100644
--- a/firmware/S905C3/video_ucode.bin
+++ b/firmware/S905C3/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C3ENG/video_ucode.bin b/firmware/S905C3ENG/video_ucode.bin
index 2af624c..57f5f5a 100644
--- a/firmware/S905C3ENG/video_ucode.bin
+++ b/firmware/S905C3ENG/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C3NMA/video_ucode.bin b/firmware/S905C3NMA/video_ucode.bin
index 5e1dac1..22db940 100644
--- a/firmware/S905C3NMA/video_ucode.bin
+++ b/firmware/S905C3NMA/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C5/video_ucode.bin b/firmware/S905C5/video_ucode.bin
index 78124f4..112bb56 100644
--- a/firmware/S905C5/video_ucode.bin
+++ b/firmware/S905C5/video_ucode.bin
Binary files differ
diff --git a/firmware/S905C5ENG/video_ucode.bin b/firmware/S905C5ENG/video_ucode.bin
index 0465ecf..348e51b 100644
--- a/firmware/S905C5ENG/video_ucode.bin
+++ b/firmware/S905C5ENG/video_ucode.bin
Binary files differ
diff --git a/firmware/S905D5/video_ucode.bin b/firmware/S905D5/video_ucode.bin
index 850f74e..585f0f8 100644
--- a/firmware/S905D5/video_ucode.bin
+++ b/firmware/S905D5/video_ucode.bin
Binary files differ
diff --git a/firmware/S905W2/video_ucode.bin b/firmware/S905W2/video_ucode.bin
index 53e22e5..d0c71a5 100644
--- a/firmware/S905W2/video_ucode.bin
+++ b/firmware/S905W2/video_ucode.bin
Binary files differ
diff --git a/firmware/S905X4/video_ucode.bin b/firmware/S905X4/video_ucode.bin
index 4833fe9..4bf4f31 100644
--- a/firmware/S905X4/video_ucode.bin
+++ b/firmware/S905X4/video_ucode.bin
Binary files differ
diff --git a/firmware/S905X5/video_ucode.bin b/firmware/S905X5/video_ucode.bin
index 569ee99..0515cbe 100644
--- a/firmware/S905X5/video_ucode.bin
+++ b/firmware/S905X5/video_ucode.bin
Binary files differ
diff --git a/firmware/S905X5L/video_ucode.bin b/firmware/S905X5L/video_ucode.bin
index 13989ed..fb2afa7 100644
--- a/firmware/S905X5L/video_ucode.bin
+++ b/firmware/S905X5L/video_ucode.bin
Binary files differ
diff --git a/firmware/S905X5M/video_ucode.bin b/firmware/S905X5M/video_ucode.bin
index b1e9b20..4d3cc9e 100644
--- a/firmware/S905X5M/video_ucode.bin
+++ b/firmware/S905X5M/video_ucode.bin
Binary files differ
diff --git a/firmware/S905X5MENG/video_ucode.bin b/firmware/S905X5MENG/video_ucode.bin
index 12f4764..be4fb24 100644
--- a/firmware/S905X5MENG/video_ucode.bin
+++ b/firmware/S905X5MENG/video_ucode.bin
Binary files differ
diff --git a/firmware/S905Y4/video_ucode.bin b/firmware/S905Y4/video_ucode.bin
index 0fffe23..3da0107 100644
--- a/firmware/S905Y4/video_ucode.bin
+++ b/firmware/S905Y4/video_ucode.bin
Binary files differ
diff --git a/firmware/S905Y5/video_ucode.bin b/firmware/S905Y5/video_ucode.bin
index 0a26458..b081440 100644
--- a/firmware/S905Y5/video_ucode.bin
+++ b/firmware/S905Y5/video_ucode.bin
Binary files differ
diff --git a/firmware/S905Y5ENG/video_ucode.bin b/firmware/S905Y5ENG/video_ucode.bin
index 3d977a1..edce903 100644
--- a/firmware/S905Y5ENG/video_ucode.bin
+++ b/firmware/S905Y5ENG/video_ucode.bin
Binary files differ
diff --git a/firmware/S905Y5R/video_ucode.bin b/firmware/S905Y5R/video_ucode.bin
index d31334f..8261322 100644
--- a/firmware/S905Y5R/video_ucode.bin
+++ b/firmware/S905Y5R/video_ucode.bin
Binary files differ
diff --git a/firmware/S928X/video_ucode.bin b/firmware/S928X/video_ucode.bin
index 5e63840..26ab451 100644
--- a/firmware/S928X/video_ucode.bin
+++ b/firmware/S928X/video_ucode.bin
Binary files differ
diff --git a/firmware/S928XENG/video_ucode.bin b/firmware/S928XENG/video_ucode.bin
index d270b7c..678ebf3 100644
--- a/firmware/S928XENG/video_ucode.bin
+++ b/firmware/S928XENG/video_ucode.bin
Binary files differ
diff --git a/firmware/T950D5/video_ucode.bin b/firmware/T950D5/video_ucode.bin
index 7e1c4d8..b47d5c4 100644
--- a/firmware/T950D5/video_ucode.bin
+++ b/firmware/T950D5/video_ucode.bin
Binary files differ
diff --git a/firmware/T950D5Z/video_ucode.bin b/firmware/T950D5Z/video_ucode.bin
index a32fbff..516726c 100644
--- a/firmware/T950D5Z/video_ucode.bin
+++ b/firmware/T950D5Z/video_ucode.bin
Binary files differ
diff --git a/firmware/T950S/video_ucode.bin b/firmware/T950S/video_ucode.bin
index 3f4ba83..42860ed 100644
--- a/firmware/T950S/video_ucode.bin
+++ b/firmware/T950S/video_ucode.bin
Binary files differ
diff --git a/firmware/T962D4/video_ucode.bin b/firmware/T962D4/video_ucode.bin
index e593cdb..afadcef 100644
--- a/firmware/T962D4/video_ucode.bin
+++ b/firmware/T962D4/video_ucode.bin
Binary files differ
diff --git a/firmware/T963D4/video_ucode.bin b/firmware/T963D4/video_ucode.bin
index 82daf51..4b46db6 100644
--- a/firmware/T963D4/video_ucode.bin
+++ b/firmware/T963D4/video_ucode.bin
Binary files differ
diff --git a/firmware/T963D4ENG/video_ucode.bin b/firmware/T963D4ENG/video_ucode.bin
index 6c31405..e1fcb70 100644
--- a/firmware/T963D4ENG/video_ucode.bin
+++ b/firmware/T963D4ENG/video_ucode.bin
Binary files differ
diff --git a/firmware/T963D4Z/video_ucode.bin b/firmware/T963D4Z/video_ucode.bin
index a5d7b8a..cfca333 100644
--- a/firmware/T963D4Z/video_ucode.bin
+++ b/firmware/T963D4Z/video_ucode.bin
Binary files differ
diff --git a/firmware/T965D4/video_ucode.bin b/firmware/T965D4/video_ucode.bin
index feb6de0..1d29df3 100644
--- a/firmware/T965D4/video_ucode.bin
+++ b/firmware/T965D4/video_ucode.bin
Binary files differ
diff --git a/firmware/T968D4/video_ucode.bin b/firmware/T968D4/video_ucode.bin
index 11af2bf..47e711f 100644
--- a/firmware/T968D4/video_ucode.bin
+++ b/firmware/T968D4/video_ucode.bin
Binary files differ
diff --git a/firmware/T982/video_ucode.bin b/firmware/T982/video_ucode.bin
index 8731b0d..18213ea 100644
--- a/firmware/T982/video_ucode.bin
+++ b/firmware/T982/video_ucode.bin
Binary files differ
diff --git a/firmware/V918D/video_ucode.bin b/firmware/V918D/video_ucode.bin
index c58ff2a..03faf47 100644
--- a/firmware/V918D/video_ucode.bin
+++ b/firmware/V918D/video_ucode.bin
Binary files differ
diff --git a/firmware/video_ucode.bin b/firmware/video_ucode.bin
index e593cdb..afadcef 100644
--- a/firmware/video_ucode.bin
+++ b/firmware/video_ucode.bin
Binary files differ
diff --git a/version.txt b/version.txt
index bc0a46b..abe6fd0 100644
--- a/version.txt
+++ b/version.txt
@@ -1,7 +1,7 @@
-0.4.166-g5426238
+0.4.167-g72c72fe
 change id history:
+I66376
 I6f63f
 Idbdf0
 I33830
 I3f33a
-I73799