1 #undef _FILE_OFFSET_BITS
2 #undef _LARGEFILE_SOURCE
3 #undef _LARGEFILE64_SOURCE
7 #include "chantables.h"
12 #include "preferences.h"
13 #include "quicktime.h"
14 #include "recordconfig.h"
15 #include "vdevicev4l2.h"
17 #include "videodevice.h"
19 #ifdef HAVE_VIDEO4LINUX2
22 #include <sys/ioctl.h>
33 VDeviceV4L2Put::VDeviceV4L2Put(VDeviceV4L2Thread *thread)
36 this->thread = thread;
38 lock = new Mutex("VDeviceV4L2Put::lock");
39 more_buffers = new Condition(0, "VDeviceV4L2Put::more_buffers");
40 putbuffers = new int[0xff];
44 VDeviceV4L2Put::~VDeviceV4L2Put()
49 more_buffers->unlock();
58 void VDeviceV4L2Put::run()
62 more_buffers->lock("VDeviceV4L2Put::run");
64 lock->lock("VDeviceV4L2Put::run");
68 buffer = putbuffers[0];
69 for(int i = 0; i < total - 1; i++)
70 putbuffers[i] = putbuffers[i + 1];
77 struct v4l2_buffer arg;
78 bzero(&arg, sizeof(arg));
79 arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
81 arg.memory = V4L2_MEMORY_MMAP;
83 Thread::enable_cancel();
84 thread->ioctl_lock->lock("VDeviceV4L2Put::run");
85 // This locks up if there's no signal.
86 if(ioctl(thread->input_fd, VIDIOC_QBUF, &arg) < 0)
87 perror("VDeviceV4L2Put::run 1 VIDIOC_QBUF");
88 thread->ioctl_lock->unlock();
89 // Delay to keep mutexes from getting stuck
90 usleep(1000000 * 1001 / 60000);
91 Thread::disable_cancel();
96 void VDeviceV4L2Put::put_buffer(int number)
98 lock->lock("VDeviceV4L2Put::put_buffer");
99 putbuffers[total++] = number;
101 more_buffers->unlock();
114 VDeviceV4L2Thread::VDeviceV4L2Thread(VideoDevice *device, int color_model)
117 this->device = device;
118 this->color_model = color_model;
120 video_lock = new Condition(0, "VDeviceV4L2Thread::video_lock");
121 buffer_lock = new Mutex("VDeviceV4L2Thread::buffer_lock");
122 ioctl_lock = new Mutex("VDeviceV4L2Thread::ioctl_lock");
125 current_inbuffer = 0;
126 current_outbuffer = 0;
135 VDeviceV4L2Thread::~VDeviceV4L2Thread()
137 if(Thread::running())
144 if(put_thread) delete put_thread;
148 delete [] buffer_valid;
151 // Buffers are not unmapped by close.
154 for(int i = 0; i < total_buffers; i++)
156 if(color_model == BC_COMPRESSED)
158 if(device_buffers[i]->get_data())
159 munmap(device_buffers[i]->get_data(),
160 device_buffers[i]->get_compressed_allocated());
164 if(device_buffers[i]->get_data())
165 munmap(device_buffers[i]->get_data(),
166 device_buffers[i]->get_data_size());
168 delete device_buffers[i];
170 delete [] device_buffers;
175 int streamoff_arg = V4L2_BUF_TYPE_VIDEO_CAPTURE;
176 if(ioctl(input_fd, VIDIOC_STREAMOFF, &streamoff_arg) < 0)
177 perror("VDeviceV4L2Thread::~VDeviceV4L2Thread VIDIOC_STREAMOFF");
186 void VDeviceV4L2Thread::start()
188 total_buffers = device->in_config->capture_length;
189 total_buffers = MAX(total_buffers, 2);
190 total_buffers = MIN(total_buffers, 0xff);
191 put_thread = new VDeviceV4L2Put(this);
196 // Allocate user space buffers
197 void VDeviceV4L2Thread::allocate_buffers(int number)
199 if(number != total_buffers)
201 if(buffer_valid) delete [] buffer_valid;
204 for(int i = 0; i < total_buffers; i++)
206 delete device_buffers[i];
208 delete [] device_buffers;
212 total_buffers = number;
213 buffer_valid = new int[total_buffers];
214 device_buffers = new VFrame*[total_buffers];
215 for(int i = 0; i < total_buffers; i++)
217 device_buffers[i] = new VFrame;
219 bzero(buffer_valid, sizeof(int) * total_buffers);
222 void VDeviceV4L2Thread::run()
226 Thread::enable_cancel();
230 if((input_fd = open(device->in_config->v4l2jpeg_in_device,
233 perror("VDeviceV4L2Thread::run");
239 device->set_cloexec_flag(input_fd, 1);
242 struct v4l2_capability cap;
243 if(ioctl(input_fd, VIDIOC_QUERYCAP, &cap))
244 perror("VDeviceV4L2Thread::run VIDIOC_QUERYCAP");
246 // printf("VDeviceV4L2Thread::run input_fd=%d driver=%s card=%s bus_info=%s version=%d\n",
252 // printf(" %s%s%s%s%s%s%s%s%s%s%s%s\n",
253 // (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ? "V4L2_CAP_VIDEO_CAPTURE " : "",
254 // (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) ? "V4L2_CAP_VIDEO_OUTPUT " : "",
255 // (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) ? "V4L2_CAP_VIDEO_OVERLAY " : "",
256 // (cap.capabilities & V4L2_CAP_VBI_CAPTURE) ? "V4L2_CAP_VBI_CAPTURE " : "",
257 // (cap.capabilities & V4L2_CAP_VBI_OUTPUT) ? "V4L2_CAP_VBI_OUTPUT " : "",
258 // (cap.capabilities & V4L2_CAP_RDS_CAPTURE) ? "V4L2_CAP_RDS_CAPTURE " : "",
259 // (cap.capabilities & V4L2_CAP_TUNER) ? "V4L2_CAP_TUNER " : "",
260 // (cap.capabilities & V4L2_CAP_AUDIO) ? "V4L2_CAP_AUDIO " : "",
261 // (cap.capabilities & V4L2_CAP_RADIO) ? "V4L2_CAP_RADIO " : "",
262 // (cap.capabilities & V4L2_CAP_READWRITE) ? "V4L2_CAP_READWRITE " : "",
263 // (cap.capabilities & V4L2_CAP_ASYNCIO) ? "V4L2_CAP_ASYNCIO " : "",
264 // (cap.capabilities & V4L2_CAP_STREAMING) ? "V4L2_CAP_STREAMING " : "");
268 struct v4l2_streamparm v4l2_parm;
269 v4l2_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
270 if(ioctl(input_fd, VIDIOC_G_PARM, &v4l2_parm) < 0)
271 perror("VDeviceV4L2Thread::run VIDIOC_G_PARM");
272 if(v4l2_parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)
274 v4l2_parm.parm.capture.capturemode |= V4L2_CAP_TIMEPERFRAME;
277 v4l2_parm.parm.capture.timeperframe.numerator = 1;
278 v4l2_parm.parm.capture.timeperframe.denominator =
279 (unsigned long)((float)1 /
282 if(ioctl(input_fd, VIDIOC_S_PARM, &v4l2_parm) < 0)
283 perror("VDeviceV4L2Thread::run VIDIOC_S_PARM");
285 if(ioctl(input_fd, VIDIOC_G_PARM, &v4l2_parm) < 0)
286 perror("VDeviceV4L2Thread::run VIDIOC_G_PARM");
290 // Set up data format
291 struct v4l2_format v4l2_params;
292 v4l2_params.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
293 if(ioctl(input_fd, VIDIOC_G_FMT, &v4l2_params) < 0)
294 perror("VDeviceV4L2Thread::run VIDIOC_G_FMT");
295 v4l2_params.fmt.pix.width = device->in_config->w;
296 v4l2_params.fmt.pix.height = device->in_config->h;
298 if(color_model == BC_COMPRESSED)
299 v4l2_params.fmt.pix.pixelformat =
302 v4l2_params.fmt.pix.pixelformat =
303 VDeviceV4L2::cmodel_to_device(color_model);
306 if(ioctl(input_fd, VIDIOC_S_FMT, &v4l2_params) < 0)
307 perror("VDeviceV4L2Thread::run VIDIOC_S_FMT");
308 if(ioctl(input_fd, VIDIOC_G_FMT, &v4l2_params) < 0)
309 perror("VDeviceV4L2Thread::run VIDIOC_G_FMT");
312 Channel *device_channel = 0;
313 if(device->channel->input >= 0 &&
314 device->channel->input < device->get_inputs()->total)
316 device_channel = device->get_inputs()->values[
317 device->channel->input];
323 if(device->get_inputs()->total)
325 device_channel = device->get_inputs()->values[0];
326 printf("VDeviceV4L2Thread::run user channel not found. Using %s\n",
327 device_channel->device_name);
331 printf("VDeviceV4L2Thread::run channel \"%s\" not found.\n",
332 device->channel->title);
339 // Set picture controls. This driver requires the values to be set once to default
340 // values and then again to different values before it takes up the values.
341 // Unfortunately VIDIOC_S_CTRL resets the audio to mono in 2.6.7.
342 PictureConfig *picture = device->picture;
343 for(int i = 0; i < picture->controls.total; i++)
345 struct v4l2_control ctrl_arg;
346 struct v4l2_queryctrl arg;
347 PictureItem *item = picture->controls.values[i];
348 arg.id = item->device_id;
349 if(!ioctl(input_fd, VIDIOC_QUERYCTRL, &arg))
351 ctrl_arg.id = item->device_id;
353 if(ioctl(input_fd, VIDIOC_S_CTRL, &ctrl_arg) < 0)
354 perror("VDeviceV4L2Thread::run VIDIOC_S_CTRL");
358 printf("VDeviceV4L2Thread::run VIDIOC_S_CTRL 1 id %d failed\n",
363 for(int i = 0; i < picture->controls.total; i++)
365 struct v4l2_control ctrl_arg;
366 struct v4l2_queryctrl arg;
367 PictureItem *item = picture->controls.values[i];
368 arg.id = item->device_id;
369 if(!ioctl(input_fd, VIDIOC_QUERYCTRL, &arg))
371 ctrl_arg.id = item->device_id;
372 ctrl_arg.value = item->value;
373 if(ioctl(input_fd, VIDIOC_S_CTRL, &ctrl_arg) < 0)
374 perror("VDeviceV4L2Thread::run VIDIOC_S_CTRL");
378 printf("VDeviceV4L2Thread::run VIDIOC_S_CTRL 2 id %d failed\n",
384 // Translate input to API structures
385 struct v4l2_tuner tuner;
388 if(ioctl(input_fd, VIDIOC_G_TUNER, &tuner) < 0)
389 perror("VDeviceV4L2Thread::run VIDIOC_G_INPUT");
391 // printf("VDeviceV4L2Thread::run audmode=%d rxsubchans=%d\n",
393 // tuner.rxsubchans);
396 tuner.index = device_channel->device_index;
397 input = device_channel->device_index;
405 tuner.type = V4L2_TUNER_ANALOG_TV;
406 tuner.audmode = V4L2_TUNER_MODE_STEREO;
407 tuner.rxsubchans = V4L2_TUNER_SUB_STEREO;
409 if(ioctl(input_fd, VIDIOC_S_INPUT, &input) < 0)
410 perror("VDeviceV4L2Thread::run VIDIOC_S_INPUT");
421 switch(device->channel->norm)
423 case NTSC: std_id = V4L2_STD_NTSC; break;
424 case PAL: std_id = V4L2_STD_PAL; break;
425 case SECAM: std_id = V4L2_STD_SECAM; break;
426 default: std_id = V4L2_STD_NTSC_M; break;
429 if(ioctl(input_fd, VIDIOC_S_STD, &std_id))
430 perror("VDeviceV4L2Thread::run VIDIOC_S_STD");
433 if(cap.capabilities & V4L2_CAP_TUNER)
435 if(ioctl(input_fd, VIDIOC_S_TUNER, &tuner) < 0)
436 perror("VDeviceV4L2Thread::run VIDIOC_S_TUNER");
438 struct v4l2_frequency frequency;
439 frequency.tuner = device->channel->tuner;
440 frequency.type = V4L2_TUNER_ANALOG_TV;
441 frequency.frequency = (int)(chanlists[
442 device->channel->freqtable].list[
443 device->channel->entry].freq * 0.016);
444 // printf("VDeviceV4L2Thread::run tuner=%d freq=%d norm=%d\n",
445 // device->channel->tuner,
446 // frequency.frequency,
447 // device->channel->norm);
448 if(ioctl(input_fd, VIDIOC_S_FREQUENCY, &frequency) < 0)
449 perror("VDeviceV4L2Thread::run VIDIOC_S_FREQUENCY");
455 if(color_model == BC_COMPRESSED)
457 struct v4l2_jpegcompression jpeg_arg;
458 if(ioctl(input_fd, VIDIOC_G_JPEGCOMP, &jpeg_arg) < 0)
459 perror("VDeviceV4L2Thread::run VIDIOC_G_JPEGCOMP");
460 jpeg_arg.quality = device->quality / 2;
461 if(ioctl(input_fd, VIDIOC_S_JPEGCOMP, &jpeg_arg) < 0)
462 perror("VDeviceV4L2Thread::run VIDIOC_S_JPEGCOMP");
465 // Allocate buffers. Errors here are fatal.
466 Thread::disable_cancel();
467 struct v4l2_requestbuffers requestbuffers;
469 printf("VDeviceV4L2Thread::run requested %d buffers\n", total_buffers);
470 requestbuffers.count = total_buffers;
471 requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
472 requestbuffers.memory = V4L2_MEMORY_MMAP;
473 if(ioctl(input_fd, VIDIOC_REQBUFS, &requestbuffers) < 0)
475 perror("VDeviceV4L2Thread::run VIDIOC_REQBUFS");
480 // The requestbuffers.count changes in the 2.6.5 version of the API
481 allocate_buffers(requestbuffers.count);
482 printf("VDeviceV4L2Thread::run got %d buffers\n", total_buffers);
483 for(int i = 0; i < total_buffers; i++)
485 struct v4l2_buffer buffer;
486 buffer.type = requestbuffers.type;
488 if(ioctl(input_fd, VIDIOC_QUERYBUF, &buffer) < 0)
490 perror("VDeviceV4L2Thread::run VIDIOC_QUERYBUF");
495 unsigned char *data = (unsigned char*)mmap(NULL,
497 PROT_READ | PROT_WRITE,
501 if(data == MAP_FAILED)
503 perror("VDeviceV4L2Thread::run mmap");
508 VFrame *frame = device_buffers[i];
509 if(color_model == BC_COMPRESSED)
511 frame->set_compressed_memory(data,
524 u_offset = device->in_config->w * device->in_config->h;
525 v_offset = device->in_config->w * device->in_config->h + device->in_config->w * device->in_config->h / 2;
529 // In 2.6.7, the v and u are inverted for 420 but not 422
530 v_offset = device->in_config->w * device->in_config->h;
531 u_offset = device->in_config->w * device->in_config->h + device->in_config->w * device->in_config->h / 4;
535 frame->reallocate(data,
539 device->in_config->w,
540 device->in_config->h,
542 VFrame::calculate_bytes_per_pixel(color_model) *
543 device->in_config->w);
547 Thread::enable_cancel();
555 for(int i = 0; i < total_buffers; i++)
557 struct v4l2_buffer buffer;
558 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
560 if(ioctl(input_fd, VIDIOC_QBUF, &buffer) < 0)
562 perror("VDeviceV4L2Thread::run VIDIOC_QBUF");
568 int streamon_arg = V4L2_BUF_TYPE_VIDEO_CAPTURE;
569 if(ioctl(input_fd, VIDIOC_STREAMON, &streamon_arg) < 0)
570 perror("VDeviceV4L2Thread::run VIDIOC_STREAMON");
573 Thread::disable_cancel();
576 // Read buffers continuously
578 while(!done && !error)
580 struct v4l2_buffer buffer;
581 bzero(&buffer, sizeof(buffer));
582 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
583 buffer.memory = V4L2_MEMORY_MMAP;
585 // The driver returns the first buffer not queued, so only one buffer
586 // can be unqueued at a time.
587 Thread::enable_cancel();
588 ioctl_lock->lock("VDeviceV4L2Thread::run");
589 int result = ioctl(input_fd, VIDIOC_DQBUF, &buffer);
590 ioctl_lock->unlock();
591 // Delay so the mutexes don't get stuck
592 usleep(1000000 * 1001 / 60000);
593 Thread::disable_cancel();
598 perror("VDeviceV4L2Thread::run VIDIOC_DQBUF");
599 Thread::enable_cancel();
601 Thread::disable_cancel();
605 buffer_lock->lock("VDeviceV4L2Thread::run");
607 // Set output frame as valid and set data size
608 current_inbuffer = buffer.index;
609 if(color_model == BC_COMPRESSED)
611 device_buffers[current_inbuffer]->set_compressed_size(
615 if(!buffer_valid[current_inbuffer])
617 // Increase valid total only if current is invalid
618 buffer_valid[current_inbuffer] = 1;
620 buffer_lock->unlock();
621 video_lock->unlock();
625 // Driver won't block on the next QBUF call because we're not requeueing the buffer.
626 buffer_lock->unlock();
627 video_lock->unlock();
631 //printf("VDeviceV4L2::run 100 %lld\n", timer.get_difference());
635 VFrame* VDeviceV4L2Thread::get_buffer(int *timed_out)
640 // Acquire buffer table
641 buffer_lock->lock("VDeviceV4L2Thread::get_buffer 1");
644 // Test for buffer availability
645 while(total_valid < 2 && !*timed_out && !first_frame)
647 buffer_lock->unlock();
648 *timed_out = video_lock->timed_lock(BUFFER_TIMEOUT,
649 "VDeviceV4L2Thread::read_frame 2");
650 buffer_lock->lock("VDeviceV4L2Thread::get_buffer 3");
656 result = device_buffers[current_outbuffer];
659 buffer_lock->unlock();
664 void VDeviceV4L2Thread::put_buffer()
666 buffer_lock->lock("VDeviceV4L2Thread::put_buffer");
667 buffer_valid[current_outbuffer] = 0;
669 // Release buffer for capturing.
670 put_thread->put_buffer(current_outbuffer);
674 if(current_outbuffer >= total_buffers)
675 current_outbuffer = 0;
676 buffer_lock->unlock();
696 VDeviceV4L2::VDeviceV4L2(VideoDevice *device)
697 : VDeviceBase(device)
702 VDeviceV4L2::~VDeviceV4L2()
707 int VDeviceV4L2::close_all()
709 if(thread) delete thread;
715 int VDeviceV4L2::initialize()
723 int VDeviceV4L2::open_input()
725 int result = get_sources(device,
726 device->in_config->v4l2_in_device);
727 device->channel->use_frequency = 1;
728 device->channel->use_fine = 1;
732 int VDeviceV4L2::get_sources(VideoDevice *device,
738 device->channel->use_norm = 1;
739 device->channel->use_input = 1;
740 if(device->in_config->driver != VIDEO4LINUX2JPEG)
741 device->channel->has_scanning = 1;
743 device->channel->has_scanning = 0;
745 if((input_fd = open(path, O_RDWR)) < 0)
747 perror("VDeviceV4L::open_input");
757 while(!done && i < 20)
759 struct v4l2_input arg;
760 bzero(&arg, sizeof(arg));
763 if(ioctl(input_fd, VIDIOC_ENUMINPUT, &arg) < 0)
770 Channel *channel = device->new_input_source((char*)arg.name);
771 channel->device_index = i;
772 channel->tuner = arg.tuner;
777 // Get the picture controls
778 for(i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++)
780 struct v4l2_queryctrl arg;
781 bzero(&arg, sizeof(arg));
783 // This returns errors for unsupported controls which is what we want.
784 if(!ioctl(input_fd, VIDIOC_QUERYCTRL, &arg))
786 // Test if control exists already
787 if(!device->picture->get_item((const char*)arg.name, arg.id))
790 PictureItem *item = device->picture->new_item((const char*)arg.name);
791 item->device_id = arg.id;
792 item->min = arg.minimum;
793 item->max = arg.maximum;
794 item->step = arg.step;
795 item->default_ = arg.default_value;
796 item->type = arg.type;
797 item->value = arg.default_value;
802 // Load defaults for picture controls
803 device->picture->load_defaults();
810 int VDeviceV4L2::cmodel_to_device(int color_model)
815 return V4L2_PIX_FMT_YUYV;
818 return V4L2_PIX_FMT_Y41P;
821 return V4L2_PIX_FMT_YVU420;
824 return V4L2_PIX_FMT_YUV422P;
827 return V4L2_PIX_FMT_RGB24;
833 int VDeviceV4L2::get_best_colormodel(Asset *asset)
835 int result = BC_RGB888;
836 result = File::get_best_colormodel(asset, device->in_config->driver);
840 int VDeviceV4L2::has_signal()
844 struct v4l2_tuner tuner;
845 if(ioctl(thread->input_fd, VIDIOC_G_TUNER, &tuner) < 0)
846 perror("VDeviceV4L2::has_signal VIDIOC_S_TUNER");
852 int VDeviceV4L2::read_buffer(VFrame *frame)
856 if((device->channel_changed || device->picture_changed) && thread)
864 device->channel_changed = 0;
865 device->picture_changed = 0;
866 thread = new VDeviceV4L2Thread(device, frame->get_color_model());
871 // Get buffer from thread
873 VFrame *buffer = thread->get_buffer(&timed_out);
876 frame->copy_from(buffer);
877 thread->put_buffer();
881 // Driver in 2.6.4 needs to be restarted when it loses sync.