unsigned long buff_flag;
unsigned long stream_buff_flag;
struct power_manager_s *pm;
+ u32 vdec_resouce_status;
};
struct canvas_status_s {
}
EXPORT_SYMBOL(vdec_destroy);
+static bool is_tunnel_pipeline(u32 pl)
+{
+ return ((pl & BIT(FRAME_BASE_PATH_DTV_TUNNEL_MODE)) ||
+ (pl & BIT(FRAME_BASE_PATH_AMLVIDEO_AMVIDEO))) ?
+ true : false;
+}
+
+static bool is_res_locked(u32 pre, u32 cur)
+{
+ return is_tunnel_pipeline(pre) ?
+ (is_tunnel_pipeline(cur) ? true : false) : false;
+}
+
+int vdec_resource_checking(struct vdec_s *vdec)
+{
+ /*
+ * If it is the single instance that the pipeline of DTV used,
+ * then have to check that the resources which is belong tunnel
+ * pipeline these are being released.
+ */
+ ulong expires = jiffies + msecs_to_jiffies(2000);
+
+ while (is_res_locked(vdec_core->vdec_resouce_status,
+ BIT(vdec->frame_base_video_path))) {
+ if (time_after(jiffies, expires)) {
+ pr_err("wait vdec resource timeout.\n");
+ return -EBUSY;
+ }
+ schedule();
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(vdec_resource_checking);
+
/*
*register vdec_device
* create output, vfm or create ionvideo output
const char *dev_name;
int id = PLATFORM_DEVID_AUTO;/*if have used my self*/
+ if (is_res_locked(vdec_core->vdec_resouce_status,
+ BIT(vdec->frame_base_video_path)))
+ return -EBUSY;
+
//pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
dev_name = get_dev_name(vdec_single(vdec), vdec->format);
vdec->vf_receiver_name);
snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE,
"vdec-map-%d", vdec->id);
- } else if (p->frame_base_video_path == FRAME_BASE_PATH_DTV_TUNNEL_MODE) {
+ } else if (p->frame_base_video_path ==
+ FRAME_BASE_PATH_DTV_TUNNEL_MODE) {
snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE,
"%s deinterlace %s", vdec->vf_provider_name,
"amvideo");
p->dolby_meta_with_el = 0;
pr_debug("vdec_init, vf_provider_name = %s, b %d\n",
p->vf_provider_name, is_cpu_tm2_revb());
+
+ mutex_lock(&vdec_mutex);
+ vdec_core->vdec_resouce_status |= BIT(p->frame_base_video_path);
+ mutex_unlock(&vdec_mutex);
+
vdec_input_prepare_bufs(/*prepared buffer for fast playing.*/
&vdec->input,
vdec->sys_info->width,
pr_debug("vdec_release instance %p, total %d\n", vdec,
atomic_read(&vdec_core->vdec_nr));
+
+ mutex_lock(&vdec_mutex);
+ vdec_core->vdec_resouce_status &= ~BIT(vdec->frame_base_video_path);
+ mutex_unlock(&vdec_mutex);
+
vdec_destroy(vdec);
mutex_lock(&vdec_mutex);
inited_vcodec_num--;
mutex_unlock(&vdec_mutex);
-
}
EXPORT_SYMBOL(vdec_release);
bool is_support_no_parser(void);
extern u32 timestamp_avsync_counter_get(void);
+
+int vdec_resource_checking(struct vdec_s *vdec);
+
#endif /* VDEC_H */
struct stream_port_s *port = priv->port;
struct vdec_s *vdec = priv->vdec;
+ r = vdec_resource_checking(vdec);
+ if (r < 0)
+ return r;
+
mutex_lock(&amstream_mutex);
if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
sub_port_release(port, psbuf);
port->pcr_inited = 0;
- port->flag = 0;
+
return 0;
}
struct stream_port_s *s;
struct stream_port_s *port = &ports[iminor(inode)];
struct port_priv_s *priv;
+
VDEC_PRINT_FUN_LINENO(__func__, __LINE__);
#ifdef G12A_BRINGUP_DEBUG
if (vdec_get_debug_flags() & 0xff0000) {
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
u32 port_flag = 0;
#endif
-
if (iminor(inode) >= amstream_port_num)
return -ENODEV;
if (i == amstream_port_num)
timestamp_firstvpts_set(0);
}
- port->flag = 0;
/* timestamp_pcrscr_set(0); */
}
case AMSTREAM_IOC_INIT_EX_STBUF: {
struct stream_buffer_metainfo parm;
- struct stream_buf_s *vbuf = &priv->vdec->vbuf;
+ struct stream_buf_s *vbuf = NULL;
+
+ if (priv->vdec == NULL) {
+ pr_err("init %s, no vdec.\n", __func__);
+ return -EFAULT;
+ }
+
+ vbuf = &priv->vdec->vbuf;
+ if (vbuf == NULL) {
+ pr_err("init %s, no stbuf.\n", __func__);
+ return -EFAULT;
+ }
if (copy_from_user(&parm, (void __user *)arg,
sizeof(struct stream_buffer_metainfo))) {
}
case AMSTREAM_IOC_WR_STBUF_META: {
struct stream_buffer_metainfo meta;
- struct stream_buf_s *vbuf = &priv->vdec->vbuf;
+ struct stream_buf_s *vbuf = NULL;
+
+ if (priv->vdec == NULL) {
+ pr_err("write %s, no vdec.\n", __func__);
+ return -EFAULT;
+ }
+
+ vbuf = &priv->vdec->vbuf;
+ if (vbuf == NULL) {
+ pr_err("write %s, no stbuf.\n", __func__);
+ return -EFAULT;
+ }
+
+ if (vbuf->ops == NULL) {
+ pr_err("write %s, no ops.\n", __func__);
+ return -EFAULT;
+ }
if (copy_from_user(&meta, (void __user *)arg,
sizeof(struct stream_buffer_metainfo))) {
}
case AMSTREAM_IOC_GET_STBUF_STATUS: {
struct stream_buffer_status st;
- struct stream_buf_s *pbuf = &priv->vdec->vbuf;
+ struct stream_buf_s *pbuf = NULL;
+
+ if (priv->vdec == NULL) {
+ pr_err("get status %s, no vdec.\n", __func__);
+ return -EFAULT;
+ }
+
+ pbuf = &priv->vdec->vbuf;
+ if (pbuf == NULL) {
+ pr_err("get status %s, no stbuf.\n", __func__);
+ return -EFAULT;
+ }
+
+ if (pbuf->ops == NULL) {
+ pr_err("get status %s, no ops.\n", __func__);
+ return -EFAULT;
+ }
st.stbuf_start = pbuf->ext_buf_addr;
st.stbuf_size = pbuf->buf_size;