7 #include "device1394output.h"
15 #include <sys/ioctl.h>
21 #include "avc1394_vcr.h"
28 #define CIP_N_NTSC 2436
29 #define CIP_D_NTSC 38400
32 #define OUTPUT_SAMPLES 262144
33 #define BUFFER_TIMEOUT 500000
36 Device1394Output::Device1394Output()
43 current_outbuffer = 0;
63 Device1394Output::~Device1394Output()
75 for(int i = 0; i < total_buffers; i++)
77 if(buffer[i]) delete [] buffer[i];
80 delete [] buffer_size;
81 delete [] buffer_valid;
84 if(audio_lock) delete audio_lock;
85 if(video_lock) delete video_lock;
86 if(start_lock) delete start_lock;
87 if(audio_buffer) delete [] audio_buffer;
91 output_queue.buffer = (output_mmap.nb_buffers + output_queue.buffer - 1) % output_mmap.nb_buffers;
93 if(ioctl(output_fd, VIDEO1394_TALK_WAIT_BUFFER, &output_queue) < 0)
96 "Device1394::close_all: VIDEO1394_TALK_WAIT_BUFFER %s: %s",
100 munmap(output_buffer, output_mmap.nb_buffers * output_mmap.buf_size);
102 if(ioctl(output_fd, VIDEO1394_UNTALK_CHANNEL, &output_mmap.channel) < 0)
104 perror("Device1394::close_all: VIDEO1394_UNTALK_CHANNEL");
110 // raw1394_destroy_handle(avc_handle);
113 if(temp_frame) delete temp_frame;
114 if(temp_frame2) delete temp_frame2;
115 if(video_encoder) dv_delete(video_encoder);
116 if(audio_encoder) dv_delete(audio_encoder);
117 if(buffer_lock) delete buffer_lock;
118 if(position_lock) delete position_lock;
122 int Device1394Output::open(char *path,
131 this->channels = channels;
133 this->samplerate = samplerate;
134 this->total_buffers = length;
137 //printf("Device1394::open_output 2 %s %d %d %d %d\n", path, port, channel, length, syt);
140 output_fd = ::open(path, O_RDWR);
145 "Device1394Output::open path=%s: %s",
152 // avc_handle = raw1394_new_handle();
153 // if(avc_handle == 0)
154 // printf("Device1394::open_output avc_handle == 0\n");
156 // struct raw1394_portinfo pinf[16];
157 // int numcards = raw1394_get_port_info(avc_handle, pinf, 16);
159 // printf("Device1394::open_output raw1394_get_port_info failed\n");
160 // if(raw1394_set_port(avc_handle, out_config->firewire_port) < 0)
161 // printf("Device1394::open_output raw1394_set_port\n");
163 // int nodecount = raw1394_get_nodecount(avc_handle);
164 // int itemcount = 0;
165 // rom1394_directory rom1394_dir;
168 // for(int currentnode = 0; currentnode < nodecount; currentnode++)
170 // rom1394_get_directory(avc_handle, currentnode, &rom1394_dir);
172 // if((rom1394_get_node_type(&rom1394_dir) == ROM1394_NODE_TYPE_AVC) &&
173 // avc1394_check_subunit_type(avc_handle, currentnode, AVC1394_SUBUNIT_TYPE_VCR))
176 // // default the phyID to the first AVC node found
177 // if(itemcount == 1) avc_id = currentnode;
181 // rom1394_free_directory(&rom1394_dir);
185 // printf("Device1394::open_output no avc_id found.\n");
187 //printf("Device1394::open_output 1 %p %d\n", avc_handle, avc_id);
188 // avc1394_vcr_record(avc_handle, avc_id);
193 output_mmap.channel = channel;
194 output_queue.channel = channel;
195 output_mmap.sync_tag = 0;
196 output_mmap.nb_buffers = total_buffers;
197 output_mmap.buf_size = 320 * 512;
198 output_mmap.packet_size = 512;
199 // Shouldn't this be handled by the video1394 driver?
200 // dvgrab originally used 19000
201 // JVC DVL300 -> 30000
202 output_mmap.syt_offset = syt;
203 output_mmap.flags = VIDEO1394_VARIABLE_PACKET_SIZE;
206 // printf("Device1394Output::open %d %d %d %d %d %d %d\n",
207 // output_mmap.channel, output_queue.channel, output_mmap.sync_tag, output_mmap.nb_buffers, output_mmap.buf_size, output_mmap.packet_size, output_mmap.syt_offset, output_mmap.flags);
208 if(ioctl(output_fd, VIDEO1394_TALK_CHANNEL, &output_mmap) < 0)
210 perror("Device1394Output::open VIDEO1394_TALK_CHANNEL:");
213 output_buffer = (unsigned char*)mmap(0,
214 output_mmap.nb_buffers * output_mmap.buf_size,
215 PROT_READ | PROT_WRITE,
219 if(output_buffer <= 0)
221 perror("Device1394Output::open mmap");
224 unused_buffers = output_mmap.nb_buffers;
225 output_queue.buffer = 0;
226 output_queue.packet_sizes = packet_sizes;
227 continuity_counter = 0;
231 buffer = new char*[total_buffers];
232 for(int i = 0; i < length; i++)
233 buffer[i] = new char[DV_PAL_SIZE];
234 buffer_size = new int[total_buffers];
235 buffer_valid = new int[total_buffers];
236 bzero(buffer_size, sizeof(int) * total_buffers);
237 bzero(buffer_valid, sizeof(int) * total_buffers);
238 bzero(buffer, sizeof(char*) * total_buffers);
239 video_lock = new Condition(0);
240 audio_lock = new Condition(0);
241 start_lock = new Condition(0);
242 buffer_lock = new Mutex;
243 position_lock = new Mutex;
245 audio_buffer = new char[OUTPUT_SAMPLES * channels * bits / 8];
252 void Device1394Output::run()
254 Thread::enable_cancel();
256 Thread::disable_cancel();
259 // Write buffers continuously
262 // Get current buffer to play
266 //printf("Device1394Output::run 1\n");
268 //printf("Device1394Output::run 10\n");
270 char *out_buffer = buffer[current_outbuffer];
271 int out_size = buffer_size[current_outbuffer];
277 // No video. Put in a fake frame for audio only
280 #include "data/fake_ntsc_dv.h"
281 out_size = sizeof(fake_ntsc_dv) - 4;
282 out_buffer = (char*)fake_ntsc_dv + 4;
284 unsigned char *output = output_buffer +
285 output_queue.buffer *
286 output_mmap.buf_size;
287 int is_pal = (out_size == DV_PAL_SIZE);
295 if(out_buffer && out_size)
297 // Calculate number of samples needed based on given pattern for
299 int samples_per_frame = 2048;
302 if(audio_samples > samples_per_frame)
305 int samples_written = dv_write_audio(encoder,
306 (unsigned char*)out_buffer,
307 (unsigned char*)audio_buffer,
312 is_pal ? DV_PAL : DV_NTSC);
314 audio_buffer + samples_written * bits * channels / 8,
315 (audio_samples - samples_written) * bits * channels / 8);
316 audio_samples -= samples_written;
317 position_lock->lock();
318 audio_position += samples_written;
319 position_lock->unlock();
322 audio_lock->unlock();
325 // Copy from current buffer to mmap buffer with firewire encryption
326 encrypt((unsigned char*)output,
327 (unsigned char*)out_buffer,
329 buffer_valid[current_outbuffer] = 0;
332 // Advance buffer number if possible
333 increment_counter(¤t_outbuffer);
335 // Reuse same buffer next time
336 if(!buffer_valid[current_outbuffer])
338 decrement_counter(¤t_outbuffer);
341 // Wait for user to reach current buffer before unlocking any more.
343 video_lock->unlock();
347 buffer_lock->unlock();
348 //printf("Device1394Output::run 100\n");
355 // Write mmap to device
356 Thread::enable_cancel();
358 if(ioctl(output_fd, VIDEO1394_TALK_QUEUE_BUFFER, &output_queue) < 0)
360 perror("Device1394Output::run VIDEO1394_TALK_QUEUE_BUFFER");
363 output_queue.buffer++;
364 if(output_queue.buffer >= output_mmap.nb_buffers)
365 output_queue.buffer = 0;
367 if(unused_buffers <= 0)
369 if(ioctl(output_fd, VIDEO1394_TALK_WAIT_BUFFER, &output_queue) < 0)
371 perror("Device1394::run VIDEO1394_TALK_WAIT_BUFFER");
375 Thread::disable_cancel();
379 // Thread::enable_cancel();
380 // start_lock->lock();
381 // Thread::disable_cancel();
384 //printf("Device1394Output::run %lld\n", timer.get_difference());
390 void Device1394Output::encrypt(unsigned char *output,
394 // Encode in IEEE1394 video encryption
395 int is_pal = (data_size == DV_PAL_SIZE);
396 int output_size = 320;
397 int packets_per_frame = (is_pal ? 300 : 250);
398 int min_packet_size = output_mmap.packet_size;
399 unsigned long frame_size = packets_per_frame * 480;
400 unsigned long vdata = 0;
401 unsigned int *packet_sizes = this->packet_sizes;
423 for(int i = 0; i < output_size && vdata < frame_size; i++)
425 unsigned char *p = output;
426 int want_sync = (cip_counter > cip_d);
428 /* Source node ID ! */
430 /* Packet size in quadlets (480 / 4) - this stays the same even for empty packets */
433 *p++ = continuity_counter;
437 /* high bit = 50/60 indicator */
440 /* timestamp - generated in driver */
448 continuity_counter++;
449 cip_counter += cip_n;
451 memcpy(p, data + vdata, 480);
456 cip_counter -= cip_d;
458 *packet_sizes++ = p - output;
459 output += min_packet_size;
467 void Device1394Output::write_frame(VFrame *input)
470 int is_pal = (input->get_h() == 576);
473 //printf("Device1394Output::write_frame 1\n");
475 if(output_fd <= 0) return;
476 if(interrupted) return;
478 // Encode frame to DV
479 if(input->get_color_model() != BC_COMPRESSED)
481 if(!temp_frame) temp_frame = new VFrame;
482 if(!encoder) encoder = dv_new();
485 // Exact resolution match. Don't do colorspace conversion
486 if(input->get_color_model() == BC_YUV422 &&
487 input->get_w() == 720 &&
488 (input->get_h() == 480 ||
489 input->get_h() == 576))
491 int norm = is_pal ? DV_PAL : DV_NTSC;
492 int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
493 temp_frame->allocate_compressed_data(data_size);
494 temp_frame->set_compressed_size(data_size);
496 dv_write_video(encoder,
497 temp_frame->get_data(),
504 // Convert resolution and color model before compressing
508 int h = input->get_h();
509 // Default to NTSC if unknown
510 if(h != 480 && h != 576) h = 480;
512 temp_frame2 = new VFrame(0,
519 int norm = is_pal ? DV_PAL : DV_NTSC;
520 int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
521 temp_frame->allocate_compressed_data(data_size);
522 temp_frame->set_compressed_size(data_size);
525 cmodel_transfer(temp_frame2->get_rows(), /* Leave NULL if non existent */
527 temp_frame2->get_y(), /* Leave NULL if non existent */
528 temp_frame2->get_u(),
529 temp_frame2->get_v(),
530 input->get_y(), /* Leave NULL if non existent */
533 0, /* Dimensions to capture from input frame */
535 MIN(temp_frame2->get_w(), input->get_w()),
536 MIN(temp_frame2->get_h(), input->get_h()),
537 0, /* Dimensions to project on output frame */
539 MIN(temp_frame2->get_w(), input->get_w()),
540 MIN(temp_frame2->get_h(), input->get_h()),
541 input->get_color_model(),
543 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
544 input->get_bytes_per_line(), /* For planar use the luma rowspan */
545 temp_frame2->get_bytes_per_line()); /* For planar use the luma rowspan */
547 dv_write_video(encoder,
548 temp_frame->get_data(),
549 temp_frame2->get_rows(),
571 // Take over buffer table
574 // Wait for buffer to become available with timeout
575 while(buffer_valid[current_inbuffer] && !result && !interrupted)
577 buffer_lock->unlock();
578 result = video_lock->timed_lock(BUFFER_TIMEOUT);
584 // Write buffer if there's room
585 if(!buffer_valid[current_inbuffer])
587 if(!buffer[current_inbuffer])
589 buffer[current_inbuffer] = new char[ptr->get_compressed_size()];
590 buffer_size[current_inbuffer] = ptr->get_compressed_size();
592 memcpy(buffer[current_inbuffer], ptr->get_data(), ptr->get_compressed_size());
593 buffer_valid[current_inbuffer] = 1;
594 increment_counter(¤t_inbuffer);
597 // Ignore it if there isn't room.
602 buffer_lock->unlock();
603 start_lock->unlock();
604 //printf("Device1394Output::write_frame 100\n");
607 void Device1394Output::write_samples(char *data, int samples)
609 //printf("Device1394Output::write_samples 1\n");
611 int timeout = (int64_t)samples *
615 if(interrupted) return;
617 //printf("Device1394Output::write_samples 2\n");
619 // Check for maximum sample count exceeded
620 if(samples > OUTPUT_SAMPLES)
622 printf("Device1394Output::write_samples samples=%d > OUTPUT_SAMPLES=%d\n",
628 //printf("Device1394Output::write_samples 3\n");
629 // Take over buffer table
631 // Wait for buffer to become available with timeout
632 while(audio_samples > OUTPUT_SAMPLES - samples && !result && !interrupted)
634 buffer_lock->unlock();
635 result = audio_lock->timed_lock(BUFFER_TIMEOUT);
639 if(!interrupted && audio_samples <= OUTPUT_SAMPLES - samples)
641 //printf("Device1394Output::write_samples 4 %d\n", audio_samples);
642 memcpy(audio_buffer + audio_samples * channels * bits / 8,
644 samples * channels * bits / 8);
645 audio_samples += samples;
647 buffer_lock->unlock();
648 start_lock->unlock();
649 //printf("Device1394Output::write_samples 100\n");
652 long Device1394Output::get_audio_position()
654 position_lock->lock();
655 long result = audio_position;
656 position_lock->unlock();
660 void Device1394Output::interrupt()
663 // Break write_samples out of a lock
664 video_lock->unlock();
665 audio_lock->unlock();
666 // Playback should stop when the object is deleted.
669 void Device1394Output::flush()
674 void Device1394Output::increment_counter(int *counter)
677 if(*counter >= total_buffers) *counter = 0;
680 void Device1394Output::decrement_counter(int *counter)
683 if(*counter < 0) *counter = total_buffers - 1;
699 #endif // HAVE_FIREWIRE