vdec: When one of the fields is empty, play the screen [1/1]
authoryuanfa.zhuang <yuanfa.zhuang@amlogic.com>
Thu, 14 Jan 2021 12:05:48 +0000 (20:05 +0800)
committerHui Zhang <hui.zhang@amlogic.com>
Wed, 20 Jan 2021 05:35:13 +0000 (21:35 -0800)
PD#SWPL-41227

Problem:
Interlaced stream is recognized as progressive,
when one of the fields is empty, the screen will be played

Solution:
When this happens, only a valid field is output

Verify:
U21BQ-S905X2

Signed-off-by: yuanfa.zhuang <yuanfa.zhuang@amlogic.com>
Change-Id: Ib5dacc09acf45ce2cddfa700b837961e87ffc106

drivers/frame_provider/decoder/h264_multi/vmh264.c

index b019a3830d853cf02b0e473eb672ad2a68eafdb6..21d3ac9c60776f26bdf621e5170a8551601b5e06 100644 (file)
@@ -2763,10 +2763,23 @@ static int post_prepare_process(struct vdec_s *vdec, struct FrameStore *frame)
        if (frame->frame == NULL &&
                        ((frame->is_used == 1 && frame->top_field)
                        || (frame->is_used == 2 && frame->bottom_field))) {
-                       dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
+               if (hw->i_only) {
+                       if (frame->is_used == 1)
+                               dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+                                       "%s   No bottom_field !!  frame_num %d  used %d\n",
+                                       __func__, frame->frame_num, frame->is_used);
+                       if (frame->is_used == 2)
+                               dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+                                       "%s   No top_field !!  frame_num %d  used %d\n",
+                                       __func__, frame->frame_num, frame->is_used);
+               }
+               else {
+                       frame->data_flag |= ERROR_FLAG;
+                               dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
                                "%s Error  frame_num %d  used %d\n",
                                __func__, frame->frame_num, frame->is_used);
-                       frame->data_flag |= ERROR_FLAG;
+               }
+
        }
        if (vdec_stream_based(vdec) && !(frame->data_flag & NODISP_FLAG)) {
                if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
@@ -3080,6 +3093,27 @@ static int post_video_frame(struct vdec_s *vdec, struct FrameStore *frame)
                                        vf->pts, vf->pts_us64, bForceInterlace);
                        }
                }
+
+               if (hw->i_only) {
+                       if (vf_count == 1 && frame->is_used == 1 && frame->top_field
+                               && frame->bottom_field == NULL && frame->frame == NULL) {
+                               vf->type =
+                                       VIDTYPE_INTERLACE_FIRST |
+                                       nv_order;
+                               vf->type |= VIDTYPE_INTERLACE_TOP;
+                               vf->duration = vf->duration/2;
+                       }
+
+                       if (vf_count == 1 && frame->is_used == 2 && frame->bottom_field
+                               && frame->top_field == NULL && frame->frame == NULL) {
+                               vf->type =
+                                       VIDTYPE_INTERLACE_FIRST |
+                                       nv_order;
+                               vf->type |= VIDTYPE_INTERLACE_BOTTOM;
+                               vf->duration = vf->duration/2;
+                       }
+               }
+
                if (i == 0) {
                        struct vdec_s *pvdec;
                        struct vdec_info vs;