summaryrefslogtreecommitdiff
authorShuide 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)
commit812222a3570125bb28a565cace8d2d3ac8db4b63 (patch)
tree73e0226d19552f8db5c933869dd2008645f8c9ff
parent1347c6a394290dcab8b0c96bcc5e96f7966ac24f (diff)
parent08324cb85dfa4a0845000b610aa41ffedecb362a (diff)
downloadcommon-812222a3570125bb28a565cace8d2d3ac8db4b63.zip
common-812222a3570125bb28a565cace8d2d3ac8db4b63.tar.gz
common-812222a3570125bb28a565cace8d2d3ac8db4b63.tar.bz2
Merge "media: keep last normal frame before reset [2/2]" into p-amlogic
Diffstat
-rw-r--r--drivers/amlogic/media/common/codec_mm/codec_mm.c32
-rw-r--r--drivers/amlogic/media/common/codec_mm/codec_mm_keeper.c5
-rw-r--r--drivers/amlogic/media/deinterlace/deinterlace.c7
-rw-r--r--drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c4
-rw-r--r--drivers/amlogic/media/video_processor/video_dev/amlvideo.c13
-rw-r--r--drivers/amlogic/media/video_sink/video.c28
-rw-r--r--drivers/amlogic/media/video_sink/video_keeper.c1
-rw-r--r--include/linux/amlogic/media/codec_mm/codec_mm.h1
-rw-r--r--include/linux/amlogic/media/codec_mm/codec_mm_keeper.h1
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
*/