diff options
Diffstat (limited to 'v4l2-mfc-example/main.c')
-rw-r--r-- | v4l2-mfc-example/main.c | 81 |
1 files changed, 66 insertions, 15 deletions
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 <k.debski@samsung.com>\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; } |