Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vdevicebuz.C

Go to the documentation of this file.
00001 // ALPHA C++ can't compile 64 bit headers
00002 #undef _LARGEFILE_SOURCE
00003 #undef _LARGEFILE64_SOURCE
00004 #undef _FILE_OFFSET_BITS
00005 
00006 #include "assets.h"
00007 #include "bcsignals.h"
00008 #include "channel.h"
00009 #include "chantables.h"
00010 #include "condition.h"
00011 #include "file.inc"
00012 #include "mutex.h"
00013 #include "picture.h"
00014 #include "playbackconfig.h"
00015 #include "preferences.h"
00016 #include "recordconfig.h"
00017 #include "strategies.inc"
00018 #include "vdevicebuz.h"
00019 #include "vframe.h"
00020 #include "videoconfig.h"
00021 #include "videodevice.h"
00022 
00023 #include <errno.h>
00024 #include <stdint.h>
00025 #include <linux/kernel.h>
00026 //#include <linux/videodev2.h>
00027 #include <linux/videodev.h>
00028 #include <fcntl.h>
00029 #include <sys/ioctl.h>
00030 #include <sys/mman.h>
00031 #include <unistd.h>
00032 
00033 
00034 
00035 #define READ_TIMEOUT 5000000
00036 
00037 
00038 VDeviceBUZInput::VDeviceBUZInput(VDeviceBUZ *device)
00039  : Thread(1, 1, 0)
00040 {
00041         this->device = device;
00042         buffer = 0;
00043         buffer_size = 0;
00044         total_buffers = 0;
00045         current_inbuffer = 0;
00046         current_outbuffer = 0;
00047         done = 0;
00048         output_lock = new Condition(0, "VDeviceBUZInput::output_lock");
00049         buffer_lock = new Mutex("VDeviceBUZInput::buffer_lock");
00050 }
00051 
00052 VDeviceBUZInput::~VDeviceBUZInput()
00053 {
00054         if(Thread::running())
00055         {
00056                 done = 1;
00057                 Thread::cancel();
00058                 Thread::join();
00059         }
00060 
00061         if(buffer)
00062         {
00063                 for(int i = 0; i < total_buffers; i++)
00064                 {
00065                         delete [] buffer[i];
00066                 }
00067                 delete [] buffer;
00068                 delete [] buffer_size;
00069         }
00070         delete output_lock;
00071         delete buffer_lock;
00072 }
00073 
00074 void VDeviceBUZInput::start()
00075 {
00076 // Create buffers
00077         total_buffers = device->device->in_config->capture_length;
00078         buffer = new char*[total_buffers];
00079         buffer_size = new int[total_buffers];
00080         bzero(buffer_size, sizeof(int) * total_buffers);
00081         for(int i = 0; i < total_buffers; i++)
00082         {
00083                 buffer[i] = new char[INPUT_BUFFER_SIZE];
00084         }
00085 
00086         Thread::start();
00087 }
00088 
00089 void VDeviceBUZInput::run()
00090 {
00091     struct buz_sync bsync;
00092 
00093 // Wait for frame
00094         while(1)
00095         {
00096                 Thread::enable_cancel();
00097                 if(ioctl(device->jvideo_fd, BUZIOC_SYNC, &bsync) < 0)
00098                 {
00099                         perror("VDeviceBUZInput::run BUZIOC_SYNC");
00100                         if(done) return;
00101                         Thread::disable_cancel();
00102                 }
00103                 else
00104                 {
00105                         Thread::disable_cancel();
00106 
00107 
00108 
00109                         int new_buffer = 0;
00110                         buffer_lock->lock("VDeviceBUZInput::run");
00111 // Save only if the current buffer is free.
00112                         if(!buffer_size[current_inbuffer])
00113                         {
00114                                 new_buffer = 1;
00115 // Copy to input buffer
00116                                 memcpy(buffer[current_inbuffer], 
00117                                         device->input_buffer + bsync.frame * device->breq.size,
00118                                         bsync.length);
00119 
00120 // Advance input buffer number and decrease semaphore.
00121                                 buffer_size[current_inbuffer] = bsync.length;
00122                                 increment_counter(&current_inbuffer);
00123                         }
00124 
00125                         buffer_lock->unlock();
00126 
00127                         if(ioctl(device->jvideo_fd, BUZIOC_QBUF_CAPT, &bsync.frame))
00128                                 perror("VDeviceBUZInput::run BUZIOC_QBUF_CAPT");
00129 
00130                         if(new_buffer) output_lock->unlock();
00131                 }
00132         }
00133 }
00134 
00135 void VDeviceBUZInput::get_buffer(char **ptr, int *size)
00136 {
00137 // Increase semaphore to wait for buffer.
00138         int result = output_lock->timed_lock(READ_TIMEOUT, "VDeviceBUZInput::get_buffer");
00139 
00140 
00141 // The driver has its own timeout routine but it doesn't work because
00142 // because the tuner lock is unlocked and relocked with no delay.
00143 //      int result = 0;
00144 //      output_lock->lock("VDeviceBUZInput::get_buffer");
00145 
00146         if(!result)
00147         {
00148 // Take over buffer table
00149                 buffer_lock->lock("VDeviceBUZInput::get_buffer");
00150                 *ptr = buffer[current_outbuffer];
00151                 *size = buffer_size[current_outbuffer];
00152                 buffer_lock->unlock();
00153         }
00154         else
00155         {
00156 //printf("VDeviceBUZInput::get_buffer 1\n");
00157                 output_lock->unlock();
00158         }
00159 }
00160 
00161 void VDeviceBUZInput::put_buffer()
00162 {
00163         buffer_lock->lock("VDeviceBUZInput::put_buffer");
00164         buffer_size[current_outbuffer] = 0;
00165         buffer_lock->unlock();
00166         increment_counter(&current_outbuffer);
00167 }
00168 
00169 void VDeviceBUZInput::increment_counter(int *counter)
00170 {
00171         (*counter)++;
00172         if(*counter >= total_buffers) *counter = 0;
00173 }
00174 
00175 void VDeviceBUZInput::decrement_counter(int *counter)
00176 {
00177         (*counter)--;
00178         if(*counter < 0) *counter = total_buffers - 1;
00179 }
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 VDeviceBUZ::VDeviceBUZ(VideoDevice *device)
00196  : VDeviceBase(device)
00197 {
00198         reset_parameters();
00199         render_strategies.append(VRENDER_MJPG);
00200         tuner_lock = new Mutex("VDeviceBUZ::tuner_lock");
00201 }
00202 
00203 VDeviceBUZ::~VDeviceBUZ()
00204 {
00205         close_all();
00206         delete tuner_lock;
00207 }
00208 
00209 int VDeviceBUZ::reset_parameters()
00210 {
00211         jvideo_fd = 0;
00212         input_buffer = 0;
00213         output_buffer = 0;
00214         frame_buffer = 0;
00215         frame_size = 0;
00216         frame_allocated = 0;
00217         input_error = 0;
00218         last_frame_no = 0;
00219         temp_frame = 0;
00220         user_frame = 0;
00221         mjpeg = 0;
00222         total_loops = 0;
00223         output_number = 0;
00224         input_thread = 0;
00225         brightness = 32768;
00226         hue = 32768;
00227         color = 32768;
00228         contrast = 32768;
00229         whiteness = 32768;
00230 }
00231 
00232 int VDeviceBUZ::close_input_core()
00233 {
00234         if(input_thread)
00235         {
00236                 delete input_thread;
00237                 input_thread = 0;
00238         }
00239 
00240 
00241         if(device->r)
00242         {
00243                 if(jvideo_fd) close(jvideo_fd);
00244                 jvideo_fd = 0;
00245         }
00246 
00247         if(input_buffer)
00248         {
00249                 if(input_buffer > 0)
00250                         munmap(input_buffer, breq.count * breq.size);
00251                 input_buffer = 0;
00252         }
00253 }
00254 
00255 int VDeviceBUZ::close_output_core()
00256 {
00257 //printf("VDeviceBUZ::close_output_core 1\n");
00258         if(device->w)
00259         {
00260                 int n = -1;
00261 //              if(ioctl(jvideo_fd, BUZIOC_QBUF_PLAY, &n) < 0)
00262 //                      perror("VDeviceBUZ::close_output_core BUZIOC_QBUF_PLAY");
00263                 if(jvideo_fd) close(jvideo_fd);
00264                 jvideo_fd = 0;
00265         }
00266         if(output_buffer)
00267         {
00268                 if(output_buffer > 0)
00269                         munmap(output_buffer, breq.count * breq.size);
00270                 output_buffer = 0;
00271         }
00272         if(temp_frame)
00273         {
00274                 delete temp_frame;
00275                 temp_frame = 0;
00276         }
00277         if(mjpeg)
00278         {
00279                 mjpeg_delete(mjpeg);
00280                 mjpeg = 0;
00281         }
00282         if(user_frame)
00283         {
00284                 delete user_frame;
00285                 user_frame = 0;
00286         }
00287 //printf("VDeviceBUZ::close_output_core 2\n");
00288         return 0;
00289 }
00290 
00291 
00292 int VDeviceBUZ::close_all()
00293 {
00294 //printf("VDeviceBUZ::close_all 1\n");
00295         close_input_core();
00296 //printf("VDeviceBUZ::close_all 1\n");
00297         close_output_core();
00298 //printf("VDeviceBUZ::close_all 1\n");
00299         if(frame_buffer) delete frame_buffer;
00300 //printf("VDeviceBUZ::close_all 1\n");
00301         reset_parameters();
00302 //printf("VDeviceBUZ::close_all 2\n");
00303         return 0;
00304 }
00305 
00306 #define COMPOSITE_TEXT "Composite"
00307 #define SVIDEO_TEXT "S-Video"
00308 #define BUZ_COMPOSITE 0
00309 #define BUZ_SVIDEO 1
00310 
00311 void VDeviceBUZ::get_inputs(ArrayList<Channel*> *input_sources)
00312 {
00313         Channel *new_source = new Channel;
00314 
00315         new_source = new Channel;
00316         strcpy(new_source->device_name, COMPOSITE_TEXT);
00317         input_sources->append(new_source);
00318 
00319         new_source = new Channel;
00320         strcpy(new_source->device_name, SVIDEO_TEXT);
00321         input_sources->append(new_source);
00322 }
00323 
00324 int VDeviceBUZ::open_input()
00325 {
00326         device->channel->use_norm = 1;
00327         device->channel->use_input = 1;
00328 
00329         device->picture->use_brightness = 1;
00330         device->picture->use_contrast = 1;
00331         device->picture->use_color = 1;
00332         device->picture->use_hue = 1;
00333         device->picture->use_whiteness = 1;
00334 
00335 // Can't open input until after the channel is set
00336         return 0;
00337 }
00338 
00339 int VDeviceBUZ::open_output()
00340 {
00341 // Can't open output until after the channel is set
00342         return 0;
00343 }
00344 
00345 int VDeviceBUZ::set_channel(Channel *channel)
00346 {
00347         if(!channel) return 0;
00348 
00349         tuner_lock->lock("VDeviceBUZ::set_channel");
00350 
00351         if(device->r)
00352         {
00353                 close_input_core();
00354                 open_input_core(channel);
00355         }
00356         else
00357         {
00358                 close_output_core();
00359                 open_output_core(channel);
00360         }
00361 
00362         tuner_lock->unlock();
00363 
00364 
00365         return 0;
00366 }
00367 
00368 void VDeviceBUZ::create_channeldb(ArrayList<Channel*> *channeldb)
00369 {
00370         ;
00371 }
00372 
00373 int VDeviceBUZ::set_picture(PictureConfig *picture)
00374 {
00375         this->brightness = (int)((float)picture->brightness / 100 * 32767 + 32768);
00376         this->hue = (int)((float)picture->hue / 100 * 32767 + 32768);
00377         this->color = (int)((float)picture->color / 100 * 32767 + 32768);
00378         this->contrast = (int)((float)picture->contrast / 100 * 32767 + 32768);
00379         this->whiteness = (int)((float)picture->whiteness / 100 * 32767 + 32768);
00380 
00381 
00382         tuner_lock->lock("VDeviceBUZ::set_picture");
00383         if(device->r)
00384         {
00385                 close_input_core();
00386                 open_input_core(0);
00387         }
00388         else
00389         {
00390                 close_output_core();
00391                 open_output_core(0);
00392         }
00393         tuner_lock->unlock();
00394 // 
00395 // 
00396 // TRACE("VDeviceBUZ::set_picture 1");
00397 //      tuner_lock->lock("VDeviceBUZ::set_picture");
00398 // TRACE("VDeviceBUZ::set_picture 2");
00399 // 
00400 // 
00401 // 
00402 //      struct video_picture picture_params;
00403 // // This call takes a long time in 2.4.22
00404 //      if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
00405 //              perror("VDeviceBUZ::set_picture VIDIOCGPICT");
00406 //      picture_params.brightness = brightness;
00407 //      picture_params.hue = hue;
00408 //      picture_params.colour = color;
00409 //      picture_params.contrast = contrast;
00410 //      picture_params.whiteness = whiteness;
00411 // // This call takes a long time in 2.4.22
00412 //      if(ioctl(jvideo_fd, VIDIOCSPICT, &picture_params) < 0)
00413 //              perror("VDeviceBUZ::set_picture VIDIOCSPICT");
00414 //      if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
00415 //              perror("VDeviceBUZ::set_picture VIDIOCGPICT");
00416 // 
00417 // 
00418 // TRACE("VDeviceBUZ::set_picture 10");
00419 // 
00420 // 
00421 //      tuner_lock->unlock();
00422 
00423         return 0;
00424 }
00425 
00426 int VDeviceBUZ::get_norm(int norm)
00427 {
00428         switch(norm)
00429         {
00430                 case NTSC:          return VIDEO_MODE_NTSC;      break;
00431                 case PAL:           return VIDEO_MODE_PAL;       break;
00432                 case SECAM:         return VIDEO_MODE_SECAM;     break;
00433         }
00434 }
00435 
00436 int VDeviceBUZ::read_buffer(VFrame *frame)
00437 {
00438         tuner_lock->lock("VDeviceBUZ::read_buffer");
00439         if(!jvideo_fd) open_input_core(0);
00440 
00441 // Get buffer from thread
00442         char *buffer = 0;
00443         int buffer_size = 0;
00444         if (input_thread)
00445                 input_thread->get_buffer(&buffer, &buffer_size);
00446 
00447         if(buffer)
00448         {
00449                 frame->allocate_compressed_data(buffer_size);
00450                 frame->set_compressed_size(buffer_size);
00451 
00452 // Transfer fields to frame
00453                 if(device->odd_field_first)
00454                 {
00455                         long field2_offset = mjpeg_get_field2((unsigned char*)buffer, buffer_size);
00456                         long field1_len = field2_offset;
00457                         long field2_len = buffer_size - field2_offset;
00458 
00459                         memcpy(frame->get_data(), buffer + field2_offset, field2_len);
00460                         memcpy(frame->get_data() + field2_len, buffer, field1_len);
00461                 }
00462                 else
00463                 {
00464                         bcopy(buffer, frame->get_data(), buffer_size);
00465                 }
00466 
00467                 input_thread->put_buffer();
00468                 tuner_lock->unlock();
00469         }
00470         else
00471         {
00472                 tuner_lock->unlock();
00473                 Timer timer;
00474 // Allow other threads to lock the tuner_lock under NPTL.
00475                 timer.delay(100);
00476         }
00477 
00478 
00479         return 0;
00480 }
00481 
00482 int VDeviceBUZ::open_input_core(Channel *channel)
00483 {
00484         jvideo_fd = open(device->in_config->buz_in_device, O_RDONLY);
00485 
00486         if(jvideo_fd <= 0)
00487         {
00488                 fprintf(stderr, "VDeviceBUZ::open_input %s: %s\n", 
00489                         device->in_config->buz_in_device,
00490                         strerror(errno));
00491                 jvideo_fd = 0;
00492                 return 1;
00493         }
00494 
00495 // Create input sources
00496         get_inputs(&device->input_sources);
00497 
00498 // Set current input source
00499         if(channel)
00500         {
00501                 for(int i = 0; i < 2; i++)
00502                 {
00503                         struct video_channel vch;
00504                         vch.channel = channel->input;
00505                         vch.norm = get_norm(channel->norm);
00506 
00507 //printf("VDeviceBUZ::open_input_core 2 %d %d\n", vch.channel, vch.norm);
00508                         if(ioctl(jvideo_fd, VIDIOCSCHAN, &vch) < 0)
00509                                 perror("VDeviceBUZ::open_input_core VIDIOCSCHAN ");
00510                 }
00511         }
00512 
00513 
00514 // Throw away
00515 //     struct video_capability vc;
00516 //      if(ioctl(jvideo_fd, VIDIOCGCAP, &vc) < 0)
00517 //              perror("VDeviceBUZ::open_input VIDIOCGCAP");
00518 
00519 // API dependant initialization
00520         if(ioctl(jvideo_fd, BUZIOC_G_PARAMS, &bparm) < 0)
00521                 perror("VDeviceBUZ::open_input BUZIOC_G_PARAMS");
00522 
00523         bparm.HorDcm = 1;
00524         bparm.VerDcm = 1;
00525         bparm.TmpDcm = 1;
00526         bparm.field_per_buff = 2;
00527         bparm.img_width = device->in_config->w;
00528         bparm.img_height = device->in_config->h / bparm.field_per_buff;
00529         bparm.img_x = 0;
00530         bparm.img_y = 0;
00531 //      bparm.APPn = 0;
00532 //      bparm.APP_len = 14;
00533         bparm.APP_len = 0;
00534         bparm.odd_even = 0;
00535     bparm.decimation = 0;
00536     bparm.quality = device->quality;
00537     bzero(bparm.APP_data, sizeof(bparm.APP_data));
00538 
00539         if(ioctl(jvideo_fd, BUZIOC_S_PARAMS, &bparm) < 0)
00540                 perror("VDeviceBUZ::open_input BUZIOC_S_PARAMS");
00541 
00542 // printf("open_input %d %d %d %d %d %d %d %d %d %d %d %d\n", 
00543 //              bparm.HorDcm,
00544 //              bparm.VerDcm,
00545 //              bparm.TmpDcm,
00546 //              bparm.field_per_buff,
00547 //              bparm.img_width,
00548 //              bparm.img_height,
00549 //              bparm.img_x,
00550 //              bparm.img_y,
00551 //              bparm.APP_len,
00552 //              bparm.odd_even,
00553 //      bparm.decimation,
00554 //      bparm.quality);
00555 
00556         breq.count = device->in_config->capture_length;
00557         breq.size = INPUT_BUFFER_SIZE;
00558         if(ioctl(jvideo_fd, BUZIOC_REQBUFS, &breq) < 0)
00559                 perror("VDeviceBUZ::open_input BUZIOC_REQBUFS");
00560 
00561 //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);
00562         if((input_buffer = (char*)mmap(0, 
00563                 breq.count * breq.size, 
00564                 PROT_READ, 
00565                 MAP_SHARED, 
00566                 jvideo_fd, 
00567                 0)) <= 0)
00568                 perror("VDeviceBUZ::open_input mmap");
00569 
00570 
00571 // Set picture quality
00572         struct video_picture picture_params;
00573 // This call takes a long time in 2.4.22
00574         if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
00575                 perror("VDeviceBUZ::set_picture VIDIOCGPICT");
00576         picture_params.brightness = brightness;
00577         picture_params.hue = hue;
00578         picture_params.colour = color;
00579         picture_params.contrast = contrast;
00580         picture_params.whiteness = whiteness;
00581 // This call takes a long time in 2.4.22
00582         if(ioctl(jvideo_fd, VIDIOCSPICT, &picture_params) < 0)
00583                 perror("VDeviceBUZ::set_picture VIDIOCSPICT");
00584         if(ioctl(jvideo_fd, VIDIOCGPICT, &picture_params) < 0)
00585                 perror("VDeviceBUZ::set_picture VIDIOCGPICT");
00586 
00587 
00588 
00589 
00590 // Start capturing
00591         for(int i = 0; i < breq.count; i++)
00592         {
00593         if(ioctl(jvideo_fd, BUZIOC_QBUF_CAPT, &i) < 0)
00594                         perror("VDeviceBUZ::open_input BUZIOC_QBUF_CAPT");
00595         }
00596 
00597 
00598         input_thread = new VDeviceBUZInput(this);
00599         input_thread->start();
00600 //printf("VDeviceBUZ::open_input_core 2\n");
00601         return 0;
00602 }
00603 
00604 int VDeviceBUZ::open_output_core(Channel *channel)
00605 {
00606 //printf("VDeviceBUZ::open_output 1\n");
00607         total_loops = 0;
00608         output_number = 0;
00609         jvideo_fd = open(device->out_config->buz_out_device, O_RDWR);
00610         if(jvideo_fd <= 0)
00611         {
00612                 perror("VDeviceBUZ::open_output");
00613                 return 1;
00614         }
00615 
00616 
00617 // Set current input source
00618         if(channel)
00619         {
00620                 struct video_channel vch;
00621                 vch.channel = channel->input;
00622                 vch.norm = get_norm(channel->norm);
00623 
00624                 if(ioctl(jvideo_fd, VIDIOCSCHAN, &vch) < 0)
00625                         perror("VDeviceBUZ::open_output_core VIDIOCSCHAN ");
00626         }
00627 
00628         breq.count = 10;
00629         breq.size = INPUT_BUFFER_SIZE;
00630         if(ioctl(jvideo_fd, BUZIOC_REQBUFS, &breq) < 0)
00631                 perror("VDeviceBUZ::open_output BUZIOC_REQBUFS");
00632         if((output_buffer = (char*)mmap(0, 
00633                 breq.count * breq.size, 
00634                 PROT_READ | PROT_WRITE, 
00635                 MAP_SHARED, 
00636                 jvideo_fd, 
00637                 0)) <= 0)
00638                 perror("VDeviceBUZ::open_output mmap");
00639 
00640         if(ioctl(jvideo_fd, BUZIOC_G_PARAMS, &bparm) < 0)
00641                 perror("VDeviceBUZ::open_output BUZIOC_G_PARAMS");
00642 
00643         bparm.decimation = 1;
00644         bparm.HorDcm = 1;
00645         bparm.field_per_buff = 2;
00646         bparm.TmpDcm = 1;
00647         bparm.VerDcm = 1;
00648         bparm.img_width = device->out_w;
00649         bparm.img_height = device->out_h / bparm.field_per_buff;
00650         bparm.img_x = 0;
00651         bparm.img_y = 0;
00652         bparm.odd_even = 0;
00653 
00654         if(ioctl(jvideo_fd, BUZIOC_S_PARAMS, &bparm) < 0)
00655                 perror("VDeviceBUZ::open_output BUZIOC_S_PARAMS");
00656 //printf("VDeviceBUZ::open_output 2\n");
00657         return 0;
00658 }
00659 
00660 
00661 
00662 int VDeviceBUZ::write_buffer(VFrame **frames, EDL *edl)
00663 {
00664 //printf("VDeviceBUZ::write_buffer 1\n");
00665         tuner_lock->lock("VDeviceBUZ::write_buffer");
00666 
00667         if(!jvideo_fd) open_output_core(0);
00668 
00669         VFrame *ptr = 0;
00670         if(frames[0]->get_color_model() != BC_COMPRESSED)
00671         {
00672                 if(!temp_frame) temp_frame = new VFrame;
00673                 if(!mjpeg)
00674                 {
00675                         mjpeg = mjpeg_new(device->out_w, device->out_h, 2);
00676                         mjpeg_set_quality(mjpeg, device->quality);
00677                         mjpeg_set_float(mjpeg, 0);
00678                 }
00679                 ptr = temp_frame;
00680                 mjpeg_compress(mjpeg, 
00681                         frames[0]->get_rows(), 
00682                         frames[0]->get_y(), 
00683                         frames[0]->get_u(), 
00684                         frames[0]->get_v(),
00685                         frames[0]->get_color_model(),
00686                         device->cpus);
00687                 temp_frame->allocate_compressed_data(mjpeg_output_size(mjpeg));
00688                 temp_frame->set_compressed_size(mjpeg_output_size(mjpeg));
00689                 bcopy(mjpeg_output_buffer(mjpeg), temp_frame->get_data(), mjpeg_output_size(mjpeg));
00690         }
00691         else
00692                 ptr = frames[0];
00693 
00694 // Wait for frame to become available
00695 // Caused close_output_core to lock up.
00696 //      if(total_loops >= 1)
00697 //      {
00698 //              if(ioctl(jvideo_fd, BUZIOC_SYNC, &output_number) < 0)
00699 //                      perror("VDeviceBUZ::write_buffer BUZIOC_SYNC");
00700 //      }
00701 
00702         if(device->out_config->buz_swap_fields)
00703         {
00704                 long field2_offset = mjpeg_get_field2((unsigned char*)ptr->get_data(), 
00705                         ptr->get_compressed_size());
00706                 long field2_len = ptr->get_compressed_size() - field2_offset;
00707                 memcpy(output_buffer + output_number * breq.size, 
00708                         ptr->get_data() + field2_offset, 
00709                         field2_len);
00710                 memcpy(output_buffer + output_number * breq.size +field2_len,
00711                         ptr->get_data(), 
00712                         field2_offset);
00713         }
00714         else
00715         {
00716                 bcopy(ptr->get_data(), 
00717                         output_buffer + output_number * breq.size, 
00718                         ptr->get_compressed_size());
00719         }
00720 
00721         if(ioctl(jvideo_fd, BUZIOC_QBUF_PLAY, &output_number) < 0)
00722                 perror("VDeviceBUZ::write_buffer BUZIOC_QBUF_PLAY");
00723 
00724         output_number++;
00725         if(output_number >= breq.count)
00726         {
00727                 output_number = 0;
00728                 total_loops++;
00729         }
00730         tuner_lock->unlock();
00731 //printf("VDeviceBUZ::write_buffer 2\n");
00732 
00733         return 0;
00734 }
00735 
00736 void VDeviceBUZ::new_output_buffer(VFrame **outputs,
00737         int colormodel)
00738 {
00739 //printf("VDeviceBUZ::new_output_buffer 1 %d\n", colormodel);
00740         if(user_frame)
00741         {
00742                 if(colormodel != user_frame->get_color_model())
00743                 {
00744                         delete user_frame;
00745                         user_frame = 0;
00746                 }
00747         }
00748 
00749         if(!user_frame)
00750         {
00751                 switch(colormodel)
00752                 {
00753                         case BC_COMPRESSED:
00754                                 user_frame = new VFrame;
00755                                 break;
00756                         default:
00757                                 user_frame = new VFrame(0,
00758                                         device->out_w,
00759                                         device->out_h,
00760                                         colormodel,
00761                                         -1);
00762                                 break;
00763                 }
00764         }
00765         user_frame->set_shm_offset(0);
00766         outputs[0] = user_frame;
00767 //printf("VDeviceBUZ::new_output_buffer 2\n");
00768 }
00769 
00770 
00771 ArrayList<int>* VDeviceBUZ::get_render_strategies()
00772 {
00773         return &render_strategies;
00774 }
00775 

Generated on Sun Jan 8 13:39:01 2006 for Cinelerra-svn by  doxygen 1.4.4