amlogic/deinterlace: Don't bypass if the stream is mixed Interlaced and Progressive
authorRay <1458889+rayelec@users.noreply.github.com>
Wed, 5 Jun 2019 09:15:04 +0000 (11:15 +0200)
committerNick Xie <nick@khadas.com>
Fri, 12 Jul 2019 05:37:05 +0000 (13:37 +0800)
It fixes slowdowns on I/P switching.
Some UK streams switch between I and P (mostly) in commercials. 98% of
the stream is still interlaced so it is safe to DI the whole stream.

drivers/amlogic/media/deinterlace/deinterlace.c

index 9f189d0..a977c31 100644 (file)
@@ -1520,9 +1520,11 @@ static unsigned char is_source_change(vframe_t *vframe)
        ((di_pre_stru.cur_inp_type & VIDTYPE_VIU_FIELD) !=
        (vframe->type & VIDTYPE_VIU_FIELD))
        ) {
-               /* just scan mode changed */
-               if (!di_pre_stru.force_interlace)
-                       pr_dbg("DI I<->P.\n");
+               if (is_progressive(vframe)) {
+                       pr_dbg("DI I->P.\n");
+               } else {
+                       pr_dbg("DI P->I.\n");
+               }
                return 2;
        }
        return 0;
@@ -1553,7 +1555,9 @@ unsigned char is_bypass(vframe_t *vf_in)
 
        if (bypass_all)
                return 1;
-       if (di_pre_stru.cur_prog_flag)
+
+       if ((di_pre_stru.cur_prog_flag) &&
+          (!di_pre_stru.force_interlace))
                return 1;
 
        if ((di_pre_stru.cur_width < 16) || (di_pre_stru.cur_height < 16))
@@ -3384,7 +3388,6 @@ static unsigned char pre_de_buf_config(void)
 #endif
                    )
                        return 0;
-
                di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false);
        } else if (di_pre_stru.prog_proc_type == 2) {
                di_linked_buf_idx = peek_free_linked_buf();
@@ -3516,8 +3519,11 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
                queue_out(di_buf);
                change_type = is_source_change(vframe);
                /* source change, when i mix p,force p as i*/
-               if (change_type == 1 || (change_type == 2 &&
-                                        di_pre_stru.cur_prog_flag == 1)) {
+               if (change_type == 1 || (change_type == 2)) {
+                       /* check if top/bot interleaved */
+                       if (change_type == 2)
+                               /* source is i interleaves p fields */
+                               di_pre_stru.force_interlace = true;
                        if (di_pre_stru.di_mem_buf_dup_p) {
                                /*avoid only 2 i field then p field*/
                                if (
@@ -3610,10 +3616,6 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
 #endif
                        di_pre_stru.field_count_for_cont = 0;
                } else if (di_pre_stru.cur_prog_flag == 0) {
-                       /* check if top/bot interleaved */
-                       if (change_type == 2)
-                               /* source is i interleaves p fields */
-                               di_pre_stru.force_interlace = true;
                        if ((di_pre_stru.cur_inp_type &
                        VIDTYPE_TYPEMASK) == (di_buf->vframe->type &
                        VIDTYPE_TYPEMASK)) {
@@ -3791,6 +3793,7 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
                                di_pre_stru.field_count_for_cont = 0;
                                /* ignore contp2rd and contprd */
                        }
+
                        di_buf->post_proc_flag = 1;
                        di_pre_stru.di_inp_buf = di_buf;
                        di_print("%s: %s[%d] => di_inp_buf\n", __func__,