📄 dv.c
字号:
/***************************************************************************** * dv.c: Digital video/Firewire input (file: access plug-in) ***************************************************************************** * Copyright (C) 2005 M2X * $Id: 570ec5ed76a223eb818d7d5b96aee3d1ad8a50ab $ * * Authors: Jean-Paul Saman <jpsaman at m2x dot nl> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_access.h>#include <errno.h>#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SYS_TIME_H# include <sys/time.h>#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#elif defined( WIN32 ) && !defined( UNDER_CE )# include <io.h>#endif#include <sys/poll.h>#include <libraw1394/raw1394.h>#include <libraw1394/csr.h>#include <libavc1394/avc1394.h>#include <libavc1394/avc1394_vcr.h>#include <libavc1394/rom1394.h>/***************************************************************************** * Module descriptor *****************************************************************************/static int Open ( vlc_object_t * );static void Close( vlc_object_t * );static block_t *Block( access_t * );static int Control( access_t *, int, va_list );#define CACHING_TEXT N_("Caching value in ms")#define CACHING_LONGTEXT N_( \ "Caching value for DV streams. This" \ "value should be set in milliseconds." )vlc_module_begin(); set_description( N_("Digital Video (Firewire/ieee1394) input") ); set_shortname( N_("dv") ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_ACCESS ); add_integer( "dv-caching", 60000 / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, true ); set_capability( "access", 0 ); add_shortcut( "dv" ); add_shortcut( "dv1394" ); add_shortcut( "raw1394" ); set_callbacks( Open, Close );vlc_module_end();typedef struct{ VLC_COMMON_MEMBERS access_t *p_access; vlc_mutex_t lock; block_t *p_frame; block_t **pp_last;} event_thread_t;static void* Raw1394EventThread( vlc_object_t * );static int Raw1394Handler( raw1394handle_t, int, size_t, quadlet_t * );static int Raw1394GetNumPorts( access_t *p_access );static raw1394handle_t Raw1394Open( access_t *, int );static void Raw1394Close( raw1394handle_t );static int DiscoverAVC( access_t *, int *, uint64_t );static raw1394handle_t AVCOpen( access_t *, int );static void AVCClose( access_t * );static int AVCResetHandler( raw1394handle_t, unsigned int );static int AVCPlay( access_t *, int );static int AVCPause( access_t *, int );static int AVCStop( access_t *, int );struct access_sys_t{ raw1394handle_t p_avc1394; raw1394handle_t p_raw1394; struct pollfd raw1394_poll; int i_cards; int i_node; int i_port; int i_channel; uint64_t i_guid; /* event */ event_thread_t *p_ev; vlc_mutex_t lock; block_t *p_frame;};/***************************************************************************** * Open: open the file *****************************************************************************/static int Open( vlc_object_t *p_this ){ access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; char *psz_name = strdup( p_access->psz_path ); struct raw1394_portinfo port_inf[ 16 ]; iso_handler_t oldhandler; msg_Dbg( p_access, "opening device %s", psz_name ); /* Set up p_access */ access_InitFields( p_access ); ACCESS_SET_CALLBACKS( NULL, Block, Control, NULL ); p_access->info.b_prebuffered = false; p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) ); if( !p_sys ) { free( psz_name ); return VLC_EGENERIC; } p_sys->i_cards = 0; p_sys->i_node = 0; p_sys->i_port = 0; p_sys->i_guid = 0; p_sys->i_channel = 63; p_sys->p_raw1394 = NULL; p_sys->p_avc1394 = NULL; p_sys->p_frame = NULL; p_sys->p_ev = NULL; vlc_mutex_init( &p_sys->lock ); p_sys->i_node = DiscoverAVC( p_access, &p_sys->i_port, p_sys->i_guid ); if( p_sys->i_node < 0 ) { msg_Err( p_access, "failed to open a Firewire (IEEE1394) connection" ); Close( p_this ); free( psz_name ); return VLC_EGENERIC; } p_sys->p_avc1394 = AVCOpen( p_access, p_sys->i_port ); if( !p_sys->p_avc1394 ) { msg_Err( p_access, "no Digital Video Control device found on %s", psz_name ); Close( p_this ); free( psz_name ); return VLC_EGENERIC; } p_sys->p_raw1394 = raw1394_new_handle(); if( !p_sys->p_raw1394 ) { msg_Err( p_access, "no Digital Video device found on %s", psz_name ); Close( p_this ); free( psz_name ); return VLC_EGENERIC; } p_sys->i_cards = raw1394_get_port_info( p_sys->p_raw1394, port_inf, 16 ); if( p_sys->i_cards < 0 ) { msg_Err( p_access, "failed to get port info for %s", psz_name ); Close( p_this ); free( psz_name ); return VLC_EGENERIC; } if( raw1394_set_port( p_sys->p_raw1394, p_sys->i_port ) < 0 ) { msg_Err( p_access, "failed to set port info for %s", psz_name ); Close( p_this ); free( psz_name ); return VLC_EGENERIC; } oldhandler = raw1394_set_iso_handler( p_sys->p_raw1394, p_sys->i_channel, Raw1394Handler ); raw1394_set_userdata( p_sys->p_raw1394, p_access ); raw1394_start_iso_rcv( p_sys->p_raw1394, p_sys->i_channel ); p_sys->raw1394_poll.fd = raw1394_get_fd( p_sys->p_raw1394 ); p_sys->raw1394_poll.events = POLLIN | POLLPRI; /* Update default_pts to a suitable value for udp access */ var_Create( p_access, "dv-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); /* Now create our event thread catcher */ p_sys->p_ev = vlc_object_create( p_access, sizeof( event_thread_t ) ); if( !p_sys->p_ev ) { msg_Err( p_access, "failed to create event thread for %s", psz_name ); Close( p_this ); free( psz_name ); return VLC_EGENERIC; } p_sys->p_ev->p_frame = NULL; p_sys->p_ev->pp_last = &p_sys->p_ev->p_frame; p_sys->p_ev->p_access = p_access; vlc_mutex_init( &p_sys->p_ev->lock ); vlc_thread_create( p_sys->p_ev, "dv event thread handler", Raw1394EventThread, VLC_THREAD_PRIORITY_OUTPUT, false ); free( psz_name ); return VLC_SUCCESS;}/***************************************************************************** * Close: free unused data structures *****************************************************************************/static void Close( vlc_object_t *p_this ){ access_t *p_access = (access_t*)p_this; access_sys_t *p_sys = p_access->p_sys; if( p_sys->p_ev ) { /* stop the event handler */ vlc_object_kill( p_sys->p_ev ); if( p_sys->p_raw1394 ) raw1394_stop_iso_rcv( p_sys->p_raw1394, p_sys->i_channel ); vlc_mutex_destroy( &p_sys->p_ev->lock ); vlc_thread_join( p_sys->p_ev ); /* Cleanup frame data */ if( p_sys->p_ev->p_frame ) { vlc_mutex_lock( &p_sys->p_ev->lock ); block_ChainRelease( p_sys->p_ev->p_frame ); p_sys->p_ev->p_frame = NULL; p_sys->p_ev->pp_last = &p_sys->p_frame; vlc_mutex_unlock( &p_sys->p_ev->lock ); } vlc_object_release( p_sys->p_ev ); } if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame ); if( p_sys->p_raw1394 ) raw1394_destroy_handle( p_sys->p_raw1394 ); AVCClose( p_access ); vlc_mutex_destroy( &p_sys->lock ); free( p_sys );}/***************************************************************************** * Control: *****************************************************************************/static int Control( access_t *p_access, int i_query, va_list args ){ access_sys_t *p_sys = p_access->p_sys; bool *pb_bool; int64_t *pi_64; switch( i_query ) { /* */ case ACCESS_CAN_PAUSE: pb_bool = (bool*)va_arg( args, bool* ); *pb_bool = true; break; case ACCESS_CAN_SEEK: case ACCESS_CAN_FASTSEEK: case ACCESS_CAN_CONTROL_PACE: pb_bool = (bool*)va_arg( args, bool* ); *pb_bool = false; break; case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); *pi_64 = var_GetInteger( p_access, "dv-caching" ) * 1000; break; /* */ case ACCESS_SET_PAUSE_STATE: AVCPause( p_access, p_sys->i_node ); break; case ACCESS_GET_TITLE_INFO: case ACCESS_SET_TITLE: case ACCESS_SET_SEEKPOINT: case ACCESS_SET_PRIVATE_ID_STATE: case ACCESS_GET_CONTENT_TYPE: return VLC_EGENERIC; default: msg_Warn( p_access, "unimplemented query in control" ); return VLC_EGENERIC; } return VLC_SUCCESS;}static block_t *Block( access_t *p_access ){ access_sys_t *p_sys = p_access->p_sys; block_t *p_block = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -