static struct vpp_frame_par_s pip_frame_parms[2];
static struct vframe_s *cur_pipbuf;
static struct vframe_s local_pip;
-static int _videopip_set_disable(u32 val);
+//int _videopip_set_disable(u32 val);
#endif
static struct device *amvideo_dev;
static u32 blackout = 1;
#endif
static u32 force_blackout;
+static u32 blackout_pip;
/* disable video */
{
return video_enabled;
}
+
+u32 get_videopip_enabled(void)
+{
+ return video2_enabled;
+}
+
/* show first frame*/
static bool show_first_frame_nosync;
bool show_first_picture;
#endif
}
-
+#ifdef VIDEO_PIP
+void safe_disble_videolayer2(void)
+{
+ DisableVideoLayer2();
+}
+#endif
/*********************************************************/
#ifdef VIDEO_PIP
static inline struct vframe_s *pip_vf_peek(void)
cur_pipbuf = vf;
if (first_picture)
pip_frame_ready_to_set = 1;
+ if (cur_pipbuf != &local_pip)
+ video_pip_keeper_new_frame_notify();
}
static void pip_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
static void pip_vf_unreg_provider(void)
{
ulong flags;
+ int keeped = 0;
/* atomic_set(&video_unreg_flag, 1); */
while (atomic_read(&video_inirq_flag) > 0)
pip_frame_count = 0;
spin_unlock_irqrestore(&lock, flags);
- disable_videopip = VIDEO_DISABLE_FORNEXT;
- DisableVideoLayer2();
+ if (blackout_pip | force_blackout) {
+ safe_disble_videolayer2();
+ try_free_keep_videopip(1);
+ }
+
+ if (cur_pipbuf)
+ keeped = vf_keep_pip_current_locked(cur_pipbuf, NULL);
+
+ if (keeped < 0) {/*keep failed.*/
+ pr_info("videopip keep failed, disable video now!\n");
+ safe_disble_videolayer2();
+ try_free_keep_videopip(1);
+ }
+
+ /*disable_videopip = VIDEO_DISABLE_FORNEXT;*/
+ /*DisableVideoLayer2();*/
}
-static void pip_vf_light_unreg_provider(void)
+static void pip_vf_light_unreg_provider(int need_keep_frame)
{
ulong flags;
cur_pipbuf = &local_pip;
}
spin_unlock_irqrestore(&lock, flags);
+ if (need_keep_frame) {
+ if (cur_pipbuf) {
+ vf_keep_pip_current_locked(cur_pipbuf, NULL);
+ }
+ }
}
static int pip_receiver_event_fun(
if (type == VFRAME_EVENT_PROVIDER_UNREG)
pip_vf_unreg_provider();
else if (type == VFRAME_EVENT_PROVIDER_RESET)
- pip_vf_light_unreg_provider();
+ pip_vf_light_unreg_provider(1);
else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG)
- pip_vf_light_unreg_provider();
+ pip_vf_light_unreg_provider(0);
else if (type == VFRAME_EVENT_PROVIDER_REG)
- pip_vf_light_unreg_provider();
+ pip_vf_light_unreg_provider(0);
return 0;
}
#endif
}
EXPORT_SYMBOL(set_blackout_policy);
+u32 get_blackout_pip_policy(void)
+{
+ return blackout_pip | force_blackout;
+}
+EXPORT_SYMBOL(get_blackout_pip_policy);
+
+u32 set_blackout_pip_policy(int policy)
+{
+ blackout_pip = policy;
+ return 0;
+}
+EXPORT_SYMBOL(set_blackout_pip_policy);
+
u8 is_vpp_postblend(void)
{
if (READ_VCBUS_REG(VPP_MISC + cur_dev->vpp_off) & VPP_VD1_POSTBLEND)
break;
case AMSTREAM_IOC_GET_VIDEOPIP_DISABLE:
+ put_user(disable_videopip, (u32 __user *)argp);
+ break;
case AMSTREAM_IOC_GET_VIDEO_DISABLE:
- if (layer->layer_id == 0)
- put_user(disable_video, (u32 __user *)argp);
-#ifdef VIDEO_PIP
- else if (layer->layer_id == 1)
- put_user(disable_videopip, (u32 __user *)argp);
-#endif
+ put_user(disable_video, (u32 __user *)argp);
break;
case AMSTREAM_IOC_SET_VIDEOPIP_DISABLE:
+ {
+ u32 val;
+
+ if (copy_from_user(&val, argp, sizeof(u32)) == 0)
+ ret = _videopip_set_disable(val);
+ else
+ ret = -EFAULT;
+ }
+ break;
case AMSTREAM_IOC_SET_VIDEO_DISABLE:
{
u32 val;
if (copy_from_user(&val, argp, sizeof(u32)) == 0) {
- if (layer->layer_id == 0)
- ret = _video_set_disable(val);
-#ifdef VIDEO_PIP
- else if (layer->layer_id == 1)
- ret = _videopip_set_disable(val);
-#endif
+ ret = _video_set_disable(val);
} else
ret = -EFAULT;
}
}
break;
+ case AMSTREAM_IOC_GET_BLACKOUT_PIP_POLICY:
+ if (copy_to_user(argp, &blackout_pip, sizeof(u32)) != 0)
+ ret = -EFAULT;
+ break;
+
+ case AMSTREAM_IOC_SET_BLACKOUT_PIP_POLICY:{
+ u32 mode;
+
+ if (copy_from_user(&mode, argp, sizeof(u32)) == 0) {
+ if (mode > 2)
+ ret = -EINVAL;
+ else
+ blackout_pip = mode;
+ } else
+ ret = -EFAULT;
+ }
+ break;
+
case AMSTREAM_IOC_CLEAR_VBUF:{
unsigned long flags;
while (atomic_read(&video_inirq_flag) > 0 ||
safe_disble_videolayer();
break;
+ case AMSTREAM_IOC_CLEAR_PIP_VBUF:{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+ cur_pipbuf = NULL;
+ spin_unlock_irqrestore(&lock, flags);
+ }
+ break;
+
+ case AMSTREAM_IOC_CLEAR_VIDEOPIP:
+ safe_disble_videolayer2();
+ break;
+
case AMSTREAM_IOC_SET_FREERUN_MODE:
if (arg > FREERUN_DUR)
ret = -EFAULT;
case AMSTREAM_IOC_SET_VIDEO_DISCONTINUE_REPORT:
case AMSTREAM_IOC_CLEAR_VBUF:
case AMSTREAM_IOC_CLEAR_VIDEO:
+ case AMSTREAM_IOC_CLEAR_PIP_VBUF:
+ case AMSTREAM_IOC_CLEAR_VIDEOPIP:
case AMSTREAM_IOC_SET_FREERUN_MODE:
case AMSTREAM_IOC_DISABLE_SLOW_SYNC:
case AMSTREAM_IOC_SET_3D_TYPE:
}
#ifdef VIDEO_PIP
-static int _videopip_set_disable(u32 val)
+int _videopip_set_disable(u32 val)
{
if (val > VIDEO_DISABLE_FORNEXT)
return -EINVAL;
if ((disable_videopip == VIDEO_DISABLE_FORNEXT)
&& cur_pipbuf && (cur_pipbuf != &local_pip))
pip_property_changed = 1;
+ try_free_keep_videopip(0);
} else {
if (cur_pipbuf && (cur_pipbuf != &local_pip))
EnableVideoLayer2();
return 0;
}
+static ssize_t videopip_blackout_policy_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", blackout_pip);
+}
+
+static ssize_t videopip_blackout_policy_store(struct class *cla,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int r;
+
+ r = kstrtoint(buf, 0, &blackout_pip);
+ if (r < 0)
+ return -EINVAL;
+
+ return count;
+}
+
static ssize_t videopip_axis_show(
struct class *cla,
struct class_attribute *attr,
0664,
video_blackout_policy_show,
video_blackout_policy_store),
+ __ATTR(blackout_pip_policy,
+ 0664,
+ videopip_blackout_policy_show,
+ videopip_blackout_policy_store),
__ATTR(video_seek_flag,
0664,
video_seek_flag_show,
static unsigned long keep_y_addr, keep_u_addr, keep_v_addr;
static int keep_video_on;
+static int keep_video_pip_on;
static int keep_id;
static int keep_head_id;
+static int keep_pip_id;
+static int keep_pip_head_id;
static int keep_el_id;
static int keep_el_head_id;
+static int keep_pip_el_id;
+static int keep_pip_el_head_id;
#define Y_BUFFER_SIZE 0x400000 /* for 1920*1088 */
#define U_BUFFER_SIZE 0x100000 /* compatible with NV21 */
EXPORT_SYMBOL(try_free_keep_video);
#endif
+void try_free_keep_videopip(int flags)
+{
+ int free_scatter_keeper = flags & 0x1;
+
+ if (keep_video_pip_on || free_scatter_keeper) {
+ /*pr_info("disbled keep video before free keep buffer.\n");*/
+ keep_video_pip_on = 0;
+ if (!get_videopip_enabled()) {
+ /*if not disable video,changed to 2 for */
+ pr_info("disbled videopip for next before free keep buffer!\n");
+ _videopip_set_disable(VIDEO_DISABLE_FORNEXT);
+ } else if (get_videopip_enabled()) {
+ safe_disble_videolayer2();
+ }
+ }
+ mutex_lock(&video_keeper_mutex);
+ video_pip_keeper_new_frame_notify();
+ free_alloced_keep_buffer();
+ mutex_unlock(&video_keeper_mutex);
+}
+EXPORT_SYMBOL(try_free_keep_videopip);
+
static void video_keeper_update_keeper_mem(
void *mem_handle, int type,
int *id)
struct vframe_s *cur_dispbuf_el)
{
int type = MEM_TYPE_CODEC_MM;
-
if (cur_dispbuf->type & VIDTYPE_SCATTER)
type = MEM_TYPE_CODEC_MM_SCATTER;
video_keeper_update_keeper_mem(
return (keep_id + keep_head_id) > 0;
}
+static int video_pip_keeper_frame_keep_locked(
+ struct vframe_s *cur_dispbuf,
+ struct vframe_s *cur_dispbuf_el)
+{
+ int type = MEM_TYPE_CODEC_MM;
+
+ if (cur_dispbuf) {
+ if (cur_dispbuf->type & VIDTYPE_SCATTER)
+ type = MEM_TYPE_CODEC_MM_SCATTER;
+ video_keeper_update_keeper_mem(
+ cur_dispbuf->mem_handle,
+ type,
+ &keep_pip_id);
+ video_keeper_update_keeper_mem(
+ cur_dispbuf->mem_head_handle,
+ MEM_TYPE_CODEC_MM,
+ &keep_pip_head_id);
+ }
+ if (cur_dispbuf_el) {
+ if (cur_dispbuf_el->type & VIDTYPE_SCATTER)
+ type = MEM_TYPE_CODEC_MM_SCATTER;
+ else
+ type = MEM_TYPE_CODEC_MM;
+ video_keeper_update_keeper_mem(
+ cur_dispbuf_el->mem_handle,
+ type,
+ &keep_pip_el_id);
+ video_keeper_update_keeper_mem(
+ cur_dispbuf_el->mem_head_handle,
+ MEM_TYPE_CODEC_MM,
+ &keep_pip_el_head_id);
+ }
+ return (keep_pip_id + keep_pip_head_id) > 0;
+}
+
/*
* call in irq.
*don't used mutex
codec_mm_keeper_unmask_keeper(keep_head_id, 120);
keep_head_id = -1;
}
+
if (keep_el_id > 0) {
/*wait 80 ms for vsync post.*/
codec_mm_keeper_unmask_keeper(keep_el_id, 120);
return;
}
+void video_pip_keeper_new_frame_notify(void)
+{
+ if (keep_video_pip_on) {
+ pr_info("new frame show, pip free keeper\n");
+ keep_video_pip_on = 0;
+ }
+ if (keep_pip_id > 0) {
+ /*wait 80 ms for vsync post.*/
+ codec_mm_keeper_unmask_keeper(keep_pip_id, 120);
+ keep_pip_id = -1;
+ }
+ if (keep_pip_head_id > 0) {
+ /*wait 80 ms for vsync post.*/
+ codec_mm_keeper_unmask_keeper(keep_pip_head_id, 120);
+ keep_pip_head_id = -1;
+ }
+ if (keep_pip_el_id > 0) {
+ /*wait 80 ms for vsync post.*/
+ codec_mm_keeper_unmask_keeper(keep_pip_el_id, 120);
+ keep_pip_el_id = -1;
+ }
+ if (keep_pip_el_head_id > 0) {
+ /*wait 80 ms for vsync post.*/
+ codec_mm_keeper_unmask_keeper(keep_pip_el_head_id, 120);
+ keep_pip_el_head_id = -1;
+ }
+
+}
+
+
static unsigned int vf_keep_current_locked(
struct vframe_s *cur_dispbuf,
struct vframe_s *cur_dispbuf_el)
return 1;
}
+
+unsigned int vf_keep_pip_current_locked(
+ struct vframe_s *cur_dispbuf,
+ struct vframe_s *cur_dispbuf_el)
+{
+ //u32 cur_index;
+ //u32 y_index, u_index, v_index;
+ //struct canvas_s cs0, cs1, cs2, cd;
+ int ret;
+
+ if (!cur_dispbuf) {
+ pr_info("keep pip exit without cur_dispbuf\n");
+ return 0;
+ }
+
+ if (get_video_debug_flags() &
+ DEBUG_FLAG_TOGGLE_SKIP_KEEP_CURRENT) {
+ pr_info("flag: keep pip exit is skip current\n");
+ return 0;
+ }
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
+ ext_frame_capture_poll(1); /*pull if have capture end frame */
+#endif
+
+ if (get_blackout_pip_policy()) {
+ pr_info("policy: keep exit is skip current\n");
+ return 0;
+ }
+
+ ret = video_pip_keeper_frame_keep_locked(
+ cur_dispbuf,
+ cur_dispbuf_el);
+
+ if (ret) {
+ /*keeped ok with codec keeper!*/
+ pr_info("keep pip buffer on!\n");
+ keep_video_pip_on = 1;
+ return 1;
+ }
+
+ keep_video_pip_on = 0;
+ return 0;
+}
+
unsigned int vf_keep_current(
struct vframe_s *cur_dispbuf,
struct vframe_s *cur_dispbuf2)
};
void safe_disble_videolayer(void);
+void safe_disble_videolayer2(void);
void update_cur_dispbuf(void *buf);
/*for video related files only.*/
int get_video_debug_flags(void);
int _video_set_disable(u32 val);
+int _videopip_set_disable(u32 val);
u32 get_video_enabled(void);
+u32 get_videopip_enabled(void);
struct device *get_video_device(void);
#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
#define AMSTREAM_IOC_GLOBAL_GET_VIDEO_OUTPUT _IOR((_A_M), 0x21, int)
#define AMSTREAM_IOC_GLOBAL_SET_VIDEO_OUTPUT _IOW((_A_M), 0x22, int)
#define AMSTREAM_IOC_GET_VIDEO_LAYER1_ON _IOR((_A_M), 0x23, int)
+/*video pip IOCTL command list*/
+#define AMSTREAM_IOC_CLEAR_VIDEOPIP _IOW((_A_M), 0x24, int)
+#define AMSTREAM_IOC_CLEAR_PIP_VBUF _IO((_A_M), 0x25)
#define AMSTREAM_IOC_GLOBAL_GET_VIDEOPIP_OUTPUT _IOR((_A_M), 0x2b, int)
#define AMSTREAM_IOC_GLOBAL_SET_VIDEOPIP_OUTPUT _IOW((_A_M), 0x2c, int)
* 0x5c, struct userdata_buf_state_t)
*/
-
#define AMSTREAM_IOC_VF_STATUS _IOR((_A_M), 0x60, int)
+
+#define AMSTREAM_IOC_GET_BLACKOUT_PIP_POLICY _IOR((_A_M), 0x62, int)
+#define AMSTREAM_IOC_SET_BLACKOUT_PIP_POLICY _IOW((_A_M), 0x63, int)
+
#define AMSTREAM_IOC_CLEAR_VBUF _IO((_A_M), 0x80)
#define AMSTREAM_IOC_APTS_LOOKUP _IOR((_A_M), 0x81, int)
int query_video_status(int type, int *value);
u32 set_blackout_policy(int policy);
u32 get_blackout_policy(void);
+u32 set_blackout_pip_policy(int policy);
+u32 get_blackout_pip_policy(void);
void set_video_angle(u32 s_value);
u32 get_video_angle(void);
extern unsigned int DI_POST_REG_RD(unsigned int addr);
#include <linux/amlogic/media/vfm/vframe.h>
void video_keeper_new_frame_notify(void);
+void video_pip_keeper_new_frame_notify(void);
void try_free_keep_video(int flags);
+void try_free_keep_videopip(int flags);
int __init video_keeper_init(void);
void __exit video_keeper_exit(void);
unsigned int vf_keep_current(
struct vframe_s *cur_dispbuf,
struct vframe_s *cur_dispbuf2);
+unsigned int vf_keep_pip_current_locked(
+ struct vframe_s *cur_dispbuf,
+ struct vframe_s *cur_dispbuf_el);
#endif