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