author | Shuide Chen <shuide.chen@amlogic.com> | 2018-10-30 09:22:13 (GMT) |
---|---|---|
committer | Gerrit Code Review <gituser@droid04> | 2018-10-30 09:22:13 (GMT) |
commit | 812222a3570125bb28a565cace8d2d3ac8db4b63 (patch) | |
tree | 73e0226d19552f8db5c933869dd2008645f8c9ff | |
parent | 1347c6a394290dcab8b0c96bcc5e96f7966ac24f (diff) | |
parent | 08324cb85dfa4a0845000b610aa41ffedecb362a (diff) | |
download | common-812222a3570125bb28a565cace8d2d3ac8db4b63.zip common-812222a3570125bb28a565cace8d2d3ac8db4b63.tar.gz common-812222a3570125bb28a565cace8d2d3ac8db4b63.tar.bz2 |
Merge "media: keep last normal frame before reset [2/2]" into p-amlogic
9 files changed, 88 insertions, 4 deletions
diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm.c b/drivers/amlogic/media/common/codec_mm/codec_mm.c index da7591c..62f07e1 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm.c @@ -729,6 +729,38 @@ void codec_mm_dma_flush(void *vaddr, } EXPORT_SYMBOL(codec_mm_dma_flush); +int codec_mm_has_owner(struct codec_mm_s *mem, const char *owner) +{ + int index; + int i; + unsigned long flags; + int is_owner = 0; + + struct codec_mm_mgt_s *mgt = get_mem_mgt(); + + if (mem) { + spin_lock_irqsave(&mgt->lock, flags); + if (!codec_mm_valid_mm_locked(mem)) { + spin_unlock_irqrestore(&mgt->lock, flags); + pr_err("codec mm %p not valied!\n", mem); + return 0; + } + + index = atomic_read(&mem->use_cnt); + + for (i = 0; i < index; i++) { + if (mem->owner[i] && + strcmp(owner, mem->owner[i]) == 0) { + is_owner = 1; + break; + } + } + spin_unlock_irqrestore(&mgt->lock, flags); + } + + return is_owner; +} + int codec_mm_request_shared_mem(struct codec_mm_s *mem, const char *owner) { struct codec_mm_mgt_s *mgt = get_mem_mgt(); diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm_keeper.c b/drivers/amlogic/media/common/codec_mm/codec_mm_keeper.c index be409ce..135ad2c 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm_keeper.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm_keeper.c @@ -56,6 +56,11 @@ static struct codec_mm_keeper_mgr *get_codec_mm_keeper_mgr(void) return &codec_keeper_mgr_private; } +int is_codec_mm_keeped(void *mem_handle) +{ + return codec_mm_has_owner(mem_handle, KEEP_NAME); +} +EXPORT_SYMBOL(is_codec_mm_keeped); /* *not call in interrupt; */ diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 95b48c8..c21b3e2 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -6413,6 +6413,13 @@ static int di_receiver_event_fun(int type, void *data, void *arg) di_blocking = 1; pr_dbg("%s: VFRAME_EVENT_PROVIDER_RESET\n", __func__); + if (is_bypass(NULL) + || bypass_state + || di_pre_stru.bypass_flag) { + vf_notify_receiver(VFM_NAME, + VFRAME_EVENT_PROVIDER_RESET, + NULL); + } goto light_unreg; } else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG) { diff --git a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c index 47d73cc..18befa0 100644 --- a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c +++ b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c @@ -530,6 +530,10 @@ static int ppmgr_receiver_event_fun(int type, void *data, void *private_data) break; case VFRAME_EVENT_PROVIDER_RESET: vf_ppmgr_reset(0); + vf_notify_receiver( + PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_RESET, + NULL); break; case VFRAME_EVENT_PROVIDER_FR_HINT: case VFRAME_EVENT_PROVIDER_FR_END_HINT: diff --git a/drivers/amlogic/media/video_processor/video_dev/amlvideo.c b/drivers/amlogic/media/video_processor/video_dev/amlvideo.c index c857498..252fa95 100644 --- a/drivers/amlogic/media/video_processor/video_dev/amlvideo.c +++ b/drivers/amlogic/media/video_processor/video_dev/amlvideo.c @@ -282,6 +282,13 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) } else if (type == VFRAME_EVENT_PROVIDER_FR_END_HINT) { vf_notify_receiver(dev->vf_provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, data); + } else if (type == VFRAME_EVENT_PROVIDER_RESET) { + dev->first_frame = 0; + vfq_init(&dev->q_ready, AMLVIDEO_POOL_SIZE + 1, + &dev->amlvideo_pool_ready[0]); + + vf_notify_receiver(dev->vf_provider_name, + VFRAME_EVENT_PROVIDER_RESET, data); } return 0; } @@ -541,6 +548,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) mutex_unlock(&dev->vfpMutex); return -EAGAIN; } + + if (dev->vf->index == 0xFFFFFFFF) { + pr_info("vidioc_dqbuf: Invalid vf\n"); + return -EAGAIN; + } + dev->vf->omx_index = dev->frame_num; dev->am_parm.signal_type = dev->vf->signal_type; dev->am_parm.master_display_colour diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 707dc9b..0c35c03 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -6685,10 +6685,17 @@ static void video_vf_unreg_provider(void) #endif } -static void video_vf_light_unreg_provider(void) +static void video_vf_light_unreg_provider(int need_keep_frame) { ulong flags; + if (need_keep_frame) { + /* wait for the end of the last toggled frame*/ + atomic_set(&video_unreg_flag, 1); + while (atomic_read(&video_inirq_flag) > 0) + schedule(); + } + spin_lock_irqsave(&lock, flags); #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA dispbuf_to_put_num = DISPBUF_TO_PUT_MAX; @@ -6704,6 +6711,19 @@ static void video_vf_light_unreg_provider(void) cur_dispbuf = &vf_local; } spin_unlock_irqrestore(&lock, flags); + + if (need_keep_frame) { + /* keep the last toggled frame*/ + if (cur_dispbuf) { + unsigned int result; + + result = vf_keep_current(cur_dispbuf, NULL); + if (result == 0) + pr_info("%s: keep cur_disbuf failed\n", + __func__); + } + atomic_set(&video_unreg_flag, 0); + } } static int get_display_info(void *data) @@ -6768,9 +6788,9 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) //init_hdr_info(); } else if (type == VFRAME_EVENT_PROVIDER_RESET) { - video_vf_light_unreg_provider(); + video_vf_light_unreg_provider(1); } else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG) - video_vf_light_unreg_provider(); + video_vf_light_unreg_provider(0); else if (type == VFRAME_EVENT_PROVIDER_REG) { enable_video_discontinue_report = 1; drop_frame_count = 0; @@ -6804,7 +6824,7 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) (void *)1); } - video_vf_light_unreg_provider(); + video_vf_light_unreg_provider(0); } else if (type == VFRAME_EVENT_PROVIDER_FORCE_BLACKOUT) { force_blackout = 1; if (debug_flag & DEBUG_FLAG_BLACKOUT) { diff --git a/drivers/amlogic/media/video_sink/video_keeper.c b/drivers/amlogic/media/video_sink/video_keeper.c index 72d442f..94b2c34 100644 --- a/drivers/amlogic/media/video_sink/video_keeper.c +++ b/drivers/amlogic/media/video_sink/video_keeper.c @@ -835,6 +835,7 @@ static unsigned int vf_keep_current_locked( cur_dispbuf_el); if (ret) { /*keeped ok with codec keeper!*/ + keep_video_on = 1; return 1; } #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC diff --git a/include/linux/amlogic/media/codec_mm/codec_mm.h b/include/linux/amlogic/media/codec_mm/codec_mm.h index 8f71042..500385b 100644 --- a/include/linux/amlogic/media/codec_mm/codec_mm.h +++ b/include/linux/amlogic/media/codec_mm/codec_mm.h @@ -121,6 +121,7 @@ unsigned long codec_mm_alloc_for_dma_ex( int buffer_id); void codec_mm_release(struct codec_mm_s *mem, const char *owner); +int codec_mm_has_owner(struct codec_mm_s *mem, const char *owner); int codec_mm_request_shared_mem(struct codec_mm_s *mem, const char *owner); /*call if not make sure valid data.*/ void codec_mm_release_with_check(struct codec_mm_s *mem, const char *owner); diff --git a/include/linux/amlogic/media/codec_mm/codec_mm_keeper.h b/include/linux/amlogic/media/codec_mm/codec_mm_keeper.h index 34a0ab8..5714def 100644 --- a/include/linux/amlogic/media/codec_mm/codec_mm_keeper.h +++ b/include/linux/amlogic/media/codec_mm/codec_mm_keeper.h @@ -26,6 +26,7 @@ */ int codec_mm_keeper_mask_keep_mem(void *mem_handle, int type); +int is_codec_mm_keeped(void *mem_handle); /* *can call in irq */ |