From c655913a3bdd7ef6413814482983c3beff00bdc0 Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Mon, 30 Jun 2014 10:45:25 +0200 Subject: v4l2-mfc-example: Add DRM support Patch adding support for DRM video rendering. Signed-off-by: Kamil Debski --- v4l2-mfc-example/Makefile | 13 ++-- v4l2-mfc-example/args.c | 63 +++++++++++++++--- v4l2-mfc-example/common.h | 49 ++++++++++++-- v4l2-mfc-example/drm.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++ v4l2-mfc-example/drm.h | 36 ++++++++++ v4l2-mfc-example/fb.c | 18 +++-- v4l2-mfc-example/fimc.c | 22 +++---- v4l2-mfc-example/fimc.h | 4 +- v4l2-mfc-example/main.c | 81 ++++++++++++++++++----- 9 files changed, 398 insertions(+), 52 deletions(-) create mode 100644 v4l2-mfc-example/drm.c create mode 100644 v4l2-mfc-example/drm.h diff --git a/v4l2-mfc-example/Makefile b/v4l2-mfc-example/Makefile index 2117e1e..2594f9b 100644 --- a/v4l2-mfc-example/Makefile +++ b/v4l2-mfc-example/Makefile @@ -19,20 +19,25 @@ # Toolchain path TCPATH = arm-linux-gnueabi- #TCPATH = -KERNELHEADERS = /home/kamil/praca/w1-party/kernel/headers/include +KERNELHEADERS = -I/home/kamil/praca/w1-party/kernel/headers/include +DRMHEADERS = -I/home/kamil/praca/drm/dst/include/libdrm \ + -I/home/kamil/praca/drm/dst/include/exynos \ + -I/home/kamil/praca/drm/dst/include +LIBRARIES = -L/home/kamil/praca/drm/dst/lib/ +LIBS = -ldrm CC = ${TCPATH}gcc AR = "${TCPATH}ar rc" AR2 = ${TCPATH}ranlib make -j4 -INCLUDES = -I$(KERNELHEADERS) +INCLUDES = $(KERNELHEADERS) $(DRMHEADERS) #INCLUDES = -I$(KERNELHEADERS)/include #-I$(TARGETROOT)/usr/include/linux -SOURCES = main.c fileops.c args.c parser.c fb.c fimc.c mfc.c queue.c +SOURCES = main.c fileops.c args.c parser.c fb.c fimc.c mfc.c queue.c drm.c OBJECTS := $(SOURCES:.c=.o) EXEC = v4l2_decode CFLAGS = -Wall -g -DS5PC1XX_FIMC -lm @@ -44,7 +49,7 @@ all: $(EXEC) $(CC) -c $(CFLAGS) $(INCLUDES) $< $(EXEC): $(OBJECTS) - $(CC) $(CFLAGS) -o $(EXEC) $(OBJECTS) -pthread + $(CC) $(CFLAGS) -o $(EXEC) $(OBJECTS) $(LIBRARIES) $(LIBS) -pthread clean: rm -f *.o $(EXEC) diff --git a/v4l2-mfc-example/args.c b/v4l2-mfc-example/args.c index 0e9e89c..e0298c0 100644 --- a/v4l2-mfc-example/args.c +++ b/v4l2-mfc-example/args.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include @@ -40,9 +41,11 @@ void print_usage(char *name) printf("\t-f - FIMC device (e.g. /dev/video4)\n"); printf("\t-i - Input file name\n"); printf("\t-m - MFC device (e.g. /dev/video8)\n"); + printf("\t-D :: - DRM module (e.g. exynos:4:17)\n"); printf("\t-V - synchronise to vsync\n"); - //printf("\t- - \n"); - printf("\tp2\n"); + printf("\t\n"); + printf("\tIf DRM or Frame buffer is used then FIMC should be suppplied.\n"); + printf("\tOnly one of the following Frame Buffer, DRM can be used at a time.\n"); printf("\n"); } @@ -71,17 +74,19 @@ int get_codec(char *str) int parse_args(struct instance *i, int argc, char **argv) { + char *tmp; int c; init_to_defaults(i); - while ((c = getopt(argc, argv, "c:d:f:i:m:V")) != -1) { + while ((c = getopt(argc, argv, "c:d:f:i:m:VD:")) != -1) { switch (c) { case 'c': i->parser.codec = get_codec(optarg); break; case 'd': i->fb.name = optarg; + i->fb.enabled = 1; break; case 'f': i->fimc.name = optarg; @@ -94,7 +99,38 @@ int parse_args(struct instance *i, int argc, char **argv) i->mfc.name = optarg; break; case 'V': - i->fb.double_buf = 1; + i->fimc.double_buf = 1; + break; + case 'D': + /* Name */ + tmp = optarg; + while (*tmp && *tmp != ':') + tmp++; + if (*tmp) { + i->drm.name = optarg; + *tmp = 0; + dbg("DRM module name: %s", optarg); + optarg = ++tmp; + } else { + break; + } + /* Crtc */ + while (*tmp && *tmp != ':') + tmp++; + if (*tmp) { + *tmp = 0; + i->drm.crtc_id = atoi(optarg); + dbg("crtc: %d (%s)", i->drm.crtc_id, optarg); + optarg = ++tmp; + } else { + break; + } + /* Crtc */ + while (*tmp && *tmp != ':') + tmp++; + i->drm.conn_id = atoi(optarg); + dbg("conn: %d (%s)", i->drm.conn_id, optarg); + i->drm.enabled = 1; break; default: err("Bad argument"); @@ -102,15 +138,24 @@ int parse_args(struct instance *i, int argc, char **argv) } } - if (!i->in.name || !i->fb.name || !i->mfc.name) { - err("The following arguments are required: -d -i -m -c"); - return -1; - } - if (!i->parser.codec) { err("Unknown or not set codec (-c)"); return -1; } + if (!i->in.name || !i->mfc.name) { + err("The following arguments are required: -i -m -c"); + return -1; + } + if (i->fimc.enabled) { + if (i->drm.enabled) { + dbg("Using DRM for display"); + } else if (i->fb.enabled) { + dbg("Using FrameBuffer for display\n"); + } else { + err("When using FIMC a framewbuffer or DRM has to be used\n"); + return -1; + } + } switch (i->parser.codec) { case V4L2_PIX_FMT_XVID: diff --git a/v4l2-mfc-example/common.h b/v4l2-mfc-example/common.h index 3f55283..aff8972 100644 --- a/v4l2-mfc-example/common.h +++ b/v4l2-mfc-example/common.h @@ -36,6 +36,14 @@ /* When DEBUG is defined debug messages are printed on the screen. * Otherwise only error messages are displayed. */ #define DEBUG +/* Remove #define DRM will disable DRM support */ +#define DRM + +#ifdef DRM +#include +#include +#include +#endif #ifdef ADD_DETAILS #define err(msg, ...) \ @@ -76,7 +84,7 @@ #define FIMC_CAP_PLANES 1 /* Maximum number of frame buffers - used for double buffering and * vsyns synchronisation */ -#define FB_MAX_BUFS 2 +#define MAX_BUFS 2 /* The buffer is free to use by MFC */ #define BUF_FREE 0 @@ -96,12 +104,35 @@ struct instance { int offs; } in; + /* DRM related parameters */ + struct { + char *name; + int fd; + + int fb[MAX_BUFS]; + int crtc[MAX_BUFS]; + + int width; + int height; + + char *p[MAX_BUFS]; + + unsigned int conn_id; + unsigned int crtc_id; +#ifdef DRM + struct drm_exynos_gem_create gem[MAX_BUFS]; + struct drm_exynos_gem_mmap mmap[MAX_BUFS]; + drmModeRes *resources; +#endif + char enabled; + + } drm; + /* Frame buffer related parameters */ struct { char *name; int fd; - char *p[FB_MAX_BUFS]; - int cur_buf; + char *p[MAX_BUFS]; int buffers; int width; int height; @@ -111,7 +142,7 @@ struct instance { int stride; int size; int full_size; - int double_buf; + char enabled; } fb; /* FIMC related parameter */ @@ -124,6 +155,16 @@ struct instance { * the MFC thread */ sem_t done; char enabled; + + int cur_buf; + int double_buf; + int size; + int buffers; + int bpp; + int width; + int stride; + int height; + char *p[MAX_BUFS]; } fimc; /* MFC related parameters */ diff --git a/v4l2-mfc-example/drm.c b/v4l2-mfc-example/drm.c new file mode 100644 index 0000000..188d394 --- /dev/null +++ b/v4l2-mfc-example/drm.c @@ -0,0 +1,164 @@ +/* + * V4L2 Codec decoding example application + * Kamil Debski + * + * DRM operations + * + * Copyright 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "drm.h" +#include + +#ifdef DRM + +#include +#include +#include + +int drm_open(struct instance *i, char *name) +{ + char mode[32]; + drmModeCrtc *crtc; + struct drm_gem_close args; + drmModeConnector *connector; + drmModeModeInfo *mode_drm; + unsigned int fb_id; + int ret; + int n; + + i->drm.fd =drmOpen(name, NULL); + if (i->drm.fd < 0) { + err("Failed to open drm module \"%s\"", name); + return -1; + } + + i->drm.resources = drmModeGetResources(i->drm.fd); + + crtc = drmModeGetCrtc(i->drm.fd, i->drm.crtc_id); + if (!crtc) { + err("Failed to get crtc: %d", i->drm.crtc_id); + return -1; + } + + i->drm.width = crtc->width; + i->drm.height = crtc->height; + + dbg("DRM crtc (%d) resolution: %dx%d @", i->drm.crtc_id, i->drm.width, + i->drm.height); + drmModeFreeCrtc(crtc); + + for (n = 0; n < (i->fimc.double_buf?2:1); n++) { + i->drm.gem[n].size = i->drm.width * i->drm.height * 4; + ret = ioctl(i->drm.fd, DRM_IOCTL_EXYNOS_GEM_CREATE, + &i->drm.gem[n]); + if (ret < 0) { + err("Failed to create gem"); + return -1; + } + args.handle = i->drm.gem[n].handle; + i->drm.mmap[n].handle = i->drm.gem[n].handle; + i->drm.mmap[n].size = i->drm.gem[n].size; + ret = ioctl(i->drm.fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &i->drm.mmap[n]); + if (ret < 0) { + ioctl(i->drm.fd, DRM_IOCTL_GEM_CLOSE, &args); + err("Failed to mmap gem"); + return -1; + } + ret = drmModeAddFB(i->drm.fd, i->drm.width, i->drm.height, 32, + 32, 4 * i->drm.width, i->drm.gem[n].handle, &fb_id); + if (ret) { + munmap((void *)(unsigned long)i->drm.mmap[n].mapped, + i->drm.gem[n].size); + ioctl(i->drm.fd, DRM_IOCTL_GEM_CLOSE, &args); + err("Failed to add fb"); + return -1; + } + i->drm.fb[n] = fb_id; + i->drm.p[n] = (char *)(unsigned int)i->drm.mmap[n].mapped; + i->fimc.p[n] = (char *)(unsigned int)i->drm.mmap[n].mapped; + } + + snprintf(mode, 32, "%dx%d", crtc->width, crtc->height); + + connector = drmModeGetConnector(i->drm.fd, i->drm.conn_id); + if (!connector || connector->connector_id != i->drm.conn_id) { + err("Couldn't find the connector"); + drmModeFreeConnector(connector); + return -1; + } + + mode_drm = 0; + + for (n = 0; n < connector->count_modes; n++) { + if (!strncmp(connector->modes[n].name, mode, 32)) { + mode_drm = &connector->modes[n]; + break; + } + } + + if (!mode_drm) { + err("Failed to find mode\n"); + drmModeFreeConnector(connector); + return -1; + } + + ret = drmModeSetCrtc(i->drm.fd, i->drm.crtc_id, i->drm.fb[0], 0, 0, + &i->drm.conn_id, 1, mode_drm); + if (ret) { + err("Failed to set crtc"); + drmModeFreeConnector(connector); + return -1; + } + + i->fimc.width = i->drm.width; + i->fimc.height = i->drm.height; + i->fimc.stride = i->drm.width * 4; + i->fimc.bpp = 32; + i->fimc.buffers = (i->fimc.double_buf?2:1); + i->fimc.size = i->drm.width * i->drm.height * 4; + + i->drm.crtc[0] = i->drm.crtc_id; + i->drm.crtc[1] = i->drm.crtc_id; + + return 0; +} + +void drm_close(struct instance *i) +{ + drmClose(i->drm.fd); +} + +#else /* DRM */ + +int drm_open(struct instance *i, char *name) +{ + return 0; +}; + +void drm_close(struct instance *i) { + return; +} + +#endif /* DRM */ diff --git a/v4l2-mfc-example/drm.h b/v4l2-mfc-example/drm.h new file mode 100644 index 0000000..1cd31e4 --- /dev/null +++ b/v4l2-mfc-example/drm.h @@ -0,0 +1,36 @@ +/* + * V4L2 Codec decoding example application + * Kamil Debski + * + * DRM operations header file + * + * Copyright 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef INCLUDE_DRM_H +#define INCLUDE_DRM_H + +#ifdef DRM + +/* Open and mmap DRM buffer. Also read its properties */ +int drm_open(struct instance *i, char *name); +/* Unmap and close the buffer */ +void drm_close(struct instance *i); + +#endif /* DRM */ + +#endif /* INCLUDE_DRM_H */ + diff --git a/v4l2-mfc-example/fb.c b/v4l2-mfc-example/fb.c index a2d0bcb..162b511 100644 --- a/v4l2-mfc-example/fb.c +++ b/v4l2-mfc-example/fb.c @@ -52,25 +52,29 @@ int fb_open(struct instance *i, char *name) dbg("Virtual resolution: vxres=%d vyres=%d", fbinfo.xres_virtual, fbinfo.yres_virtual); - i->fb.width = fbinfo.xres; - i->fb.height = fbinfo.yres; + i->fimc.width = i->fb.width = fbinfo.xres; + i->fimc.height = i->fb.height = fbinfo.yres; i->fb.virt_width = fbinfo.xres_virtual; i->fb.virt_height = fbinfo.yres_virtual; - i->fb.bpp = fbinfo.bits_per_pixel; - i->fb.stride = i->fb.virt_width * i->fb.bpp / 8; - i->fb.full_size = i->fb.stride * i->fb.virt_height; - i->fb.size = i->fb.stride * fbinfo.yres; + i->fimc.bpp = i->fb.bpp = fbinfo.bits_per_pixel; + i->fimc.stride = i->fb.stride = i->fb.virt_width * i->fb.bpp / 8; + i->fb.full_size = i->fb.stride * i->fb.virt_height; + i->fimc.size = i->fb.size = i->fb.stride * fbinfo.yres; i->fb.p[0] = mmap(0, i->fb.full_size, PROT_WRITE | PROT_READ, MAP_SHARED, i->fb.fd, 0); i->fb.buffers = 1; - if (i->fb.double_buf) { + if (i->fimc.double_buf) { i->fb.p[1] = i->fb.p[0] + i->fb.size; i->fb.buffers = 2; } + i->fimc.buffers = i->fb.buffers; + i->fimc.p[0] = i->fb.p[0]; + i->fimc.p[1] = i->fb.p[1]; + return fb_set_virt_y_offset(i, 0); } diff --git a/v4l2-mfc-example/fimc.c b/v4l2-mfc-example/fimc.c index 4af3aa3..61476ba 100644 --- a/v4l2-mfc-example/fimc.c +++ b/v4l2-mfc-example/fimc.c @@ -152,7 +152,7 @@ int fimc_setup_output_from_mfc(struct instance *i) return 0; } -int fimc_setup_capture_from_fb(struct instance *i) +int fimc_setup_capture(struct instance *i) { struct v4l2_plane_pix_format planes[MFC_OUT_PLANES]; struct v4l2_requestbuffers reqbuf; @@ -160,10 +160,10 @@ int fimc_setup_capture_from_fb(struct instance *i) int ret; memzero(planes); - planes[0].sizeimage = i->fb.stride * i->fb.height; - planes[0].bytesperline = i->fb.stride; + planes[0].sizeimage = i->fimc.stride * i->fimc.height; + planes[0].bytesperline = i->fimc.stride; - switch (i->fb.bpp) { + switch (i->fimc.bpp) { case 16: fmt = V4L2_PIX_FMT_RGB565; break; @@ -171,18 +171,18 @@ int fimc_setup_capture_from_fb(struct instance *i) fmt = V4L2_PIX_FMT_RGB32; break; default: - err("Framebuffer format in not recognized. Bpp=%d", i->fb.bpp); + err("Framebuffer format in not recognized. Bpp=%d", i->fimc.bpp); return -1; } - ret = fimc_sfmt(i, i->fb.width, i->fb.height, + ret = fimc_sfmt(i, i->fimc.width, i->fimc.height, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, fmt, 1, planes); if (ret) return -1; memzero(reqbuf); - reqbuf.count = i->fb.buffers; + reqbuf.count = i->fimc.buffers; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; reqbuf.memory = V4L2_MEMORY_USERPTR; @@ -249,7 +249,7 @@ int fimc_dec_queue_buf_out_from_mfc(struct instance *i, int n) return 0; } -int fimc_dec_queue_buf_cap_from_fb(struct instance *i, int n) +int fimc_dec_queue_buf_cap(struct instance *i, int n) { struct v4l2_buffer buf; struct v4l2_plane planes[FIMC_CAP_PLANES]; @@ -263,9 +263,9 @@ int fimc_dec_queue_buf_cap_from_fb(struct instance *i, int n) buf.m.planes = planes; buf.length = FIMC_CAP_PLANES; - buf.m.planes[0].bytesused = i->fb.size; - buf.m.planes[0].length = i->fb.size; - buf.m.planes[0].m.userptr = (unsigned long)i->fb.p[n]; + buf.m.planes[0].bytesused = i->fimc.size; + buf.m.planes[0].length = i->fimc.size; + buf.m.planes[0].m.userptr = (unsigned long)i->fimc.p[n]; ret = ioctl(i->fimc.fd, VIDIOC_QBUF, &buf); diff --git a/v4l2-mfc-example/fimc.h b/v4l2-mfc-example/fimc.h index 7a3f08b..5102547 100644 --- a/v4l2-mfc-example/fimc.h +++ b/v4l2-mfc-example/fimc.h @@ -36,13 +36,13 @@ int fimc_sfmt(struct instance *i, int width, int height, /* Setup OUTPUT queue of FIMC basing on the configuration of MFC */ int fimc_setup_output_from_mfc(struct instance *i); /* Setup CAPTURE queue of FIMC basing on the configuration of the frame buffer */ -int fimc_setup_capture_from_fb(struct instance *i); +int fimc_setup_capture(struct instance *i); /* Control streaming status */ int fimc_stream(struct instance *i, enum v4l2_buf_type type, int status); /* Convenience function for queueing buffers from MFC */ int fimc_dec_queue_buf_out_from_mfc(struct instance *i, int n); /* Convenience function for queueing buffers from frame buffer*/ -int fimc_dec_queue_buf_cap_from_fb(struct instance *i, int n); +int fimc_dec_queue_buf_cap(struct instance *i, int n); /* Dequeue buffer */ int fimc_dec_dequeue_buf(struct instance *i, int *n, int nplanes, int type); /* Dequeue buffer from the CAPTURE queue. The argument *n is set to the index of diff --git a/v4l2-mfc-example/main.c b/v4l2-mfc-example/main.c index fef0c8d..6453c07 100644 --- a/v4l2-mfc-example/main.c +++ b/v4l2-mfc-example/main.c @@ -33,6 +33,7 @@ #include "fileops.h" #include "mfc.h" #include "parser.h" +#include "drm.h" /* This is the size of the buffer for the compressed stream. * It limits the maximum compressed frame size. */ @@ -55,7 +56,10 @@ void cleanup(struct instance *i) fb_close(i); if (i->in.fd) input_close(i); - queue_free(&i->fimc.queue); + if (i->drm.fd) + drm_close(i); + if (i->fimc.enabled) + queue_free(&i->fimc.queue); } int extract_and_process_header(struct instance *i) @@ -287,6 +291,14 @@ void *mfc_thread_func(void *args) return 0; } +void +page_flip_handler(int fd, unsigned int frame, + unsigned int sec, unsigned int usec, void *data) +{ + printf("Handled %d %d %d\n", frame, sec, usec); + +} + /* This thread handles FIMC processing and optionally frame buffer * switching and synchronisation to the vsync of frame buffer. */ void *fimc_thread_func(void *args) @@ -296,6 +308,8 @@ void *fimc_thread_func(void *args) struct instance *i = (struct instance *)args; int n, tmp; + i->fimc.cur_buf = 0; + while (!i->error && (!i->finish || (i->finish && !queue_empty(&i->fimc.queue)) )) { @@ -324,18 +338,12 @@ void *fimc_thread_func(void *args) break; } - i->fb.cur_buf = 0; - - if (i->fb.double_buf) { - i->fb.cur_buf++; - i->fb.cur_buf %= i->fb.buffers; - } - - if (fimc_dec_queue_buf_cap_from_fb(i, i->fb.cur_buf)) { + if (fimc_dec_queue_buf_cap(i, i->fimc.cur_buf)) { i->error = 1; break; } + if (first_run) { /* Since our fabulous V4L2 framework enforces that at * least one buffer is queued before switching streaming @@ -369,11 +377,49 @@ void *fimc_thread_func(void *args) break; } - if (i->fb.double_buf) { - fb_set_virt_y_offset(i, i->fb.height); + if (i->fimc.double_buf && i->fb.enabled) { + fb_set_virt_y_offset(i, i->fimc.cur_buf * i->fb.height); fb_wait_for_vsync(i); } + if (i->fimc.double_buf && i->drm.enabled) { + drmModePageFlip(i->drm.fd, i->drm.crtc[i->fimc.cur_buf], + i->drm.fb[i->fimc.cur_buf], + DRM_MODE_PAGE_FLIP_EVENT, 0); + + while (1) { + struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; + fd_set fds; + int ret; + drmEventContext evctx; + + memset(&evctx, 0, sizeof evctx); + evctx.version = DRM_EVENT_CONTEXT_VERSION; + evctx.vblank_handler = NULL; + evctx.page_flip_handler = page_flip_handler; + + FD_ZERO(&fds); + FD_SET(0, &fds); + FD_SET(i->drm.fd, &fds); + ret = select(i->drm.fd + 1, &fds, NULL, NULL, &timeout); + + if (ret <= 0) + continue; + else if (FD_ISSET(0, &fds)) + break; + + drmHandleEvent(i->drm.fd, &evctx); + break; + + } + + } + + if (i->fimc.double_buf) { + i->fimc.cur_buf++; + i->fimc.cur_buf %= i->fimc.buffers; + } + i->mfc.cap_buf_flag[n] = BUF_FREE; sem_post(&i->fimc.done); @@ -393,7 +439,7 @@ int main(int argc, char **argv) printf("V4L2 Codec decoding example application\n"); printf("Kamil Debski \n"); - printf("Copyright 2012 Samsung Electronics Co., Ltd.\n\n"); + printf("Copyright 2012-2014 Samsung Electronics Co., Ltd.\n\n"); if (parse_args(&inst, argc, argv)) { print_usage(argv[0]); @@ -408,12 +454,17 @@ int main(int argc, char **argv) return 1; } - if (fb_open(&inst, inst.fb.name)) { + if (inst.fb.enabled && fb_open(&inst, inst.fb.name)) { + cleanup(&inst); + return 1; + } + + if (inst.drm.enabled && drm_open(&inst, inst.drm.name)) { cleanup(&inst); return 1; } - if (inst.fimc.name && fimc_open(&inst, inst.fimc.name)) { + if (inst.fimc.enabled && fimc_open(&inst, inst.fimc.name)) { cleanup(&inst); return 1; } @@ -453,7 +504,7 @@ int main(int argc, char **argv) return 1; } - if (inst.fimc.enabled && fimc_setup_capture_from_fb(&inst)) { + if (inst.fimc.enabled && fimc_setup_capture(&inst)) { cleanup(&inst); return 1; } -- cgit v1.2.3