<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6359123674111950823</id><updated>2012-02-16T21:05:44.536+11:00</updated><title type='text'>v4l4j</title><subtitle type='html'>Random thoughts about v4l4j's current state and future directions</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://v4l4j.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://v4l4j.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Gilles</name><uri>http://www.blogger.com/profile/11365818069882552580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6359123674111950823.post-309280183902603448</id><published>2010-11-11T16:07:00.001+11:00</published><updated>2010-12-06T14:17:43.387+11:00</updated><title type='text'>Improving frame buffer exchange</title><content type='html'>Ok, I thought it was time for a v4l4j update, and decided to improve the way image buffers are retrieved from libvideo, converted and passed to Java. I ll briefly explain how v4l4j does this now, look at alternative ways of doing things, and explain my choices.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Current design&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;During the call to init_capture(), libvideo maps a certain number of memory chunks   into the driver. v4l4j asks for 4 chunks,&amp;nbsp; but the driver may decide to create more&amp;nbsp; or less. These chunks will hold images captured from the video device. The mappings' addresses are decided by the system call, ie. the memory chunks are not allocated by v4l4j but during the mmap() syscall. &lt;br /&gt;&lt;br /&gt;Then, v4l4j creates as many ByteBuffer objects as there are mmap'ed buffers. Each ByteBuffer has its own memory block used as a storage area backing the ByteBuffer.&lt;br /&gt;&lt;br /&gt;When retrieving the next frame, libvideo's dequeue_buffer() returns a pointer to the mmap'ed buffer containing the latest frame. v4l4j passes it to its conversion routines along with a pointer to a destination buffer where the converted image will be stored. If no conversion is required, a simple copy is made. The destination buffer is the address of the backing buffer behind the first ByteBuffer. (ByteBuffers are then used in a round-robin fashion).&lt;br /&gt;&lt;br /&gt;Last, the contents of the ByteBuffer object is then copied into a java byte array.&lt;br /&gt;&lt;br /&gt;Looking back on it, this is hugely inefficient. There can be up to 3 copy operations plus a possible format conversion. This leaves a lot of room for improvement.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;What can be changed ?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let's start with the end result: from Java, what is the best object type to encapsulate the image data ? When I started v4l4j, I was immediately attracted to the java.nio package and its ByteBuffer class (which is the one used in the current implementation), mostly because it is readily available from native code. However, this may not be the easiest type to deal with when trying to do anything useful with the image inside. Most of the time, the ByteBuffer data has to be transferred to a byte array in order to be used, specially when trying to display the image in a GUI element. I believe a copy can be avoided if the data was readily available in a Java byte[] instead of a ByteBuffer.&lt;br /&gt;&lt;br /&gt;Next, let's see what the best way is to have the latest image stored in a byte array. The ideal option would be to have the byte arrays allocated in the Java code (so as to avoid a new allocation every time a frame arrives), then obtain a C pointer to the byte array and mmap() it in the driver memory, so that new frames are directly placed into the Java byte array. Reading the JNI documentation on arrays thoroughly, there are two ways to obtain a C pointer to a Java byte array: GetByteArrayElements() and GetPrimitiveArrayCritical().&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The first one does not guarantee that the JVM will return a pointer to the actual Java array, ie it may copy the array into a C heap-allocated array and return a pointer to that array, later on synchronised when ReleaseByteArrayElements() is called. Looking at &lt;a href="http://hg.openjdk.java.net/jdk6/jdk6/hotspot/file/b69c41ea1764/src/share/vm/prims/jni.cpp"&gt;the implementation of these methods&lt;/a&gt; in the OpenJDK HotSpot JVM v6 &amp;amp; 7 source code, confirmed one thing: these JVM implementations do indeed copy the Java array into a C array. Always. Bad news ! &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;This leaves us with GetPrimitiveArrayCritical(). Even with this method, the JVM may return a copy of the array, but, in the Javadoc's own words, it is "[...] more likely that the native code will obtain an uncopied version of the array". Looking at the JVM source code again confirmed that the OpenJDK JVM v6 &amp;amp; 7 will always return a pointer to the Java byte array, not a copy. However, the only issue with this method is that the code between GetPrimitiveArrayCritical() and its counterpart ReleasePrimitiveArrayCritical() has very similar restrictions to that of critical sections: it must execute fast, and it must not sleep. This is not good either because if we want the driver to place bytes in our mmap()'ed byte array, we must call libvideo's dequeue_buffer which calls ioctl(DEQUEUE_BUF), which blocks...&lt;/li&gt;&lt;/ul&gt;With this in mind, I came up with the following design:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use mmap() provided memory buffers&lt;/li&gt;&lt;li&gt;Call GetPrimitiveArrayCritical()&lt;/li&gt;&lt;li&gt;Either copy the image into the Java byte array or convert the image directly into the Java byte array&lt;/li&gt;&lt;li&gt;Call ReleasePrimitiveArrayCritical()&lt;/li&gt;&lt;/ul&gt;This way, for each image, the code between the Get/ReleasePrimitivearrayCritical() does not sleep, and at most one copy or one conversion will occur.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6359123674111950823-309280183902603448?l=v4l4j.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://v4l4j.blogspot.com/feeds/309280183902603448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://v4l4j.blogspot.com/2010/11/improving-frame-buffer-exchange.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/309280183902603448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/309280183902603448'/><link rel='alternate' type='text/html' href='http://v4l4j.blogspot.com/2010/11/improving-frame-buffer-exchange.html' title='Improving frame buffer exchange'/><author><name>Gilles</name><uri>http://www.blogger.com/profile/11365818069882552580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6359123674111950823.post-815986916726157805</id><published>2010-02-12T11:30:00.002+11:00</published><updated>2010-02-12T14:20:28.149+11:00</updated><title type='text'>VIDIOC_REQBUFS behaviour</title><content type='html'>&lt;div style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;A few days ago, Daniel posted a message on the v4l4j mailing list with an issue I had not seen before: the test-gui application captures video fine the first time, but subsequent attempts fail. The only way to get the capture going again is by restarting the test application. The entire discussion can be found &lt;a href="http://groups.google.com/group/v4l4j/t/a80cb345876acf76"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Finding out what went wrong&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Looking at the debug log generated by the test application, it is clear that everything works well for the first capture, but when the second is initiated, setting the capture parameters (namely the resolution and pixel format) fails, as indicated by this line in the log:&lt;/div&gt;&lt;pre&gt;[v4l2-input.c:247 apply_image_format] CAP: palette 0x56595559 rejected&lt;/pre&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The requested capture parameters are given to the driver using the&lt;/span&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIO_S_FMT&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; ioctl, which is precisely what causes the second capture to fail, this ioctl call returns&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; EBUSY (device or resource busy). Now, at this point, I could not explain why this ioctl would work the first time, but not the second one.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Looking at the driver side&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I now need to check what the driver does upon reception of an &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIO_S_FMT&lt;/span&gt; ioctl. I updated my mercurial copy of the v4l-dvb tree and took a look at uvc-v4l2.c . The function handling the &lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIO_S_FMT&lt;/span&gt;  ioctl is at line 244 (&lt;/span&gt;uvc_v4l2_set_format() ). This function returns EBUSY if&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; uvc_queue_allocated() != 0&lt;/span&gt;. &lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;A quick look at uvc_queue.c reveals that&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; uvc_queue_allocated()&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; returns 0 if no buffers have been allocated, or if all allocated buffers have been released... &lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;There it is, that's the solution to the problem: making sure no buffers were allocated before calling&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIO_S_FMT&lt;/span&gt;.&lt;/span&gt; &lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;However, I could not remember reading anything about this in the V4L2 API specs when writing v4l4j... So I headed back to the V4L2 specs pages, specifically,&lt;/span&gt; the one about&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;a href="http://v4l2spec.bytesex.org/spec-single/v4l2.html#VIDIOC-G-FMT"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; VIDIO_S_FMT&lt;/span&gt;&lt;/a&gt;  &lt;/span&gt; .&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; I realised that I overlooked this (self-explanatory) line:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;When I/O is already in progress or the resource is not available for other reasons drivers return the &lt;span class="ERRORCODE"&gt;EBUSY&lt;/span&gt; error code.&lt;/blockquote&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;How to release buffers&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Here again, I could not remember reading anything about this in the V4L2 specs at the time I wrote v4l4j. Buffers are requested using the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIOC_REQBUF&lt;/span&gt; ioctl. Back in uvc_v4l2.c, it is clear by reading the code handling &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIOC_REQBUF&lt;/span&gt; (at line 867) that this ioctl can be called with a value of 0 for the number of buffers requested. A quick look at the documentation for this ioctl (&lt;a href="http://v4l2spec.bytesex.org/spec-single/v4l2.html#VIDIOC-REQBUFS"&gt;here&lt;/a&gt;) indicates that a value of 0 is perfectly acceptable... Weird, I really dont remember reading this, maybe it was added afterwards. Just to confirmed whether it's something recent, I decided to take a quick look at other drivers to see if they also accept a value of 0 when calling &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;VIDIOC_REQBUF&lt;/span&gt; . Interestingly, the pwc driver will silently ignore it and do nothing. The gspca driver will gladly accept a value of 0, and release existing buffers. On the other hand, the bttv and zr364xx drivers both use the V4L-generic function videobuf_reqbufs() (in videobuf-core.c) to do the buffer allocation, which will fail (EINVAL) with a buffer count of 0. It seems that different drivers behave differently when handling this ioctl... I should (and will) discuss that on the V4L mailing list.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Solves Daniel's problem ?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I now needed to confirm whether or not these findings would help solving Daniel's issue.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I quickly hacked up a simple capture application (&lt;a href="http://v4l4j.googlecode.com/svn/v4l4j/utils/capture-test"&gt;here&lt;/a&gt;) which runs a video capture twice. Without releasing the buffers, the capture fails the second time (just like it did with the v4l4j test-gui app). And releasing the buffers does allow capture the second time !!!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Next, implementing the fix in v4l4j&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I am still working on this one. However, because it seems some drivers will fail when asked to release buffers, I will probably end up adding code to release allocated buffers when stopping an on-going capture and ignore the result.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6359123674111950823-815986916726157805?l=v4l4j.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://v4l4j.blogspot.com/feeds/815986916726157805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://v4l4j.blogspot.com/2010/02/vidiocreqbufs-behaviour.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/815986916726157805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/815986916726157805'/><link rel='alternate' type='text/html' href='http://v4l4j.blogspot.com/2010/02/vidiocreqbufs-behaviour.html' title='VIDIOC_REQBUFS behaviour'/><author><name>Gilles</name><uri>http://www.blogger.com/profile/11365818069882552580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6359123674111950823.post-6850564300282574218</id><published>2009-10-03T12:02:00.001+10:00</published><updated>2009-10-03T12:11:01.969+10:00</updated><title type='text'>Ideas for future work on v4l4j</title><content type='html'>These are some of the ideas I came up with, to add functionality to v4l4j and achieve better integratation it with other projects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Review and perhaps improve the way frames are given to the user. For now, ByteBuffers are used but they involve a memory copy operation, at least to transfer the contents of the ByteBuffer to a byte array which can be then passed on to other SWING objects for display. It might not be necessary when doing video streaming over the network for instance (I believe it is possible to&amp;nbsp; send the contents of the ByteBuffer to a socket without extra copy, but I have not tested this). Also worth investigating is whether implementing a push model would be useful.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Add support for MPEG image format: in order to achieve this, libvideo must first be modified to return not just a pointer to the frame buffer, but most of the fields present in the &lt;a href="http://v4l2spec.bytesex.org/spec/x5953.htm#V4L2-BUFFER"&gt;struct v4l2_buffer&lt;/a&gt; so as to report timecode, frame type, ... The reason I havent implemented things this way originally, is because MPEG is only available in v4l2, and I wanted to investigate more how to emulate (or fake) these fields that are present in v4l2 but missing in v4l1. However, with a bit more experience now and after making libvideo fake (a lot) of missing things to make it behave like v4l2 in a lot of ways, I believe it shouldnt be too hard to implment.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Integration with &lt;a href="http://fmj-sf.net/"&gt;FMJ&lt;/a&gt;: FMJ is an open source implementation of the (now dead) JMF (Java Media Framework). FMJ is API-compatible with JMF, so applications written to use JMF can (in theory, not tested) work with FMj without modification. Alexandra has submitted &lt;a href="http://groups.google.com/group/v4l4j/browse_thread/thread/61bb1604f66a69fc"&gt;some sample code&lt;/a&gt; to quickly create a JMF DataSource out of a v4l4j VideoDevice, but it needs some refactoring.&lt;/li&gt;&lt;li&gt;Since I am currently deeply involved with DirectShow at work, I cant help but thinking about making v4l4j use DirectShow to capture video streams. Of course, the v4l part in v4l4j wont be too relevant there, but I think a project rename is acceptable if it means supporting addtional platforms. &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This is all I can think for now.&amp;nbsp; As always, comments (on &lt;a href="http://groups.google.com/group/v4l4j/topics"&gt;the mailing list &lt;/a&gt;please) are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6359123674111950823-6850564300282574218?l=v4l4j.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://v4l4j.blogspot.com/feeds/6850564300282574218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://v4l4j.blogspot.com/2009/10/ideas-for-future-work-on-v4l4j.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/6850564300282574218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/6850564300282574218'/><link rel='alternate' type='text/html' href='http://v4l4j.blogspot.com/2009/10/ideas-for-future-work-on-v4l4j.html' title='Ideas for future work on v4l4j'/><author><name>Gilles</name><uri>http://www.blogger.com/profile/11365818069882552580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6359123674111950823.post-3180901797780546675</id><published>2009-08-31T21:01:00.001+10:00</published><updated>2010-02-12T16:33:38.587+11:00</updated><title type='text'>Changelog for v0.8.6</title><content type='html'>v4l4j 0.8.6 packs in support for a brand new feature: dealing with capture frame rate.&lt;br /&gt;&lt;br /&gt;With this version, an application can dynamically find out wheter a video device supports adjustable capture frame rates, enumerate them and set an appropriate one for capture.&lt;br /&gt;Of course, this feature is available only if the driver and video device support it. I have made a few test with the hardware I have at hands and I managed to achieve capture rates of up to 30 frame per seconds ! I have listed my results on &lt;a href="http://code.google.com/p/v4l4j/wiki/FrameInterval"&gt;this wiki page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6359123674111950823-3180901797780546675?l=v4l4j.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://v4l4j.blogspot.com/feeds/3180901797780546675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://v4l4j.blogspot.com/2009/08/changelog-for-v086.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/3180901797780546675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/3180901797780546675'/><link rel='alternate' type='text/html' href='http://v4l4j.blogspot.com/2009/08/changelog-for-v086.html' title='Changelog for v0.8.6'/><author><name>Gilles</name><uri>http://www.blogger.com/profile/11365818069882552580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6359123674111950823.post-1081347318337048614</id><published>2009-08-31T20:44:00.000+10:00</published><updated>2009-08-31T20:44:49.680+10:00</updated><title type='text'>First post</title><content type='html'>I have just setup this blog about a project I have been running for a while now: &lt;a href="http://v4l4j.googlecode.com/"&gt;v4l4j&lt;/a&gt;. In short, the goal of v4l4j is to bring video capture capability &amp;amp; video device control to Java. It is an API through which a Java application can :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;enumerate capabilities of a video device, such as the supported image format, resolution and frame rate,&lt;/li&gt;&lt;li&gt; setup a video device and capture images from it,&lt;/li&gt;&lt;li&gt;enumerate video controls and act on them.&lt;/li&gt;&lt;/ul&gt;A lot more information is available on the website.&lt;br /&gt;&lt;br /&gt;With this blog, I am hoping to post design ideas, future directions &amp;amp; improvements as well as keeping a changelog of updates to v4l4j.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6359123674111950823-1081347318337048614?l=v4l4j.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://v4l4j.blogspot.com/feeds/1081347318337048614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://v4l4j.blogspot.com/2009/08/first-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/1081347318337048614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6359123674111950823/posts/default/1081347318337048614'/><link rel='alternate' type='text/html' href='http://v4l4j.blogspot.com/2009/08/first-post.html' title='First post'/><author><name>Gilles</name><uri>http://www.blogger.com/profile/11365818069882552580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
