Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / cinelerra / iec61883output.C
diff --git a/cinelerra-5.0/cinelerra/iec61883output.C b/cinelerra-5.0/cinelerra/iec61883output.C
deleted file mode 100644 (file)
index f06c6bc..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-
-/*
- * 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_FIREWIRE
-
-
-
-#include "audiodevice.h"
-#include "condition.h"
-#include "iec61883output.h"
-#include "mutex.h"
-#include "playbackconfig.h"
-#include "bctimer.h"
-#include "vframe.h"
-#include "videodevice.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <sys/utsname.h>
-
-
-
-
-
-// Crazy DV internals
-#define CIP_N_NTSC 2436
-#define CIP_D_NTSC 38400
-#define CIP_N_PAL 1
-#define CIP_D_PAL 16
-#define OUTPUT_SAMPLES 262144
-#define BUFFER_TIMEOUT 500000
-
-
-IEC61883Output::IEC61883Output(AudioDevice *adevice)
- : Thread(1, 0, 0)
-{
-       reset();
-       this->adevice = adevice;
-}
-
-IEC61883Output::IEC61883Output(VideoDevice *vdevice)
- : Thread(1, 0, 0)
-{
-       reset();
-       this->vdevice = vdevice;
-}
-
-IEC61883Output::~IEC61883Output()
-{
-       if(Thread::running())
-       {
-               done = 1;
-               start_lock->unlock();
-               Thread::cancel();
-               Thread::join();
-       }
-
-       if(buffer)
-       {
-               for(int i = 0; i < total_buffers; i++)
-               {
-                       if(buffer[i]) delete [] buffer[i];
-               }
-               delete [] buffer;
-               delete [] buffer_size;
-               delete [] buffer_valid;
-       }
-
-       if(audio_lock) delete audio_lock;
-       if(video_lock) delete video_lock;
-       if(start_lock) delete start_lock;
-       if(audio_buffer) delete [] audio_buffer;
-
-       if(temp_frame) delete temp_frame;
-       if(temp_frame2) delete temp_frame2;
-       if(video_encoder) dv_delete(video_encoder);
-       if(audio_encoder) dv_delete(audio_encoder);
-       if(buffer_lock) delete buffer_lock;
-       if(position_lock) delete position_lock;
-       if(frame) iec61883_dv_close(frame);
-       if(handle) raw1394_destroy_handle(handle);
-}
-
-
-void IEC61883Output::reset()
-{
-       handle = 0;
-       fd = 0;
-       frame = 0;
-       out_position = 0;
-       out_buffer = 0;
-       out_size = 0;
-
-       buffer = 0;
-       buffer_size = 0;
-       total_buffers = 0;
-       current_inbuffer = 0;
-       current_outbuffer = 0;
-       done = 0;
-       audio_lock = 0;
-       video_lock = 0;
-       start_lock = 0;
-       buffer_lock = 0;
-       position_lock = 0;
-       video_encoder = 0;
-       audio_encoder = 0;
-       audio_buffer = 0;
-       audio_samples = 0;
-       temp_frame = 0;
-       temp_frame2 = 0;
-       audio_position = 0;
-       interrupted = 0;
-       have_video = 0;
-       adevice = 0;
-       vdevice = 0;
-       is_pal = 0;
-}
-
-
-
-static int read_frame_static(unsigned char *data, int n, unsigned int dropped, void *ptr)
-{
-       IEC61883Output *output = (IEC61883Output*)ptr;
-       return output->read_frame(data, n, dropped);
-}
-
-
-
-
-
-int IEC61883Output::open(int port,
-       int channel,
-       int length,
-       int channels, 
-       int bits, 
-       int samplerate,
-       int syt)
-{
-       this->channels = channels;
-       this->bits = bits;
-       this->samplerate = samplerate;
-       this->total_buffers = length;
-       this->syt = syt;
-
-// Set PAL mode based on frame height
-       if(vdevice) is_pal = (vdevice->out_h == 576);
-
-
-
-
-       if(!handle)
-       {
-               handle = raw1394_new_handle_on_port(port);
-               if(handle)
-               {
-                       frame = iec61883_dv_xmit_init(handle, 
-                               is_pal, 
-                               read_frame_static, 
-                               (void *)this);
-                       if(frame)
-                       {
-                               if(!iec61883_dv_xmit_start(frame, channel))
-                               {
-                                       fd = raw1394_get_fd(handle);
-                               }
-                       }
-               }
-
-// Create buffers
-               buffer = new char*[total_buffers];
-               for(int i = 0; i < length; i++)
-                       buffer[i] = new char[DV_PAL_SIZE];
-               buffer_size = new int[total_buffers];
-               buffer_valid = new int[total_buffers];
-               bzero(buffer_size, sizeof(int) * total_buffers);
-               bzero(buffer_valid, sizeof(int) * total_buffers);
-               bzero(buffer, sizeof(char*) * total_buffers);
-               video_lock = new Condition(0, "IEC61883Output::video_lock");
-               audio_lock = new Condition(0, "IEC61883Output::audio_lock");
-               start_lock = new Condition(0, "IEC61883Output::start_lock");
-               buffer_lock = new Mutex("IEC61883Output::buffer_lock");
-               position_lock = new Mutex("IEC61883Output::position_lock");
-               encoder = dv_new();
-               audio_buffer = new char[OUTPUT_SAMPLES * channels * bits / 8];
-               Thread::start();
-       }
-       return 0;
-}
-
-void IEC61883Output::run()
-{
-       Thread::enable_cancel();
-       start_lock->lock("IEC61883Output::run");
-       Thread::disable_cancel();
-
-       while(!done)
-       {
-               struct timeval tv;
-               fd_set rfds;
-               FD_ZERO (&rfds);
-               FD_SET (fd, &rfds);
-               tv.tv_sec = 0;
-               tv.tv_usec = 20000;
-               if(select(fd + 1, &rfds, 0, 0, &tv) > 0)
-                       raw1394_loop_iterate (handle);
-       }
-}
-
-
-
-int IEC61883Output::read_frame(unsigned char *data, int n, unsigned int dropped)
-{
-// Next frame
-       if(!out_buffer || out_position + 480 > out_size)
-       {
-               buffer_lock->lock("IEC61883Output read_frame 1");
-
-               out_buffer = buffer[current_outbuffer];
-               out_size = buffer_size[current_outbuffer];
-               out_position = 0;
-
-
-// No video.  Put in a fake frame for audio only
-               if(!have_video)
-               {
-#include "data/fake_ntsc_dv.h"
-                       out_size = sizeof(fake_ntsc_dv) - 4;
-                       out_buffer = (char*)fake_ntsc_dv + 4;
-               }
-
-
-
-
-
-
-
-
-// Calculate number of samples needed based on given pattern for 
-// norm.
-               int samples_per_frame = 2048;
-
-// Encode audio
-               if(audio_samples > samples_per_frame)
-               {
-                       int samples_written = dv_write_audio(encoder,
-                               (unsigned char*)out_buffer,
-                               (unsigned char*)audio_buffer,
-                               samples_per_frame,
-                               channels,
-                               bits,
-                               samplerate,
-                               is_pal ? DV_PAL : DV_NTSC);
-                       memcpy(audio_buffer, 
-                               audio_buffer + samples_written * bits * channels / 8,
-                               (audio_samples - samples_written) * bits * channels / 8);
-                       audio_samples -= samples_written;
-                       position_lock->lock("IEC61883Output::run");
-                       audio_position += samples_written;
-                       position_lock->unlock();
-
-
-                       audio_lock->unlock();
-               }
-
-
-               buffer_lock->unlock();
-       }
-
-
-
-
-// Write next chunk of current frame
-       if(out_buffer && out_position + 480 <= out_size)
-       {
-               memcpy(data, out_buffer + out_position, 480);
-               out_position += 480;
-
-
-
-               if(out_position >= out_size)
-               {
-                       buffer_lock->lock("IEC61883Output read_frame 2");
-                       buffer_valid[current_outbuffer] = 0;
-
-// Advance buffer number if possible
-                       increment_counter(&current_outbuffer);
-
-// Reuse same buffer next time
-                       if(!buffer_valid[current_outbuffer])
-                       {
-                               decrement_counter(&current_outbuffer);
-                       }
-                       else
-// Wait for user to reach current buffer before unlocking any more.
-                       {
-                               video_lock->unlock();
-                       }
-
-                       buffer_lock->unlock();
-               }
-       }
-       return 0;
-}
-
-
-
-
-void IEC61883Output::write_frame(VFrame *input)
-{
-       VFrame *ptr = 0;
-       int result = 0;
-
-//printf("IEC61883Output::write_frame 1\n");
-
-       if(fd <= 0) return;
-       if(interrupted) return;
-
-// Encode frame to DV
-       if(input->get_color_model() != BC_COMPRESSED)
-       {
-               if(!temp_frame) temp_frame = new VFrame;
-               if(!encoder) encoder = dv_new();
-               ptr = temp_frame;
-
-// Exact resolution match.  Don't do colorspace conversion
-               if(input->get_color_model() == BC_YUV422 &&
-                       input->get_w() == 720 &&
-                       (input->get_h() == 480 ||
-                       input->get_h() == 576))
-               {
-                       int norm = is_pal ? DV_PAL : DV_NTSC;
-                       int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
-                       temp_frame->allocate_compressed_data(data_size);
-                       temp_frame->set_compressed_size(data_size);
-
-                       dv_write_video(encoder,
-                               temp_frame->get_data(),
-                               input->get_rows(),
-                               BC_YUV422,
-                               norm);
-                       ptr = temp_frame;
-               }
-               else
-// Convert resolution and color model before compressing
-               {
-                       if(!temp_frame2)
-                       {
-                               int h = input->get_h();
-// Default to NTSC if unknown
-                               if(h != 480 && h != 576) h = 480;
-
-                               temp_frame2 = new VFrame(0,
-                                       -1,
-                                       720,
-                                       h,
-                                       BC_YUV422,
-                                       -1);
-                               
-                       }
-
-                       int norm = is_pal ? DV_PAL : DV_NTSC;
-                       int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
-                       temp_frame->allocate_compressed_data(data_size);
-                       temp_frame->set_compressed_size(data_size);
-
-
-                       BC_CModels::transfer(temp_frame2->get_rows(), /* Leave NULL if non existent */
-                               input->get_rows(),
-                               temp_frame2->get_y(), /* Leave NULL if non existent */
-                               temp_frame2->get_u(),
-                               temp_frame2->get_v(),
-                               input->get_y(), /* Leave NULL if non existent */
-                               input->get_u(),
-                               input->get_v(),
-                               0,        /* Dimensions to capture from input frame */
-                               0, 
-                               MIN(temp_frame2->get_w(), input->get_w()),
-                               MIN(temp_frame2->get_h(), input->get_h()),
-                               0,       /* Dimensions to project on output frame */
-                               0, 
-                               MIN(temp_frame2->get_w(), input->get_w()),
-                               MIN(temp_frame2->get_h(), input->get_h()),
-                               input->get_color_model(), 
-                               BC_YUV422,
-                               0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
-                               input->get_bytes_per_line(),       /* For planar use the luma rowspan */
-                               temp_frame2->get_bytes_per_line());     /* For planar use the luma rowspan */
-
-                       dv_write_video(encoder,
-                               temp_frame->get_data(),
-                               temp_frame2->get_rows(),
-                               BC_YUV422,
-                               norm);
-
-
-
-                       ptr = temp_frame;
-               }
-       }
-       else
-               ptr = input;
-
-
-
-
-
-
-
-
-
-
-
-// Take over buffer table
-       buffer_lock->lock("IEC61883Output::write_frame 1");
-       have_video = 1;
-// Wait for buffer to become available with timeout
-       while(buffer_valid[current_inbuffer] && !result && !interrupted)
-       {
-               buffer_lock->unlock();
-               result = video_lock->timed_lock(BUFFER_TIMEOUT);
-               buffer_lock->lock("IEC61883Output::write_frame 2");
-       }
-
-
-
-// Write buffer if there's room
-       if(!buffer_valid[current_inbuffer])
-       {
-               if(!buffer[current_inbuffer])
-               {
-                       buffer[current_inbuffer] = new char[ptr->get_compressed_size()];
-                       buffer_size[current_inbuffer] = ptr->get_compressed_size();
-               }
-               memcpy(buffer[current_inbuffer], ptr->get_data(), ptr->get_compressed_size());
-               buffer_valid[current_inbuffer] = 1;
-               increment_counter(&current_inbuffer);
-       }
-       else
-// Ignore it if there isn't room.
-       {
-               ;
-       }
-
-       buffer_lock->unlock();
-       start_lock->unlock();
-//printf("IEC61883Output::write_frame 100\n");
-}
-
-void IEC61883Output::write_samples(char *data, int samples)
-{
-//printf("IEC61883Output::write_samples 1\n");
-       int result = 0;
-       //int timeout = (samples * 1000000LL * 2) / samplerate;
-       if(interrupted) return;
-
-//printf("IEC61883Output::write_samples 2\n");
-
-// Check for maximum sample count exceeded
-       if(samples > OUTPUT_SAMPLES)
-       {
-               printf("IEC61883Output::write_samples samples=%d > OUTPUT_SAMPLES=%d\n",
-                       samples,
-                       OUTPUT_SAMPLES);
-               return;
-       }
-
-//printf("IEC61883Output::write_samples 3\n");
-// Take over buffer table
-       buffer_lock->lock("IEC61883Output::write_samples 1");
-// Wait for buffer to become available with timeout
-       while(audio_samples > OUTPUT_SAMPLES - samples && !result && !interrupted)
-       {
-               buffer_lock->unlock();
-               result = audio_lock->timed_lock(BUFFER_TIMEOUT);
-               buffer_lock->lock("IEC61883Output::write_samples 2");
-       }
-
-       if(!interrupted && audio_samples <= OUTPUT_SAMPLES - samples)
-       {
-//printf("IEC61883Output::write_samples 4 %d\n", audio_samples);
-               memcpy(audio_buffer + audio_samples * channels * bits / 8,
-                       data,
-                       samples * channels * bits / 8);
-               audio_samples += samples;
-       }
-       buffer_lock->unlock();
-       start_lock->unlock();
-//printf("IEC61883Output::write_samples 100\n");
-}
-
-long IEC61883Output::get_audio_position()
-{
-       position_lock->lock("IEC61883Output::get_audio_position");
-       long result = audio_position;
-       position_lock->unlock();
-       return result;
-}
-
-void IEC61883Output::interrupt()
-{
-       interrupted = 1;
-// Break write_samples out of a lock
-       video_lock->unlock();
-       audio_lock->unlock();
-// Playback should stop when the object is deleted.
-}
-
-void IEC61883Output::flush()
-{
-       
-}
-
-void IEC61883Output::increment_counter(int *counter)
-{
-       (*counter)++;
-       if(*counter >= total_buffers) *counter = 0;
-}
-
-void IEC61883Output::decrement_counter(int *counter)
-{
-       (*counter)--;
-       if(*counter < 0) *counter = total_buffers - 1;
-}
-
-
-
-
-
-
-
-
-
-
-
-#endif // HAVE_FIREWIRE
-
-
-
-
-
-