X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;ds=sidebyside;f=cinelerra-5.1%2Fcinelerra%2Fvdevicev4l.C;fp=cinelerra-5.1%2Fcinelerra%2Fvdevicev4l.C;h=0000000000000000000000000000000000000000;hb=49f85559268fc040fe7ba5611cc0520793cf728b;hp=3d289df6f324439a62ad7a80cd2cbbcbf4e35805;hpb=a284b8c124e0719cf7bde9f3ad4f91a67b7c7f85;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/vdevicev4l.C b/cinelerra-5.1/cinelerra/vdevicev4l.C deleted file mode 100644 index 3d289df6..00000000 --- a/cinelerra-5.1/cinelerra/vdevicev4l.C +++ /dev/null @@ -1,573 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 2008 Adam Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - - -#ifdef HAVE_VIDEO4LINUX - -// V4L2 is incompatible with large file support -// ALPHA C++ can't compile 64 bit headers -#undef _FILE_OFFSET_BITS -#undef _LARGEFILE_SOURCE -#undef _LARGEFILE64_SOURCE - - -#include "assets.h" -#include "bcsignals.h" -#include "channel.h" -#include "chantables.h" -#include "clip.h" -#include "file.h" -#include "picture.h" -#include "preferences.h" -#include "recordconfig.h" -#include "vdevicev4l.h" -#include "vframe.h" -#include "videodevice.h" - -#include -#include -#include -#include -#include - -VDeviceV4L::VDeviceV4L(VideoDevice *device) - : VDeviceBase(device) -{ - initialize(); -} - -VDeviceV4L::~VDeviceV4L() -{ -} - -int VDeviceV4L::initialize() -{ - capture_buffer = 0; - capture_frame_number = 0; - read_frame_number = 0; - shared_memory = 0; - initialization_complete = 0; - return 0; -} - -int VDeviceV4L::open_input() -{ - device->channel->use_frequency = 1; - device->channel->use_fine = 1; - device->channel->use_norm = 1; - device->channel->use_input = 1; - - - device->picture->use_brightness = 1; - device->picture->use_contrast = 1; - device->picture->use_color = 1; - device->picture->use_hue = 1; - device->picture->use_whiteness = 1; - - if((input_fd = open(device->in_config->v4l_in_device, O_RDWR)) < 0) - { - perror("VDeviceV4L::open_input"); - return 1; - } - else - { - v4l1_get_inputs(); - close(input_fd); - } - return 0; -} - -int VDeviceV4L::close_all() -{ - close_v4l(); - return 0; -} - -int VDeviceV4L::close_v4l() -{ - unmap_v4l_shmem(); - if(input_fd != -1) close(input_fd); - return 0; -} - -int VDeviceV4L::unmap_v4l_shmem() -{ - if(capture_buffer) - { - if(shared_memory) - munmap(capture_buffer, capture_params.size); - else - delete capture_buffer; - capture_buffer = 0; - } - return 0; -} - -int VDeviceV4L::v4l_init() -{ - input_fd = open(device->in_config->v4l_in_device, O_RDWR); - - if(input_fd < 0) - perror("VDeviceV4L::v4l_init"); - else - { - set_cloexec_flag(input_fd, 1); - set_mute(0); - if(ioctl(input_fd, VIDIOCGWIN, &window_params) < 0) - perror("VDeviceV4L::v4l_init VIDIOCGWIN"); - window_params.x = 0; - window_params.y = 0; - window_params.width = device->in_config->w; - window_params.height = device->in_config->h; - window_params.chromakey = 0; - window_params.flags = 0; - window_params.clipcount = 0; - if(ioctl(input_fd, VIDIOCSWIN, &window_params) < 0) - perror("VDeviceV4L::v4l_init VIDIOCSWIN"); - if(ioctl(input_fd, VIDIOCGWIN, &window_params) < 0) - perror("VDeviceV4L::v4l_init VIDIOCGWIN"); - - device->in_config->w = window_params.width; - device->in_config->h = window_params.height; - - PictureConfig picture(0); - set_picture(&picture); - - if(ioctl(input_fd, VIDIOCGMBUF, &capture_params) < 0) - perror("VDeviceV4L::v4l_init VIDIOCGMBUF"); - - capture_buffer = (char*)mmap(0, - capture_params.size, - PROT_READ|PROT_WRITE, - MAP_SHARED, - input_fd, - 0); - - capture_frame_number = 0; - - if(capture_buffer == MAP_FAILED) - { -// Use read instead. - perror("VDeviceV4L::v4l_init mmap"); - shared_memory = 0; - capture_buffer = new char[capture_params.size]; - } - else - { -// Get all frames capturing - shared_memory = 1; - } - } - got_first_frame = 0; - return 0; -} - -void VDeviceV4L::v4l1_start_capture() -{ - for(int i = 0; i < MIN(capture_params.frames, device->in_config->capture_length); i++) - capture_frame(i); -} - - - - - - - - -int VDeviceV4L::v4l1_get_inputs() -{ - struct video_channel channel_struct; - int i = 0, done = 0; - - while(!done && i < 20) - { - channel_struct.channel = i; - if(ioctl(input_fd, VIDIOCGCHAN, &channel_struct) < 0) - { -// Finished - done = 1; - } - else - { - Channel *channel = new Channel; - strcpy(channel->device_name, channel_struct.name); - device->input_sources.append(channel); - } - i++; - } - return 0; -} - -void VDeviceV4L::set_mute(int muted) -{ -// Open audio, which obviously is controlled by the video driver. -// and apparently resets the input source. - v4l1_set_mute(muted); -} - -int VDeviceV4L::v4l1_set_mute(int muted) -{ - struct video_audio audio; - - if(ioctl(input_fd, VIDIOCGAUDIO, &audio)) - if(ioctl(input_fd, VIDIOCGAUDIO, &audio) < 0) - perror("VDeviceV4L::ioctl VIDIOCGAUDIO"); - - audio.volume = 65535; - audio.bass = 65535; - audio.treble = 65535; - if(muted) - audio.flags |= VIDEO_AUDIO_MUTE | VIDEO_AUDIO_VOLUME; - else - audio.flags &= ~VIDEO_AUDIO_MUTE; - - if(ioctl(input_fd, VIDIOCSAUDIO, &audio) < 0) - perror("VDeviceV4L::ioctl VIDIOCSAUDIO"); - return 0; -} - - -int VDeviceV4L::set_cloexec_flag(int desc, int value) -{ - int oldflags = fcntl(desc, F_GETFD, 0); - if(oldflags < 0) return oldflags; - if(value != 0) - oldflags |= FD_CLOEXEC; - else - oldflags &= ~FD_CLOEXEC; - return fcntl(desc, F_SETFD, oldflags); -} - - - - - -int VDeviceV4L::get_best_colormodel(Asset *asset) -{ - int result = BC_RGB888; - -// Get best colormodel for hardware acceleration - - result = File::get_best_colormodel(asset, device->in_config->driver); - - -// Need to get color model before opening device but don't call this -// unless you want to open the device either. - if(!initialization_complete) - { - device_colormodel = translate_colormodel(result); - this->colormodel = result; - v4l_init(); - initialization_complete = 1; - } -// printf("VDeviceV4L::get_best_colormodel %c%c%c%c\n", -// ((char*)&device_colormodel)[0], -// ((char*)&device_colormodel)[1], -// ((char*)&device_colormodel)[2], -// ((char*)&device_colormodel)[3]); - return result; -} - -unsigned long VDeviceV4L::translate_colormodel(int colormodel) -{ - unsigned long result = 0; - switch(colormodel) - { - case BC_YUV422: result = VIDEO_PALETTE_YUV422; break; - case BC_YUV420P: result = VIDEO_PALETTE_YUV420P; break; - case BC_YUV422P: result = VIDEO_PALETTE_YUV422P; break; - case BC_YUV411P: result = VIDEO_PALETTE_YUV411P; break; - case BC_RGB888: result = VIDEO_PALETTE_RGB24; break; - default: result = VIDEO_PALETTE_RGB24; break; - } -//printf("VDeviceV4L::translate_colormodel %d\n", result); - return result; -} - -int VDeviceV4L::set_channel(Channel *channel) -{ - return v4l1_set_channel(channel); -} - -int VDeviceV4L::v4l1_set_channel(Channel *channel) -{ - struct video_channel channel_struct; - struct video_tuner tuner_struct; - unsigned long new_freq; - -// Mute changed the input to TV -// set_mute(1); - -//printf("VDeviceV4L::v4l1_set_channel 1 %d\n", channel->input); -// Read norm/input defaults - channel_struct.channel = channel->input; - if(ioctl(input_fd, VIDIOCGCHAN, &channel_struct) < 0) - perror("VDeviceV4L::v4l1_set_channel VIDIOCGCHAN"); - -// Set norm/input - channel_struct.channel = channel->input; - channel_struct.norm = v4l1_get_norm(channel->norm); - if(ioctl(input_fd, VIDIOCSCHAN, &channel_struct) < 0) - perror("VDeviceV4L::v4l1_set_channel VIDIOCSCHAN"); - - if(channel_struct.flags & VIDEO_VC_TUNER) - { -// Read tuner defaults - tuner_struct.tuner = channel->input; - if(ioctl(input_fd, VIDIOCGTUNER, &tuner_struct) < 0) - perror("VDeviceV4L::v4l1_set_channel VIDIOCGTUNER"); - -// Set tuner - tuner_struct.mode = v4l1_get_norm(channel->norm); - if(ioctl(input_fd, VIDIOCSTUNER, &tuner_struct) < 0) - perror("VDeviceV4L::v4l1_set_channel VIDIOCSTUNER"); - - new_freq = chanlists[channel->freqtable].list[channel->entry].freq; - new_freq = (int)(new_freq * 0.016); - new_freq += channel->fine_tune; - - if(ioctl(input_fd, VIDIOCSFREQ, &new_freq) < 0) - perror("VDeviceV4L::v4l1_set_channel VIDIOCSFREQ"); - } -// set_mute(0); - return 0; -} - -int VDeviceV4L::v4l1_get_norm(int norm) -{ - switch(norm) - { - case NTSC: return VIDEO_MODE_NTSC; break; - case PAL: return VIDEO_MODE_PAL; break; - case SECAM: return VIDEO_MODE_SECAM; break; - } - return 0; -} - -int VDeviceV4L::set_picture(PictureConfig *picture) -{ - v4l1_set_picture(picture); - return 0; -} - - -int VDeviceV4L::v4l1_set_picture(PictureConfig *picture) -{ - int brightness = (int)((float)picture->brightness / 100 * 32767 + 32768); - int hue = (int)((float)picture->hue / 100 * 32767 + 32768); - int color = (int)((float)picture->color / 100 * 32767 + 32768); - int contrast = (int)((float)picture->contrast / 100 * 32767 + 32768); - int whiteness = (int)((float)picture->whiteness / 100 * 32767 + 32768); - - if(ioctl(input_fd, VIDIOCGPICT, &picture_params) < 0) - perror("VDeviceV4L::v4l1_set_picture VIDIOCGPICT"); - picture_params.brightness = brightness; - picture_params.hue = hue; - picture_params.colour = color; - picture_params.contrast = contrast; - picture_params.whiteness = whiteness; -// Bogus. Values are only set in the capture routine. - picture_params.depth = 3; - picture_params.palette = device_colormodel; - if(ioctl(input_fd, VIDIOCSPICT, &picture_params) < 0) - perror("VDeviceV4L::v4l1_set_picture VIDIOCSPICT"); - if(ioctl(input_fd, VIDIOCGPICT, &picture_params) < 0) - perror("VDeviceV4L::v4l1_set_picture VIDIOCGPICT"); - return 0; -} - - -int VDeviceV4L::capture_frame(int capture_frame_number) -{ - struct video_mmap params; - params.frame = capture_frame_number; - params.width = device->in_config->w; - params.height = device->in_config->h; -// Required to actually set the palette. - params.format = device_colormodel; -// Tells the driver the buffer is available for writing - if(ioctl(input_fd, VIDIOCMCAPTURE, ¶ms) < 0) - perror("VDeviceV4L::capture_frame VIDIOCMCAPTURE"); - return 0; -} - -int VDeviceV4L::wait_v4l_frame() -{ -//printf("VDeviceV4L::wait_v4l_frame 1 %d\n", capture_frame_number); - if(ioctl(input_fd, VIDIOCSYNC, &capture_frame_number)) - perror("VDeviceV4L::wait_v4l_frame VIDIOCSYNC"); -//printf("VDeviceV4L::wait_v4l_frame 2 %d\n", capture_frame_number); - return 0; -} - -int VDeviceV4L::read_v4l_frame(VFrame *frame) -{ - frame_to_vframe(frame, (unsigned char*)capture_buffer + capture_params.offsets[capture_frame_number]); - return 0; -} - -#ifndef MIN -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#endif - -int VDeviceV4L::frame_to_vframe(VFrame *frame, unsigned char *input) -{ - int inwidth, inheight; - int width, height; - - inwidth = window_params.width; - inheight = window_params.height; - - width = MIN(inwidth, frame->get_w()); - height = MIN(inheight, frame->get_h()); -//printf("VDeviceV4L::frame_to_vframe %d %d\n", colormodel, frame->get_color_model()); - - if(frame->get_color_model() == colormodel) - { - switch(frame->get_color_model()) - { - case BC_RGB888: - { - unsigned char *row_in; - unsigned char *row_out_start, *row_out_end; - int bytes_per_inrow = inwidth * 3; - int bytes_per_outrow = frame->get_bytes_per_line(); - unsigned char **rows_out = frame->get_rows(); - - for(int i = 0; i < frame->get_h(); i++) - { - row_in = input + bytes_per_inrow * i; - row_out_start = rows_out[i]; - row_out_end = row_out_start + - MIN(bytes_per_outrow, bytes_per_inrow); - - while(row_out_start < row_out_end) - { - *row_out_start++ = row_in[2]; - *row_out_start++ = row_in[1]; - *row_out_start++ = row_in[0]; - row_in += 3; - } - } - break; - } - - case BC_YUV420P: - case BC_YUV411P: - memcpy(frame->get_y(), input, width * height); - memcpy(frame->get_u(), input + width * height, width * height / 4); - memcpy(frame->get_v(), input + width * height + width * height / 4, width * height / 4); - break; - - case BC_YUV422P: - memcpy(frame->get_y(), input, width * height); - memcpy(frame->get_u(), input + width * height, width * height / 2); - memcpy(frame->get_v(), input + width * height + width * height / 2, width * height / 2); - break; - - case BC_YUV422: - memcpy(frame->get_data(), - input, - VFrame::calculate_data_size(width, - height, - -1, - frame->get_color_model())); - break; - } - } - else - { - VFrame *in_frame = new VFrame(input, - -1, - inwidth, - inheight, - colormodel, - -1); - BC_CModels::transfer(frame->get_rows(), - in_frame->get_rows(), - frame->get_y(), - frame->get_u(), - frame->get_v(), - in_frame->get_y(), - in_frame->get_u(), - in_frame->get_v(), - 0, - 0, - inwidth, - inheight, - 0, - 0, - frame->get_w(), - frame->get_h(), - colormodel, - frame->get_color_model(), - 0, - inwidth, - inheight); - } - return 0; -} - - - -int VDeviceV4L::next_frame(int previous_frame) -{ - int result = previous_frame + 1; - - if(result >= MIN(capture_params.frames, device->in_config->capture_length)) result = 0; - return result; -} - -int VDeviceV4L::read_buffer(VFrame *frame) -{ -SET_TRACE - if(shared_memory) - { -// Read the current frame - if(!got_first_frame) v4l1_start_capture(); - wait_v4l_frame(); - read_v4l_frame(frame); -// Free this frame up for capturing - capture_frame(capture_frame_number); -// Advance the frame to capture. - capture_frame_number = next_frame(capture_frame_number); - } - else - { - read(input_fd, capture_buffer, capture_params.size); - } - - got_first_frame = 1; -SET_TRACE - return 0; -} - - - - -#endif // HAVE_VIDEO4LINUX - - - - - -