deinterlace: optimize reset/light unreg flow [1/1]

PD#SWPL-14059

Problem:
video stuck after reset or light unreg.

Solution:
optimize reset/light unreg flow

Verify:
G12A

Change-Id: I982ef4ee618a25d0b562f70b5e7df0fad2d87278
Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>
This commit is contained in:
Jihong Sui
2019-09-16 11:20:43 +08:00
committed by Tao Zeng
parent 6c7d8691a1
commit 55ba0d911f
2 changed files with 82 additions and 14 deletions

View File

@@ -4633,10 +4633,16 @@ static int check_recycle_buf(void)
struct di_buf_s *di_buf = NULL;/* , *ptmp; */
int itmp;
int ret = 0;
bool blk_flg = 0;
#ifdef DI_KEEP_HIS
if (di_blocking)
return ret;
#endif
queue_for_each_entry(di_buf, ptmp, QUEUE_RECYCLE, list) {
if (di_blocking)
blk_flg = 1;
if ((di_buf->pre_ref_count == 0) &&
(di_buf->post_ref_count == 0)) {
if (di_buf->type == VFRAME_TYPE_IN) {
@@ -4688,6 +4694,10 @@ static int check_recycle_buf(void)
#endif
}
}
if (blk_flg)
pr_info("di:blk:recycle\n");
return ret;
}
@@ -7313,6 +7323,35 @@ static enum hrtimer_restart di_pre_hrtimer_func(struct hrtimer *timer)
di_patch_post_update_mc();
return HRTIMER_RESTART;
}
static void post_display_buf_clear(void)
{
struct di_buf_s *p = NULL;
int itmp;
pr_info("%s:\n", __func__);
queue_for_each_entry(p, ptmp, QUEUE_DISPLAY, list) {
pr_info("\t%s,%d\n", vframe_type_name[p->type], p->index);
if (p->type == VFRAME_TYPE_POST) {
if (!atomic_dec_and_test(&p->di_cnt))
di_print("%s,di_cnt > 0\n", __func__);
recycle_vframe_type_post(p);
} else {
queue_in(p, QUEUE_RECYCLE);
di_print("%s: %s[%d] =>recycle_list\n", __func__,
vframe_type_name[p->type], p->index);
}
}
}
static void dbg_check_list(void)
{
unsigned int post_display;
post_display = list_count(QUEUE_DISPLAY);
di_pr_info("display:%d\n", post_display);
}
/*
* provider/receiver interface
*/
@@ -7382,40 +7421,64 @@ static int di_receiver_event_fun(int type, void *data, void *arg)
mutex_unlock(&di_event_mutex);
pr_info("DI: unreg f\n");
} else if (type == VFRAME_EVENT_PROVIDER_RESET) {
di_blocking = 1;
/*di_blocking = 1;*/
mutex_lock(&di_event_mutex);
pr_info("%s: VFRAME_EVENT_PROVIDER_RESET\n", __func__);
if (is_bypass(NULL)
|| bypass_state
|| di_pre_stru.bypass_flag) {
/* only if di is bypassed, then we send the message of
* VFRAME_EVENT_PROVIDER_RESET to video and notify
* it to keep the last canvas buffer which was
* alloced by codec not by di.
*/
vf_notify_receiver(VFM_NAME,
VFRAME_EVENT_PROVIDER_RESET,
NULL);
di_blocking = 1;
spin_lock_irqsave(&plist_lock, flags);
post_display_buf_clear();
spin_unlock_irqrestore(&plist_lock, flags);
}
goto light_unreg;
} else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG) {
di_blocking = 1;
pr_info("%s: vf_notify_receiver ligth unreg\n", __func__);
light_unreg:
/*-----------------------------------*/
spin_lock_irqsave(&plist_lock, flags);
for (i = 0; i < MAX_IN_BUF_NUM; i++) {
if (vframe_in[i])
pr_dbg("DI:clear vframe_in[%d]\n", i);
pr_info("DI:clear vframe_in[%d]\n", i);
vframe_in[i] = NULL;
}
spin_unlock_irqrestore(&plist_lock, flags);
di_blocking = 0;
mutex_unlock(&di_event_mutex);
pr_info("\treset:end\n");
/*goto light_unreg;*/
} else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG) {
mutex_lock(&di_event_mutex);
di_blocking = 1;
pr_info("%s: LIGHT_UNREG\n", __func__);
/*light_unreg:*/
#if 1
spin_lock_irqsave(&plist_lock, flags);
for (i = 0; i < MAX_IN_BUF_NUM; i++) {
if (vframe_in[i])
pr_info("DI:clear vframe_in[%d]\n", i);
vframe_in[i] = NULL;
}
spin_unlock_irqrestore(&plist_lock, flags);
#endif
di_blocking = 0;
mutex_unlock(&di_event_mutex);
pr_info("\tlight unreg:end\n");
} else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME) {
unsigned char vf_put_flag = 0;
pr_dbg(
"%s:VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME\n",
__func__);
pr_info("%s:LIGHT_UNREG_RETURN_VFRAME\n", __func__);
/*
* do not display garbage when 2d->3d or 3d->2d
*/
@@ -7552,6 +7615,7 @@ light_unreg:
if (reg_flag) {
pr_err("[DI] no muti instance.\n");
mutex_unlock(&di_event_mutex);
dbg_check_list();
return -1;
}
pr_info("%s: vframe provider reg %s\n", __func__,
@@ -7873,8 +7937,10 @@ static void di_vf_put(vframe_t *vf, void *arg)
di_print("%s: 0x%p\n", __func__, vf);
return;
}
#ifdef DI_KEEP_HIS
if (di_blocking)
return;
#endif
log_buffer_state("pu_");
di_buf = (struct di_buf_s *)vf->private_data;
if (IS_ERR_OR_NULL(di_buf)) {

View File

@@ -473,4 +473,6 @@ struct di_buf_s *get_di_buf(int queue_idx, int *start_pos);
#define pr_error(fmt, args ...) pr_err("DI: " fmt, ## args)
/******************************************/
/*#define DI_KEEP_HIS 0*/
#endif