r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / device1394input.C
blobd63f2b6ba8185012170ce754c676a01888d768b4
1 #include "condition.h"
2 #include "device1394input.h"
3 #include "mutex.h"
4 #include "vframe.h"
5 #include "video1394.h"
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
11 #define INPUT_SAMPLES 131072
12 #define BUFFER_TIMEOUT 500000
15 Device1394Input::Device1394Input()
16  : Thread(1, 1, 0)
18         buffer = 0;
19         buffer_valid = 0;
20         done = 0;
21         total_buffers = 0;
22         current_inbuffer = 0;
23         current_outbuffer = 0;
24         buffer_size = 0;
25         temp = 0;
26         bytes_read = 0;
27         audio_buffer = 0;
28         audio_samples = 0;
29         video_lock = 0;
30         audio_lock = 0;
31         buffer_lock = 0;
32         handle = 0;
33         decoder = 0;
36 Device1394Input::~Device1394Input()
39 // Driver crashes if it isn't stopped before cancelling the thread.
40 // May still crash during the cancel though.
41         if(handle > 0)
42         {
43                 raw1394_stop_iso_rcv(handle, channel);
44         }
46         if(Thread::running())
47         {
48                 done = 1;
49                 Thread::cancel();
50                 Thread::join();
51         }
53         if(buffer)
54         {
55                 for(int i = 0; i < total_buffers; i++)
56                         delete [] buffer[i];
57                 delete [] buffer;
58                 delete [] buffer_valid;
59         }
61         if(temp)
62         {
63                 delete [] temp;
64         }
66         if(audio_buffer)
67         {
68                 delete [] audio_buffer;
69         }
71         if(handle > 0)
72         {
73                 raw1394_destroy_handle(handle);
74         }
76         if(decoder)
77         {
78                 dv_delete(decoder);
79         }
81         if(video_lock) delete video_lock;
82         if(audio_lock) delete audio_lock;
83         if(buffer_lock) delete buffer_lock;
86 int Device1394Input::open(int port,
87         int channel,
88         int length,
89         int channels,
90         int samplerate,
91         int bits)
93         int result = 0;
94         this->channel = channel;
95         this->length = length;
96         this->channels = channels;
97         this->samplerate = samplerate;
98         this->bits = bits;
100 // Initialize grabbing
101         if(!handle)
102         {
103                 int numcards;
104         struct raw1394_portinfo pinf[16];
106         if(!(handle = raw1394_new_handle()))
107                 {
108                 perror("Device1394::open_input: raw1394_get_handle");
109                         handle = 0;
110                 return 1;
111         }
113         if((numcards = raw1394_get_port_info(handle, pinf, 16)) < 0)
114                 {
115                 perror("Device1394::open_input: raw1394_get_port_info");
116                         raw1394_destroy_handle(handle);
117                         handle = 0;
118                 return 1;
119         }
121                 if(!pinf[port].nodes)
122                 {
123                         printf("Device1394::open_input: pinf[port].nodes == 0\n");
124                         raw1394_destroy_handle(handle);
125                         handle = 0;
126                         return 1;
127                 }
129         if(raw1394_set_port(handle, port) < 0)
130                 {
131                 perror("Device1394::open_input: raw1394_set_port");
132                         raw1394_destroy_handle(handle);
133                         handle = 0;
134                 return 1;
135         }
137                 raw1394_set_iso_handler(handle, channel, dv_iso_handler);
138 //              raw1394_set_bus_reset_handler(handle, dv_reset_handler);
139                 raw1394_set_userdata(handle, this);
140         if(raw1394_start_iso_rcv(handle, channel) < 0)
141                 {
142                 perror("Device1394::open_input: raw1394_start_iso_rcv");
143                         raw1394_destroy_handle(handle);
144                         handle = 0;
145                 return 1;
146         }
152                 total_buffers = length;
153                 buffer = new char*[total_buffers];
154                 buffer_valid = new int[total_buffers];
155                 bzero(buffer_valid, sizeof(int) * total_buffers);
156                 for(int i = 0; i < total_buffers; i++)
157                 {
158                         buffer[i] = new char[DV_PAL_SIZE];
159                 }
161                 temp = new char[DV_PAL_SIZE];
163                 audio_buffer = new char[INPUT_SAMPLES * 2 * channels];
165                 audio_lock = new Condition(0);
166                 video_lock = new Condition(0);
167                 buffer_lock = new Mutex;
169                 decoder = dv_new();
171                 Thread::start();
172         }
173         return result;
176 void Device1394Input::run()
178         while(!done)
179         {
180                 Thread::enable_cancel();
181                 raw1394_loop_iterate(handle);
182                 Thread::disable_cancel();
183         }
186 void Device1394Input::increment_counter(int *counter)
188         (*counter)++;
189         if(*counter >= total_buffers) *counter = 0;
192 void Device1394Input::decrement_counter(int *counter)
194         (*counter)--;
195         if(*counter < 0) *counter = total_buffers - 1;
200 int Device1394Input::read_video(VFrame *data)
202         int result = 0;
204 //printf("Device1394Input::read_video 1\n");
205 // Take over buffer table
206         buffer_lock->lock();
207 //printf("Device1394Input::read_video 1\n");
208 // Wait for buffer with timeout
209         while(!buffer_valid[current_outbuffer] && !result)
210         {
211                 buffer_lock->unlock();
212                 result = video_lock->timed_lock(BUFFER_TIMEOUT);
213                 buffer_lock->lock();
214         }
215 //printf("Device1394Input::read_video 1\n");
217 // Copy frame
218         if(buffer_valid[current_outbuffer])
219         {
220                 data->allocate_compressed_data(buffer_size);
221                 data->set_compressed_size(buffer_size);
222                 memcpy(data->get_data(), buffer[current_outbuffer], buffer_size);
223                 buffer_valid[current_outbuffer] = 0;
224                 increment_counter(&current_outbuffer);
225         }
226 //printf("Device1394Input::read_video 100\n");
228         buffer_lock->unlock();
229         return result;
235 int Device1394Input::read_audio(char *data, int samples)
237         int result = 0;
238 //printf("Device1394Input::read_audio 1\n");
239         int timeout = (int64_t)samples * (int64_t)1000000 * (int64_t)2 / (int64_t)samplerate;
240         if(timeout < 500000) timeout = 500000;
241 //printf("Device1394Input::read_audio 1\n");
243 // Take over buffer table
244         buffer_lock->lock();
245 // Wait for buffer with timeout
246         while(audio_samples < samples && !result)
247         {
248                 buffer_lock->unlock();
249                 result = audio_lock->timed_lock(timeout);
250                 buffer_lock->lock();
251         }
252 //printf("Device1394Input::read_audio 1 %d %d\n", result, timeout);
254         if(audio_samples >= samples)
255         {
256                 memcpy(data, audio_buffer, samples * bits * channels / 8);
257                 memcpy(audio_buffer, 
258                         audio_buffer + samples * bits * channels / 8,
259                         (audio_samples - samples) * bits * channels / 8);
260                 audio_samples -= samples;
261         }
262 //printf("Device1394Input::read_audio 100\n");
263         buffer_lock->unlock();
264         return result;
272 int Device1394Input::dv_iso_handler(raw1394handle_t handle, 
273                 int channel, 
274                 size_t length,
275                 quadlet_t *data)
277         Device1394Input *thread = (Device1394Input*)raw1394_get_userdata(handle);
279 //printf("Device1394Input::dv_iso_handler 1\n");
280         thread->Thread::disable_cancel();
282 #define BLOCK_SIZE 480
283         if(length > 16)
284         {
285                 unsigned char *ptr = (unsigned char*)&data[3];
286                 int section_type = ptr[0] >> 5;
287                 int dif_sequence = ptr[1] >> 4;
288                 int dif_block = ptr[2];
290 // Frame completed
291                 if(section_type == 0 && 
292                         dif_sequence == 0 && 
293                         thread->bytes_read)
294                 {
295 // Need to conform the frame size so our format detection is right
296 //printf("Device1394Input::dv_iso_handler 10\n");
297                         if(thread->bytes_read == DV_PAL_SIZE ||
298                                 thread->bytes_read == DV_NTSC_SIZE)
299                         {
300 // Copy frame to buffer
301 //printf("Device1394Input::dv_iso_handler 20\n");
302                                 thread->buffer_size = thread->bytes_read;
305                                 thread->buffer_lock->lock();
306 //printf("Device1394Input::dv_iso_handler 21 %p\n", thread->buffer[thread->current_inbuffer]);
307                                 memcpy(thread->buffer[thread->current_inbuffer],
308                                         thread->temp,
309                                         thread->bytes_read);
310 //printf("Device1394Input::dv_iso_handler 22 %p\n", thread->buffer[thread->current_inbuffer]);
311                                 thread->buffer_valid[thread->current_inbuffer] = 1;
312                                 thread->video_lock->unlock();
314 // Decode audio to audio store
315                                 if(thread->audio_samples < INPUT_SAMPLES - 2048)
316                                 {
317                                         int decode_result = dv_read_audio(thread->decoder, 
318                                                 (unsigned char*)thread->audio_buffer + 
319                                                         thread->audio_samples * 2 * 2,
320                                                 (unsigned char*)thread->temp,
321                                                 thread->bytes_read,
322                                                 thread->channels,
323                                                 thread->bits);
324                                         thread->audio_samples += decode_result;
326 //printf("Device1394Input::dv_iso_handler 25 %d\n", decode_result);
327                                         thread->audio_lock->unlock();
328                                 }
330 // Advance buffer if possible
331                                 thread->increment_counter(&thread->current_inbuffer);
332                                 if(thread->buffer_valid[thread->current_inbuffer])
333                                         thread->decrement_counter(&thread->current_inbuffer);
335                                 thread->buffer_lock->unlock();
336 //printf("Device1394Input::dv_iso_handler 30\n");
337                         }
338                         thread->bytes_read = 0;
339                 }
341 //printf("Device1394Input::dv_iso_handler 40\n");
342                 switch(section_type)
343                 {
344                         case 0: // Header
345                 memcpy(thread->temp + 
346                                         dif_sequence * 150 * 80, ptr, BLOCK_SIZE);
347                                 break;
349                         case 1: // Subcode
350                                 memcpy(thread->temp + 
351                                         dif_sequence * 150 * 80 + (1 + dif_block) * 80, 
352                                         ptr, 
353                                         BLOCK_SIZE);
354                                 break;
356                         case 2: // VAUX
357                                 memcpy(thread->temp + 
358                                         dif_sequence * 150 * 80 + (3 + dif_block) * 80, 
359                                         ptr, 
360                                         BLOCK_SIZE);
361                                 break;
363                         case 3: // Audio block
364                                 memcpy(thread->temp + 
365                                         dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, 
366                                         ptr, 
367                                         BLOCK_SIZE);
368                                 break;
370                         case 4: // Video block
371                                 memcpy(thread->temp + 
372                                         dif_sequence * 150 * 80 + (7 + (dif_block / 15) + dif_block) * 80, 
373                                         ptr, 
374                                         BLOCK_SIZE);
375                                 break;
376                         
377                         default:
378                                 break;
379                 }
380 //printf("Device1394Input::dv_iso_handler 50\n");
382                 thread->bytes_read += BLOCK_SIZE;
383         }
384 //printf("Device1394Input::dv_iso_handler 100\n");
386         return 0;
389 bus_reset_handler_t Device1394Input::dv_reset_handler(raw1394handle_t handle, 
390         unsigned int generation)
392         printf("Device1394::dv_reset_handler: generation=%p\n", generation);
393     return 0;