diff --git a/package/starfive/v4l2_test/common.h b/package/starfive/v4l2_test/common.h index 48660ab9..1cb8f4ab 100644 --- a/package/starfive/v4l2_test/common.h +++ b/package/starfive/v4l2_test/common.h @@ -26,7 +26,8 @@ #define TEST_VERSION "v0.0.1" #endif -#define BUFCOUNT 4 +#define PINGPONG_BUFCOUNT 2 /* For pingpong buffer mapping in drm + mmap mode*/ +#define BUFCOUNT 4 #define CLEAR(x) memset (&(x), 0, sizeof (x)) #define PCLEAR(x) memset ((x), 0, sizeof (*x)) diff --git a/package/starfive/v4l2_test/stf_v4l2.c b/package/starfive/v4l2_test/stf_v4l2.c index 674c72d1..6981255b 100644 --- a/package/starfive/v4l2_test/stf_v4l2.c +++ b/package/starfive/v4l2_test/stf_v4l2.c @@ -406,14 +406,14 @@ static void stf_v4l2_readInit(V4l2Param_t *param) LOG(STF_LEVEL_TRACE, "Exit\n"); } -static void stf_v4l2_mmapInit(V4l2Param_t *param) +static void stf_v4l2_mmapInit(V4l2Param_t *param, int buf_count) { int i = 0; struct v4l2_requestbuffers req; CLEAR(req); LOG(STF_LEVEL_TRACE, "Enter\n"); - req.count = BUFCOUNT; + req.count = buf_count; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(param->fd, VIDIOC_REQBUFS, &req)) { @@ -556,7 +556,7 @@ static void stf_v4l2_userptrInit(V4l2Param_t *param) param->image_size = buffer_size; } -void sft_v4l2_prepare_capturing(V4l2Param_t *param, int *dmabufs, int count) +void sft_v4l2_prepare_capturing(V4l2Param_t *param, int *dmabufs, STF_DISP_TYPE disp_type) { LOG(STF_LEVEL_TRACE, "Enter\n"); switch (param->io_mthd) { @@ -565,7 +565,11 @@ void sft_v4l2_prepare_capturing(V4l2Param_t *param, int *dmabufs, int count) break; case IO_METHOD_MMAP: - stf_v4l2_mmapInit(param); + if(STF_DISP_DRM == disp_type) { + stf_v4l2_mmapInit(param, PINGPONG_BUFCOUNT); + } else { + stf_v4l2_mmapInit(param, BUFCOUNT); + } break; case IO_METHOD_USERPTR: @@ -573,7 +577,7 @@ void sft_v4l2_prepare_capturing(V4l2Param_t *param, int *dmabufs, int count) break; case IO_METHOD_DMABUF: - stf_v4l2_dmabufInit(param, dmabufs, count); + stf_v4l2_dmabufInit(param, dmabufs, BUFCOUNT); break; default: diff --git a/package/starfive/v4l2_test/stf_v4l2.h b/package/starfive/v4l2_test/stf_v4l2.h index f49f9fc7..9a4b5833 100644 --- a/package/starfive/v4l2_test/stf_v4l2.h +++ b/package/starfive/v4l2_test/stf_v4l2.h @@ -41,7 +41,8 @@ extern void stf_v4l2_open(V4l2Param_t *param, char *device_name); extern void stf_v4l2_close(V4l2Param_t *param); extern void stf_v4l2_init(V4l2Param_t *param); extern void stf_v4l2_uninit(V4l2Param_t *param); -extern void sft_v4l2_prepare_capturing(V4l2Param_t *param, int *dmabufs, int count); +extern void sft_v4l2_prepare_capturing(V4l2Param_t *param, + int *dmabufs, STF_DISP_TYPE disp_type); extern void sft_v4l2_start_capturing(V4l2Param_t *param); extern void stf_v4l2_stop_capturing(V4l2Param_t *param); diff --git a/package/starfive/v4l2_test/v4l2_test.c b/package/starfive/v4l2_test/v4l2_test.c index a3315a18..92ec19ba 100644 --- a/package/starfive/v4l2_test/v4l2_test.c +++ b/package/starfive/v4l2_test/v4l2_test.c @@ -40,6 +40,17 @@ static const enum_value_t g_iomthd_values[] = { { IO_METHOD_READ, "READ"} }; +//Only support for using drm mmap dmabuf 0 & 1 +typedef struct { + volatile uint8_t readable[2]; + volatile uint8_t foreground_index; +} pingpong_buffer_index_t; + +static pingpong_buffer_index_t g_pp_index = { + .readable = { 0, 0 }, + .foreground_index = 0, +}; + typedef struct { V4l2Param_t v4l2_param; FBParam_t fb_param; @@ -59,7 +70,6 @@ ConfigParam_t *gp_cfg_param = NULL; static int g_drm_buf_next_idx = -1; static int g_drm_buf_curr_idx = 0; -static int drm_buf_id = 0; static void alloc_default_config(ConfigParam_t **pp_data) { @@ -404,15 +414,15 @@ static int frameRead(void) struct v4l2_buffer buf; V4l2Param_t *pv4l2_param = &gp_cfg_param->v4l2_param; uint8_t *dst = NULL; - int next_index; + int background_index; if (STF_DISP_FB == gp_cfg_param->disp_type) { dst = gp_cfg_param->fb_param.screen_buf; } else if (STF_DISP_DRM == gp_cfg_param->disp_type && IO_METHOD_DMABUF != gp_cfg_param->io_mthd) { + background_index = !g_pp_index.foreground_index; //Get ready to compose the backgound buffer - next_index = (drm_buf_id + 1) % 2; - dst = gp_cfg_param->drm_param.dev_head->bufs[next_index].buf; + dst = gp_cfg_param->drm_param.dev_head->bufs[background_index].buf; } else { LOG(STF_LEVEL_LOG, "Not display\n"); } @@ -447,19 +457,20 @@ static int frameRead(void) buf.index, gp_cfg_param->v4l2_param.n_buffers); imageProcess((uint8_t *)(pv4l2_param->pBuffers[buf.index].start), dst, buf.timestamp); if (STF_DISP_DRM == gp_cfg_param->disp_type) { - drm_buf_id = next_index; // Move background buffer to foreground + g_pp_index.readable[background_index] = 1; static int first_frame = 1; if(first_frame) { drm_dev_t* dev = gp_cfg_param->drm_param.dev_head; + g_pp_index.foreground_index = background_index; /* First buffer to DRM */ if (drmModeSetCrtc(gp_cfg_param->drm_param.fd, - dev->crtc_id, dev->bufs[drm_buf_id].fb_id, + dev->crtc_id, dev->bufs[g_pp_index.foreground_index].fb_id, 0, 0, &dev->conn_id, 1, &dev->mode)) { fatal("drmModeSetCrtc() failed"); } /* First flip */ drmModePageFlip(gp_cfg_param->drm_param.fd, - dev->crtc_id, dev->bufs[drm_buf_id].fb_id, + dev->crtc_id, dev->bufs[g_pp_index.foreground_index].fb_id, DRM_MODE_PAGE_FLIP_EVENT, dev); first_frame = 0; } @@ -549,12 +560,23 @@ static void page_flip_handler(int fd, unsigned int frame, DRM_MODE_PAGE_FLIP_EVENT, dev); } +static uint8_t check_background_buf_readable(void) +{ + return g_pp_index.readable[!g_pp_index.foreground_index]; +} + static void mmap_page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { + if(check_background_buf_readable()) { + //Move background buffer to foreground + g_pp_index.readable[g_pp_index.foreground_index] = 0; + g_pp_index.foreground_index = !g_pp_index.foreground_index; + } + drmModePageFlip(gp_cfg_param->drm_param.fd, gp_cfg_param->drm_param.dev_head->crtc_id, - gp_cfg_param->drm_param.dev_head->bufs[drm_buf_id].fb_id, + gp_cfg_param->drm_param.dev_head->bufs[g_pp_index.foreground_index].fb_id, DRM_MODE_PAGE_FLIP_EVENT, gp_cfg_param->drm_param.dev_head); } @@ -983,7 +1005,7 @@ int main(int argc, char **argv) } // prepare and start v4l2 capturing - sft_v4l2_prepare_capturing(&gp_cfg_param->v4l2_param, gp_cfg_param->dmabufs, BUFCOUNT); + sft_v4l2_prepare_capturing(&gp_cfg_param->v4l2_param, gp_cfg_param->dmabufs, gp_cfg_param->disp_type); sft_v4l2_start_capturing(&(gp_cfg_param->v4l2_param)); // process frames