--- /dev/null
+;
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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
+
+// ALPHA C++ can't compile 64 bit headers
+#undef _LARGEFILE_SOURCE
+#undef _LARGEFILE64_SOURCE
+#undef _FILE_OFFSET_BITS
+
+#include "assets.h"
+#include "bcsignals.h"
+#include "channel.h"
+#include "chantables.h"
+#include "condition.h"
+#include "file.inc"
+#include "mutex.h"
+#include "picture.h"
+#include "playbackconfig.h"
+#include "preferences.h"
+#include "recordconfig.h"
+#include "strategies.inc"
+#include "vdevicebuz.h"
+#include "videodev.h"
+#include "vframe.h"
+#include "videoconfig.h"
+#include "videodevice.h"
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <linux/kernel.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define BASE_VIDIOCPRIVATE 192
+
+#define READ_TIMEOUT 5000000
+
+
+VDeviceBUZInput::VDeviceBUZInput(VDeviceBUZ *device)
+ : Thread(1, 1, 0)
+{
+ this->device = device;
+ buffer = 0;
+ buffer_size = 0;
+ total_buffers = 0;
+ current_inbuffer = 0;
+ current_outbuffer = 0;
+ done = 0;
+ output_lock = new Condition(0, "VDeviceBUZInput::output_lock");
+ buffer_lock = new Mutex("VDeviceBUZInput::buffer_lock");
+}
+
+VDeviceBUZInput::~VDeviceBUZInput()
+{
+ if(Thread::running())
+ {
+ done = 1;
+ Thread::cancel();
+ Thread::join();
+ }
+
+ if(buffer)
+ {
+ for(int i = 0; i < total_buffers; i++)
+ {
+ delete [] buffer[i];
+ }
+ delete [] buffer;
+ delete [] buffer_size;
+ }
+ delete output_lock;
+ delete buffer_lock;
+}
+
+void VDeviceBUZInput::start()
+{
+// Create buffers
+ total_buffers = device->device->in_config->capture_length;
+ buffer = new char*[total_buffers];
+ buffer_size = new int[total_buffers];
+ bzero(buffer_size, sizeof(int) * total_buffers);
+ for(int i = 0; i < total_buffers; i++)
+ {
+ buffer[i] = new char[INPUT_BUFFER_SIZE];
+ }
+
+ Thread::start();
+}
+
+void VDeviceBUZInput::run()
+{
+ struct buz_sync bsync;
+
+// Wait for frame
+ while(1)
+ {
+ Thread::enable_cancel();
+ if(ioctl(device->jvideo_fd, BUZIOC_SYNC, &bsync) < 0)
+ {
+ perror("VDeviceBUZInput::run BUZIOC_SYNC");
+ if(done) return;
+ Thread::disable_cancel();
+ }
+ else
+ {
+ Thread::disable_cancel();
+
+
+
+ int new_buffer = 0;
+ buffer_lock->lock("VDeviceBUZInput::run");
+// Save only if the current buffer is free.
+ if(!buffer_size[current_inbuffer])
+ {
+ new_buffer = 1;
+// Copy to input buffer
+ memcpy(buffer[current_inbuffer],
+ device->input_buffer + bsync.frame * device->breq.size,
+ bsync.length);
+
+// Advance input buffer number and decrease semaphore.
+ buffer_size[current_inbuffer] = bsync.length;
+ increment_counter(¤t_inbuffer);
+ }
+
+ buffer_lock->unlock();
+
+ if(ioctl(device->jvideo_fd, BUZIOC_QBUF_CAPT, &bsync.frame))
+ perror("VDeviceBUZInput::run BUZIOC_QBUF_CAPT");
+
+ if(new_buffer) output_lock->unlock();
+ }
+ }
+}
+
+void VDeviceBUZInput::get_buffer(char **ptr, int *size)
+{
+// Increase semaphore to wait for buffer.
+ int result = output_lock->timed_lock(READ_TIMEOUT, "VDeviceBUZInput::get_buffer");
+
+
+// The driver has its own timeout routine but it doesn't work because
+// because the tuner lock is unlocked and relocked with no delay.
+// int result = 0;
+// output_lock->lock("VDeviceBUZInput::get_buffer");
+
+ if(!result)
+ {
+// Take over buffer table
+ buffer_lock->lock("VDeviceBUZInput::get_buffer");
+ *ptr = buffer[current_outbuffer];
+ *size = buffer_size[current_outbuffer];
+ buffer_lock->unlock();
+ }
+ else
+ {
+//printf("VDeviceBUZInput::get_buffer 1\n");
+ output_lock->unlock();
+ }
+}
+
+void VDeviceBUZInput::put_buffer()
+{
+ buffer_lock->lock("VDeviceBUZInput::put_buffer");
+ buffer_size[current_outbuffer] = 0;
+ buffer_lock->unlock();
+ increment_counter(¤t_outbuffer);
+}
+
+void VDeviceBUZInput::increment_counter(int *counter)
+{
+ (*counter)++;
+ if(*counter >= total_buffers) *counter = 0;
+}
+
+void VDeviceBUZInput::decrement_counter(int *counter)
+{
+ (*counter)--;
+ if(*counter < 0) *counter = total_buffers - 1;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+VDeviceBUZ::VDeviceBUZ(VideoDevice *device)
+ : VDeviceBase(device)
+{
+ reset_parameters();
+ render_strategies.append(VRENDER_MJPG);
+ tuner_lock = new Mutex("VDeviceBUZ::tuner_lock");
+}
+
+VDeviceBUZ::~VDeviceBUZ()
+{
+ close_all();
+ delete tuner_lock;
+}
+
+void VDeviceBUZ::reset_parameters()
+{
+ jvideo_fd = 0;
+ input_buffer = 0;
+ output_buffer = 0;
+ frame_buffer = 0;
+ frame_size = 0;
+ frame_allocated = 0;
+ input_error = 0;
+ last_frame_no = 0;
+ temp_frame = 0;
+ user_frame = 0;
+ mjpeg = 0;
+ total_loops = 0;
+ output_number = 0;
+ input_thread = 0;
+ brightness = 32768;
+ hue = 32768;
+ color = 32768;
+ contrast = 32768;
+ whiteness = 32768;
+ return 0;
+}
+
+void VDeviceBUZ::close_input_core()
+{
+ if(input_thread)
+ {
+ delete input_thread;
+ input_thread = 0;
+ }
+
+
+ if(device->r)
+ {
+ if(jvideo_fd) close(jvideo_fd);
+ jvideo_fd = 0;
+ }
+
+ if(input_buffer)
+ {
+ if(input_buffer > 0)
+ munmap(input_buffer, breq.count * breq.size);
+ input_buffer = 0;
+ }
+ return 0;
+}
+
+int VDeviceBUZ::close_output_core()
+{
+//printf("VDeviceBUZ::close_output_core 1\n");
+ if(device->w)
+ {
+// if(ioctl(jvideo_fd, BUZIOC_QBUF_PLAY, &n) < 0)
+// perror("VDeviceBUZ::close_output_core BUZIOC_QBUF_PLAY");
+ if(jvideo_fd) close(jvideo_fd);
+ jvideo_fd = 0;
+ }
+ if(output_buffer)
+ {
+ if(output_buffer > 0)
+ munmap(output_buffer, breq.count * breq.size);
+ output_buffer = 0;
+ }
+ if(temp_frame)
+ {
+ delete temp_frame;
+ temp_frame = 0;
+ }
+ if(mjpeg)
+ {
+ mjpeg_delete(mjpeg);
+ mjpeg = 0;
+ }
+ if(user_frame)
+ {
+ delete user_frame;
+ user_frame = 0;
+ }
+//printf("VDeviceBUZ::close_output_core 2\n");
+ return 0;
+}
+
+
+int VDeviceBUZ::close_all()
+{
+//printf("VDeviceBUZ::close_all 1\n");
+ close_input_core();
+//printf("VDeviceBUZ::close_all 1\n");
+ close_output_core();
+//printf("VDeviceBUZ::close_all 1\n");
+ if(frame_buffer) delete frame_buffer;
+//printf("VDeviceBUZ::close_all 1\n");
+ reset_parameters();
+//printf("VDeviceBUZ::close_all 2\n");
+ return 0;
+}
+
+#define COMPOSITE_TEXT "Composite"
+#define SVIDEO_TEXT "S-Video"
+#define BUZ_COMPOSITE 0
+#define BUZ_SVIDEO 1
+
+void VDeviceBUZ::get_inputs(ArrayList<Channel*> *input_sources)
+{
+ Channel *new_source = new Channel;
+
+ strcpy(new_source->device_name, COMPOSITE_TEXT);
+ input_sources->append(new_source);
+
+ new_source = new Channel;
+ strcpy(new_source->device_name, SVIDEO_TEXT);
+ input_sources->append(new_source);
+}
+
+int VDeviceBUZ::open_input()
+{
+ 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;
+
+// Can't open input until after the channel is set
+ return 0;
+}
+
+int VDeviceBUZ::open_output()
+{
+// Can't open output until after the channel is set
+ return 0;
+}
+
+int VDeviceBUZ::set_channel(Channel *channel)
+{
+ if(!channel) return 0;
+
+ tuner_lock->lock("VDeviceBUZ::set_channel");
+
+ if(device->r)
+ {
+ close_input_core();
+ open_input_core(channel);
+ }
+ else
+ {
+ close_output_core();
+ open_output_core(channel);
+ }
+
+ tuner_lock->unlock();
+
+
+ return 0;
+}
+
+int VDeviceBUZ::create_channeldb(ArrayList<Channel*> *channeldb)
+{
+ return 0;
+}
+
+int VDeviceBUZ::set_picture(PictureConfig *picture)
+{
+ this->brightness = (int)((float)picture->brightness / 100 * 32767 + 32768);
+ this->hue = (int)((float)picture->hue / 100 * 32767 + 32768);
+ this->color = (int)((float)picture->color / 100 * 32767 + 32768);
+ this->contrast = (int)((float)picture->contrast / 100 * 32767 + 32768);
+ this->whiteness = (int)((float)picture->whiteness / 100 * 32767 + 32768);
+
+
+ tuner_lock->lock("VDeviceBUZ::set_picture");
+ if(device->r)
+ {
+ close_input_core();
+ open_input_core(0);
+ }
+ else
+ {
+ close_output_core();
+ open_output_core(0);
+ }
+ tuner_lock->unlock();
+//
+//
+// TRACE("VDeviceBUZ::set_picture 1");
+// tuner_lock->lock("VDeviceBUZ::set_picture");
+// TRACE("VDeviceBUZ::set_picture 2");
+//
+//
+//
+// struct video_picture picture_params;
+// // This call takes a long time in 2.4.22
+// if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
+// perror("VDeviceBUZ::set_picture VIDIOCGPICT");
+// picture_params.brightness = brightness;
+// picture_params.hue = hue;
+// picture_params.colour = color;
+// picture_params.contrast = contrast;
+// picture_params.whiteness = whiteness;
+// // This call takes a long time in 2.4.22
+// if(ioctl(jvideo_fd, VIDIOCSPICT, &picture_params) < 0)
+// perror("VDeviceBUZ::set_picture VIDIOCSPICT");
+// if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
+// perror("VDeviceBUZ::set_picture VIDIOCGPICT");
+//
+//
+// TRACE("VDeviceBUZ::set_picture 10");
+//
+//
+// tuner_lock->unlock();
+
+ return 0;
+}
+
+int VDeviceBUZ::get_norm(int norm)
+{
+ switch(norm)
+ {
+ case NTSC: return VIDEO_MODE_NTSC;
+ case PAL: return VIDEO_MODE_PAL;
+ case SECAM: return VIDEO_MODE_SECAM;
+ }
+ printf("VDeviceBUZ::get_norm: unknown norm %d\n", norm);
+ return VIDEO_MODE_NTSC;
+}
+
+int VDeviceBUZ::read_buffer(VFrame *frame)
+{
+ tuner_lock->lock("VDeviceBUZ::read_buffer");
+ if(!jvideo_fd) open_input_core(0);
+
+// Get buffer from thread
+ char *buffer = 0;
+ int buffer_size = 0;
+ if(input_thread)
+ input_thread->get_buffer(&buffer, &buffer_size);
+
+ if(buffer)
+ {
+ frame->allocate_compressed_data(buffer_size);
+ frame->set_compressed_size(buffer_size);
+
+// Transfer fields to frame
+ if(device->odd_field_first)
+ {
+ long field2_offset = mjpeg_get_field2((unsigned char*)buffer, buffer_size);
+ long field1_len = field2_offset;
+ long field2_len = buffer_size - field2_offset;
+
+ memcpy(frame->get_data(), buffer + field2_offset, field2_len);
+ memcpy(frame->get_data() + field2_len, buffer, field1_len);
+ }
+ else
+ {
+ bcopy(buffer, frame->get_data(), buffer_size);
+ }
+
+ input_thread->put_buffer();
+ tuner_lock->unlock();
+ }
+ else
+ {
+ tuner_lock->unlock();
+ Timer timer;
+// Allow other threads to lock the tuner_lock under NPTL.
+ timer.delay(100);
+ }
+
+
+ return 0;
+}
+
+int VDeviceBUZ::open_input_core(Channel *channel)
+{
+ jvideo_fd = open(device->in_config->buz_in_device, O_RDONLY);
+
+ if(jvideo_fd <= 0)
+ {
+ fprintf(stderr, "VDeviceBUZ::open_input %s: %s\n",
+ device->in_config->buz_in_device,
+ strerror(errno));
+ jvideo_fd = 0;
+ return 1;
+ }
+
+// Create input sources
+ get_inputs(&device->input_sources);
+
+// Set current input source
+ if(channel)
+ {
+ for(int i = 0; i < 2; i++)
+ {
+ struct video_channel vch;
+ vch.channel = channel->input;
+ vch.norm = get_norm(channel->norm);
+
+//printf("VDeviceBUZ::open_input_core 2 %d %d\n", vch.channel, vch.norm);
+ if(ioctl(jvideo_fd, VIDIOCSCHAN, &vch) < 0)
+ perror("VDeviceBUZ::open_input_core VIDIOCSCHAN ");
+ }
+ }
+
+
+// Throw away
+// struct video_capability vc;
+// if(ioctl(jvideo_fd, VIDIOCGCAP, &vc) < 0)
+// perror("VDeviceBUZ::open_input VIDIOCGCAP");
+
+// API dependant initialization
+ if(ioctl(jvideo_fd, BUZIOC_G_PARAMS, &bparm) < 0)
+ perror("VDeviceBUZ::open_input BUZIOC_G_PARAMS");
+
+ bparm.HorDcm = 1;
+ bparm.VerDcm = 1;
+ bparm.TmpDcm = 1;
+ bparm.field_per_buff = 2;
+ bparm.img_width = device->in_config->w;
+ bparm.img_height = device->in_config->h / bparm.field_per_buff;
+ bparm.img_x = 0;
+ bparm.img_y = 0;
+// bparm.APPn = 0;
+// bparm.APP_len = 14;
+ bparm.APP_len = 0;
+ bparm.odd_even = 0;
+ bparm.decimation = 0;
+ bparm.quality = device->quality;
+ bzero(bparm.APP_data, sizeof(bparm.APP_data));
+
+ if(ioctl(jvideo_fd, BUZIOC_S_PARAMS, &bparm) < 0)
+ perror("VDeviceBUZ::open_input BUZIOC_S_PARAMS");
+
+// printf("open_input %d %d %d %d %d %d %d %d %d %d %d %d\n",
+// bparm.HorDcm,
+// bparm.VerDcm,
+// bparm.TmpDcm,
+// bparm.field_per_buff,
+// bparm.img_width,
+// bparm.img_height,
+// bparm.img_x,
+// bparm.img_y,
+// bparm.APP_len,
+// bparm.odd_even,
+// bparm.decimation,
+// bparm.quality);
+
+ breq.count = device->in_config->capture_length;
+ breq.size = INPUT_BUFFER_SIZE;
+ if(ioctl(jvideo_fd, BUZIOC_REQBUFS, &breq) < 0)
+ perror("VDeviceBUZ::open_input BUZIOC_REQBUFS");
+
+//printf("open_input %s %d %d %d %d\n", device->in_config->buz_in_device, breq.count, breq.size, bparm.img_width, bparm.img_height);
+ if((input_buffer = (char*)mmap(0,
+ breq.count * breq.size,
+ PROT_READ,
+ MAP_SHARED,
+ jvideo_fd,
+ 0)) == MAP_FAILED)
+ perror("VDeviceBUZ::open_input mmap");
+
+
+// Set picture quality
+ struct video_picture picture_params;
+// This call takes a long time in 2.4.22
+ if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
+ perror("VDeviceBUZ::set_picture VIDIOCGPICT");
+ picture_params.brightness = brightness;
+ picture_params.hue = hue;
+ picture_params.colour = color;
+ picture_params.contrast = contrast;
+ picture_params.whiteness = whiteness;
+// This call takes a long time in 2.4.22
+ if(ioctl(jvideo_fd, VIDIOCSPICT, &picture_params) < 0)
+ perror("VDeviceBUZ::set_picture VIDIOCSPICT");
+ if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
+ perror("VDeviceBUZ::set_picture VIDIOCGPICT");
+
+
+// Start capturing
+ int count = breq.count;
+ for(int i = 0; i < count; i++)
+ {
+ if(ioctl(jvideo_fd, BUZIOC_QBUF_CAPT, &i) < 0)
+ perror("VDeviceBUZ::open_input BUZIOC_QBUF_CAPT");
+ }
+
+
+ input_thread = new VDeviceBUZInput(this);
+ input_thread->start();
+//printf("VDeviceBUZ::open_input_core 2\n");
+ return 0;
+}
+
+int VDeviceBUZ::open_output_core(Channel *channel)
+{
+//printf("VDeviceBUZ::open_output 1\n");
+ total_loops = 0;
+ output_number = 0;
+ jvideo_fd = open(device->out_config->buz_out_device, O_RDWR);
+ if(jvideo_fd <= 0)
+ {
+ perror("VDeviceBUZ::open_output");
+ return 1;
+ }
+
+
+// Set current input source
+ if(channel)
+ {
+ struct video_channel vch;
+ vch.channel = channel->input;
+ vch.norm = get_norm(channel->norm);
+
+ if(ioctl(jvideo_fd, VIDIOCSCHAN, &vch) < 0)
+ perror("VDeviceBUZ::open_output_core VIDIOCSCHAN ");
+ }
+
+ breq.count = 10;
+ breq.size = INPUT_BUFFER_SIZE;
+ if(ioctl(jvideo_fd, BUZIOC_REQBUFS, &breq) < 0)
+ perror("VDeviceBUZ::open_output BUZIOC_REQBUFS");
+ if((output_buffer = (char*)mmap(0,
+ breq.count * breq.size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ jvideo_fd,
+ 0)) == MAP_FAILED)
+ perror("VDeviceBUZ::open_output mmap");
+
+ if(ioctl(jvideo_fd, BUZIOC_G_PARAMS, &bparm) < 0)
+ perror("VDeviceBUZ::open_output BUZIOC_G_PARAMS");
+
+ bparm.decimation = 1;
+ bparm.HorDcm = 1;
+ bparm.field_per_buff = 2;
+ bparm.TmpDcm = 1;
+ bparm.VerDcm = 1;
+ bparm.img_width = device->out_w;
+ bparm.img_height = device->out_h / bparm.field_per_buff;
+ bparm.img_x = 0;
+ bparm.img_y = 0;
+ bparm.odd_even = 0;
+
+ if(ioctl(jvideo_fd, BUZIOC_S_PARAMS, &bparm) < 0)
+ perror("VDeviceBUZ::open_output BUZIOC_S_PARAMS");
+//printf("VDeviceBUZ::open_output 2\n");
+ return 0;
+}
+
+
+
+int VDeviceBUZ::write_buffer(VFrame *frame, EDL *edl)
+{
+//printf("VDeviceBUZ::write_buffer 1\n");
+ tuner_lock->lock("VDeviceBUZ::write_buffer");
+
+ if(!jvideo_fd) open_output_core(0);
+
+ VFrame *ptr = 0;
+ if(frame->get_color_model() != BC_COMPRESSED)
+ {
+ if(!temp_frame) temp_frame = new VFrame;
+ if(!mjpeg)
+ {
+ mjpeg = mjpeg_new(device->out_w, device->out_h, 2);
+ mjpeg_set_quality(mjpeg, device->quality);
+ mjpeg_set_float(mjpeg, 0);
+ }
+ ptr = temp_frame;
+ mjpeg_compress(mjpeg,
+ frame->get_rows(),
+ frame->get_y(),
+ frame->get_u(),
+ frame->get_v(),
+ frame->get_color_model(),
+ device->cpus);
+ temp_frame->allocate_compressed_data(mjpeg_output_size(mjpeg));
+ temp_frame->set_compressed_size(mjpeg_output_size(mjpeg));
+ bcopy(mjpeg_output_buffer(mjpeg), temp_frame->get_data(), mjpeg_output_size(mjpeg));
+ }
+ else
+ ptr = frame;
+
+// Wait for frame to become available
+// Caused close_output_core to lock up.
+// if(total_loops >= 1)
+// {
+// if(ioctl(jvideo_fd, BUZIOC_SYNC, &output_number) < 0)
+// perror("VDeviceBUZ::write_buffer BUZIOC_SYNC");
+// }
+
+ if(device->out_config->buz_swap_fields)
+ {
+ long field2_offset = mjpeg_get_field2((unsigned char*)ptr->get_data(),
+ ptr->get_compressed_size());
+ long field2_len = ptr->get_compressed_size() - field2_offset;
+ memcpy(output_buffer + output_number * breq.size,
+ ptr->get_data() + field2_offset,
+ field2_len);
+ memcpy(output_buffer + output_number * breq.size +field2_len,
+ ptr->get_data(),
+ field2_offset);
+ }
+ else
+ {
+ bcopy(ptr->get_data(),
+ output_buffer + output_number * breq.size,
+ ptr->get_compressed_size());
+ }
+
+ if(ioctl(jvideo_fd, BUZIOC_QBUF_PLAY, &output_number) < 0)
+ perror("VDeviceBUZ::write_buffer BUZIOC_QBUF_PLAY");
+
+ output_number++;
+ if(output_number >= (int)breq.count)
+ {
+ output_number = 0;
+ total_loops++;
+ }
+ tuner_lock->unlock();
+//printf("VDeviceBUZ::write_buffer 2\n");
+
+ return 0;
+}
+
+void VDeviceBUZ::new_output_buffer(VFrame *output,
+ int colormodel)
+{
+//printf("VDeviceBUZ::new_output_buffer 1 %d\n", colormodel);
+ if(user_frame)
+ {
+ if(colormodel != user_frame->get_color_model())
+ {
+ delete user_frame;
+ user_frame = 0;
+ }
+ }
+
+ if(!user_frame)
+ {
+ switch(colormodel)
+ {
+ case BC_COMPRESSED:
+ user_frame = new VFrame;
+ break;
+ default:
+ user_frame = new VFrame(0,
+ -1,
+ device->out_w,
+ device->out_h,
+ colormodel,
+ -1);
+ break;
+ }
+ }
+// user_frame->set_shm_offset(0);
+ output = user_frame;
+//printf("VDeviceBUZ::new_output_buffer 2\n");
+}
+
+
+ArrayList<int>* VDeviceBUZ::get_render_strategies()
+{
+ return &render_strategies;
+}
+
+
+#endif // HAVE_VIDEO4LINUX
+
+