Forum Replies Created
-
AuthorPosts
-
Participant
I’d love to have this feature too
I was going to wrap Linux v4l2 API but just haven’t had the chance. Native cross platform support would be great though, especially on mobile devices!
July 25, 2016 at 2:13 am in reply to: Should "asset::" be plural? #2413Why not allow either?
July 19, 2016 at 9:42 pm in reply to: module std/graphics/color.monkey2 additions #2287As long as documentation is good. I don’t see where the confusion would be. I know of no other paint or color program that deals with rgb data as floats, so to me this is a different kind of inconsistency. Quite actually I’d also like an overload for htmlcolor strings as well
Nevertheless. For my own needs I’ll just extend Color and add my own overloads- was just adding my opinion
July 19, 2016 at 8:56 pm in reply to: module std/graphics/color.monkey2 additions #2285I would like to see the New method overloaded for a more common convention of using 0-255 Ints while creating colors. Of course, floats would still be used internally, but for convenience I think this would be nice
Monkey12Method New( r:Int,g:Int,b:Int,a:Float=1 )July 19, 2016 at 11:19 am in reply to: Generator ? #2277Mark covered implementing Generators using Fibers and gives a few examples in his Feb 1st “Fun with fibers” blog post on the main page. It has all the info you need to make your own generators
July 15, 2016 at 1:28 am in reply to: Latest files on GitHub #2151ParticipantIt’s pretty easy
Install git
From the command line in the directory you want to clone monkey 2 to, run:
git clone https://github.com/blitz-research/monkey2.git
That’ll install the current build. Then anytime you want to pull in New changes just run
git pull
And files will be updated. Rebuildall and you’re set
July 7, 2016 at 4:49 pm in reply to: Developing modules in parallel with a game #1846I do pretty much what Mark suggested – just build them as extra source files during development until I feel they are done, then I’ll make them into a module if I feel it’s something I might use again.
I’m not a huge fan of the modules system yet in Monkey2 yet though. I think the ability to organize in subfolders is a must, as my modules folder is already a jumbled mess. I really liked how it was implemented in BlitzMax. All of BRL’s stuff was in brl.mod, and each subfolder could be another module. Under BMX, I had my own jmd.mod, with several individual modules that I could import one at a time if needed.
July 7, 2016 at 4:42 pm
in reply to: monkey2-pi release 001
#1845
ParticipantI’m still looking forward to seeing this as well
ParticipantI have a couple modules I would upload, add me in
July 4, 2016 at 6:34 pm
in reply to: PixMap->Image bug
#1727
ParticipantGood point – I actually didn’t know that that the Color class worked in 0.0 to 1.0 for the R G B aspects, the documentation wasn’t clear. But looking at color.monkey2 I can see you’re right. Either way, there seems to be a problem converting from pixmap colorspace to Image colorspace somewhere in the mojo code
July 4, 2016 at 3:16 pm
in reply to: monkey2-pi release 001
#1694
ParticipantI’m looking forward to trying this when I get a chance. I hope Mark decides to merge in changes – there are a ton of great ARM boards available and there will be no shortage of them in the future either
July 3, 2016 at 8:58 pm
in reply to: Help converting old Blitzmax code that uses Extern
#1660
ParticipantThanks guys, I knew it was going to be something that makes a lot of sense once I heard it!
July 3, 2016 at 7:27 pm
in reply to: Help converting old Blitzmax code that uses Extern
#1655
ParticipantHere’s the contents of v4l2.c if it helps at all…
Monkey
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <getopt.h> // getopt_long()#include <fcntl.h> // low-level i/o#include <unistd.h>#include <errno.h>#include <malloc.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/time.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <asm/types.h> // for videodev2.h#include <linux/videodev2.h> // the meat and potatoes#define CLEAR(x) memset (&(x), 0, sizeof (x))//GLOBALS TO IMPORT INTO BLITZ MAX (with sensible defaults)char *dev_name = "/dev/video0";//NULL;int dev_width = 640;int dev_height = 480;//END GLOBALSint pix_pitch = 3; //3 bytes - R, G and Btypedef enum {IO_METHOD_READ,IO_METHOD_MMAP,IO_METHOD_USERPTR,r} io_method;struct buffer {void * start;size_t length;};struct buffer *buffers = NULL;io_method io = IO_METHOD_MMAP;int fd = -1;unsigned int n_buffers = 0;void errno_exit(const char *s){fprintf (stderr, "%s error %d, %sn",s, errno, strerror (errno));exit (EXIT_FAILURE);}int xioctl(int fd,int request,void *arg){int r;do r = ioctl (fd, request, arg);while (-1 == r && EINTR == errno);return r;}int read_frame(void){struct v4l2_buffer buf;unsigned int i;switch (io) {case IO_METHOD_READ:if (-1 == read (fd, buffers[0].start, buffers[0].length)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit ("read");}}break;case IO_METHOD_MMAP:CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit ("VIDIOC_DQBUF");}}assert (buf.index < n_buffers);if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");break;case IO_METHOD_USERPTR:CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_USERPTR;if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit ("VIDIOC_DQBUF");}}for (i = 0; i < n_buffers; ++i)if (buf.m.userptr == (unsigned long) buffers[i].start&& buf.length == buffers[i].length)break;assert (i < n_buffers);if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");break;}return 1;}unsigned char *grab_one(){unsigned char *buf_rgb24[dev_width*dev_height];for (;;) {fd_set fds;struct timeval tv;int r;FD_ZERO (&fds);FD_SET (fd, &fds);// Timeout.tv.tv_sec = 2;tv.tv_usec = 0;r = select (fd + 1, &fds, NULL, NULL, &tv);if (-1 == r) {if (EINTR == errno)continue;errno_exit ("select");}if (0 == r) {fprintf (stderr, "select timeoutn");exit (EXIT_FAILURE);}if (read_frame ()) {//yuyv2rgb(buffers[0].start,dev_width, dev_height);yuyv_to_rgb24 (dev_width, dev_height, buffers[0].start, buf_rgb24);return buf_rgb24;//buffers[0].start;}}}void stop_capturing(void){enum v4l2_buf_type type;switch (io) {case IO_METHOD_READ:/* Nothing to do. */break;case IO_METHOD_MMAP:case IO_METHOD_USERPTR:type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))errno_exit ("VIDIOC_STREAMOFF");break;}}void start_capturing(void){unsigned int i;enum v4l2_buf_type type;switch (io) {case IO_METHOD_READ:/* Nothing to do. */break;case IO_METHOD_MMAP:for (i = 0; i < n_buffers; ++i) {struct v4l2_buffer buf;CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = i;if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");}type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))errno_exit ("VIDIOC_STREAMON");break;case IO_METHOD_USERPTR:for (i = 0; i < n_buffers; ++i) {struct v4l2_buffer buf;CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_USERPTR;buf.index = i;buf.m.userptr = (unsigned long) buffers[i].start;buf.length = buffers[i].length;if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");}type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))errno_exit ("VIDIOC_STREAMON");break;}}void uninit_device(void){unsigned int i;switch (io) {case IO_METHOD_READ:free (buffers[0].start);break;case IO_METHOD_MMAP:for (i = 0; i < n_buffers; ++i)if (-1 == munmap (buffers[i].start, buffers[i].length))errno_exit ("munmap");break;case IO_METHOD_USERPTR:for (i = 0; i < n_buffers; ++i)free (buffers[i].start);break;}free (buffers);}void init_read(unsigned int buffer_size){buffers = calloc (1, sizeof (*buffers));if (!buffers) {fprintf (stderr, "Out of memoryn");exit (EXIT_FAILURE);}buffers[0].length = buffer_size;buffers[0].start = malloc (buffer_size);if (!buffers[0].start) {fprintf (stderr, "Out of memoryn");exit (EXIT_FAILURE);}}void init_mmap(void){struct v4l2_requestbuffers req;CLEAR (req);req.count = 4;req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory = V4L2_MEMORY_MMAP;if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {if (EINVAL == errno) {fprintf (stderr, "%s does not support ""memory mappingn", dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_REQBUFS");}}if (req.count < 2) {fprintf (stderr, "Insufficient buffer memory on %sn",dev_name);exit (EXIT_FAILURE);}buffers = calloc (req.count, sizeof (*buffers));if (!buffers) {fprintf (stderr, "Out of memoryn");exit (EXIT_FAILURE);}for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {struct v4l2_buffer buf;CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = n_buffers;if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))errno_exit ("VIDIOC_QUERYBUF");buffers[n_buffers].length = buf.length;buffers[n_buffers].start =mmap (NULL /* start anywhere */,buf.length,PROT_READ | PROT_WRITE /* required */,MAP_SHARED /* recommended */,fd, buf.m.offset);if (MAP_FAILED == buffers[n_buffers].start)errno_exit ("mmap");}}void init_userp(unsigned int buffer_size){struct v4l2_requestbuffers req;unsigned int page_size;page_size = getpagesize ();buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);CLEAR (req);req.count = 4;req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory = V4L2_MEMORY_USERPTR;if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {if (EINVAL == errno) {fprintf (stderr, "%s does not support ""user pointer i/on", dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_REQBUFS");}}buffers = calloc (4, sizeof (*buffers));if (!buffers) {fprintf (stderr, "Out of memoryn");exit (EXIT_FAILURE);}for (n_buffers = 0; n_buffers < 4; ++n_buffers) {buffers[n_buffers].length = buffer_size;buffers[n_buffers].start = memalign (/* boundary */ page_size,buffer_size);if (!buffers[n_buffers].start) {fprintf (stderr, "Out of memoryn");exit (EXIT_FAILURE);}}}void init_device(void){struct v4l2_capability cap;struct v4l2_cropcap cropcap;struct v4l2_crop crop;struct v4l2_format fmt;struct v4l2_input input;v4l2_std_id std_id;unsigned int min;if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {if (EINVAL == errno) {fprintf (stderr, "%s is no V4L2 devicen",dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_QUERYCAP");}}if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {fprintf (stderr, "%s is no video capture devicen",dev_name);exit (EXIT_FAILURE);}switch (io) {case IO_METHOD_READ:if (!(cap.capabilities & V4L2_CAP_READWRITE)) {fprintf (stderr, "%s does not support read i/on",dev_name);exit (EXIT_FAILURE);}break;case IO_METHOD_MMAP:case IO_METHOD_USERPTR:if (!(cap.capabilities & V4L2_CAP_STREAMING)) {fprintf (stderr, "%s does not support streaming i/on",dev_name);exit (EXIT_FAILURE);}break;}/* Select video input, video standard and tune here.memset (&input, 0, sizeof (input));if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) {perror ("VIDIOC_G_INPUT");exit (EXIT_FAILURE);}if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) {perror ("VIDIOC_ENUM_INPUT");exit (EXIT_FAILURE);}if (0 == (input.std & V4L2_PAL_BG)) {fprintf (stderr, "Oops. B/G PAL is not supported.n");exit (EXIT_FAILURE);}*/CLEAR (cropcap);cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;crop.c = cropcap.defrect; /* reset to default */if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {switch (errno) {case EINVAL:/* Cropping not supported. */break;default:/* Errors ignored. */break;}}} else {/* Errors ignored. */}CLEAR (fmt);fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.width = dev_width;fmt.fmt.pix.height = dev_height;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))errno_exit ("VIDIOC_S_FMT");/* Note VIDIOC_S_FMT may change width and height. *//* Buggy driver paranoia. */min = fmt.fmt.pix.width * 2;if (fmt.fmt.pix.bytesperline < min)fmt.fmt.pix.bytesperline = min;min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;if (fmt.fmt.pix.sizeimage < min)fmt.fmt.pix.sizeimage = min;switch (io) {case IO_METHOD_READ:init_read (fmt.fmt.pix.sizeimage);break;case IO_METHOD_MMAP:init_mmap ();break;case IO_METHOD_USERPTR:init_userp (fmt.fmt.pix.sizeimage);break;}}void close_device(void){if (-1 == close (fd))errno_exit ("close");fd = -1;}void open_device(void){struct stat st;if (-1 == stat (dev_name, &st)) {fprintf (stderr, "Cannot identify '%s': %d, %sn",dev_name, errno, strerror (errno));exit (EXIT_FAILURE);}if (!S_ISCHR (st.st_mode)) {fprintf (stderr, "%s is no devicen", dev_name);exit (EXIT_FAILURE);}fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);if (-1 == fd) {fprintf (stderr, "Cannot open '%s': %d, %sn",dev_name, errno, strerror (errno));exit (EXIT_FAILURE);}}//Convert from YUV 4:2:2 to RGB24 format!void yuyv_to_rgb24 (int width, int height, unsigned int *src, unsigned char *dst){unsigned char *s;unsigned char *d;int l, c;int r, g, b, cr, cg, cb, y1, y2;l = height;s = src;d = dst;while (l--) {c = width >> 1;while (c--) {y1 = *s++;cb = ((*s - 128) * 454) >> 8;cg = (*s++ - 128) * 88;y2 = *s++;cr = ((*s - 128) * 359) >> 8;cg = (cg + (*s++ - 128) * 183) >> 8;r = y1 + cr;b = y1 + cb;g = y1 - cg;r=limit(r,0,255);g=limit(g,0,255);b=limit(b,0,255);*d++ = r;*d++ = g;*d++ = b;r = y2 + cr;b = y2 + cb;g = y2 - cg;r=limit(r,0,255);g=limit(g,0,255);b=limit(b,0,255);*d++ = r;*d++ = g;*d++ = b;}}}int limit(int val, int min, int max) {if(val<min)return min;if(val>max)return max;return val;}I’ve played with this all day and still the defined Externs refuse to be recognized
July 3, 2016 at 4:39 pm in reply to: V1.0.0 now out and hearts are back! #1645ParticipantI jumped on the Patreon funding wagon – same username
Looking forward to seeing Monkey2 grow
July 3, 2016 at 2:50 pm
in reply to: Help converting old Blitzmax code that uses Extern
#1639
Participant<deleted>
-
AuthorPosts