📄 interface.c
字号:
/***************************************************************************** * interface.c: interface access for other threads * This library provides basic functions for threads to interact with user * interface, such as command line. ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN * * Authors: * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include "defs.h"#include <errno.h> /* ENOMEM */#include <stdlib.h> /* free(), strtol() */#include <stdio.h> /* FILE */#include <string.h> /* strerror() */#include <sys/types.h> /* on BSD, uio.h needs types.h */#include <sys/uio.h> /* for input.h */#include "config.h"#include "common.h"#include "threads.h"#include "mtime.h"#include "plugins.h"#include "input.h"#include "audio_output.h"#include "intf_msg.h"#include "interface.h"#include "intf_cmd.h"#include "intf_console.h"#include "video.h"#include "video_output.h"#include "main.h"/***************************************************************************** * intf_channel_t: channel description ***************************************************************************** * A 'channel' is a descriptor of an input method. It is used to switch easily * from source to source without having to specify the whole input thread * configuration. The channels array, stored in the interface thread object, is * loaded in intf_Create, and unloaded in intf_Destroy. *****************************************************************************/typedef struct intf_channel_s{ /* Channel description */ int i_channel; /* channel number, -1 for end of array */ char * psz_description; /* channel description (owned) */ /* Input configuration */ int i_input_method; /* input method descriptor */ char * psz_input_source; /* source string (owned) */ int i_input_port; /* port */ int i_input_vlan; /* vlan */} intf_channel_t;/***************************************************************************** * Local prototypes *****************************************************************************/static int LoadChannels ( intf_thread_t *p_intf, char *psz_filename );static void UnloadChannels ( intf_thread_t *p_intf );static int ParseChannel ( intf_channel_t *p_channel, char *psz_str );/***************************************************************************** * intf_Create: prepare interface before main loop ***************************************************************************** * This function opens output devices and creates specific interfaces. It sends * its own error messages. *****************************************************************************/intf_thread_t* intf_Create( void ){ intf_thread_t *p_intf; char * psz_method; /* Allocate structure */ p_intf = malloc( sizeof( intf_thread_t ) ); if( !p_intf ) { intf_ErrMsg("error: %s\n", strerror( ENOMEM ) ); return( NULL ); } /* Request an interface plugin */ psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD ); if( RequestPlugin( &p_intf->intf_plugin, "intf", psz_method ) < 0 ) { intf_ErrMsg( "error: could not open interface plugin intf_%s.so\n", psz_method ); free( p_intf ); return( NULL ); } /* Get plugins */ p_intf->p_sys_create = GetPluginFunction( p_intf->intf_plugin, "intf_SysCreate" ); p_intf->p_sys_manage = GetPluginFunction( p_intf->intf_plugin, "intf_SysManage" ); p_intf->p_sys_destroy = GetPluginFunction( p_intf->intf_plugin, "intf_SysDestroy" ); /* Initialize structure */ p_intf->b_die = 0; p_intf->p_vout = NULL; p_intf->p_input = NULL; /* Load channels - the pointer will be set to NULL on failure. The * return value is ignored since the program can work without * channels */ LoadChannels( p_intf, main_GetPszVariable( INTF_CHANNELS_VAR, INTF_CHANNELS_DEFAULT )); /* Start interfaces */ p_intf->p_console = intf_ConsoleCreate(); if( p_intf->p_console == NULL ) { intf_ErrMsg("error: can't create control console\n"); TrashPlugin( p_intf->intf_plugin ); free( p_intf ); return( NULL ); } if( p_intf->p_sys_create( p_intf ) ) { intf_ErrMsg("error: can't create interface\n"); intf_ConsoleDestroy( p_intf->p_console ); TrashPlugin( p_intf->intf_plugin ); free( p_intf ); return( NULL ); } intf_Msg("Interface initialized\n"); return( p_intf );}/***************************************************************************** * intf_Run ***************************************************************************** * Initialization script and main interface loop. *****************************************************************************/void intf_Run( intf_thread_t *p_intf ){ if( p_intf->p_playlist ) { p_intf->p_input = input_CreateThread( INPUT_METHOD_TS_FILE, (void *)p_intf->p_playlist, p_intf->i_list_index, 0, p_main->p_intf->p_vout, p_main->p_aout, NULL ); } /* Execute the initialization script - if a positive number is returned, * the script could be executed but failed */ else if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 ) { intf_ErrMsg("warning: error(s) during startup script\n"); } /* Main loop */ while(!p_intf->b_die) { /* Flush waiting messages */ intf_FlushMsg(); /* Manage specific interface */ p_intf->p_sys_manage( p_intf ); /* Check attached threads status */ if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error ) { /* FIXME: add aout error detection ?? */ p_intf->b_die = 1; } if( (p_intf->p_input != NULL) && p_intf->p_input->b_error ) { input_DestroyThread( p_intf->p_input, NULL ); p_intf->p_input = NULL; intf_DbgMsg("Input thread destroyed\n"); } /* Sleep to avoid using all CPU - since some interfaces needs to access * keyboard events, a 100ms delay is a good compromise */ msleep( INTF_IDLE_SLEEP ); }}/***************************************************************************** * intf_Destroy: clean interface after main loop ***************************************************************************** * This function destroys specific interfaces and close output devices. *****************************************************************************/void intf_Destroy( intf_thread_t *p_intf ){ /* Destroy interfaces */ p_intf->p_sys_destroy( p_intf ); intf_ConsoleDestroy( p_intf->p_console ); /* Unload channels */ UnloadChannels( p_intf ); /* Close plugin */ TrashPlugin( p_intf->intf_plugin ); /* Free structure */ free( p_intf );}/***************************************************************************** * intf_SelectChannel: change channel ***************************************************************************** * Kill existing input, if any, and try to open a new one, using an input * configuration table. *****************************************************************************/int intf_SelectChannel( intf_thread_t * p_intf, int i_channel ){ intf_channel_t * p_channel; /* channel */ /* Look for channel in array */ if( p_intf->p_channel != NULL ) { for( p_channel = p_intf->p_channel; p_channel->i_channel != -1; p_channel++ ) { if( p_channel->i_channel == i_channel ) { /* * Change channel */ /* Kill existing input, if any */ if( p_intf->p_input != NULL ) { input_DestroyThread( p_intf->p_input, NULL ); } intf_Msg("Channel %d: %s\n", i_channel, p_channel->psz_description ); /* Open a new input */ p_intf->p_input = input_CreateThread( p_channel->i_input_method, p_channel->psz_input_source, p_channel->i_input_port, p_channel->i_input_vlan, p_intf->p_vout, p_main->p_aout, NULL ); return( p_intf->p_input == NULL ); } } } /* Channel does not exist */ intf_Msg("Channel %d does not exist\n", i_channel ); return( 1 );}/***************************************************************************** * intf_ProcessKey: process standard keys ***************************************************************************** * This function will process standard keys and return non 0 if the key was * unknown. *****************************************************************************/int intf_ProcessKey( intf_thread_t *p_intf, int i_key ){ static int i_volbackup; switch( i_key ) { case 'Q': /* quit order */ case 'q': case 27: /* escape key */ case 3: /* ^C */ p_intf->b_die = 1; break; case '0': /* source change */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Change channel - return code is ignored since SelectChannel displays * its own error messages */ intf_SelectChannel( p_intf, i_key - '0' ); break; case '+': /* volume + */ if( (p_main->p_aout != NULL) && (p_main->p_aout->vol < VOLMAX) ) p_main->p_aout->vol += VOLSTEP; break; case '-': /* volume - */ if( (p_main->p_aout != NULL) && (p_main->p_aout->vol > VOLSTEP) ) p_main->p_aout->vol -= VOLSTEP; break; case 'M': /* toggle mute */ case 'm':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -