v4l2test: Solve blurred screen problem in 45 or 60 fps.
1. Fix the error buffer count for v4l2 when using pingpong buffer. 2. Add readable flag for pingpong buffers exchange to avoid overproduction. Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user