so i am doing a project that involves v4l2 video capturing applications, and so i am reading this one example that they give here: http://v4l2spec.bytesex.org/spec/a16706.htm
and a little ways down it defines 'buffers' as a pointer to a structure of type 'buffer':
struct buffer
{
void * start;
size_t length;
};
struct buffer * buffers = NULL;
first off, what does it mean if the pointer is NULL? it just does not point to any place in particular? that sees odd to me...
anyways, from there, at one point the program calls the function read():
if (-1 == read (fd, buffers[0].start, buffers[0].length)) {
//error handling things
}
my question is, what does the [0] mean? i can understand that the program tells it to read from the location pointed to by buffers.start for buffers.length many bits, but what does the [0] have to do with it? and why did they declare the pointer as NULL? thanks! much appreciated!
first off, what does it mean if the pointer is NULL?
You are correct in thinking that setting a pointer to NULL tells it to point to nowhere. The reason why NULL is used is because it is safer than simply having the pointer point to random garbage. Because:
1) you can easily check to see if a pointer is NULL (invalid) before dereferencing.
ie: if(myponter) { dothejob(); } else {dont(); }
2) If you do happen to dereference it, it will instantly crash the program instead of corrupting memory. This makes it much easier to track down bugs which occur due to dereferencing a bad pointer.
what does the [0] mean?
'buffers' is a pointer. you can't do buffers.start because the '.' operator works on objects, not on pointers to objects. Therefore the [0] dereferences the pointer (via indexing), getting the object.
There are a few ways to do this in C/C++:
1 2 3 4 5
buffers->start // dereferences the pointer with the -> operator
buffers[0].start // indexes buffers, returning the first object
// pointed to by 'buffers', and accessing its member with .
(*buffers).start // dereferences the pointer with the * operator
// then accesses the member with .
Those 3 lines of code all do exactly the same thing.
for (;;) {
fd_set fds;
struct timeval tv; //defined in <sys/time.h>, tv_sec = value returned from time(), tv_usec = # of usecs into that.
int r;
FD_ZERO (&fds);
FD_SET (fd, &fds);
/* Timeout. */
tv.tv_sec = 2; //2 seconds
tv.tv_usec = 0; //and 0 microseconds
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 ())
break;
/* EAGAIN - continue select loop. */
}
so i do not really understand what is going on here. first off, what are FD_ZERO and FD_SET? i imagine they have something to do with filedescriptors, but i do not know where they are defined. (and what is the type fd_set? i dont see the definitions...)
now, what i think is probably much more central to the code: what does the select() function do? i googled around and did not find an explanation for it, just other forum-goers baffled as i am.
It's a typical multiplexed asynchronous I/O using a file descriptors.
Each Unix object that is file-like, is assigned a file-descriptor, which is used as a index into som internal data structure. Originally, they were files, but the BSD folk used them for sockets too.
Anyway, when select returns, it tells you whch file descriptors are ready (for read or write) so you can call read or write without blocking.
hmm.. interesting. do you know of an internet tutorial or something that would explain this in more depth, like what the parameters represent and everything? thanks!
okay, so i have comiled this entire program now that i think i understand it a little bit, but some things seem to be coming up:
first off, i successfully compiled it like this:
cd Desktop/webcam
gcc -o webcam webcam.c
but when i try to run it like so:
cd Desktop/webcam
webcam
it tells me
bash: webcam: command not found.
however were i to do this:
Desktop/webcam/webcam
it works just fine. (at least it gives me the error message which i will describe next.)
(if you cant tell, i am a newcomer to programming under linux.)
secondly, this is the error message i get when i actually run the program like i did above:
Cannot identify '/dev/video' : 2, No such file or directory
is this an issue of how the program gives the filepath? because i thought that the '/' at the beginning tells it to start over from the base of the 'file tree'...
thanks for any help! i really appreciate it!
well, i figured something out about the second part, still no idea what is causing the first part, though. here is where the program screws up:
1 2 3 4 5 6 7 8 9 10 11
staticvoid
open_device (void)
{
struct stat st;
if (-1 == stat (dev_name, &st)) { // dev_name = '/dev/video' btw, defined in main
fprintf (stderr, "Cannot identify '%s': %d, %s\n",
dev_name, errno, strerror (errno));
exit (EXIT_FAILURE);
}
it seems to trip up at this part, for some reason cannot identify the filepath. what do the %s %d and %s stand for? and what does stat() even do? thanks!
For the first problem u need to run it like this ./webcam
The reason to do it that way is that ur working directory is not par of ur $PATH so u need to add the "./" (dot slash) to point to ur current working directory. if u just typed webcam it will usually go look for it in "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
For the second problem u need to point to where ur webcam is mounted. Seems /dev/webcam is not the moint point for it.
Also if u want a tutorial for select, there is a good book actually explaining it "Linux system programming" as well as other linux internal stuff. Just read chapter 2 and u will find all about file descriptors, select, and read system calls.