From 595c5f8b7e4adee8cd681120ea2a5558a6b6b402 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Fri, 21 Sep 2018 01:18:20 +0800 Subject: [PATCH] media: fixed some issues for the v4l2 decode. [2/2] PD#SWPL-5314 Problem: 1. add a dummy vframe flag VFRAME_FLAG_EMPTY_FRAME_V4L. 2. add the FRAME_BASE_PATH_V4L_* for v4l2 display 3. recycle vframes when the isr recevie the empty vframe. Solution: 1. fixed some issues for the v4l2 decode. 2. add pause and resume for v4l2 m2m job. Verify: todo Change-Id: I00b44ad4d3a75f7e2167ca347562d002c2690430 Signed-off-by: Nanxin Qin --- drivers/amlogic/media/video_sink/video.c | 38 ++++++++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++ drivers/media/v4l2-core/v4l2-mem2mem.c | 36 ++++++++++++++++++++++++++ include/linux/amlogic/media/utils/amstream.h | 1 + include/linux/amlogic/media/vfm/vframe.h | 2 +- include/media/v4l2-mem2mem.h | 18 +++++++++++++ include/uapi/linux/videodev2.h | 2 ++ 7 files changed, 98 insertions(+), 1 deletion(-) diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 34d8a0e..4c883fb 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -3604,6 +3604,39 @@ bool has_enhanced_layer(struct vframe_s *vf) } u32 property_changed_true; +static bool has_receive_dummy_vframe(void) +{ + int i; + struct vframe_s *vf; + + vf = video_vf_peek(); + + if (vf && vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { + /* get dummy vf. */ + vf = video_vf_get(); + +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA /* recycle vframe. */ + for (i = 0; i < dispbuf_to_put_num; i++) { + if (dispbuf_to_put[i]) { + video_vf_put(dispbuf_to_put[i]); + dispbuf_to_put[i] = NULL; + } + dispbuf_to_put_num = 0; + } +#endif + /* recycle the last vframe. */ + if (cur_dispbuf) + video_vf_put(cur_dispbuf); + + /*pr_info("put dummy vframe.\n");*/ + video_vf_put(vf); + + return true; + } + + return false; +} + static u64 func_div(u64 number, u32 divid) { u64 tmp = number; @@ -6922,6 +6955,11 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) #endif vsync_toggle_frame(vf, __LINE__); toggle_frame = vf; + + /* The v4l2 capture needs a empty vframe to flush */ + if (has_receive_dummy_vframe()) + break; + #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (is_dolby_vision_enable()) { toggle_vf = dolby_vision_toggle_frame(vf); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 610caa1..bc3c51a 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1287,6 +1287,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; + case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; + case V4L2_PIX_FMT_VP9: descr = "VP9"; break; default: WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); if (fmt->description[0]) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 6bc27e7..1337fad 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -304,6 +304,42 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, } EXPORT_SYMBOL(v4l2_m2m_job_finish); +void v4l2_m2m_job_pause(struct v4l2_m2m_dev *m2m_dev, + struct v4l2_m2m_ctx *m2m_ctx) +{ + unsigned long flags; + + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + if (!m2m_dev->curr_ctx || m2m_dev->curr_ctx != m2m_ctx) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + dprintk("Called by an instance not currently running\n"); + return; + } + + list_del(&m2m_dev->curr_ctx->queue); + m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); + m2m_dev->curr_ctx->job_flags |= TRANS_ABORT; + wake_up(&m2m_dev->curr_ctx->finished); + m2m_dev->curr_ctx = NULL; + + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); +} +EXPORT_SYMBOL(v4l2_m2m_job_pause); + +void v4l2_m2m_job_resume(struct v4l2_m2m_dev *m2m_dev, + struct v4l2_m2m_ctx *m2m_ctx) +{ + unsigned long flags; + + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + m2m_ctx->job_flags &= ~TRANS_ABORT; + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + + v4l2_m2m_try_schedule(m2m_ctx); + v4l2_m2m_try_run(m2m_dev); +} +EXPORT_SYMBOL(v4l2_m2m_job_resume); + int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs) { diff --git a/include/linux/amlogic/media/utils/amstream.h b/include/linux/amlogic/media/utils/amstream.h index 1343d43..789887d 100644 --- a/include/linux/amlogic/media/utils/amstream.h +++ b/include/linux/amlogic/media/utils/amstream.h @@ -267,6 +267,7 @@ enum FRAME_BASE_VIDEO_PATH { FRAME_BASE_PATH_AMVIDEO2, FRAME_BASE_PATH_V4L_VIDEO, FRAME_BASE_PATH_TUNNEL_MODE, + FRAME_BASE_PATH_V4L_OSD, FRAME_BASE_PATH_MAX }; diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index dd7c882..8214dcf 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -79,7 +79,7 @@ #define VFRAME_FLAG_ERROR_RECOVERY 8 #define VFRAME_FLAG_SYNCFRAME 0x10 #define VFRAME_FLAG_GAME_MODE 0x20 -#define VFRAME_FLAG_EMPTY_FRAME_V4L 0x80 +#define VFRAME_FLAG_EMPTY_FRAME_V4L 0x800 enum pixel_aspect_ratio_e { PIXEL_ASPECT_RATIO_1_1, diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 1b35534..a22d0c1 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -485,6 +485,24 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx); } +/* + * v4l2_m2m_job_pause() - paused the schedule of data which from the job queue. + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + */ +void v4l2_m2m_job_pause(struct v4l2_m2m_dev *m2m_dev, + struct v4l2_m2m_ctx *m2m_ctx); + + /* + * v4l2_m2m_job_resume() - resumed the schedule of data which from the job que. + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + */ +void v4l2_m2m_job_resume(struct v4l2_m2m_dev *m2m_dev, + struct v4l2_m2m_ctx *m2m_ctx); + /* v4l2 ioctl helpers */ int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv, diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 7f34d3c..3d16db2 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -602,6 +602,8 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ +#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ +#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC with start codes */ /* Vendor-specific formats */ #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ -- 2.7.4