1 #undef _FILE_OFFSET_BITS
2 #undef _LARGEFILE_SOURCE
3 #undef _LARGEFILE64_SOURCE
7 #include "chantables.h"
13 #include "preferences.h"
14 #include "quicktime.h"
15 #include "recordconfig.h"
16 #include "vdevicev4l2.h"
18 #include "videodevice.h"
20 #ifdef HAVE_VIDEO4LINUX2
24 #include <sys/ioctl.h>
35 VDeviceV4L2Put::VDeviceV4L2Put(VDeviceV4L2Thread *thread)
38 this->thread = thread;
40 lock = new Mutex("VDeviceV4L2Put::lock");
41 more_buffers = new Condition(0, "VDeviceV4L2Put::more_buffers");
42 putbuffers = new int[0xff];
46 VDeviceV4L2Put::~VDeviceV4L2Put()
51 more_buffers->unlock();
60 void VDeviceV4L2Put::run()
64 more_buffers->lock("VDeviceV4L2Put::run");
66 lock->lock("VDeviceV4L2Put::run");
70 buffer = putbuffers[0];
71 for(int i = 0; i < total - 1; i++)
72 putbuffers[i] = putbuffers[i + 1];
79 struct v4l2_buffer arg;
80 bzero(&arg, sizeof(arg));
81 arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
83 arg.memory = V4L2_MEMORY_MMAP;
85 Thread::enable_cancel();
86 thread->ioctl_lock->lock("VDeviceV4L2Put::run");
87 // This locks up if there's no signal.
88 if(ioctl(thread->input_fd, VIDIOC_QBUF, &arg) < 0)
89 perror("VDeviceV4L2Put::run 1 VIDIOC_QBUF");
90 thread->ioctl_lock->unlock();
91 // Delay to keep mutexes from getting stuck
92 usleep(1000000 * 1001 / 60000);
93 Thread::disable_cancel();
98 void VDeviceV4L2Put::put_buffer(int number)
100 lock->lock("VDeviceV4L2Put::put_buffer");
101 putbuffers[total++] = number;
103 more_buffers->unlock();
116 VDeviceV4L2Thread::VDeviceV4L2Thread(VideoDevice *device, int color_model)
119 this->device = device;
120 this->color_model = color_model;
122 video_lock = new Condition(0, "VDeviceV4L2Thread::video_lock");
123 buffer_lock = new Mutex("VDeviceV4L2Thread::buffer_lock");
124 ioctl_lock = new Mutex("VDeviceV4L2Thread::ioctl_lock");
127 current_inbuffer = 0;
128 current_outbuffer = 0;
137 VDeviceV4L2Thread::~VDeviceV4L2Thread()
139 if(Thread::running())
146 if(put_thread) delete put_thread;
150 delete [] buffer_valid;
153 // Buffers are not unmapped by close.
156 for(int i = 0; i < total_buffers; i++)
158 if(color_model == BC_COMPRESSED)
160 if(device_buffers[i]->get_data())
161 munmap(device_buffers[i]->get_data(),
162 device_buffers[i]->get_compressed_allocated());
166 if(device_buffers[i]->get_data())
167 munmap(device_buffers[i]->get_data(),
168 device_buffers[i]->get_data_size());
170 delete device_buffers[i];
172 delete [] device_buffers;
177 int streamoff_arg = V4L2_BUF_TYPE_VIDEO_CAPTURE;
178 if(ioctl(input_fd, VIDIOC_STREAMOFF, &streamoff_arg) < 0)
179 perror("VDeviceV4L2Thread::~VDeviceV4L2Thread VIDIOC_STREAMOFF");
188 void VDeviceV4L2Thread::start()
190 total_buffers = device->in_config->capture_length;
191 total_buffers = MAX(total_buffers, 2);
192 total_buffers = MIN(total_buffers, 0xff);
193 put_thread = new VDeviceV4L2Put(this);
198 // Allocate user space buffers
199 void VDeviceV4L2Thread::allocate_buffers(int number)
201 if(number != total_buffers)
203 if(buffer_valid) delete [] buffer_valid;
206 for(int i = 0; i < total_buffers; i++)
208 delete device_buffers[i];
210 delete [] device_buffers;
214 total_buffers = number;
215 buffer_valid = new int[total_buffers];
216 device_buffers = new VFrame*[total_buffers];
217 for(int i = 0; i < total_buffers; i++)
219 device_buffers[i] = new VFrame;
221 bzero(buffer_valid, sizeof(int) * total_buffers);
224 void VDeviceV4L2Thread::run()
228 Thread::enable_cancel();
232 if((input_fd = open(device->in_config->v4l2jpeg_in_device,
235 perror("VDeviceV4L2Thread::run");
241 device->set_cloexec_flag(input_fd, 1);
244 struct v4l2_capability cap;
245 if(ioctl(input_fd, VIDIOC_QUERYCAP, &cap))
246 perror("VDeviceV4L2Thread::run VIDIOC_QUERYCAP");
248 // printf("VDeviceV4L2Thread::run input_fd=%d driver=%s card=%s bus_info=%s version=%d\n",
254 // printf(" %s%s%s%s%s%s%s%s%s%s%s%s\n",
255 // (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ? "V4L2_CAP_VIDEO_CAPTURE " : "",
256 // (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) ? "V4L2_CAP_VIDEO_OUTPUT " : "",
257 // (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) ? "V4L2_CAP_VIDEO_OVERLAY " : "",
258 // (cap.capabilities & V4L2_CAP_VBI_CAPTURE) ? "V4L2_CAP_VBI_CAPTURE " : "",
259 // (cap.capabilities & V4L2_CAP_VBI_OUTPUT) ? "V4L2_CAP_VBI_OUTPUT " : "",
260 // (cap.capabilities & V4L2_CAP_RDS_CAPTURE) ? "V4L2_CAP_RDS_CAPTURE " : "",
261 // (cap.capabilities & V4L2_CAP_TUNER) ? "V4L2_CAP_TUNER " : "",
262 // (cap.capabilities & V4L2_CAP_AUDIO) ? "V4L2_CAP_AUDIO " : "",
263 // (cap.capabilities & V4L2_CAP_RADIO) ? "V4L2_CAP_RADIO " : "",
264 // (cap.capabilities & V4L2_CAP_READWRITE) ? "V4L2_CAP_READWRITE " : "",
265 // (cap.capabilities & V4L2_CAP_ASYNCIO) ? "V4L2_CAP_ASYNCIO " : "",
266 // (cap.capabilities & V4L2_CAP_STREAMING) ? "V4L2_CAP_STREAMING " : "");
270 struct v4l2_streamparm v4l2_parm;
271 v4l2_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
272 if(ioctl(input_fd, VIDIOC_G_PARM, &v4l2_parm) < 0)
273 perror("VDeviceV4L2Thread::run VIDIOC_G_PARM");
274 if(v4l2_parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)
276 v4l2_parm.parm.capture.capturemode |= V4L2_CAP_TIMEPERFRAME;
279 v4l2_parm.parm.capture.timeperframe.numerator = 1;
280 v4l2_parm.parm.capture.timeperframe.denominator =
281 (unsigned long)((float)1 /
284 if(ioctl(input_fd, VIDIOC_S_PARM, &v4l2_parm) < 0)
285 perror("VDeviceV4L2Thread::run VIDIOC_S_PARM");
287 if(ioctl(input_fd, VIDIOC_G_PARM, &v4l2_parm) < 0)
288 perror("VDeviceV4L2Thread::run VIDIOC_G_PARM");
292 // Set up data format
293 struct v4l2_format v4l2_params;
294 v4l2_params.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
295 if(ioctl(input_fd, VIDIOC_G_FMT, &v4l2_params) < 0)
296 perror("VDeviceV4L2Thread::run VIDIOC_G_FMT");
297 v4l2_params.fmt.pix.width = device->in_config->w;
298 v4l2_params.fmt.pix.height = device->in_config->h;
300 if(color_model == BC_COMPRESSED)
301 v4l2_params.fmt.pix.pixelformat =
304 v4l2_params.fmt.pix.pixelformat =
305 VDeviceV4L2::cmodel_to_device(color_model);
308 if(ioctl(input_fd, VIDIOC_S_FMT, &v4l2_params) < 0)
309 perror("VDeviceV4L2Thread::run VIDIOC_S_FMT");
310 if(ioctl(input_fd, VIDIOC_G_FMT, &v4l2_params) < 0)
311 perror("VDeviceV4L2Thread::run VIDIOC_G_FMT");
314 Channel *device_channel = 0;
315 if(device->channel->input >= 0 &&
316 device->channel->input < device->get_inputs()->total)
318 device_channel = device->get_inputs()->values[
319 device->channel->input];
325 if(device->get_inputs()->total)
327 device_channel = device->get_inputs()->values[0];
328 printf("VDeviceV4L2Thread::run user channel not found. Using %s\n",
329 device_channel->device_name);
333 printf("VDeviceV4L2Thread::run channel \"%s\" not found.\n",
334 device->channel->title);
341 // Set picture controls. This driver requires the values to be set once to default
342 // values and then again to different values before it takes up the values.
343 // Unfortunately VIDIOC_S_CTRL resets the audio to mono in 2.6.7.
344 PictureConfig *picture = device->picture;
345 for(int i = 0; i < picture->controls.total; i++)
347 struct v4l2_control ctrl_arg;
348 struct v4l2_queryctrl arg;
349 PictureItem *item = picture->controls.values[i];
350 arg.id = item->device_id;
351 if(!ioctl(input_fd, VIDIOC_QUERYCTRL, &arg))
353 ctrl_arg.id = item->device_id;
355 if(ioctl(input_fd, VIDIOC_S_CTRL, &ctrl_arg) < 0)
356 perror("VDeviceV4L2Thread::run VIDIOC_S_CTRL");
360 printf("VDeviceV4L2Thread::run VIDIOC_S_CTRL 1 id %d failed\n",
365 for(int i = 0; i < picture->controls.total; i++)
367 struct v4l2_control ctrl_arg;
368 struct v4l2_queryctrl arg;
369 PictureItem *item = picture->controls.values[i];
370 arg.id = item->device_id;
371 if(!ioctl(input_fd, VIDIOC_QUERYCTRL, &arg))
373 ctrl_arg.id = item->device_id;
374 ctrl_arg.value = item->value;
375 if(ioctl(input_fd, VIDIOC_S_CTRL, &ctrl_arg) < 0)
376 perror("VDeviceV4L2Thread::run VIDIOC_S_CTRL");
380 printf("VDeviceV4L2Thread::run VIDIOC_S_CTRL 2 id %d failed\n",
386 // Translate input to API structures
387 struct v4l2_tuner tuner;
390 if(ioctl(input_fd, VIDIOC_G_TUNER, &tuner) < 0)
391 perror("VDeviceV4L2Thread::run VIDIOC_G_INPUT");
393 // printf("VDeviceV4L2Thread::run audmode=%d rxsubchans=%d\n",
395 // tuner.rxsubchans);
398 tuner.index = device_channel->device_index;
399 input = device_channel->device_index;
407 tuner.type = V4L2_TUNER_ANALOG_TV;
408 tuner.audmode = V4L2_TUNER_MODE_STEREO;
409 tuner.rxsubchans = V4L2_TUNER_SUB_STEREO;
411 if(ioctl(input_fd, VIDIOC_S_INPUT, &input) < 0)
412 perror("VDeviceV4L2Thread::run VIDIOC_S_INPUT");
423 switch(device->channel->norm)
425 case NTSC: std_id = V4L2_STD_NTSC; break;
426 case PAL: std_id = V4L2_STD_PAL; break;
427 case SECAM: std_id = V4L2_STD_SECAM; break;
428 default: std_id = V4L2_STD_NTSC_M; break;
431 if(ioctl(input_fd, VIDIOC_S_STD, &std_id))
432 perror("VDeviceV4L2Thread::run VIDIOC_S_STD");
435 if(cap.capabilities & V4L2_CAP_TUNER)
437 if(ioctl(input_fd, VIDIOC_S_TUNER, &tuner) < 0)
438 perror("VDeviceV4L2Thread::run VIDIOC_S_TUNER");
440 struct v4l2_frequency frequency;
441 frequency.tuner = device->channel->tuner;
442 frequency.type = V4L2_TUNER_ANALOG_TV;
443 frequency.frequency = (int)(chanlists[
444 device->channel->freqtable].list[
445 device->channel->entry].freq * 0.016);
446 // printf("VDeviceV4L2Thread::run tuner=%d freq=%d norm=%d\n",
447 // device->channel->tuner,
448 // frequency.frequency,
449 // device->channel->norm);
450 if(ioctl(input_fd, VIDIOC_S_FREQUENCY, &frequency) < 0)
451 perror("VDeviceV4L2Thread::run VIDIOC_S_FREQUENCY");
457 if(color_model == BC_COMPRESSED)
459 struct v4l2_jpegcompression jpeg_arg;
460 if(ioctl(input_fd, VIDIOC_G_JPEGCOMP, &jpeg_arg) < 0)
461 perror("VDeviceV4L2Thread::run VIDIOC_G_JPEGCOMP");
462 jpeg_arg.quality = device->quality / 2;
463 if(ioctl(input_fd, VIDIOC_S_JPEGCOMP, &jpeg_arg) < 0)
464 perror("VDeviceV4L2Thread::run VIDIOC_S_JPEGCOMP");
467 // Allocate buffers. Errors here are fatal.
468 Thread::disable_cancel();
469 struct v4l2_requestbuffers requestbuffers;
471 printf("VDeviceV4L2Thread::run requested %d buffers\n", total_buffers);
472 requestbuffers.count = total_buffers;
473 requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
474 requestbuffers.memory = V4L2_MEMORY_MMAP;
475 if(ioctl(input_fd, VIDIOC_REQBUFS, &requestbuffers) < 0)
477 perror("VDeviceV4L2Thread::run VIDIOC_REQBUFS");
482 // The requestbuffers.count changes in the 2.6.5 version of the API
483 allocate_buffers(requestbuffers.count);
485 printf("VDeviceV4L2Thread::run got %d buffers\n", total_buffers);
486 for(int i = 0; i < total_buffers; i++)
488 struct v4l2_buffer buffer;
489 buffer.type = requestbuffers.type;
491 if(ioctl(input_fd, VIDIOC_QUERYBUF, &buffer) < 0)
493 perror("VDeviceV4L2Thread::run VIDIOC_QUERYBUF");
498 unsigned char *data = (unsigned char*)mmap(NULL,
500 PROT_READ | PROT_WRITE,
504 if(data == MAP_FAILED)
506 perror("VDeviceV4L2Thread::run mmap");
511 VFrame *frame = device_buffers[i];
512 if(color_model == BC_COMPRESSED)
514 frame->set_compressed_memory(data,
527 u_offset = device->in_config->w * device->in_config->h;
528 v_offset = device->in_config->w * device->in_config->h + device->in_config->w * device->in_config->h / 2;
532 // In 2.6.7, the v and u are inverted for 420 but not 422
533 v_offset = device->in_config->w * device->in_config->h;
534 u_offset = device->in_config->w * device->in_config->h + device->in_config->w * device->in_config->h / 4;
538 //printf("VDeviceV4L2Thread::run color_model=%d\n", color_model);
539 frame->reallocate(data,
543 device->in_config->w,
544 device->in_config->h,
546 VFrame::calculate_bytes_per_pixel(color_model) *
547 device->in_config->w);
551 Thread::enable_cancel();
559 for(int i = 0; i < total_buffers; i++)
561 struct v4l2_buffer buffer;
562 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
563 buffer.memory = V4L2_MEMORY_MMAP;
565 if(ioctl(input_fd, VIDIOC_QBUF, &buffer) < 0)
567 perror("VDeviceV4L2Thread::run VIDIOC_QBUF");
573 int streamon_arg = V4L2_BUF_TYPE_VIDEO_CAPTURE;
574 if(ioctl(input_fd, VIDIOC_STREAMON, &streamon_arg) < 0)
575 perror("VDeviceV4L2Thread::run VIDIOC_STREAMON");
578 Thread::disable_cancel();
581 // Read buffers continuously
583 while(!done && !error)
585 struct v4l2_buffer buffer;
586 bzero(&buffer, sizeof(buffer));
587 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
588 buffer.memory = V4L2_MEMORY_MMAP;
590 // The driver returns the first buffer not queued, so only one buffer
591 // can be unqueued at a time.
592 Thread::enable_cancel();
593 ioctl_lock->lock("VDeviceV4L2Thread::run");
594 int result = ioctl(input_fd, VIDIOC_DQBUF, &buffer);
595 ioctl_lock->unlock();
596 // Delay so the mutexes don't get stuck
597 usleep(1000000 * 1001 / 60000);
598 Thread::disable_cancel();
603 perror("VDeviceV4L2Thread::run VIDIOC_DQBUF");
604 Thread::enable_cancel();
606 Thread::disable_cancel();
610 buffer_lock->lock("VDeviceV4L2Thread::run");
612 // Set output frame as valid and set data size
613 current_inbuffer = buffer.index;
614 if(color_model == BC_COMPRESSED)
616 device_buffers[current_inbuffer]->set_compressed_size(
620 if(!buffer_valid[current_inbuffer])
622 // Increase valid total only if current is invalid
623 buffer_valid[current_inbuffer] = 1;
625 buffer_lock->unlock();
626 video_lock->unlock();
630 // Driver won't block on the next QBUF call because we're not requeueing the buffer.
631 buffer_lock->unlock();
632 video_lock->unlock();
636 //printf("VDeviceV4L2::run 100 %lld\n", timer.get_difference());
640 VFrame* VDeviceV4L2Thread::get_buffer(int *timed_out)
645 // Acquire buffer table
646 buffer_lock->lock("VDeviceV4L2Thread::get_buffer 1");
649 // Test for buffer availability
650 while(total_valid < 2 && !*timed_out && !first_frame)
652 buffer_lock->unlock();
653 *timed_out = video_lock->timed_lock(BUFFER_TIMEOUT,
654 "VDeviceV4L2Thread::read_frame 2");
655 buffer_lock->lock("VDeviceV4L2Thread::get_buffer 3");
661 result = device_buffers[current_outbuffer];
664 buffer_lock->unlock();
669 void VDeviceV4L2Thread::put_buffer()
671 buffer_lock->lock("VDeviceV4L2Thread::put_buffer");
672 buffer_valid[current_outbuffer] = 0;
674 // Release buffer for capturing.
675 put_thread->put_buffer(current_outbuffer);
679 if(current_outbuffer >= total_buffers)
680 current_outbuffer = 0;
681 buffer_lock->unlock();
701 VDeviceV4L2::VDeviceV4L2(VideoDevice *device)
702 : VDeviceBase(device)
707 VDeviceV4L2::~VDeviceV4L2()
712 int VDeviceV4L2::close_all()
714 if(thread) delete thread;
720 int VDeviceV4L2::initialize()
728 int VDeviceV4L2::open_input()
730 int result = get_sources(device,
731 device->in_config->v4l2_in_device);
732 device->channel->use_frequency = 1;
733 device->channel->use_fine = 1;
737 int VDeviceV4L2::get_sources(VideoDevice *device,
743 device->channel->use_norm = 1;
744 device->channel->use_input = 1;
745 if(device->in_config->driver != VIDEO4LINUX2JPEG)
746 device->channel->has_scanning = 1;
748 device->channel->has_scanning = 0;
750 if((input_fd = open(path, O_RDWR)) < 0)
752 printf("VDeviceV4L2::open_input %s: %s\n", path, strerror(errno));
762 while(!done && i < 20)
764 struct v4l2_input arg;
765 bzero(&arg, sizeof(arg));
768 if(ioctl(input_fd, VIDIOC_ENUMINPUT, &arg) < 0)
775 Channel *channel = device->new_input_source((char*)arg.name);
776 channel->device_index = i;
777 channel->tuner = arg.tuner;
782 // Get the picture controls
783 for(i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++)
785 struct v4l2_queryctrl arg;
786 bzero(&arg, sizeof(arg));
788 // This returns errors for unsupported controls which is what we want.
789 if(!ioctl(input_fd, VIDIOC_QUERYCTRL, &arg))
791 // Test if control exists already
792 if(!device->picture->get_item((const char*)arg.name, arg.id))
795 PictureItem *item = device->picture->new_item((const char*)arg.name);
796 item->device_id = arg.id;
797 item->min = arg.minimum;
798 item->max = arg.maximum;
799 item->step = arg.step;
800 item->default_ = arg.default_value;
801 item->type = arg.type;
802 item->value = arg.default_value;
807 // Load defaults for picture controls
808 device->picture->load_defaults();
815 int VDeviceV4L2::cmodel_to_device(int color_model)
820 return V4L2_PIX_FMT_YUYV;
823 return V4L2_PIX_FMT_Y41P;
826 return V4L2_PIX_FMT_YVU420;
829 return V4L2_PIX_FMT_YUV422P;
832 return V4L2_PIX_FMT_RGB24;
838 int VDeviceV4L2::get_best_colormodel(Asset *asset)
840 int result = BC_RGB888;
841 result = File::get_best_colormodel(asset, device->in_config->driver);
845 int VDeviceV4L2::has_signal()
849 struct v4l2_tuner tuner;
850 if(ioctl(thread->input_fd, VIDIOC_G_TUNER, &tuner) < 0)
851 perror("VDeviceV4L2::has_signal VIDIOC_S_TUNER");
857 int VDeviceV4L2::read_buffer(VFrame *frame)
861 if((device->channel_changed || device->picture_changed) && thread)
869 device->channel_changed = 0;
870 device->picture_changed = 0;
871 thread = new VDeviceV4L2Thread(device, frame->get_color_model());
876 // Get buffer from thread
878 VFrame *buffer = thread->get_buffer(&timed_out);
881 frame->copy_from(buffer);
882 thread->put_buffer();
886 // Driver in 2.6.4 needs to be restarted when it loses sync.