📄 dv.c
字号:
#if 0 if( !p_access->psz_demux ) { free( p_access->psz_demux ); p_access->psz_demux = strdup( "rawdv" ); }#endif vlc_mutex_lock( &p_sys->lock ); p_block = p_sys->p_frame; //msg_Dbg( p_access, "sending frame %p",p_block ); p_sys->p_frame = NULL; vlc_mutex_unlock( &p_sys->lock ); return p_block;}static void* Raw1394EventThread( vlc_object_t *p_this ){ event_thread_t *p_ev = (event_thread_t *) p_this; access_t *p_access = (access_t *) p_ev->p_access; access_sys_t *p_sys = (access_sys_t *) p_access->p_sys; int result = 0; AVCPlay( p_access, p_sys->i_node ); vlc_thread_ready( p_this ); while( vlc_object_alive (p_sys->p_ev) ) { while( ( result = poll( &(p_sys->raw1394_poll), 1, 200 ) ) < 0 ) { if( !( errno == EAGAIN || errno == EINTR ) ) { perror( "error: raw1394 poll" ); msg_Err( p_access, "retrying device raw1394" ); } } if( !vlc_object_alive (p_sys->p_ev) ) break; if( result > 0 && ( ( p_sys->raw1394_poll.revents & POLLIN ) || ( p_sys->raw1394_poll.revents & POLLPRI ) ) ) result = raw1394_loop_iterate( p_sys->p_raw1394 ); } AVCStop( p_access, p_sys->i_node ); return NULL;}static int Raw1394Handler( raw1394handle_t handle, int channel, size_t length, quadlet_t *data ){ access_t *p_access = NULL; access_sys_t *p_sys = NULL; block_t *p_block = NULL; p_access = (access_t *) raw1394_get_userdata( handle ); if( !p_access ) return 0; p_sys = p_access->p_sys; /* skip empty packets */ if ( length > 16 ) { unsigned char * p = ( unsigned char* ) &data[ 3 ]; int section_type = p[ 0 ] >> 5; /* section type is in bits 5 - 7 */ int dif_sequence = p[ 1 ] >> 4; /* dif sequence number is in bits 4 - 7 */ int dif_block = p[ 2 ]; vlc_mutex_lock( &p_sys->p_ev->lock ); /* if we are at the beginning of a frame, we put the previous frame in our output_queue. */ if( (section_type == 0) && (dif_sequence == 0) ) { vlc_mutex_lock( &p_sys->lock ); if( p_sys->p_ev->p_frame ) { /* Push current frame to p_access thread. */ //p_sys->p_ev->p_frame->i_pts = mdate(); block_ChainAppend( &p_sys->p_frame, p_sys->p_ev->p_frame ); } /* reset list */ p_sys->p_ev->p_frame = block_New( p_access, 144000 ); p_sys->p_ev->pp_last = &p_sys->p_frame; vlc_mutex_unlock( &p_sys->lock ); } p_block = p_sys->p_ev->p_frame; if( p_block ) { switch ( section_type ) { case 0: /* 1 Header block */ /* p[3] |= 0x80; // hack to force PAL data */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80, p, 480 ); break; case 1: /* 2 Subcode blocks */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 1 + dif_block ) * 80, p, 480 ); break; case 2: /* 3 VAUX blocks */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 3 + dif_block ) * 80, p, 480 ); break; case 3: /* 9 Audio blocks interleaved with video */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 6 + dif_block * 16 ) * 80, p, 480 ); break; case 4: /* 135 Video blocks interleaved with audio */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 7 + ( dif_block / 15 ) + dif_block ) * 80, p, 480 ); break; default: /* we can´t handle any other data */ block_Release( p_block ); p_block = NULL; break; } } vlc_mutex_unlock( &p_sys->p_ev->lock ); } return 0;}/* * Routing borrowed from dvgrab-1.8 * Copyright by Arne Schirmacher <dvgrab@schirmacher.de> * Dan Dennedy <dan@dennedy.org> and others */static int Raw1394GetNumPorts( access_t *p_access ){ int n_ports; struct raw1394_portinfo pinf[ 16 ]; raw1394handle_t handle; /* get a raw1394 handle */ if ( !( handle = raw1394_new_handle() ) ) { msg_Err( p_access, "raw1394 - failed to get handle: %m." ); return VLC_EGENERIC; } if ( ( n_ports = raw1394_get_port_info( handle, pinf, 16 ) ) < 0 ) { msg_Err( p_access, "raw1394 - failed to get port info: %m.\n" ); raw1394_destroy_handle( handle ); return VLC_EGENERIC; } raw1394_destroy_handle( handle ); return n_ports;}static raw1394handle_t Raw1394Open( access_t *p_access, int port ){ int n_ports; struct raw1394_portinfo pinf[ 16 ]; raw1394handle_t handle; /* get a raw1394 handle */#ifdef RAW1394_V_0_8 handle = raw1394_get_handle();#else handle = raw1394_new_handle();#endif if ( !handle ) { msg_Err( p_access, "raw1394 - failed to get handle: %m." ); return NULL; } if ( ( n_ports = raw1394_get_port_info( handle, pinf, 16 ) ) < 0 ) { msg_Err( p_access, "raw1394 - failed to get port info: %m." ); raw1394_destroy_handle( handle ); return NULL; } /* tell raw1394 which host adapter to use */ if ( raw1394_set_port( handle, port ) < 0 ) { msg_Err( p_access, "raw1394 - failed to set set port: %m." ); return NULL; } return handle;}static void Raw1394Close( raw1394handle_t handle ){ raw1394_destroy_handle( handle );}static int DiscoverAVC( access_t *p_access, int* port, uint64_t guid ){ rom1394_directory rom_dir; raw1394handle_t handle = NULL; int device = -1; int i, j = 0; int m = Raw1394GetNumPorts( p_access ); if( *port >= 0 ) { /* search on explicit port */ j = *port; m = *port + 1; } for( ; j < m && device == -1; j++ ) { handle = Raw1394Open( p_access, j ); if( !handle ) return -1; for( i = 0; i < raw1394_get_nodecount( handle ); ++i ) { if( guid != 0 ) { /* select explicitly by GUID */ if( guid == rom1394_get_guid( handle, i ) ) { device = i; *port = j; break; } } else { /* select first AV/C Tape Reccorder Player node */ if( rom1394_get_directory( handle, i, &rom_dir ) < 0 ) { msg_Err( p_access, "error reading config rom directory for node %d\n", i ); continue; } if( ( rom1394_get_node_type( &rom_dir ) == ROM1394_NODE_TYPE_AVC ) && avc1394_check_subunit_type( handle, i, AVC1394_SUBUNIT_TYPE_VCR ) ) { device = i; *port = j; break; } } } Raw1394Close( handle ); } return device;}/* * Handle AVC commands */static raw1394handle_t AVCOpen( access_t *p_access, int port ){ access_sys_t *p_sys = p_access->p_sys; int numcards; struct raw1394_portinfo pinf[ 16 ]; p_sys->p_avc1394 = raw1394_new_handle(); if( !p_sys->p_avc1394 ) return NULL; numcards = raw1394_get_port_info( p_sys->p_avc1394, pinf, 16 ); if( numcards < -1 ) return NULL; if( raw1394_set_port( p_sys->p_avc1394, port ) < 0 ) return NULL; raw1394_set_bus_reset_handler( p_sys->p_avc1394, AVCResetHandler ); return p_sys->p_avc1394;}static void AVCClose( access_t *p_access ){ access_sys_t *p_sys = p_access->p_sys; if( p_sys->p_avc1394 ) { raw1394_destroy_handle( p_sys->p_avc1394 ); p_sys->p_avc1394 = NULL; }}static int AVCResetHandler( raw1394handle_t handle, unsigned int generation ){ raw1394_update_generation( handle, generation ); return 0;}static int AVCPlay( access_t *p_access, int phyID ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "send play command over Digital Video control channel" ); if( !p_sys->p_avc1394 ) return 0; if( phyID >= 0 ) { if( !avc1394_vcr_is_recording( p_sys->p_avc1394, phyID ) && avc1394_vcr_is_playing( p_sys->p_avc1394, phyID ) != AVC1394_VCR_OPERAND_PLAY_FORWARD ) avc1394_vcr_play( p_sys->p_avc1394, phyID ); } return 0;}static int AVCPause( access_t *p_access, int phyID ){ access_sys_t *p_sys = p_access->p_sys; if( !p_sys->p_avc1394 ) return 0; if( phyID >= 0 ) { if( !avc1394_vcr_is_recording( p_sys->p_avc1394, phyID ) && ( avc1394_vcr_is_playing( p_sys->p_avc1394, phyID ) != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE ) ) avc1394_vcr_pause( p_sys->p_avc1394, phyID ); } return 0;}static int AVCStop( access_t *p_access, int phyID ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "closing Digital Video control channel" ); if( !p_sys->p_avc1394 ) return 0; if ( phyID >= 0 ) avc1394_vcr_stop( p_sys->p_avc1394, phyID ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -