]> git.sesse.net Git - vlc/blob - modules/access/dv.c
Removed fake access.
[vlc] / modules / access / dv.c
1 /*****************************************************************************
2  * dv.c: Digital video/Firewire input (file: access plug-in)
3  *****************************************************************************
4  * Copyright (C) 2005 M2X
5  * $Id$
6  *
7  * Authors: Jean-Paul Saman <jpsaman at m2x dot nl>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_access.h>
34
35 #include <errno.h>
36 #include <sys/types.h>
37 #ifdef HAVE_UNISTD_H
38 #   include <unistd.h>
39 #elif defined( WIN32 ) && !defined( UNDER_CE )
40 #   include <io.h>
41 #endif
42
43 #include <sys/poll.h>
44
45 #include <libraw1394/raw1394.h>
46 #include <libraw1394/csr.h>
47 #include <libavc1394/avc1394.h>
48 #include <libavc1394/avc1394_vcr.h>
49 #include <libavc1394/rom1394.h>
50
51 /*****************************************************************************
52  * Module descriptor
53  *****************************************************************************/
54 static int  Open ( vlc_object_t * );
55 static void Close( vlc_object_t * );
56 static block_t *Block( access_t * );
57 static int Control( access_t *, int, va_list );
58
59 #define CACHING_TEXT N_("Caching value in ms")
60 #define CACHING_LONGTEXT N_( \
61     "Caching value for DV streams. This " \
62     "value should be set in milliseconds." )
63
64 vlc_module_begin ()
65     set_description( N_("Digital Video (Firewire/ieee1394)  input") )
66     set_shortname( N_("DV") )
67     set_category( CAT_INPUT )
68     set_subcategory( SUBCAT_INPUT_ACCESS )
69     add_integer( "dv-caching", 60000 / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, true )
70         change_safe()
71     set_capability( "access", 0 )
72     add_shortcut( "dv" )
73     add_shortcut( "dv1394" )
74     add_shortcut( "raw1394" )
75     set_callbacks( Open, Close )
76 vlc_module_end ()
77
78 typedef struct
79 {
80     VLC_COMMON_MEMBERS
81
82     access_t        *p_access;
83     vlc_mutex_t     lock;
84     block_t         *p_frame;
85     block_t         **pp_last;
86
87 } event_thread_t;
88
89 static void* Raw1394EventThread( vlc_object_t * );
90 static enum raw1394_iso_disposition
91 Raw1394Handler(raw1394handle_t, unsigned char *,
92         unsigned int, unsigned char,
93         unsigned char, unsigned char, unsigned int,
94         unsigned int);
95
96 static int Raw1394GetNumPorts( access_t *p_access );
97 static raw1394handle_t Raw1394Open( access_t *, int );
98 static void Raw1394Close( raw1394handle_t );
99
100 static int DiscoverAVC( access_t *, int *, uint64_t );
101 static raw1394handle_t AVCOpen( access_t *, int );
102 static void AVCClose( access_t * );
103 static int AVCResetHandler( raw1394handle_t, unsigned int );
104 static int AVCPlay( access_t *, int );
105 static int AVCPause( access_t *, int );
106 static int AVCStop( access_t *, int );
107
108 struct access_sys_t
109 {
110     raw1394handle_t p_avc1394;
111     raw1394handle_t p_raw1394;
112     struct pollfd   raw1394_poll;
113
114     int i_cards;
115     int i_node;
116     int i_port;
117     int i_channel;
118     uint64_t i_guid;
119
120     /* event */
121     event_thread_t *p_ev;
122     vlc_mutex_t lock;
123     block_t *p_frame;
124 };
125
126 #define ISOCHRONOUS_QUEUE_LENGTH 1000
127 #define ISOCHRONOUS_MAX_PACKET_SIZE 4096
128
129 /*****************************************************************************
130  * Open: open the file
131  *****************************************************************************/
132 static int Open( vlc_object_t *p_this )
133 {
134     access_t     *p_access = (access_t*)p_this;
135     access_sys_t *p_sys;
136
137     struct raw1394_portinfo port_inf[ 16 ];
138
139     msg_Dbg( p_access, "opening device" );
140
141     /* Set up p_access */
142     access_InitFields( p_access );
143     ACCESS_SET_CALLBACKS( NULL, Block, Control, NULL );
144
145     p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
146     if( !p_sys )
147         return VLC_EGENERIC;
148
149     p_sys->i_cards = 0;
150     p_sys->i_node = 0;
151     p_sys->i_port = 0;
152     p_sys->i_guid = 0;
153     p_sys->i_channel = 63;
154     p_sys->p_raw1394 = NULL;
155     p_sys->p_avc1394 = NULL;
156     p_sys->p_frame = NULL;
157     p_sys->p_ev = NULL;
158
159     vlc_mutex_init( &p_sys->lock );
160
161     p_sys->i_node = DiscoverAVC( p_access, &p_sys->i_port, p_sys->i_guid );
162     if( p_sys->i_node < 0 )
163     {
164         msg_Err( p_access, "failed to open a Firewire (IEEE1394) connection" );
165         Close( p_this );
166         return VLC_EGENERIC;
167     }
168
169     p_sys->p_avc1394 = AVCOpen( p_access, p_sys->i_port );
170     if( !p_sys->p_avc1394 )
171     {
172         msg_Err( p_access, "no Digital Video Control device found" );
173         Close( p_this );
174         return VLC_EGENERIC;
175     }
176
177     p_sys->p_raw1394 = raw1394_new_handle();
178     if( !p_sys->p_raw1394 )
179     {
180         msg_Err( p_access, "no Digital Video device found" );
181         Close( p_this );
182         return VLC_EGENERIC;
183     }
184
185     p_sys->i_cards = raw1394_get_port_info( p_sys->p_raw1394, port_inf, 16 );
186     if( p_sys->i_cards < 0 )
187     {
188         msg_Err( p_access, "failed to get port info" );
189         Close( p_this );
190         return VLC_EGENERIC;
191     }
192
193     if( raw1394_set_port( p_sys->p_raw1394, p_sys->i_port ) < 0 )
194     {
195         msg_Err( p_access, "failed to set port info" );
196         Close( p_this );
197         return VLC_EGENERIC;
198     }
199
200     if ( raw1394_iso_recv_init( p_sys->p_raw1394, Raw1394Handler,
201                 ISOCHRONOUS_QUEUE_LENGTH, ISOCHRONOUS_MAX_PACKET_SIZE,
202                 p_sys->i_channel, RAW1394_DMA_PACKET_PER_BUFFER, -1 ) < 0 )
203     {
204         msg_Err( p_access, "failed to init isochronous recv" );
205         Close( p_this );
206         return VLC_EGENERIC;
207     }
208
209     raw1394_set_userdata( p_sys->p_raw1394, p_access );
210     raw1394_iso_recv_start( p_sys->p_raw1394, -1, -1, 0 );
211
212     p_sys->raw1394_poll.fd = raw1394_get_fd( p_sys->p_raw1394 );
213     p_sys->raw1394_poll.events = POLLIN | POLLPRI;
214
215     /* Update default_pts to a suitable value for udp access */
216     var_Create( p_access, "dv-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
217
218     /* Now create our event thread catcher */
219     p_sys->p_ev = vlc_object_create( p_access, sizeof( event_thread_t ) );
220     if( !p_sys->p_ev )
221     {
222         msg_Err( p_access, "failed to create event thread" );
223         Close( p_this );
224         return VLC_EGENERIC;
225     }
226
227     p_sys->p_ev->p_frame = NULL;
228     p_sys->p_ev->pp_last = &p_sys->p_ev->p_frame;
229     p_sys->p_ev->p_access = p_access;
230     vlc_mutex_init( &p_sys->p_ev->lock );
231     vlc_thread_create( p_sys->p_ev, "dv event thread handler",
232                        Raw1394EventThread, VLC_THREAD_PRIORITY_OUTPUT );
233
234     return VLC_SUCCESS;
235 }
236
237 /*****************************************************************************
238  * Close: free unused data structures
239  *****************************************************************************/
240 static void Close( vlc_object_t *p_this )
241 {
242     access_t     *p_access = (access_t*)p_this;
243     access_sys_t *p_sys = p_access->p_sys;
244
245     if( p_sys->p_ev )
246     {
247         /* stop the event handler */
248         vlc_object_kill( p_sys->p_ev );
249
250         if( p_sys->p_raw1394 )
251             raw1394_iso_shutdown( p_sys->p_raw1394 );
252
253         vlc_thread_join( p_sys->p_ev );
254         vlc_mutex_destroy( &p_sys->p_ev->lock );
255
256         /* Cleanup frame data */
257         if( p_sys->p_ev->p_frame )
258         {
259             block_ChainRelease( p_sys->p_ev->p_frame );
260             p_sys->p_ev->p_frame = NULL;
261             p_sys->p_ev->pp_last = &p_sys->p_frame;
262         }
263         vlc_object_release( p_sys->p_ev );
264     }
265
266     if( p_sys->p_frame )
267         block_ChainRelease( p_sys->p_frame );
268     if( p_sys->p_raw1394 )
269         raw1394_destroy_handle( p_sys->p_raw1394 );
270
271     AVCClose( p_access );
272
273     vlc_mutex_destroy( &p_sys->lock );
274     free( p_sys );
275 }
276
277 /*****************************************************************************
278  * Control:
279  *****************************************************************************/
280 static int Control( access_t *p_access, int i_query, va_list args )
281 {
282     switch( i_query )
283     {
284         /* */
285         case ACCESS_CAN_PAUSE:
286             *va_arg( args, bool* ) = true;
287             break;
288
289        case ACCESS_CAN_SEEK:
290        case ACCESS_CAN_FASTSEEK:
291        case ACCESS_CAN_CONTROL_PACE:
292             *va_arg( args, bool* ) = false;
293             break;
294
295         case ACCESS_GET_PTS_DELAY:
296             *va_arg( args, int64_t * )
297                    = (int64_t)var_GetInteger( p_access, "dv-caching" ) * 1000;
298             break;
299
300         /* */
301         case ACCESS_SET_PAUSE_STATE:
302             AVCPause( p_access, p_access->p_sys->i_node );
303             break;
304
305         case ACCESS_GET_TITLE_INFO:
306         case ACCESS_SET_TITLE:
307         case ACCESS_SET_SEEKPOINT:
308         case ACCESS_SET_PRIVATE_ID_STATE:
309         case ACCESS_GET_CONTENT_TYPE:
310             return VLC_EGENERIC;
311
312         default:
313             msg_Warn( p_access, "unimplemented query in control" );
314             return VLC_EGENERIC;
315
316     }
317     return VLC_SUCCESS;
318 }
319
320 static block_t *Block( access_t *p_access )
321 {
322     access_sys_t *p_sys = p_access->p_sys;
323     block_t *p_block = NULL;
324
325     vlc_mutex_lock( &p_sys->lock );
326     p_block = p_sys->p_frame;
327     //msg_Dbg( p_access, "sending frame %p",p_block );
328     p_sys->p_frame = NULL;
329     vlc_mutex_unlock( &p_sys->lock );
330
331     return p_block;
332 }
333
334 static void* Raw1394EventThread( vlc_object_t *p_this )
335 {
336     event_thread_t *p_ev = (event_thread_t *) p_this;
337     access_t *p_access = (access_t *) p_ev->p_access;
338     access_sys_t *p_sys = (access_sys_t *) p_access->p_sys;
339     int result = 0;
340     int canc = vlc_savecancel ();
341
342     AVCPlay( p_access, p_sys->i_node );
343
344     while( vlc_object_alive (p_sys->p_ev) )
345     {
346         while( ( result = poll( &(p_sys->raw1394_poll), 1, 200 ) ) < 0 )
347         {
348             if( !( errno == EAGAIN || errno == EINTR ) )
349             {
350                 perror( "error: raw1394 poll" );
351                 msg_Err( p_access, "retrying device raw1394" );
352             }
353         }
354         if( !vlc_object_alive (p_sys->p_ev) )
355                 break;
356         if( result > 0 && ( ( p_sys->raw1394_poll.revents & POLLIN )
357                 || ( p_sys->raw1394_poll.revents & POLLPRI ) ) )
358             result = raw1394_loop_iterate( p_sys->p_raw1394 );
359     }
360
361     AVCStop( p_access, p_sys->i_node );
362     vlc_restorecancel (canc);
363     return NULL;
364 }
365
366 static enum raw1394_iso_disposition
367 Raw1394Handler(raw1394handle_t handle, unsigned char *data,
368         unsigned int length, unsigned char channel,
369         unsigned char tag, unsigned char sy, unsigned int cycle,
370         unsigned int dropped)
371 {
372     access_t *p_access = NULL;
373     access_sys_t *p_sys = NULL;
374     block_t *p_block = NULL;
375     VLC_UNUSED(channel); VLC_UNUSED(tag);
376     VLC_UNUSED(sy); VLC_UNUSED(cycle); VLC_UNUSED(dropped);
377
378     p_access = (access_t *) raw1394_get_userdata( handle );
379     if( !p_access ) return 0;
380
381     p_sys = p_access->p_sys;
382
383     /* skip empty packets */
384     if( length > 16 )
385     {
386         unsigned char * p = data + 8;
387         int section_type = p[ 0 ] >> 5;           /* section type is in bits 5 - 7 */
388         int dif_sequence = p[ 1 ] >> 4;           /* dif sequence number is in bits 4 - 7 */
389         int dif_block = p[ 2 ];
390
391         vlc_mutex_lock( &p_sys->p_ev->lock );
392
393         /* if we are at the beginning of a frame, we put the previous
394            frame in our output_queue. */
395         if( (section_type == 0) && (dif_sequence == 0) )
396         {
397             vlc_mutex_lock( &p_sys->lock );
398             if( p_sys->p_ev->p_frame )
399             {
400                 /* Push current frame to p_access thread. */
401                 //p_sys->p_ev->p_frame->i_pts = mdate();
402                 block_ChainAppend( &p_sys->p_frame, p_sys->p_ev->p_frame );
403             }
404             /* reset list */
405             p_sys->p_ev->p_frame = block_New( p_access, 144000 );
406             p_sys->p_ev->pp_last = &p_sys->p_frame;
407             vlc_mutex_unlock( &p_sys->lock );
408         }
409
410         p_block = p_sys->p_ev->p_frame;
411         if( p_block )
412         {
413             switch ( section_type )
414             {
415             case 0:    /* 1 Header block */
416                 /* p[3] |= 0x80; // hack to force PAL data */
417                 memcpy( p_block->p_buffer + dif_sequence * 150 * 80, p, 480 );
418                 break;
419
420             case 1:    /* 2 Subcode blocks */
421                 memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 1 + dif_block ) * 80, p, 480 );
422                 break;
423
424             case 2:    /* 3 VAUX blocks */
425                 memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 3 + dif_block ) * 80, p, 480 );
426                 break;
427
428             case 3:    /* 9 Audio blocks interleaved with video */
429                 memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 6 + dif_block * 16 ) * 80, p, 480 );
430                 break;
431
432             case 4:    /* 135 Video blocks interleaved with audio */
433                 memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 7 + ( dif_block / 15 ) + dif_block ) * 80, p, 480 );
434                 break;
435
436             default:    /* we canĀ“t handle any other data */
437                 block_Release( p_block );
438                 p_block = NULL;
439                 break;
440             }
441         }
442
443         vlc_mutex_unlock( &p_sys->p_ev->lock );
444     }
445     return 0;
446 }
447
448 /*
449  * Routing borrowed from dvgrab-1.8
450  * Copyright by Arne Schirmacher <dvgrab@schirmacher.de>
451  * Dan Dennedy <dan@dennedy.org> and others
452  */
453 static int Raw1394GetNumPorts( access_t *p_access )
454 {
455     int n_ports;
456     struct raw1394_portinfo pinf[ 16 ];
457     raw1394handle_t handle;
458
459     /* get a raw1394 handle */
460     if( !( handle = raw1394_new_handle() ) )
461     {
462         msg_Err( p_access, "raw1394 - failed to get handle: %m." );
463         return VLC_EGENERIC;
464     }
465
466     if( ( n_ports = raw1394_get_port_info( handle, pinf, 16 ) ) < 0 )
467     {
468         msg_Err( p_access, "raw1394 - failed to get port info: %m." );
469         raw1394_destroy_handle( handle );
470         return VLC_EGENERIC;
471     }
472     raw1394_destroy_handle( handle );
473
474     return n_ports;
475 }
476
477 static raw1394handle_t Raw1394Open( access_t *p_access, int port )
478 {
479     int n_ports;
480     struct raw1394_portinfo pinf[ 16 ];
481     raw1394handle_t handle;
482
483     /* get a raw1394 handle */
484     handle = raw1394_new_handle();
485     if( !handle )
486     {
487         msg_Err( p_access, "raw1394 - failed to get handle: %m." );
488         return NULL;
489     }
490
491     if( ( n_ports = raw1394_get_port_info( handle, pinf, 16 ) ) < 0 )
492     {
493         msg_Err( p_access, "raw1394 - failed to get port info: %m." );
494         raw1394_destroy_handle( handle );
495         return NULL;
496     }
497
498     /* tell raw1394 which host adapter to use */
499     if( raw1394_set_port( handle, port ) < 0 )
500     {
501         msg_Err( p_access, "raw1394 - failed to set set port: %m." );
502         return NULL;
503     }
504
505     return handle;
506 }
507
508 static void Raw1394Close( raw1394handle_t handle )
509 {
510     raw1394_destroy_handle( handle );
511 }
512
513 static int DiscoverAVC( access_t *p_access, int* port, uint64_t guid )
514 {
515     rom1394_directory rom_dir;
516     raw1394handle_t handle = NULL;
517     int device = -1;
518     int i, j = 0;
519     int m = Raw1394GetNumPorts( p_access );
520
521     if( *port >= 0 )
522     {
523         /* search on explicit port */
524         j = *port;
525         m = *port + 1;
526     }
527
528     for( ; j < m && device == -1; j++ )
529     {
530         handle = Raw1394Open( p_access, j );
531         if( !handle )
532             return -1;
533
534         for( i = 0; i < raw1394_get_nodecount( handle ); ++i )
535         {
536             if( guid != 0 )
537             {
538                 /* select explicitly by GUID */
539                 if( guid == rom1394_get_guid( handle, i ) )
540                 {
541                     device = i;
542                     *port = j;
543                     break;
544                 }
545             }
546             else
547             {
548                 /* select first AV/C Tape Reccorder Player node */
549                 if( rom1394_get_directory( handle, i, &rom_dir ) < 0 )
550                 {
551                     msg_Err( p_access, "error reading config rom directory for node %d", i );
552                     continue;
553                 }
554                 if( ( rom1394_get_node_type( &rom_dir ) == ROM1394_NODE_TYPE_AVC ) &&
555                         avc1394_check_subunit_type( handle, i, AVC1394_SUBUNIT_TYPE_VCR ) )
556                 {
557                     device = i;
558                     *port = j;
559                     break;
560                 }
561             }
562         }
563         Raw1394Close( handle );
564     }
565
566     return device;
567 }
568
569 /*
570  * Handle AVC commands
571  */
572 static raw1394handle_t AVCOpen( access_t *p_access, int port )
573 {
574     access_sys_t *p_sys = p_access->p_sys;
575     struct raw1394_portinfo pinf[ 16 ];
576     int numcards;
577
578     p_sys->p_avc1394 = raw1394_new_handle();
579     if( !p_sys->p_avc1394 )
580         return NULL;
581
582     numcards = raw1394_get_port_info( p_sys->p_avc1394, pinf, 16 );
583     if( numcards < -1 )
584         return NULL;
585     if( raw1394_set_port( p_sys->p_avc1394, port ) < 0 )
586         return NULL;
587
588     raw1394_set_bus_reset_handler( p_sys->p_avc1394, AVCResetHandler );
589
590     return  p_sys->p_avc1394;
591 }
592
593 static void AVCClose( access_t *p_access )
594 {
595     access_sys_t *p_sys = p_access->p_sys;
596
597     if( p_sys->p_avc1394 )
598     {
599         raw1394_destroy_handle( p_sys->p_avc1394 );
600         p_sys->p_avc1394 = NULL;
601     }
602 }
603
604 static int AVCResetHandler( raw1394handle_t handle, unsigned int generation )
605 {
606     raw1394_update_generation( handle, generation );
607     return 0;
608 }
609
610 static int AVCPlay( access_t *p_access, int phyID )
611 {
612     access_sys_t *p_sys = p_access->p_sys;
613
614     msg_Dbg( p_access, "send play command over Digital Video control channel" );
615
616     if( p_sys->p_avc1394 && phyID >= 0 )
617     {
618         if( !avc1394_vcr_is_recording( p_sys->p_avc1394, phyID ) &&
619             avc1394_vcr_is_playing( p_sys->p_avc1394, phyID ) != AVC1394_VCR_OPERAND_PLAY_FORWARD )
620                 avc1394_vcr_play( p_sys->p_avc1394, phyID );
621     }
622     return 0;
623 }
624
625 static int AVCPause( access_t *p_access, int phyID )
626 {
627     access_sys_t *p_sys = p_access->p_sys;
628
629     if( p_sys->p_avc1394 && phyID >= 0 )
630     {
631         if( !avc1394_vcr_is_recording( p_sys->p_avc1394, phyID ) &&
632             ( avc1394_vcr_is_playing( p_sys->p_avc1394, phyID ) != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE ) )
633                 avc1394_vcr_pause( p_sys->p_avc1394, phyID );
634     }
635     return 0;
636 }
637
638
639 static int AVCStop( access_t *p_access, int phyID )
640 {
641     access_sys_t *p_sys = p_access->p_sys;
642
643     msg_Dbg( p_access, "closing Digital Video control channel" );
644
645     if ( p_sys->p_avc1394 && phyID >= 0 )
646         avc1394_vcr_stop( p_sys->p_avc1394, phyID );
647
648     return 0;
649 }