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