4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "audiodevice.h"
27 #include "condition.h"
28 #include "iec61883output.h"
30 #include "playbackconfig.h"
33 #include "videodevice.h"
38 #include <sys/ioctl.h>
41 #include <sys/utsname.h>
48 #define CIP_N_NTSC 2436
49 #define CIP_D_NTSC 38400
52 #define OUTPUT_SAMPLES 262144
53 #define BUFFER_TIMEOUT 500000
56 IEC61883Output::IEC61883Output(AudioDevice *adevice)
60 this->adevice = adevice;
63 IEC61883Output::IEC61883Output(VideoDevice *vdevice)
67 this->vdevice = vdevice;
70 IEC61883Output::~IEC61883Output()
82 for(int i = 0; i < total_buffers; i++)
84 if(buffer[i]) delete [] buffer[i];
87 delete [] buffer_size;
88 delete [] buffer_valid;
91 if(audio_lock) delete audio_lock;
92 if(video_lock) delete video_lock;
93 if(start_lock) delete start_lock;
94 if(audio_buffer) delete [] audio_buffer;
96 if(temp_frame) delete temp_frame;
97 if(temp_frame2) delete temp_frame2;
98 if(video_encoder) dv_delete(video_encoder);
99 if(audio_encoder) dv_delete(audio_encoder);
100 if(encoder) dv_delete(encoder);
101 if(buffer_lock) delete buffer_lock;
102 if(position_lock) delete position_lock;
103 if(frame) iec61883_dv_close(frame);
104 if(handle) raw1394_destroy_handle(handle);
108 void IEC61883Output::reset()
120 current_inbuffer = 0;
121 current_outbuffer = 0;
145 static int read_frame_static(unsigned char *data, int n, unsigned int dropped, void *ptr)
147 IEC61883Output *output = (IEC61883Output*)ptr;
148 return output->read_frame(data, n, dropped);
155 int IEC61883Output::open(int port,
163 this->channels = channels;
165 this->samplerate = samplerate;
166 this->total_buffers = length;
169 // Set PAL mode based on frame height
170 if(vdevice) is_pal = (vdevice->out_h == 576);
177 handle = raw1394_new_handle_on_port(port);
180 frame = iec61883_dv_xmit_init(handle,
186 if(!iec61883_dv_xmit_start(frame, channel))
188 fd = raw1394_get_fd(handle);
194 buffer = new char*[total_buffers];
195 bzero(buffer, sizeof(char*) * total_buffers);
196 for(int i = 0; i < length; i++)
197 buffer[i] = new char[DV_PAL_SIZE];
198 buffer_size = new int[total_buffers];
199 buffer_valid = new int[total_buffers];
200 bzero(buffer_size, sizeof(int) * total_buffers);
201 bzero(buffer_valid, sizeof(int) * total_buffers);
202 video_lock = new Condition(0, "IEC61883Output::video_lock");
203 audio_lock = new Condition(0, "IEC61883Output::audio_lock");
204 start_lock = new Condition(0, "IEC61883Output::start_lock");
205 buffer_lock = new Mutex("IEC61883Output::buffer_lock");
206 position_lock = new Mutex("IEC61883Output::position_lock");
208 audio_buffer = new char[OUTPUT_SAMPLES * channels * bits / 8];
214 void IEC61883Output::run()
216 Thread::enable_cancel();
217 start_lock->lock("IEC61883Output::run");
218 Thread::disable_cancel();
228 if(select(fd + 1, &rfds, 0, 0, &tv) > 0)
229 raw1394_loop_iterate (handle);
235 int IEC61883Output::read_frame(unsigned char *data, int n, unsigned int dropped)
238 if(!out_buffer || out_position + 480 > out_size)
240 buffer_lock->lock("IEC61883Output read_frame 1");
242 out_buffer = buffer[current_outbuffer];
243 out_size = buffer_size[current_outbuffer];
247 // No video. Put in a fake frame for audio only
250 #include "data/fake_ntsc_dv.h"
251 out_size = sizeof(fake_ntsc_dv) - 4;
252 out_buffer = (char*)fake_ntsc_dv + 4;
262 // Calculate number of samples needed based on given pattern for
264 int samples_per_frame = 2048;
267 if(audio_samples > samples_per_frame)
269 int samples_written = dv_write_audio(encoder,
270 (unsigned char*)out_buffer,
271 (unsigned char*)audio_buffer,
276 is_pal ? DV_PAL : DV_NTSC);
278 audio_buffer + samples_written * bits * channels / 8,
279 (audio_samples - samples_written) * bits * channels / 8);
280 audio_samples -= samples_written;
281 position_lock->lock("IEC61883Output::run");
282 audio_position += samples_written;
283 position_lock->unlock();
286 audio_lock->unlock();
290 buffer_lock->unlock();
296 // Write next chunk of current frame
297 if(out_buffer && out_position + 480 <= out_size)
299 memcpy(data, out_buffer + out_position, 480);
304 if(out_position >= out_size)
306 buffer_lock->lock("IEC61883Output read_frame 2");
307 buffer_valid[current_outbuffer] = 0;
309 // Advance buffer number if possible
310 increment_counter(¤t_outbuffer);
312 // Reuse same buffer next time
313 if(!buffer_valid[current_outbuffer])
315 decrement_counter(¤t_outbuffer);
318 // Wait for user to reach current buffer before unlocking any more.
320 video_lock->unlock();
323 buffer_lock->unlock();
332 void IEC61883Output::write_frame(VFrame *input)
337 //printf("IEC61883Output::write_frame 1\n");
340 if(interrupted) return;
342 // Encode frame to DV
343 if(input->get_color_model() != BC_COMPRESSED)
345 if(!temp_frame) temp_frame = new VFrame;
346 if(!encoder) encoder = dv_new();
349 // Exact resolution match. Don't do colorspace conversion
350 if(input->get_color_model() == BC_YUV422 &&
351 input->get_w() == 720 &&
352 (input->get_h() == 480 ||
353 input->get_h() == 576))
355 int norm = is_pal ? DV_PAL : DV_NTSC;
356 int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
357 temp_frame->allocate_compressed_data(data_size);
358 temp_frame->set_compressed_size(data_size);
360 dv_write_video(encoder,
361 temp_frame->get_data(),
368 // Convert resolution and color model before compressing
372 int h = input->get_h();
373 // Default to NTSC if unknown
374 if(h != 480 && h != 576) h = 480;
375 temp_frame2 = new VFrame(720, h, BC_YUV422, 0);
378 int norm = is_pal ? DV_PAL : DV_NTSC;
379 int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
380 temp_frame->allocate_compressed_data(data_size);
381 temp_frame->set_compressed_size(data_size);
384 BC_CModels::transfer(temp_frame2->get_rows(), /* Leave NULL if non existent */
386 temp_frame2->get_y(), /* Leave NULL if non existent */
387 temp_frame2->get_u(),
388 temp_frame2->get_v(),
389 input->get_y(), /* Leave NULL if non existent */
392 0, /* Dimensions to capture from input frame */
394 MIN(temp_frame2->get_w(), input->get_w()),
395 MIN(temp_frame2->get_h(), input->get_h()),
396 0, /* Dimensions to project on output frame */
398 MIN(temp_frame2->get_w(), input->get_w()),
399 MIN(temp_frame2->get_h(), input->get_h()),
400 input->get_color_model(),
402 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
403 input->get_bytes_per_line(), /* For planar use the luma rowspan */
404 temp_frame2->get_bytes_per_line()); /* For planar use the luma rowspan */
406 dv_write_video(encoder,
407 temp_frame->get_data(),
408 temp_frame2->get_rows(),
430 // Take over buffer table
431 buffer_lock->lock("IEC61883Output::write_frame 1");
433 // Wait for buffer to become available with timeout
434 while(buffer_valid[current_inbuffer] && !result && !interrupted)
436 buffer_lock->unlock();
437 result = video_lock->timed_lock(BUFFER_TIMEOUT);
438 buffer_lock->lock("IEC61883Output::write_frame 2");
443 // Write buffer if there's room
444 if(!buffer_valid[current_inbuffer])
446 if(!buffer[current_inbuffer])
448 buffer[current_inbuffer] = new char[ptr->get_compressed_size()];
449 buffer_size[current_inbuffer] = ptr->get_compressed_size();
451 memcpy(buffer[current_inbuffer], ptr->get_data(), ptr->get_compressed_size());
452 buffer_valid[current_inbuffer] = 1;
453 increment_counter(¤t_inbuffer);
456 // Ignore it if there isn't room.
461 buffer_lock->unlock();
462 start_lock->unlock();
463 //printf("IEC61883Output::write_frame 100\n");
466 void IEC61883Output::write_samples(char *data, int samples)
468 //printf("IEC61883Output::write_samples 1\n");
470 //int timeout = (samples * 1000000LL * 2) / samplerate;
471 if(interrupted) return;
473 //printf("IEC61883Output::write_samples 2\n");
475 // Check for maximum sample count exceeded
476 if(samples > OUTPUT_SAMPLES)
478 printf("IEC61883Output::write_samples samples=%d > OUTPUT_SAMPLES=%d\n",
484 //printf("IEC61883Output::write_samples 3\n");
485 // Take over buffer table
486 buffer_lock->lock("IEC61883Output::write_samples 1");
487 // Wait for buffer to become available with timeout
488 while(audio_samples > OUTPUT_SAMPLES - samples && !result && !interrupted)
490 buffer_lock->unlock();
491 result = audio_lock->timed_lock(BUFFER_TIMEOUT);
492 buffer_lock->lock("IEC61883Output::write_samples 2");
495 if(!interrupted && audio_samples <= OUTPUT_SAMPLES - samples)
497 //printf("IEC61883Output::write_samples 4 %d\n", audio_samples);
498 memcpy(audio_buffer + audio_samples * channels * bits / 8,
500 samples * channels * bits / 8);
501 audio_samples += samples;
503 buffer_lock->unlock();
504 start_lock->unlock();
505 //printf("IEC61883Output::write_samples 100\n");
508 long IEC61883Output::get_audio_position()
510 position_lock->lock("IEC61883Output::get_audio_position");
511 long result = audio_position;
512 position_lock->unlock();
516 void IEC61883Output::interrupt()
519 // Break write_samples out of a lock
520 video_lock->unlock();
521 audio_lock->unlock();
522 // Playback should stop when the object is deleted.
525 void IEC61883Output::flush()
530 void IEC61883Output::increment_counter(int *counter)
533 if(*counter >= total_buffers) *counter = 0;
536 void IEC61883Output::decrement_counter(int *counter)
539 if(*counter < 0) *counter = total_buffers - 1;
552 #endif // HAVE_FIREWIRE