diff options
Diffstat (limited to 'xine_frontend_main.c')
| -rw-r--r-- | xine_frontend_main.c | 723 |
1 files changed, 0 insertions, 723 deletions
diff --git a/xine_frontend_main.c b/xine_frontend_main.c deleted file mode 100644 index 17f4df9e..00000000 --- a/xine_frontend_main.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Simple main() routine for stand-alone frontends. - * - * See the main source file 'xineliboutput.c' for copyright information and - * how to reach the author. - * - * $Id: xine_frontend_main.c,v 1.41 2008-05-19 06:54:58 phintuka Exp $ - * - */ - -#include <termios.h> -#include <unistd.h> -#include <syslog.h> -#include <getopt.h> -#include <signal.h> - -#include "tools/vdrdiscovery.h" - - -#if 0 -static void xine_log_cb(void *data, int section) -{ - fprintf(stderr, "xine: log section %d\n",section); -} - -static void print_xine_log(xine_t *xine) -{ - int i, j; - int logs = xine_get_log_section_count(xine); - const char * const * names = xine_get_log_names(xine); - for(i=0; i<logs; i++) { - const char * const * lines = xine_get_log(xine, i); - if(lines[0]) { - printf("\nLOG: %s\n",names[i]); - j=-1; - while(lines[++j] && *lines[++j] ) - printf(" %2d: %s", j, lines[j]); - } - } -} -#endif - -static void list_plugins_type(xine_t *xine, const char *msg, typeof (xine_list_audio_output_plugins) list_func) -{ - static xine_t *tmp_xine = NULL; - if(!xine) { - if(!tmp_xine) - xine_init(tmp_xine = xine_new()); - xine = tmp_xine; - } - const char *const *list = list_func(xine); - - printf("%s", msg); - while(list && *list) - printf(" %s", *list++); - printf("\n"); -} - -static void list_plugins(xine_t *xine, int verbose) -{ - list_plugins_type (xine, "Available video drivers:", xine_list_video_output_plugins); - list_plugins_type (xine, "Available audio drivers:", xine_list_audio_output_plugins); - if(verbose) { - list_plugins_type (xine, "Available post plugins: ", xine_list_post_plugins); - list_plugins_type (xine, "Available input plugins:", xine_list_input_plugins); - list_plugins_type (xine, "Available demux plugins:", xine_list_demuxer_plugins); - list_plugins_type (xine, "Available audio decoder plugins:", xine_list_audio_decoder_plugins); - list_plugins_type (xine, "Available video decoder plugins:", xine_list_video_decoder_plugins); - list_plugins_type (xine, "Available SPU decoder plugins: ", xine_list_spu_plugins); - } -} - -/* static data */ -pthread_t kbd_thread; -struct termios tm, saved_tm; -volatile int terminate_key_pressed = 0; - -/* include LIRC forwarding code */ -#include "xine_frontend_lirc.c" - -static int read_key(void) -{ - unsigned char ch; - int err; - struct pollfd pfd; - pfd.fd = STDIN_FILENO; - pfd.events = POLLIN; - - errno = 0; - if(1 == (err=poll(&pfd, 1, 50))) { - - if (1 == (err = read(STDIN_FILENO, &ch, 1))) - return (int)ch; - - if (err < 0) - LOGERR("read_key: read(stdin) failed"); - else - LOGERR("read_key: read(stdin) failed: no stdin"); - return -2; - - } else if(err < 0 && errno != EINTR) { - LOGERR("read_key: poll(stdin) failed"); - return -2; - } - - return -1; -} - -static uint64_t read_key_seq(void) -{ - /* from vdr, remote.c */ - uint64_t k = 0; - int key1; - - if ((key1 = read_key()) >= 0) { - k = key1; - if (key1 == 0x1B) { - // Start of escape sequence - if ((key1 = read_key()) >= 0) { - k <<= 8; - k |= key1 & 0xFF; - switch (key1) { - case 0x4F: // 3-byte sequence - if ((key1 = read_key()) >= 0) { - k <<= 8; - k |= key1 & 0xFF; - } - break; - case 0x5B: // 3- or more-byte sequence - if ((key1 = read_key()) >= 0) { - k <<= 8; - k |= key1 & 0xFF; - switch (key1) { - case 0x31 ... 0x3F: // more-byte sequence - case 0x5B: // strange, may apparently occur - do { - if ((key1 = read_key()) < 0) - break; // Sequence ends here - k <<= 8; - k |= key1 & 0xFF; - } while (key1 != 0x7E); - break; - } - } - break; - } - } - } - } - if(key1==-2) - return 0xffff; - return k; -} - -#ifndef IS_FBFE -static void sxfe_toggle_fullscreen(sxfe_t *this); -#endif - -static void *kbd_receiver_thread(void *fe) -{ - uint64_t code = 0; - char str[64]; - - terminate_key_pressed = 0; - - system("setterm -cursor off"); - system("setterm -blank off"); - - /* Set stdin to deliver keypresses without buffering whole lines */ - tcgetattr(STDIN_FILENO, &saved_tm); - if (tcgetattr(STDIN_FILENO, &tm) == 0) { - tm.c_iflag = 0; - tm.c_lflag &= ~(ICANON | ECHO); - tm.c_cc[VMIN] = 0; - tm.c_cc[VTIME] = 0; - tcsetattr(STDIN_FILENO, TCSANOW, &tm); - } - - do { - alarm(0); - errno = 0; - code = read_key_seq(); - alarm(3); /* watchdog */ - if(code == 0) - continue; - if(code == 27) { - terminate_key_pressed = 1; - break; - } -#if defined(XINELIBOUTPUT_FE_TOGGLE_FULLSCREEN) || defined(INTERPRET_LIRC_KEYS) -# ifndef IS_FBFE - if(code == 'f' || code == 'F') { - sxfe_toggle_fullscreen((sxfe_t*)fe); - continue; - } else -# endif - if(code == 'd' || code == 'D') { - fe_t *this = (fe_t*)fe; - xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, - xine_get_param(this->stream, XINE_PARAM_VO_DEINTERLACE) ? 0 : 1); - continue; - } else -#endif - if(code == 0xffff) - break; - - snprintf(str, sizeof(str), "%016" PRIX64, code); - if(find_input((fe_t*)fe)) - process_xine_keypress(((fe_t*)fe)->input, "KBD", str, 0, 0); - - } while(!terminate_key_pressed && code != 0xffff); - - alarm(0); - LOGDBG("Keyboard thread terminated"); - tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm); - system("setterm -cursor on"); - - pthread_exit(NULL); - return NULL; /* never reached */ -} - -static void *slave_receiver_thread(void *fe) -{ - char str[128], *pt; - - terminate_key_pressed = 0; - tcgetattr(STDIN_FILENO, &saved_tm); - - do { - - errno = 0; - str[0] = 0; - - if(!fgets(str, sizeof(str), stdin)) - break; - - if(NULL != (pt = strchr(str, '\r'))) - *pt = 0; - if(NULL != (pt = strchr(str, '\n'))) - *pt = 0; - - if(!strncasecmp(str, "QUIT", 4)) { - break; - -#ifndef IS_FBFE - } else if(!strncasecmp(str, "FULLSCREEN", 10)) { - sxfe_toggle_fullscreen((sxfe_t*)fe); -#endif - - } else if(!strncasecmp(str, "DEINTERLACE ", 12)) { - fe_t *this = (fe_t*)fe; - int val = atoi(str+12); - xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, val ? 1 : 0); - - } else if(!strncasecmp(str, "HITK ", 5)) { - if(find_input((fe_t*)fe)) - process_xine_keypress(((fe_t*)fe)->input, NULL, str+5, 0, 0); - - } else { - LOGMSG("Unknown slave mode command: %s", str); - } - - } while(!terminate_key_pressed); - - LOGDBG("Slave mode receiver terminated"); - tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm); - terminate_key_pressed = 1; - - pthread_exit(NULL); - return NULL; /* never reached */ -} - -static void kbd_stop(void) -{ - void *p; - - pthread_cancel (kbd_thread); - pthread_join (kbd_thread, &p); - - tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm); - system("setterm -cursor on"); -} - -static void SignalHandler(int signum) -{ - if (signum != SIGPIPE) - terminate_key_pressed = 1; - - signal(signum, SignalHandler); -} - -static char *strcatrealloc(char *dest, const char *src) -{ - size_t l; - - if (!src || !*src) - return dest; - - l = (dest ? strlen(dest) : 0) + strlen(src) + 1; - if(dest) { - dest = (char *)realloc(dest, l); - strcat(dest, src); - } else { - dest = (char*)malloc(l); - strcpy(dest, src); - } - return dest; -} - -static const char help_str[] = -"When server address is not given, server is searched from local network.\n" -"If server is not found, localhost (127.0.0.1) is used as default.\n\n" - " --help Show (this) help message\n" - " --audio=audiodriver[:device] Select audio driver and optional port\n" - " --video=videodriver[:device] Select video driver and optional port\n" -#ifndef IS_FBFE - " --display=displayaddress X11 display address\n" - " --wid=id Use existing X11 window\n" -#endif - " --aspect=[auto|4:3|16:9|16:10|default]\n" - " Display aspect ratio\n" - " Use script to control HW aspect ratio:\n" - " --aspect=auto:path_to_script\n" - " --fullscreen Fullscreen mode\n" - " --hud Head Up Display OSD mode\n" - " --width=x Video window width\n" - " --height=x Video window height\n" - " --noscaling Disable all video scaling\n" - " --post=name[:arg=val[,arg=val]] Load and use xine post plugin(s)\n" - " examples:\n" - " --post=upmix\n" - " --post=upmix;tvtime:enabled=1,cheap_mode=1\n" - " --lirc[=devicename] Use lirc input device\n" - " Optional lirc socket name can be given\n" - " --verbose Verbose debug output\n" - " --silent Silent mode (report only errors)\n" - " --syslog Write all output to system log\n" - " --nokbd Disable keyboard input\n" - " --daemon Run as daemon (disable keyboard,\n" - " log to syslog and fork to background)\n" - " --slave Enable slave mode (read commands from stdin)\r\n" - " --reconnect Automatically reconnect when connection has been lost" - " --tcp Use TCP transport\n" - " --udp Use UDP transport\n" - " --rtp Use RTP transport\n\n" - " If no transport options are given, transports\n" - " are tried in following order:\n" - " local pipe, rtp, udp, tcp\n\n"; - -static const char short_options[] = "HL:A:V:d:a:fDw:h:P:vslkbtur"; - -static const struct option long_options[] = { - { "help", no_argument, NULL, 'H' }, - { "audio", required_argument, NULL, 'A' }, - { "video", required_argument, NULL, 'V' }, - { "display", required_argument, NULL, 'd' }, - { "wid", required_argument, NULL, 'W' }, - { "aspect", required_argument, NULL, 'a' }, - { "fullscreen", no_argument, NULL, 'f' }, - { "hud", no_argument, NULL, 'D' }, - { "width", required_argument, NULL, 'w' }, - { "height", required_argument, NULL, 'h' }, - { "noscaling", no_argument, NULL, 'n' }, - { "post", required_argument, NULL, 'P' }, - { "lirc", optional_argument, NULL, 'L' }, - - { "verbose", no_argument, NULL, 'v' }, - { "silent", no_argument, NULL, 's' }, - { "syslog", no_argument, NULL, 'l' }, - { "nokbd", no_argument, NULL, 'k' }, - { "daemon", no_argument, NULL, 'b' }, - { "slave", no_argument, NULL, 'S' }, - - { "reconnect", no_argument, NULL, 'R' }, - { "tcp", no_argument, NULL, 't' }, - { "udp", no_argument, NULL, 'u' }, - { "rtp", no_argument, NULL, 'r' }, - { NULL } -}; - -#define PRINTF(x...) do { if(SysLogLevel>1) printf(x); } while(0) - -int main(int argc, char *argv[]) -{ - char *mrl = NULL, *gdrv = NULL, *adrv = NULL, *adev = NULL; - int ftcp = 0, fudp = 0, frtp = 0, reconnect = 0, firsttry = 1; - int fullscreen = 0, hud = 0, width = 720, height = 576; - int scale_video = 1, aspect = 1; - int daemon_mode = 0, nokbd = 0, slave_mode = 0; - char *video_port = NULL; -#ifndef IS_FBFE - int window_id = -1; -#endif - int xmajor, xminor, xsub; - int err, c; - frontend_t *fe = NULL; - extern const fe_creator_f fe_creator; - char *static_post_plugins = NULL; - char *lirc_dev = NULL; - char *aspect_controller = NULL; - int repeat_emu = 0; - char *exec_name = argv[0]; - - if(strrchr(argv[0],'/')) - exec_name = strrchr(argv[0],'/')+1; - - xine_get_version(&xmajor, &xminor, &xsub); - printf("%s %s (build with xine-lib %d.%d.%d, using xine-lib %d.%d.%d)\n\n", - exec_name, - FE_VERSION_STR, - XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION, - xmajor, xminor, xsub); - - /* Parse arguments */ - while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { - switch (c) { - default: - case 'H': printf("\nUsage: %s [options] [xvdr[+udp|+tcp|+rtp]:[//host[:port]]] \n" - "\nAvailable options:\n", exec_name); - printf("%s", help_str); - list_plugins(NULL, verbose_xine_log); - exit(0); - case 'A': adrv = strdup(optarg); - adev = strchr(adrv, ':'); - if(adev) - *(adev++) = 0; - PRINTF("Audio driver: %s\n",adrv); - if(adev) - PRINTF("Audio device: %s\n",adev); - break; - case 'V': gdrv = strdup(optarg); - if(strchr(gdrv, ':')) { - video_port = strchr(gdrv, ':'); - *video_port = 0; - video_port++; - PRINTF("Video port: %s\n",video_port); - } - PRINTF("Video driver: %s\n",gdrv); - break; -#ifndef IS_FBFE - case 'W': window_id = atoi(optarg); - break; - case 'd': video_port = strdup(optarg); - break; -#endif - case 'a': if(!strncmp(optarg, "auto", 4)) - aspect = 0; - if(!strncmp(optarg, "4:3", 3)) - aspect = 2; - if(!strncmp(optarg, "16:9", 4)) - aspect = 3; - if(!strncmp(optarg, "16:10", 5)) - aspect = 4; - if(aspect == 0 && optarg[5] == ':') - aspect_controller = strdup(optarg+5); - PRINTF("Aspect ratio: %s\n", - aspect==0?"Auto":aspect==2?"4:3":aspect==3?"16:9": - aspect==4?"16:10":"Default"); - if(aspect_controller) - PRINTF("Using %s to switch aspect ratio\n", - aspect_controller); - break; - case 'f': fullscreen=1; - PRINTF("Fullscreen mode\n"); - break; - case 'D': hud=1; - PRINTF("HUD OSD mode\n"); - break; - case 'w': width = atoi(optarg); - PRINTF("Width: %d\n", width); - break; - case 'h': height = atoi(optarg); - PRINTF("Height: %d\n", height); - break; - case 'n': scale_video = 0; - PRINTF("Video scaling disabled\n"); - break; - case 'P': if(static_post_plugins) - strcatrealloc(static_post_plugins, ";"); - static_post_plugins = strcatrealloc(static_post_plugins, optarg); - PRINTF("Post plugins: %s\n", static_post_plugins); - break; - case 'L': lirc_dev = optarg ? : strdup("/dev/lircd"); - if(strstr((char*)lirc_dev, ",repeatemu")) { - *strstr((char*)lirc_dev, ",repeatemu") = 0; - repeat_emu = 1; - } - PRINTF("LIRC device: %s%s\n", lirc_dev, - repeat_emu?", emulating key repeat":""); - break; - case 'v': verbose_xine_log = 1; - SysLogLevel = 3; - PRINTF("Verbose mode\n"); - break; - case 's': verbose_xine_log = 0; - SysLogLevel = 1; - PRINTF("Silent mode\n"); - break; - case 'S': slave_mode = 1; - PRINTF("Slave mode\n"); - break; - case 'l': LogToSysLog = 1; - openlog(exec_name, LOG_PID|LOG_CONS, LOG_USER); - break; - case 'k': nokbd = 1; - PRINTF("Keyboard input disabled\n"); - break; - case 'b': nokbd = daemon_mode = 1; - PRINTF("Keyboard input disabled\n"); - break; - case 'R': reconnect = 1; - PRINTF("Automatic reconnection enabled\n"); - break; - case 't': ftcp = 1; - PRINTF("Protocol: TCP\n"); - break; - case 'u': fudp = 1; - PRINTF("Protocol: UDP\n"); - break; - case 'r': frtp = 1; - PRINTF("Protocol: RTP\n"); - break; - case 1: printf("arg 1 (%s)\n", long_options[optind].name); exit(0); - } - } - - if (optind < argc) { - mrl = strdup(argv[optind]); - PRINTF("VDR Server: %s\n", mrl); - while (++optind < argc) - printf("Unknown argument: %s\n", argv[optind]); - } - - PRINTF("\n"); - - /* check xine-lib version */ - if(!xine_check_version(1, 1, 0)) { - fprintf(stderr,"ERROR: xine-lib is too old, require at least " - "xine library version 1.1.0\n"); - return -1; - } - -#if 1 - /* backward compability */ - if(mrl && ( !strncmp(mrl, "xvdr:tcp:", 9) || - !strncmp(mrl, "xvdr:udp:", 9) || - !strncmp(mrl, "xvdr:rtp:", 9) || - !strncmp(mrl, "xvdr:pipe:", 10))) - mrl[5] = '+'; -#endif - - /* If server address not given, try to find server automatically */ - if(!mrl || - !strcmp(mrl, "xvdr:") || - !strcmp(mrl, "xvdr+tcp:") || - !strcmp(mrl, "xvdr+udp:") || - !strcmp(mrl, "xvdr+rtp:") || - !strcmp(mrl, "xvdr+pipe:")) { - char address[1024] = ""; - int port = -1; - PRINTF("VDR server not given, searching ...\n"); - if(udp_discovery_find_server(&port, &address[0])) { - PRINTF("Found VDR server: host %s, port %d\n", address, port); - if(mrl) { - char *tmp = mrl; - mrl = NULL; - asprintf(&mrl, "%s//%s:%d", tmp, address, port); - free(tmp); - } else - asprintf(&mrl, "xvdr://%s:%d", address, port); - } else { - PRINTF("---------------------------------------------------------------\n" - "WARNING: MRL not given and server not found from local network.\n" - " Trying to connect to default port on local host.\n" - "---------------------------------------------------------------\n"); - mrl = strdup("xvdr://127.0.0.1"); - } - } - - if(mrl && strncmp(mrl, "xvdr:", 5) && strncmp(mrl, "xvdr+", 5)) { - char *mrl2 = mrl; - PRINTF("WARNING: MRL does not start with \'xvdr:\' (%s)", mrl); - asprintf(&mrl, "xvdr://%s", mrl); - free(mrl2); - } - - { - char *tmp = NULL, *mrl2 = mrl; - if(frtp && !strstr(mrl, "rtp:")) - tmp = strdup("xvdr+rtp:"); - else if(fudp && !strstr(mrl, "udp:")) - tmp = strdup("xvdr+udp:"); - else if(ftcp && !strstr(mrl, "tcp:")) - tmp = strdup("xvdr+tcp:"); - if(tmp) { - mrl = strcatrealloc(tmp, strchr(mrl, '/')); - free(mrl2); - } - } - - if(daemon_mode) { - PRINTF("Entering daemon mode\n\n"); - if (daemon(1, 0) == -1) { - fprintf(stderr, "%s: %m\n", exec_name); - LOGERR("daemon() failed"); - return -2; - } - } - - /* Create front-end */ - fe = (*fe_creator)(); - if(!fe) { - fprintf(stderr, "Error initializing frontend\n"); - return -3; - } -#ifndef IS_FBFE - ((fe_t*)fe)->window_id = window_id; -#endif - ((fe_t*)fe)->aspect_controller = aspect_controller; - - /* Initialize display */ - if(!fe->fe_display_open(fe, width, height, fullscreen, hud, 0, - "", aspect, NULL, video_port, scale_video, 0)) { - fprintf(stderr, "Error opening display\n"); - fe->fe_free(fe); - return -4; - } - - /* Initialize xine */ - if(!fe->xine_init(fe, adrv, adev, gdrv, 250, static_post_plugins)) { - fprintf(stderr, "Error initializing xine\n"); - fe->fe_free(fe); - list_plugins(NULL, verbose_xine_log); - return -5; - } - if(SysLogLevel>2) - list_plugins(((fe_t*)fe)->xine, verbose_xine_log); - - /* signal handlers */ - - if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN); - if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN); - if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN); - if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN); - - /* Start LIRC forwarding */ - lirc_start((fe_t*)fe, lirc_dev, repeat_emu); - - PRINTF("\n\nPress Esc to exit\n\n"); - - /* Start keyboard listener thread */ - if(!nokbd) { - if ((err = pthread_create (&kbd_thread, - NULL, - slave_mode ? slave_receiver_thread : kbd_receiver_thread, - (void*)fe)) != 0) { - fprintf(stderr, "Can't create new thread for keyboard (%s)\n", - strerror(err)); - } - sleep(1); - } - - do { - - if(!firsttry) { - PRINTF("Connection to server lost. Reconnecting after two seconds...\n"); - sleep(2); - PRINTF("Reconnecting...\n"); - } - - /* Connect to VDR xineliboutput server */ - if(!fe_xine_open(fe, mrl)) { - /*print_xine_log(((fe_t *)fe)->xine);*/ - if(!firsttry) { - PRINTF("Error opening %s\n", mrl); - continue; - } - fprintf(stderr, "Error opening %s\n", mrl); - lirc_stop(); - if(!nokbd) kbd_stop(); - fe->fe_free(fe); - return -6; - } - - if(!fe->xine_play(fe)) { - /*print_xine_log(((fe_t *)fe)->xine);*/ - /*printf("Error playing %s//%s:%s\n", argv[1], host, port);*/ - if(!firsttry) { - PRINTF("Error playing %s\n", argv[1]); - continue; - } - fprintf(stderr, "Error playing %s\n", argv[1]); - lirc_stop(); - if(!nokbd) kbd_stop(); - fe->fe_free(fe); - return -7; - } - - /* Main loop */ - - sleep(2); /* give input_vdr some time to establish connection */ - - fflush(stdout); - fflush(stderr); - - while(fe->fe_run(fe) && !fe->xine_is_finished(fe,0) && !terminate_key_pressed) - ; - - fe->xine_close(fe); - firsttry = 0; - - } while(!terminate_key_pressed && reconnect); - - /* Clean up */ - - PRINTF("Terminating...\n"); - - lirc_stop(); - if(!nokbd) kbd_stop(); - - fe->fe_free(fe); - return terminate_key_pressed ? 0 : 1; -} |
