summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6e74616)
raw | patch | inline | side by side (parent: 6e74616)
author | Nikhil Devshatwar <nikhil.nd@ti.com> | |
Thu, 5 Dec 2013 22:15:32 +0000 (03:45 +0530) | ||
committer | Amarinder Bindra <a-bindra@ti.com> | |
Wed, 11 Dec 2013 06:30:05 +0000 (12:00 +0530) |
Using '--dual' option, two different video nodes can be openeed
Running the loopback in a thred with common display.
One thread runs in full screen while other is overlayed on top of it.
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Running the loopback in a thred with common display.
One thread runs in full screen while other is overlayed on top of it.
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Makefile.am | patch | blob | history | |
dmabuftest.c | patch | blob | history | |
util/v4l2.c | patch | blob | history |
diff --git a/Makefile.am b/Makefile.am
index 19cfa05ca8064295c24a3816f45ed96c61104897..5521dbfbf32830126b77ac6d74d1b9214d84313a 100644 (file)
--- a/Makefile.am
+++ b/Makefile.am
if ENABLE_V4L2_DMABUF
dmabuftest_SOURCES = dmabuftest.c
-dmabuftest_LDADD = $(LDADD_COMMON)
+dmabuftest_LDADD = $(LDADD_COMMON) -lpthread
endif
if ENABLE_DCE
diff --git a/dmabuftest.c b/dmabuftest.c
index 016acdcd2da04457903df8f3b3959df821a5c6fd..a8329eb723e7330b0381d23f4d9c37f7f2e895e6 100644 (file)
--- a/dmabuftest.c
+++ b/dmabuftest.c
*/
+#include <pthread.h>
#include "util.h"
#define NBUF 3
#define CNT 500
+enum display_area {
+ FULL,
+ OVERLAY
+};
+
+struct thr_data {
+ struct display *disp;
+ struct v4l2 *v4l2;
+ uint32_t fourcc, width, height;
+ enum display_area area;
+};
+
static void
usage(char *name)
{
v4l2_usage();
}
+void *
+capture_loop(void *arg)
+{
+ struct thr_data *data = (struct thr_data *)arg;
+ struct display *disp = data->disp;
+ struct v4l2 *v4l2 = data->v4l2;
+ uint32_t fourcc = data->fourcc;
+ uint32_t width = data->width, height = data->height;
+
+ struct buffer **buffers;
+ int ret, i;
+
+ buffers = disp_get_vid_buffers(disp, NBUF, fourcc, width, height);
+ if (!buffers) {
+ return NULL;
+ }
+
+ ret = v4l2_reqbufs(v4l2, buffers, NBUF);
+ if (ret) {
+ return NULL;
+ }
+
+ if(data->area == OVERLAY) {
+ for (i = 0; i < NBUF; i++) {
+ buffers[i]->noScale = true;
+ get_overlay_plane(disp, buffers[i]);
+ }
+ }
+ v4l2_qbuf(v4l2, buffers[0]);
+ v4l2_streamon(v4l2);
+ for (i = 1; i < CNT; i++) {
+ v4l2_qbuf(v4l2, buffers[i % NBUF]);
+
+ switch(data->area) {
+ case FULL:
+ ret = disp_post_vid_buffer(disp, v4l2_dqbuf(v4l2),
+ 0, 0, width, height);
+ break;
+ case OVERLAY:
+ ret = disp_post_vid_buffer(disp, v4l2_dqbuf(v4l2),
+ 0, 0, width, height);
+ break;
+ }
+ if (ret) {
+ return NULL;
+ }
+ }
+ v4l2_streamoff(v4l2);
+
+ MSG("Ok!");
+ return disp;
+}
+
int
main(int argc, char **argv)
{
struct display *disp;
struct v4l2 *v4l2;
- struct buffer *framebuf;
- struct buffer **buffers;
- uint32_t fourcc, width, height;
- int ret, i;
+ pthread_t threads[2];
+ struct thr_data tdata[2];
+ void *result = NULL;
+ int ret = 0, i, dual = 0;
MSG("Opening Display..");
disp = disp_open(argc, argv);
return 1;
}
+ for (i = 1; i < argc; i++) {
+ if (!argv[i])
+ continue;
+
+ if (!strcmp("--dual", argv[i])) {
+ dual = 1;
+ argv[i] = NULL;
+ }
+ }
+
MSG("Opening V4L2..");
- v4l2 = v4l2_open(argc, argv, &fourcc, &width, &height);
+ v4l2 = v4l2_open(argc, argv, &tdata[0].fourcc,
+ &tdata[0].width, &tdata[0].height);
if (!v4l2) {
usage(argv[0]);
return 1;
}
+ tdata[0].disp = disp;
+ tdata[0].v4l2 = v4l2;
+ tdata[0].area = FULL;
+
+ if(dual) {
+ MSG("Opening second V4L2..");
+ v4l2 = v4l2_open(argc, argv, &tdata[1].fourcc,
+ &tdata[1].width, &tdata[1].height);
+ if (!v4l2) {
+ usage(argv[0]);
+ return 1;
+ }
+ tdata[1].disp = disp;
+ tdata[1].v4l2 = v4l2;
+ tdata[1].area = OVERLAY;
+ }
if (check_args(argc, argv)) {
/* remaining args.. print usage msg */
return 0;
}
- framebuf = disp_get_fb(disp);
-
- buffers = disp_get_vid_buffers(disp, NBUF, fourcc, width, height);
- if (!buffers) {
- return 1;
- }
-
- ret = v4l2_reqbufs(v4l2, buffers, NBUF);
- if (ret) {
- return 1;
- }
-
- v4l2_qbuf(v4l2, buffers[0]);
- v4l2_streamon(v4l2);
- for (i = 1; i < CNT; i++) {
- v4l2_qbuf(v4l2, buffers[i % NBUF]);
- ret = disp_post_vid_buffer(disp, v4l2_dqbuf(v4l2),
- 0, 0, width, height);
- if (ret) {
- return ret;
+ if(dual) {
+ ret = pthread_create(&threads[0], NULL, capture_loop, &tdata[0]);
+ if(ret) {
+ MSG("Failed creating thread");
}
+ ret = pthread_create(&threads[1], NULL, capture_loop, &tdata[1]);
+ if(ret) {
+ MSG("Failed creating thread");
+ }
+ } else {
+ capture_loop(&tdata[0]);
}
- v4l2_streamoff(v4l2);
- v4l2_dqbuf(v4l2);
- MSG("Ok!");
+ pthread_join(threads[0], &result);
+ pthread_join(threads[1], &result);
+
disp_close(disp);
return ret;
diff --git a/util/v4l2.c b/util/v4l2.c
index 1a5c905186a0a8d9e71a76704c3353800d591261..33293e2ef43a51f9b1c179339c4e1130dfb6682c 100644 (file)
--- a/util/v4l2.c
+++ b/util/v4l2.c
};
struct v4l2 *v4l2;
int i, ret;
- bool mcf = false;
+ bool mcf = false, user_format = false, user_dev = false;
+ char devname[20] = "/dev/video1";
v4l2 = calloc(1, sizeof(*v4l2));
- v4l2->fd = open("/dev/video1", O_RDWR);
-
- ret = ioctl(v4l2->fd, VIDIOC_G_FMT, &format);
- if (ret < 0) {
- ERROR("VIDIOC_G_FMT failed: %s (%d)", strerror(errno), ret);
- goto fail;
- }
/* note: set args to NULL after we've parsed them so other modules know
* that it is already parsed (since the arg parsing is decentralized)
if (!argv[i]) {
continue;
}
- if (!strcmp("-c", argv[i])) {
+ if (!strcmp("-d", argv[i])) {
+ if(user_dev)
+ continue;
+
+ argv[i++] = NULL;
+ if (sscanf(argv[i], "%s", devname) != 1) {
+ ERROR("invalid device node: %s", argv[i]);
+ goto fail;
+ }
+ user_dev = true;
+ } else if (!strcmp("-c", argv[i])) {
+ if(user_format)
+ continue;
+
char fourccstr[5];
argv[i++] = NULL;
if (sscanf(argv[i], "%ux%u@%4s",
- &format.fmt.pix.width,
- &format.fmt.pix.height,
+ width,
+ height,
fourccstr) != 3) {
ERROR("invalid arg: %s", argv[i]);
goto fail;
}
- format.fmt.pix.pixelformat = FOURCC_STR(fourccstr);
+ *fourcc = FOURCC_STR(fourccstr);
+ user_format = true;
} else if (!strcmp(argv[i], "-m")) {
mcf = true;
} else {
argv[i] = NULL;
}
- if ((format.fmt.pix.width == 0) ||
- (format.fmt.pix.height == 0) ||
+ v4l2->fd = open(devname, O_RDWR);
+
+ ret = ioctl(v4l2->fd, VIDIOC_G_FMT, &format);
+ if (ret < 0) {
+ ERROR("VIDIOC_G_FMT failed: %s (%d)", strerror(errno), ret);
+ goto fail;
+ }
+
+ if (user_format) {
+ format.fmt.pix.pixelformat = *fourcc;
+ format.fmt.pix.width = *width;
+ format.fmt.pix.height = *height;
+ }
+
+ if ((format.fmt.pix.width == 0) || (format.fmt.pix.height == 0) ||
(format.fmt.pix.pixelformat == 0)) {
+
ERROR("invalid capture settings '%dx%d@%4s' (did you not use '-c'?)",
- format.fmt.pix.width, format.fmt.pix.height,
- (char *)&format.fmt.pix.pixelformat);
+ format.fmt.pix.width, format.fmt.pix.height,
+ (char *)&format.fmt.pix.pixelformat);
goto fail;
}
- *fourcc = format.fmt.pix.pixelformat;
- *width = format.fmt.pix.width;
- *height = format.fmt.pix.height;
-
if (mcf) {
ret = media_setup(&format);
if (ret < 0) {