About Monkey 2 › Forums › Monkey 2 Programming Help › Help converting old Blitzmax code that uses Extern
This topic contains 5 replies, has 3 voices, and was last updated by
jondecker76
2 years, 9 months ago.
-
AuthorPosts
-
July 3, 2016 at 1:04 pm #1635
I’ve been bashing my face against a wall trying to figure out Externs in monkey2.
Here is my old BMax code that would grab images from a webcam
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116Import "v4l2.c"Import "TWebcam.bmx"ExternGlobal dev_name:Byte PtrGlobal dev_width:IntGlobal dev_height:IntFunction open_device()Function init_device()Function start_capturing()Function stop_capturing()Function uninit_device()Function close_device()Function grab_one:Byte Ptr()End ExternType Tv4l2 Extends TWebCamFunction Create:Tv4l2(dev:String, width:Int, height:Int,Threaded:Int)Local a:Tv4l2a = New Tv4l2dev_name = dev.tocstring()dev_width = widthdev_height = heighta.pixmap:TPixmap = CreatePixmap(dev_width,dev_height,PF_RGB888)a.grabbedPixmap=CreatePixmap(dev_width,dev_height,PF_RGB888)'a.pixmap.ClearPixels(255)If Threadeda.pixmapMutex=CreateMutex()'a.imageMutex = CreateMutex()a.isThreaded=TrueElsea.isThreaded=FalseEndIfReturn aEnd FunctionMethod open()open_device()init_device()start_capturing()End MethodMethod Update()If isThreadedIf Not threadthread=CreateThread(GetFrame,Self)EndIfElseGetFrame(Self)EndIfEnd MethodFunction GetFrame:Object(thisObject:Object)Local _self:Tv4l2 = Tv4l2(thisObject)Repeat_Self.grabbedPixmap.pixels=grab_one()'Update the instance's pixmapIf _Self.pixmapMutex Then LockMutex(_Self.pixmapMutex)If _Self.grabbedPixMap Then _Self.pixmap=_Self.grabbedPixMap 'TODO: maybe copypixmap?If _Self.pixmapMutex Then UnlockMutex(_self.pixmapMutex)'Update the instance's image'If _Self.imageMutex Then LockMutex(_Self.imageMutex)'If _Self.pixmap Then _Self.image=LoadImage(_Self.pixmap)'If _Self.imageMutex Then UnlockMutex(_Self.imageMutex)Until _self.isThreaded=FalseEnd FunctionMethod Draw(x:Int,y:Int,w:Int,h:Int,mirrored:Byte=True)Local scalex:FloatLocal scaley:FloatLocal thisImage:TImagescalex = Float(w) / Float(dev_width)scaley = Float(h) / Float(dev_height)If(mirrored) Then scalex=scalex * -1SetScale(scalex,scaley)If pixmap<>NullIf Self.pixmapMutex Then LockMutex Self.pixmapMutexthisImage=LoadImage(pixmap)If Self.pixmapMutex Then UnlockMutex Self.pixmapMutexDrawImage(thisImage,x+w,y)EndIfSetScale(1.0,1.0)End MethodMethod GetPixmap:TPixmap()Local thisPixmap:TPixmap = CreatePixmap(dev_width,dev_height,PF_RGB888)If Self.pixmapMutex Then LockMutex(Self.pixmapMutex)thisPixmap=CopyPixmap(Self.pixmap)If Self.pixmapMutex Then UnlockMutex(Self.pixmapMutex)Return thisPixmapEnd MethodMethod close()Self.isThreaded = FalseDelay(100) 'TODO: is this delay needed or too long??stop_capturing()uninit_device()close_device()End MethodEnd Type'=========================================='END V4L2 STUFF'==========================================I’ve converted most of the code (minus some threading stuff that isn’t present yet in monkey2)
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144Namespace webcam#Import "v4l2.c"#Import "<std>"#Import "<mojo>"Using std..Using mojo..'#Import "cam.monkey2"Extern publicGlobal dev_name:Byte PtrGlobal dev_width:IntGlobal dev_height:IntFunction open_device()Function init_device()Function start_capturing()Function stop_capturing()Function uninit_device()Function close_device()Function grab_one:UByte Ptr()PublicClass Webcam 'Extends Webcam' Grabbed from cam.monkey2!Field pixmap:PixmapField grabbedPixmap:Pixmap'Field thread:TThread'Field pixmapMutex:TMutexField isThreaded:ByteMethod New(dev:String, width:Int, height:Int,Threaded:Bool)dev.ToCString(dev_name)dev_width = widthdev_height = heightpixmap = New Pixmap(dev_width,dev_height,PixelFormat.RGB24)grabbedPixmap = New Pixmap(dev_width,dev_height,PixelFormat.RGB24)pixmap.Clear(New Color(0,0,0,1))If Threaded'pixmapMutex=CreateMutex()'imageMutex = CreateMutex()isThreaded=TrueElseisThreaded=FalseEndIfEnd MethodMethod open()open_device()init_device()start_capturing()End MethodMethod Update()'If isThreaded' If Not thread'thread=CreateThread(GetFrame,Self)' EndIf'ElseGetFrame()'EndIfEnd MethodMethod GetFrame()'Local _self:Tv4l2 = Tv4l2(thisObject)'Repeat'grabbedPixmap.pixels=grab_one()grabbedPixmap = New Pixmap(dev_width,dev_height,PixelFormat.RGB24,grab_one(),1)'Update the instance's pixmap'If _Self.pixmapMutex Then LockMutex(_Self.pixmapMutex)If grabbedPixmap Then pixmap=grabbedPixmap 'TODO: maybe copypixmap?'If _Self.pixmapMutex Then UnlockMutex(_self.pixmapMutex)'Update the instance's image'If _Self.imageMutex Then LockMutex(_Self.imageMutex)'If pixmap Then image=LoadImage(_Self.pixmap)'If _Self.imageMutex Then UnlockMutex(_Self.imageMutex)'Until _self.isThreaded=FalseEndMethod Draw(x:Int,y:Int,w:Int,h:Int,mirrored:Byte=True)Local scalex:FloatLocal scaley:FloatLocal thisImage:Imagescalex = Float(w) / Float(dev_width)scaley = Float(h) / Float(dev_height)If(mirrored) Then scalex=scalex * -1'SetScale(scalex,scaley)If pixmap<>Null'If Self.pixmapMutex Then LockMutex Self.pixmapMutexthisImage=New Image(pixmap)'If Self.pixmapMutex Then UnlockMutex Self.pixmapMutex'DrawImage(thisImage,x+w,y)EndIf'SetScale(1.0,1.0)End MethodMethod GetPixmap:Pixmap()' THIS DOES NOT APPEAR TO BE USED'Local thisPixmap:= New Pixmap(dev_width,dev_height,PF_RGB888)'If Self.pixmapMutex Then LockMutex(Self.pixmapMutex)'thisPixmap=CopyPixmap(Self.pixmap)'If Self.pixmapMutex Then UnlockMutex(Self.pixmapMutex)'Return thisPixmapReturn pixmapEnd MethodMethod GetImage:Image()Return New Image(pixmap)EndMethod close()Self.isThreaded = False'Delay(100) 'TODO: is this delay needed or too long??stop_capturing()uninit_device()close_device()End MethodEnd Class'=========================================='END V4L2 STUFF'==========================================Function Main()endBut I’m pretty sure that I’m not getting the externs correct, causing all kinds of problems just trying to compile. Here are my errors trying to compile the module:
Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061Parsing...Semanting...Translating...Compiling....Build error: System command 'g++ -std=c++11 -O3 -DNDEBUG -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/freetype/freetype-2.6.3/include/" -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/sdl2-mixer/SDL_mixer/" -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/sdl2/SDL/include/" -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/monkey/native" -c -o "/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_0webcam.cpp.o" "/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp"' failed.g++ -std=c++11 -O3 -DNDEBUG -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/freetype/freetype-2.6.3/include/" -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/sdl2-mixer/SDL_mixer/" -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/sdl2/SDL/include/" -I"/home/jondecker76/Downloads/monkey2-1.0.0/modules/monkey/native" -c -o "/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_0webcam.cpp.o" "/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp"/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp: In constructor t_webcam_Webcam::t_webcam_Webcam(bbString, bbInt, bbInt, bbBool):/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:18:28: error: dev_name was not declared in this scopel_dev.toCString(((void*)(dev_name)));^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:19:3: error: dev_width was not declared in this scopedev_width=l_width;^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:20:3: error: dev_height was not declared in this scopedev_height=l_height;^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp: In member function void t_webcam_Webcam::m_open():/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:32:15: error: open_device was not declared in this scopeopen_device();^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:33:15: error: init_device was not declared in this scopeinit_device();^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:34:19: error: start_capturing was not declared in this scopestart_capturing();^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp: In member function void t_webcam_Webcam::m_close():/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:39:18: error: stop_capturing was not declared in this scopestop_capturing();^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:40:17: error: uninit_device was not declared in this scopeuninit_device();^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:41:16: error: close_device was not declared in this scopeclose_device();^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp: In member function void t_webcam_Webcam::m_GetFrame():/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:57:56: error: dev_width was not declared in this scopethis->m_grabbedPixmap=bbGCNew<t_std_graphics_Pixmap>(dev_width,dev_height,4,grab_one(),1);^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:57:66: error: dev_height was not declared in this scopethis->m_grabbedPixmap=bbGCNew<t_std_graphics_Pixmap>(dev_width,dev_height,4,grab_one(),1);^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:57:88: error: grab_one was not declared in this scopethis->m_grabbedPixmap=bbGCNew<t_std_graphics_Pixmap>(dev_width,dev_height,4,grab_one(),1);^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp: In member function void t_webcam_Webcam::m_Draw(bbInt, bbInt, bbInt, bbInt, bbByte):/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:72:34: error: dev_width was not declared in this scopel_scalex=(bbFloat(l_w)/bbFloat(dev_width));^/home/jondecker76/Downloads/monkey2-1.0.0/modules/webcam/webcam.buildv1.0.0/build_cache/desktop_release_linux/webcam_webcam.cpp:73:34: error: dev_height was not declared in this scopel_scaley=(bbFloat(l_h)/bbFloat(dev_height));^***** Fatal mx2cc error *****Build error.It’s not seeing any of the defined externs
Any thoughts?July 3, 2016 at 2:50 pm #1639<deleted>
July 3, 2016 at 7:27 pm #1655Here’s the contents of v4l2.c if it helps at all…
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622#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, %s\n",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 timeout\n");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 memory\n");exit (EXIT_FAILURE);}buffers[0].length = buffer_size;buffers[0].start = malloc (buffer_size);if (!buffers[0].start) {fprintf (stderr, "Out of memory\n");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 mapping\n", dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_REQBUFS");}}if (req.count < 2) {fprintf (stderr, "Insufficient buffer memory on %s\n",dev_name);exit (EXIT_FAILURE);}buffers = calloc (req.count, sizeof (*buffers));if (!buffers) {fprintf (stderr, "Out of memory\n");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/o\n", dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_REQBUFS");}}buffers = calloc (4, sizeof (*buffers));if (!buffers) {fprintf (stderr, "Out of memory\n");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 memory\n");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 device\n",dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_QUERYCAP");}}if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {fprintf (stderr, "%s is no video capture device\n",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/o\n",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/o\n",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, %s\n",dev_name, errno, strerror (errno));exit (EXIT_FAILURE);}if (!S_ISCHR (st.st_mode)) {fprintf (stderr, "%s is no device\n", dev_name);exit (EXIT_FAILURE);}fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);if (-1 == fd) {fprintf (stderr, "Cannot open '%s': %d, %s\n",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 8:18 pm #1657You need a .h file that declares the externs, and the monkey2 code needs to import that too, eg:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142// file v412.h - contains declarations only.//#ifndef BB_V412_H#define BB_V412_H#ifdef __cplusplusextern "C"{#endifextern char *dev_name;extern void init_device();...etc...#ifdef __cplusplus}#endif#endif// file v412.c - contains definitions, ie: actual code//#include "v412.h"char *dev_name;void init_device(){}...etc...' file v412.monkey2#import "v412.c"#import "v412.h"...etc...The weird #ifdef __cplusplus stuff is necessary because c and c++ ‘mangle’ names differently. If you make the c file a cpp file instead, you can ditch this.
Also, you might want to prefix all the native code idents with ‘v412_’ or something to prevent potential name clashes with other native code.
July 3, 2016 at 8:21 pm #1658From a quick browse I would change Extern Public to plain Extern and add a header file.
In monkey2, importing “v4l2.c” adds that file to a list for compiling and linking but I’m pretty sure monkey2 needs an additional “v4l2.h” file to be able to compile your monkey2 code.
Oops too late.
July 3, 2016 at 8:58 pm #1660Thanks guys, I knew it was going to be something that makes a lot of sense once I heard it!
-
AuthorPosts
You must be logged in to reply to this topic.