add missing GPL information in guicast program files
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / device1394output.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_FIREWIRE
23
24
25
26 #include "audiodevice.h"
27 #include "bccmodels.h"
28 #include "condition.h"
29 #include "device1394output.h"
30 #include "mutex.h"
31 #include "playbackconfig.h"
32 #include "bctimer.h"
33 #include "vframe.h"
34 #include "videodevice.h"
35
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <string.h>
39 #include <sys/ioctl.h>
40 #include <sys/mman.h>
41 #include <unistd.h>
42 #include <sys/utsname.h>
43
44
45
46
47
48 // Crazy DV internals
49 #define CIP_N_NTSC 2436
50 #define CIP_D_NTSC 38400
51 #define CIP_N_PAL 1
52 #define CIP_D_PAL 16
53 #define OUTPUT_SAMPLES 262144
54 #define BUFFER_TIMEOUT 500000
55
56
57 Device1394Output::Device1394Output(AudioDevice *adevice)
58  : Thread(1, 0, 0)
59 {
60         reset();
61         this->adevice = adevice;
62
63         set_ioctls();
64 }
65
66 Device1394Output::Device1394Output(VideoDevice *vdevice)
67  : Thread(1, 0, 0)
68 {
69         reset();
70         this->vdevice = vdevice;
71
72         set_ioctls();
73 }
74
75 Device1394Output::~Device1394Output()
76 {
77         if(Thread::running())
78         {
79                 done = 1;
80                 start_lock->unlock();
81                 Thread::cancel();
82         }
83         Thread::join();
84
85         if(buffer)
86         {
87                 for(int i = 0; i < total_buffers; i++)
88                 {
89                         if(buffer[i]) delete [] buffer[i];
90                 }
91                 delete [] buffer;
92                 delete [] buffer_size;
93                 delete [] buffer_valid;
94         }
95
96         if(audio_lock) delete audio_lock;
97         if(video_lock) delete video_lock;
98         if(start_lock) delete start_lock;
99         if(audio_buffer) delete [] audio_buffer;
100
101         if(output_fd >= 0)
102         {
103         output_queue.buffer = (output_mmap.nb_buffers + output_queue.buffer - 1) % output_mmap.nb_buffers;
104
105                 if(get_dv1394())
106                 {
107                         if(ioctl(output_fd, DV1394_IOC_WAIT_FRAMES, status.init.n_frames - 1) < 0)
108                         {
109                                 fprintf(stderr,
110                                         "Device1394Output::close_all: DV1394_WAIT_FRAMES %i: %s",
111                                         output_mmap.nb_buffers,
112                                         strerror(errno));
113                         }
114                         munmap(output_buffer, status.init.n_frames *
115                                 (is_pal ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE));
116                         if(ioctl(output_fd, DV1394_IOC_SHUTDOWN, NULL) < 0)
117                         {
118                                 perror("Device1394Output::close_all: DV1394_SHUTDOWN");
119                         }
120                 }
121                 else
122                 {
123                         if(ioctl(output_fd, video1394_talk_wait_buffer, &output_queue) < 0)
124                         {
125                                 fprintf(stderr,
126                                         "Device1394::close_all: VIDEO1394_TALK_WAIT_BUFFER %p: %s",
127                                         &output_queue, strerror(errno));
128                         }
129                         munmap(output_buffer, output_mmap.nb_buffers * output_mmap.buf_size);
130
131                         if(ioctl(output_fd, video1394_untalk_channel, &output_mmap.channel) < 0)
132                         {
133                                 perror("Device1394::close_all: VIDEO1394_UNTALK_CHANNEL");
134                         }
135                 }
136
137                 close(output_fd);
138
139 //              if(avc_handle)
140 //                      raw1394_destroy_handle(avc_handle);
141         }
142
143         if(temp_frame) delete temp_frame;
144         if(temp_frame2) delete temp_frame2;
145         if(video_encoder) dv_delete(video_encoder);
146         if(position_presented) delete [] position_presented;
147         if(audio_encoder) dv_delete(audio_encoder);
148         if(buffer_lock) delete buffer_lock;
149         if(position_lock) delete position_lock;
150 }
151
152
153 void Device1394Output::reset()
154 {
155         buffer = 0;
156         buffer_size = 0;
157         total_buffers = 0;
158         current_inbuffer = 0;
159         current_outbuffer = 0;
160         done = 0;
161         audio_lock = 0;
162         video_lock = 0;
163         start_lock = 0;
164         buffer_lock = 0;
165         position_lock = 0;
166         video_encoder = 0;
167         audio_encoder = 0;
168         audio_buffer = 0;
169         audio_samples = 0;
170         output_fd = -1;
171 //      avc_handle = 0;
172         temp_frame = 0;
173         temp_frame2 = 0;
174         audio_position = 0;
175         interrupted = 0;
176         position_presented = 0;
177         have_video = 0;
178         adevice = 0;
179         vdevice = 0;
180         is_pal = 0;
181 }
182
183 int Device1394Output::get_dv1394()
184 {
185         if(adevice) return adevice->out_config->driver == AUDIO_DV1394;
186         if(vdevice) return vdevice->out_config->driver == PLAYBACK_DV1394;
187         return 0;
188 }
189
190 int Device1394Output::open(char *path,
191         int port,
192         int channel,
193         int length,
194         int channels,
195         int bits,
196         int samplerate,
197         int syt)
198 {
199         this->channels = channels;
200         this->bits = bits;
201         this->samplerate = samplerate;
202         this->total_buffers = length;
203         if (get_dv1394())
204         {
205 // dv1394 syt is given in frames and limited to 2 or 3, default is 3
206 // Needs to be accurate to calculate presentation time
207                 if (syt < 2 || syt > 3)
208                         syt = 3;
209         }
210         this->syt = syt;
211
212 // Set PAL mode based on frame height
213         if(vdevice) is_pal = (vdevice->out_h == 576);
214
215     struct dv1394_init setup =
216         {
217        api_version: DV1394_API_VERSION,
218        channel:     (unsigned int)channel,
219            n_frames:    (unsigned int)length,
220        format:      is_pal ? DV1394_PAL : DV1394_NTSC,
221        cip_n:       0,
222        cip_d:       0,
223        syt_offset:  (unsigned int)syt
224     };
225
226
227
228 //printf("Device1394::open_output 2 %s %d %d %d %d\n", path, port, channel, length, syt);
229         if(output_fd < 0)
230         {
231         output_fd = ::open(path, O_RDWR);
232
233                 if(output_fd <= 0)
234                 {
235                         fprintf(stderr,
236                                 "Device1394Output::open path=%s: %s\n",
237                                 path,
238                                 strerror(errno));
239                         return 1;
240                 }
241                 else
242                 {
243                 output_mmap.channel = channel;
244                 output_queue.channel = channel;
245                 output_mmap.sync_tag = 0;
246                 output_mmap.nb_buffers = total_buffers;
247                 output_mmap.buf_size = 320 * 512;
248                 output_mmap.packet_size = 512;
249 // Shouldn't this be handled by the video1394 driver?
250 // dvgrab originally used 19000
251 // JVC DVL300 -> 30000
252                 output_mmap.syt_offset = syt;
253                 output_mmap.flags = VIDEO1394_VARIABLE_PACKET_SIZE;
254
255
256
257                         if(get_dv1394())
258                         {
259                                 if(ioctl(output_fd, DV1394_IOC_INIT, &setup) < 0)
260                                 {
261                                         perror("Device1394Output::open DV1394_INIT");
262                                 }
263
264                                 if(ioctl(output_fd, DV1394_IOC_GET_STATUS, &status) < 0)
265                                 {
266                                         perror("Device1394Output::open DV1394_GET_STATUS");
267                                 }
268
269                         output_buffer = (unsigned char*)mmap(0,
270                         output_mmap.nb_buffers * (is_pal ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE),
271                         PROT_READ | PROT_WRITE,
272                         MAP_SHARED,
273                         output_fd,
274                         0);
275
276                                 if(position_presented) delete [] position_presented;
277                                 position_presented = new long[length];
278                                 for (int i = 0; i < length; i++)
279                                         position_presented[i] = 0;
280                         }
281                         else
282                         {
283                         if(ioctl(output_fd, video1394_talk_channel, &output_mmap) < 0)
284                                 {
285                         perror("Device1394Output::open VIDEO1394_TALK_CHANNEL:");
286                         }
287
288                         output_buffer = (unsigned char*)mmap(0,
289                                         output_mmap.nb_buffers * output_mmap.buf_size,
290                         PROT_READ | PROT_WRITE,
291                                         MAP_SHARED,
292                                         output_fd,
293                                         0);
294                         }
295
296                 if(output_buffer == MAP_FAILED)
297                         {
298                 perror("Device1394Output::open mmap");
299                 }
300
301                         unused_buffers = output_mmap.nb_buffers;
302                 output_queue.buffer = 0;
303                 output_queue.packet_sizes = packet_sizes;
304                 continuity_counter = 0;
305                 cip_counter = 0;
306
307 // Create buffers
308                         buffer = new char*[total_buffers];
309                         for(int i = 0; i < length; i++)
310                                 buffer[i] = new char[get_dv1394() ?
311                                         (is_pal ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE) :
312                                         DV_PAL_SIZE];
313                         buffer_size = new int[total_buffers];
314                         buffer_valid = new int[total_buffers];
315                         bzero(buffer_size, sizeof(int) * total_buffers);
316                         bzero(buffer_valid, sizeof(int) * total_buffers);
317                         bzero(buffer, sizeof(char*) * total_buffers);
318                         video_lock = new Condition(0, "Device1394Output::video_lock");
319                         audio_lock = new Condition(0, "Device1394Output::audio_lock");
320                         start_lock = new Condition(0, "Device1394Output::start_lock");
321                         buffer_lock = new Mutex("Device1394Output::buffer_lock");
322                         position_lock = new Mutex("Device1394Output::position_lock");
323                         encoder = dv_new();
324                         audio_buffer = new char[OUTPUT_SAMPLES * channels * bits / 8];
325                         Thread::start();
326         }
327         }
328         return 0;
329 }
330
331 void Device1394Output::run()
332 {
333         unsigned char *output;
334         char *out_buffer;
335         int out_size;
336
337         Thread::enable_cancel();
338         start_lock->lock("Device1394Output::run");
339         Thread::disable_cancel();
340
341 //Timer timer;
342 // Write buffers continuously
343         while(!done)
344         {
345 // Get current buffer to play
346                 if(done) return;
347
348                 buffer_lock->lock("Device1394Output::run 1");
349
350                 out_buffer = buffer[current_outbuffer];
351                 out_size = buffer_size[current_outbuffer];
352
353
354
355
356
357 // No video.  Put in a fake frame for audio only
358                 if(!have_video)
359                 {
360 #include "data/fake_ntsc_dv.h"
361                         out_size = sizeof(fake_ntsc_dv) - 4;
362                         out_buffer = (char*)fake_ntsc_dv + 4;
363                 }
364
365
366
367
368                 if(get_dv1394())
369                 {
370                         output = output_buffer +
371                                 out_size *
372                                 status.first_clear_frame;
373                 }
374                 else
375                 {
376                         output = output_buffer +
377                                 output_queue.buffer *
378                                 output_mmap.buf_size;
379                 }
380
381
382
383
384
385
386
387
388 // Got a buffer
389                 if(out_buffer && out_size)
390                 {
391 // Calculate number of samples needed based on given pattern for
392 // norm.
393                         int samples_per_frame = 2048;
394
395 // Encode audio
396                         if(audio_samples > samples_per_frame)
397                         {
398
399                                 int samples_written = dv_write_audio(encoder,
400                                         (unsigned char*)out_buffer,
401                                         (unsigned char*)audio_buffer,
402                                         samples_per_frame,
403                                         channels,
404                                         bits,
405                                         samplerate,
406                                         is_pal ? DV_PAL : DV_NTSC);
407                                 memcpy(audio_buffer,
408                                         audio_buffer + samples_written * bits * channels / 8,
409                                         (audio_samples - samples_written) * bits * channels / 8);
410                                 audio_samples -= samples_written;
411                                 position_lock->lock("Device1394Output::run");
412
413                                 if (get_dv1394())
414                                 {
415 // When this frame is being uploaded to the 1394 device,
416 // the frame actually playing on the device will be the one
417 // uploaded syt frames before.
418                                         position_presented[status.first_clear_frame] =
419                                                 audio_position - syt * samples_per_frame;
420                                         if (position_presented[status.first_clear_frame] < 0)
421                                                 position_presented[status.first_clear_frame] = 0;
422                                 }
423
424                                 audio_position += samples_written;
425                                 position_lock->unlock();
426
427
428                                 audio_lock->unlock();
429                         }
430
431 // Copy from current buffer to mmap buffer with firewire encryption
432                         if(get_dv1394())
433                         {
434                                 memcpy(output, out_buffer, out_size);
435                         }
436                         else
437                         {
438                                 encrypt((unsigned char*)output,
439                                         (unsigned char*)out_buffer,
440                                         out_size);
441                         }
442                         buffer_valid[current_outbuffer] = 0;
443                 }
444
445 // Advance buffer number if possible
446                 increment_counter(&current_outbuffer);
447
448 // Reuse same buffer next time
449                 if(!buffer_valid[current_outbuffer])
450                 {
451                         decrement_counter(&current_outbuffer);
452                 }
453                 else
454 // Wait for user to reach current buffer before unlocking any more.
455                 {
456                         video_lock->unlock();
457                 }
458
459
460                 buffer_lock->unlock();
461 //printf("Device1394Output::run 100\n");
462
463
464
465                 if(out_size > 0)
466                 {
467
468 // Write mmap to device
469                         Thread::enable_cancel();
470                         unused_buffers--;
471
472
473                         if(get_dv1394())
474                         {
475                                 if(ioctl(output_fd, DV1394_IOC_SUBMIT_FRAMES, 1) < 0)
476                                 {
477                                         perror("Device1394Output::run DV1394_SUBMIT_FRAMES");
478                                 }
479                                 if(ioctl(output_fd, DV1394_IOC_WAIT_FRAMES, 1) < 0)
480                                 {
481                                         perror("Device1394Output::run DV1394_WAIT_FRAMES");
482                                 }
483                                 if(ioctl(output_fd, DV1394_IOC_GET_STATUS, &status) < 0)
484                                 {
485                                         perror("Device1394Output::run DV1394_GET_STATUS");
486                                 }
487                         }
488                         else
489                         {
490                                 if(ioctl(output_fd, video1394_talk_queue_buffer, &output_queue) < 0)
491                                 {
492                                 perror("Device1394Output::run VIDEO1394_TALK_QUEUE_BUFFER");
493                         }
494                         }
495
496                 output_queue.buffer++;
497                         if(output_queue.buffer >= output_mmap.nb_buffers)
498                                 output_queue.buffer = 0;
499
500                         if(unused_buffers <= 0)
501                         {
502                                 if(!get_dv1394())
503                                 {
504                                 if(ioctl(output_fd, video1394_talk_wait_buffer, &output_queue) < 0)
505                                         {
506                                         perror("Device1394::run VIDEO1394_TALK_WAIT_BUFFER");
507                                 }
508                                 }
509                                 unused_buffers++;
510                         }
511
512
513                         Thread::disable_cancel();
514                 }
515                 else
516                 {
517 //                      Thread::enable_cancel();
518 //                      start_lock->lock();
519 //                      Thread::disable_cancel();
520                 }
521
522 //printf("Device1394Output::run %jd\n", timer.get_difference());
523         }
524 }
525
526
527
528 void Device1394Output::encrypt(unsigned char *output,
529         unsigned char *data,
530         int data_size)
531 {
532 // Encode in IEEE1394 video encryption
533         int output_size = 320;
534         int packets_per_frame = (is_pal ? 300 : 250);
535         int min_packet_size = output_mmap.packet_size;
536         unsigned long frame_size = packets_per_frame * 480;
537         unsigned long vdata = 0;
538         unsigned int *packet_sizes = this->packet_sizes;
539
540     if(cip_counter == 0)
541         {
542         if(!is_pal)
543                 {
544             cip_n = CIP_N_NTSC;
545             cip_d = CIP_D_NTSC;
546             f50_60 = 0x00;
547         }
548                 else
549                 {
550             cip_n = CIP_N_PAL;
551             cip_d = CIP_D_PAL;
552             f50_60 = 0x80;
553         }
554         cip_counter = cip_n;
555     }
556
557
558
559
560         for(int i = 0; i < output_size && vdata < frame_size; i++)
561         {
562         unsigned char *p = output;
563         int want_sync = (cip_counter > cip_d);
564
565 /* Source node ID ! */
566         *p++ = 0x01;
567 /* Packet size in quadlets (480 / 4) - this stays the same even for empty packets */
568         *p++ = 0x78;
569         *p++ = 0x00;
570         *p++ = continuity_counter;
571
572 /* const */
573         *p++ = 0x80;
574 /* high bit = 50/60 indicator */
575         *p++ = f50_60;
576
577 /* timestamp - generated in driver */
578         *p++ = 0xff;
579 /* timestamp */
580         *p++ = 0xff;
581
582 /* video data */
583         if(!want_sync)
584                 {
585             continuity_counter++;
586             cip_counter += cip_n;
587
588             memcpy(p, data + vdata, 480);
589             p += 480;
590             vdata += 480;
591         }
592         else
593             cip_counter -= cip_d;
594
595         *packet_sizes++ = p - output;
596         output += min_packet_size;
597         }
598         *packet_sizes++ = 0;
599 }
600
601
602
603
604 void Device1394Output::write_frame(VFrame *input)
605 {
606         VFrame *ptr = 0;
607         int result = 0;
608
609 //printf("Device1394Output::write_frame 1\n");
610
611         if(output_fd <= 0) return;
612         if(interrupted) return;
613
614 // Encode frame to DV
615         if(input->get_color_model() != BC_COMPRESSED)
616         {
617                 if(!temp_frame) temp_frame = new VFrame;
618                 if(!encoder) encoder = dv_new();
619                 ptr = temp_frame;
620
621 // Exact resolution match.  Don't do colorspace conversion
622                 if(input->get_color_model() == BC_YUV422 &&
623                         input->get_w() == 720 &&
624                         (input->get_h() == 480 ||
625                         input->get_h() == 576))
626                 {
627                         int norm = is_pal ? DV_PAL : DV_NTSC;
628                         int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
629                         temp_frame->allocate_compressed_data(data_size);
630                         temp_frame->set_compressed_size(data_size);
631
632                         dv_write_video(encoder,
633                                 temp_frame->get_data(),
634                                 input->get_rows(),
635                                 BC_YUV422,
636                                 norm);
637                         ptr = temp_frame;
638                 }
639                 else
640 // Convert resolution and color model before compressing
641                 {
642                         if(!temp_frame2)
643                         {
644                                 int h = input->get_h();
645 // Default to NTSC if unknown
646                                 if(h != 480 && h != 576) h = 480;
647                                 temp_frame2 = new VFrame(720, h, BC_YUV422, 0);
648
649                         }
650
651                         int norm = is_pal ? DV_PAL : DV_NTSC;
652                         int data_size = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE;
653                         temp_frame->allocate_compressed_data(data_size);
654                         temp_frame->set_compressed_size(data_size);
655
656
657                         BC_CModels::transfer(temp_frame2->get_rows(), /* Leave NULL if non existent */
658                                 input->get_rows(),
659                                 temp_frame2->get_y(), /* Leave NULL if non existent */
660                                 temp_frame2->get_u(),
661                                 temp_frame2->get_v(),
662                                 input->get_y(), /* Leave NULL if non existent */
663                                 input->get_u(),
664                                 input->get_v(),
665                                 0,        /* Dimensions to capture from input frame */
666                                 0,
667                                 MIN(temp_frame2->get_w(), input->get_w()),
668                                 MIN(temp_frame2->get_h(), input->get_h()),
669                                 0,       /* Dimensions to project on output frame */
670                                 0,
671                                 MIN(temp_frame2->get_w(), input->get_w()),
672                                 MIN(temp_frame2->get_h(), input->get_h()),
673                                 input->get_color_model(),
674                                 BC_YUV422,
675                                 0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
676                                 input->get_bytes_per_line(),       /* For planar use the luma rowspan */
677                                 temp_frame2->get_bytes_per_line());     /* For planar use the luma rowspan */
678
679                         dv_write_video(encoder,
680                                 temp_frame->get_data(),
681                                 temp_frame2->get_rows(),
682                                 BC_YUV422,
683                                 norm);
684
685
686
687                         ptr = temp_frame;
688                 }
689         }
690         else
691                 ptr = input;
692
693
694
695
696
697
698
699
700
701
702
703 // Take over buffer table
704         buffer_lock->lock("Device1394Output::write_frame 1");
705         have_video = 1;
706 // Wait for buffer to become available with timeout
707         while(buffer_valid[current_inbuffer] && !result && !interrupted)
708         {
709                 buffer_lock->unlock();
710                 result = video_lock->timed_lock(BUFFER_TIMEOUT);
711                 buffer_lock->lock("Device1394Output::write_frame 2");
712         }
713
714
715
716 // Write buffer if there's room
717         if(!buffer_valid[current_inbuffer])
718         {
719                 if(!buffer[current_inbuffer])
720                 {
721                         buffer[current_inbuffer] = new char[ptr->get_compressed_size()];
722                         buffer_size[current_inbuffer] = ptr->get_compressed_size();
723                 }
724                 memcpy(buffer[current_inbuffer], ptr->get_data(), ptr->get_compressed_size());
725                 buffer_valid[current_inbuffer] = 1;
726                 increment_counter(&current_inbuffer);
727         }
728         else
729 // Ignore it if there isn't room.
730         {
731                 ;
732         }
733
734         buffer_lock->unlock();
735         start_lock->unlock();
736 //printf("Device1394Output::write_frame 100\n");
737 }
738
739 void Device1394Output::write_samples(char *data, int samples)
740 {
741 //printf("Device1394Output::write_samples 1\n");
742         int result = 0;
743         //int timeout = (samples * 1000000LL * 2)/ samplerate;
744         if(interrupted) return;
745
746 //printf("Device1394Output::write_samples 2\n");
747
748 // Check for maximum sample count exceeded
749         if(samples > OUTPUT_SAMPLES)
750         {
751                 printf("Device1394Output::write_samples samples=%d > OUTPUT_SAMPLES=%d\n",
752                         samples,
753                         OUTPUT_SAMPLES);
754                 return;
755         }
756
757 //printf("Device1394Output::write_samples 3\n");
758 // Take over buffer table
759         buffer_lock->lock("Device1394Output::write_samples 1");
760 // Wait for buffer to become available with timeout
761         while(audio_samples > OUTPUT_SAMPLES - samples && !result && !interrupted)
762         {
763                 buffer_lock->unlock();
764                 result = audio_lock->timed_lock(BUFFER_TIMEOUT);
765                 buffer_lock->lock("Device1394Output::write_samples 2");
766         }
767
768         if(!interrupted && audio_samples <= OUTPUT_SAMPLES - samples)
769         {
770 //printf("Device1394Output::write_samples 4 %d\n", audio_samples);
771                 memcpy(audio_buffer + audio_samples * channels * bits / 8,
772                         data,
773                         samples * channels * bits / 8);
774                 audio_samples += samples;
775         }
776         buffer_lock->unlock();
777         start_lock->unlock();
778 //printf("Device1394Output::write_samples 100\n");
779 }
780
781 long Device1394Output::get_audio_position()
782 {
783         position_lock->lock("Device1394Output::get_audio_position");
784         long result = audio_position;
785         if (get_dv1394())
786         {
787 // Take delay between placing in buffer and presentation
788 // on device into account for dv1394
789                 result = position_presented[status.active_frame];
790         }
791         position_lock->unlock();
792         return result;
793 }
794
795 void Device1394Output::interrupt()
796 {
797         interrupted = 1;
798 // Break write_samples out of a lock
799         video_lock->unlock();
800         audio_lock->unlock();
801 // Playback should stop when the object is deleted.
802 }
803
804 void Device1394Output::flush()
805 {
806
807 }
808
809 void Device1394Output::increment_counter(int *counter)
810 {
811         (*counter)++;
812         if(*counter >= total_buffers) *counter = 0;
813 }
814
815 void Device1394Output::decrement_counter(int *counter)
816 {
817         (*counter)--;
818         if(*counter < 0) *counter = total_buffers - 1;
819 }
820
821 void Device1394Output::set_ioctls()
822 {
823         // It would make sense to simply change the file that is included in
824         // order to change the IOCTLs, but it isn't reasonable to think that
825         // people will rebuild their software every time the update their
826         // kernel, hence this fix.
827
828         struct utsname buf;
829
830         // Get the kernel version so we can set the right ioctls
831         uname(&buf);
832
833         char *ptr = strchr(buf.release, '.');
834         int major = 2;
835         int minor = 6;
836         int point = 7;
837         if(ptr)
838         {
839                 *ptr++ = 0;
840                 major = atoi(buf.release);
841                 char *ptr2 = strchr(ptr, '.');
842                 if(ptr2)
843                 {
844                         *ptr2++ = 0;
845                         minor = atoi(ptr);
846                         point = atoi(ptr2);
847                 }
848         }
849
850         if( (major >= 2 && minor >= 6 && point >= 0) ||
851             (major >= 2 && minor >= 4 && point >= 23) )
852         {
853                 // video1394
854                 video1394_listen_channel = VIDEO1394_IOC_LISTEN_CHANNEL;
855                 video1394_unlisten_channel = VIDEO1394_IOC_UNLISTEN_CHANNEL;
856                 video1394_listen_queue_buffer = VIDEO1394_IOC_LISTEN_QUEUE_BUFFER;
857                 video1394_listen_wait_buffer = VIDEO1394_IOC_LISTEN_WAIT_BUFFER;
858                 video1394_talk_channel = VIDEO1394_IOC_TALK_CHANNEL;
859                 video1394_untalk_channel = VIDEO1394_IOC_UNTALK_CHANNEL;
860                 video1394_talk_queue_buffer = VIDEO1394_IOC_TALK_QUEUE_BUFFER;
861                 video1394_talk_wait_buffer = VIDEO1394_IOC_TALK_WAIT_BUFFER;
862                 video1394_listen_poll_buffer = VIDEO1394_IOC_LISTEN_POLL_BUFFER;
863
864                 // raw1394
865                 // Nothing uses this right now, so I didn't include it.
866         }
867         else     // we are using an older kernel
868         {
869       // video1394
870       video1394_listen_channel = VIDEO1394_LISTEN_CHANNEL;
871       video1394_unlisten_channel = VIDEO1394_UNLISTEN_CHANNEL;
872       video1394_listen_queue_buffer = VIDEO1394_LISTEN_QUEUE_BUFFER;
873       video1394_listen_wait_buffer = VIDEO1394_LISTEN_WAIT_BUFFER;
874       video1394_talk_channel = VIDEO1394_TALK_CHANNEL;
875       video1394_untalk_channel = VIDEO1394_UNTALK_CHANNEL;
876       video1394_talk_queue_buffer = VIDEO1394_TALK_QUEUE_BUFFER;
877       video1394_talk_wait_buffer = VIDEO1394_TALK_WAIT_BUFFER;
878       video1394_listen_poll_buffer = VIDEO1394_LISTEN_POLL_BUFFER;
879         }
880 }
881
882
883
884
885
886
887
888
889
890
891
892
893 #endif // HAVE_FIREWIRE
894
895
896
897
898
899