eXine() { /* this should be done once. */ if(!xine_check_version(1, 1, 0)) { int major, minor, sub; xine_get_version (&major, &minor, &sub); eWarning("Require xine library version 1.1.0, found %d.%d.%d.\n", major, minor,sub); return; } else { int major, minor, sub; eDebug("Built with xine library %d.%d.%d (%s)\n", XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION, XINE_VERSION); xine_get_version (&major, &minor, &sub); eDebug("Found xine library version: %d.%d.%d (%s).\n", major, minor, sub, xine_get_version_string()); } xine = xine_new(); xine_engine_set_param(xine, XINE_ENGINE_PARAM_VERBOSITY, 1); xine_init(xine); }
int main(int argc, char *argv[]) { int ftcp = 0, fudp = 0, frtp = 0, reconnect = 0, firsttry = 1; int fullscreen = 0, hud = 0, opengl = 0, xpos = 0, ypos = 0, width = 720, height = 576; int pes_buffers = 250; int scale_video = 1, aspect = 1, modeswitch = 0; int daemon_mode = 0, nokbd = 0, noxkbd = 0, slave_mode = 0; int repeat_emu = 0; int touchscreen = 0; int window_id = WINDOW_ID_NONE; int xmajor, xminor, xsub; int c; int xine_finished = FE_XINE_ERROR; int inactivity_timer = 0; char *mrl = NULL; char *video_driver = NULL; char *audio_driver = NULL; char *static_post_plugins = NULL; char *lirc_dev = NULL; int cec_hdmi_port = 0, cec_dev_type = 0; char *p; const char *audio_device = NULL; const char *video_port = NULL; const char *aspect_controller = NULL; const char *tty = NULL; const char *exec_name = argv[0]; const char *config_file = NULL; const char *power_off_cmd = NULL; extern const fe_creator_f fe_creator; frontend_t *fe = NULL; LogToSysLog = 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] [" MRL_ID "[+udp|+tcp|+rtp]:[//host[:port]]] \n" "\nAvailable options:\n", exec_name); printf("%s", help_str); list_xine_plugins(NULL, SysLogLevel>2); exit(0); case 'A': audio_driver = strdup(optarg); if (NULL != (p = strchr(audio_driver, ':'))) { *p = 0; audio_device = p + 1; } PRINTF("Audio driver: %s\n", audio_driver); if (audio_device) PRINTF("Audio device: %s\n", audio_device); break; case 'V': video_driver = strdup(optarg); if (NULL != (p = strchr(video_driver, ':'))) { *p = 0; video_port = p + 1; } PRINTF("Video driver: %s\n", video_driver); if (video_port) PRINTF("Video port: %s\n", video_port); break; #ifndef IS_FBFE case 'W': if (!strcmp(optarg, "root")) window_id = WINDOW_ID_ROOT; else window_id = atoi(optarg); break; case 'm': modeswitch = 1; #ifdef HAVE_XRANDR PRINTF("Video mode switching enabled\n"); #else PRINTF("Video mode switching not supported\n"); #endif break; case 'd': video_port = optarg; break; case 'x': noxkbd = 1; 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[4] == ':') aspect_controller = 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; #ifndef IS_FBFE case 'f': fullscreen=1; PRINTF("Fullscreen mode\n"); break; case 'D': # ifdef HAVE_XRENDER hud = HUD_COMPOSITE; PRINTF("HUD OSD mode\n"); # else EXIT("HUD OSD not supported\n"); # endif if (optarg && strstr(optarg, "opengl")) { # ifdef HAVE_OPENGL hud |= HUD_OPENGL; PRINTF("OpenGL HUD OSD mode\n"); break; # else EXIT("OpenGL HUD OSD not supported\n"); # endif } if (optarg && strstr(optarg, "xrender")) { # ifdef HAVE_XCOMPOSITE hud |= HUD_XRENDER; PRINTF("XRender HUD OSD mode\n"); break; # else EXIT("XRender HUD OSD not supported\n"); # endif } if (optarg && strstr(optarg, "xshape")) { # ifdef HAVE_XSHAPE hud |= HUD_XSHAPE; PRINTF("XShape HUD OSD mode\n"); # else EXIT("XShape HUD OSD not supported\n"); # endif } break; case 'O': # ifdef HAVE_OPENGL opengl = 1; PRINTF("Using OpenGL to draw video and OSD\n"); # else EXIT("OpenGL not supported\n"); # endif break; case 'w': width = atoi(optarg); PRINTF("Width: %d\n", width); break; case 'g': sscanf (optarg, "%dx%d+%d+%d", &width, &height, &xpos, &ypos); PRINTF("Geometry: %dx%d+%d+%d\n", width, height, xpos, ypos); break; case 'h': height = atoi(optarg); PRINTF("Height: %d\n", height); break; #endif // !IS_FBFE case 'B': pes_buffers = atoi(optarg); PRINTF("Buffers: %d\n", pes_buffers); break; case 'T': tty = optarg; if (access(tty, R_OK | W_OK) < 0) { EXIT("Can't access terminal: %s\n", tty); } PRINTF("Terminal: %s\n", tty); break; case 'n': scale_video = 0; PRINTF("Video scaling disabled\n"); break; case 'p': inactivity_timer = atoi(optarg); power_off_cmd = strchr(optarg, ':'); power_off_cmd = power_off_cmd ? power_off_cmd+1 : "/sbin/shutdown"; PRINTF("Shutdown after %d minutes of inactivity using %s\n", inactivity_timer, power_off_cmd); 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 'C': config_file = optarg; PRINTF("Config file: %s\n", config_file); break; case 'L': lirc_dev = strdup(optarg ? : "/dev/lircd"); if (strstr(lirc_dev, ",repeatemu")) { *strstr(lirc_dev, ",repeatemu") = 0; repeat_emu = 1; } PRINTF("LIRC device: %s%s\n", lirc_dev, repeat_emu?", emulating key repeat":""); break; case 'E': cec_hdmi_port = -1; break; case 'e': cec_hdmi_port = 0; #ifdef HAVE_LIBCEC if (optarg) sscanf(optarg, "%d,%d", &cec_hdmi_port, &cec_dev_type); PRINTF("HDMI-CEC enabled. Connected to HDMI port %d (type %d)\n", cec_hdmi_port, cec_dev_type); #else EXIT("HDMI-CEC support not compiled in\n"); #endif break; case 'v': SysLogLevel = (SysLogLevel<SYSLOGLEVEL_DEBUG) ? SYSLOGLEVEL_DEBUG : SysLogLevel+1; PRINTF("Verbose mode\n"); break; case 's': 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 'o': gui_hotkeys = 1; PRINTF("GUI hotkeys enabled\n" " mapping keyboard f,F -> fullscreen toggle\n" " keyboard d,D -> deinterlace toggle\n" " keyboard p,P -> power off\n" " LIRC Deinterlace -> deinterlace toggle\n" " LIRC Fullscreen -> fullscreen toggle\n" " LIRC PowerOff -> power off\n" " LIRC Quit -> exit\n"); break; case 'U': touchscreen = 1; PRINTF("Touchscreen input enabled\n"); PRINTF("Display is divided to 4x3 buttons:\n"); PRINTF(" Menu Up Back Ok \n"); PRINTF(" Left Down Right \n"); PRINTF(" Red Green Yellow Blue\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"); if (tty) { /* claim new controlling terminal */ stdin = freopen(tty, "r", stdin); stdout = freopen(tty, "w", stdout); stderr = freopen(tty, "w", stderr); } #if 1 /* backward compability */ if (mrl && ( !strncmp(mrl, MRL_ID ":tcp:", MRL_ID_LEN+5) || !strncmp(mrl, MRL_ID ":udp:", MRL_ID_LEN+5) || !strncmp(mrl, MRL_ID ":rtp:", MRL_ID_LEN+5) || !strncmp(mrl, MRL_ID ":pipe:", MRL_ID_LEN+6))) mrl[4] = '+'; #endif /* If server address not given, try to find server automatically */ if (!mrl || !strcmp(mrl, MRL_ID ":") || !strcmp(mrl, MRL_ID "+tcp:") || !strcmp(mrl, MRL_ID "+udp:") || !strcmp(mrl, MRL_ID "+rtp:") || !strcmp(mrl, MRL_ID "+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; if (asprintf(&mrl, "%s//%s:%d", tmp, address, port) < 0) return -1; free(tmp); } else if (asprintf(&mrl, MRL_ID "://%s:%d", address, port) < 0) return -1; } 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(MRL_ID "://127.0.0.1"); } } if (mrl && strncmp(mrl, MRL_ID ":", MRL_ID_LEN+1) && strncmp(mrl, MRL_ID "+", MRL_ID_LEN+1)) { char *mrl2 = mrl; PRINTF("WARNING: MRL does not start with \'" MRL_ID ":\' (%s)\n", mrl); if (asprintf(&mrl, MRL_ID "://%s", mrl) < 0) return -1; free(mrl2); } { char *tmp = NULL, *mrl2 = mrl; if (frtp && !strstr(mrl, "rtp:")) tmp = strdup(MRL_ID "+rtp:"); else if (fudp && !strstr(mrl, "udp:")) tmp = strdup(MRL_ID "+udp:"); else if (ftcp && !strstr(mrl, "tcp:")) tmp = strdup(MRL_ID "+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; } /* Initialize display */ if (!fe->fe_display_open(fe, xpos, ypos, width, height, fullscreen, hud, opengl, modeswitch, "", aspect, noxkbd, gui_hotkeys, touchscreen, video_port, scale_video, aspect_controller, window_id)) { fprintf(stderr, "Error opening display\n"); fe->fe_free(fe); return -4; } /* Initialize xine */ if (!fe->xine_init(fe, audio_driver, audio_device, video_driver, pes_buffers, static_post_plugins, config_file)) { fprintf(stderr, "Error initializing xine\n"); list_xine_plugins(fe, SysLogLevel>2); fe->fe_free(fe); return -5; } if (power_off_cmd) { fe->shutdown_init(fe, power_off_cmd, inactivity_timer * 60); } if (SysLogLevel > 2) list_xine_plugins(fe, SysLogLevel>2); /* 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); 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); fe->fe_free(fe); return -6; } if (!fe->xine_play(fe)) { if (!firsttry) { PRINTF("Error playing %s\n", argv[1]); continue; } fprintf(stderr, "Error playing %s\n", argv[1]); fe->fe_free(fe); return -7; } if (firsttry) { /* Start LIRC forwarding */ lirc_start(fe, lirc_dev, repeat_emu); cec_start(fe, cec_hdmi_port, cec_dev_type); /* Start keyboard listener thread */ if (!nokbd) { PRINTF("\n\nPress Esc to exit\n\n"); kbd_start(fe, slave_mode); } } /* Main loop */ fflush(stdout); fflush(stderr); while (!last_signal && fe->fe_run(fe)) ; xine_finished = fe->xine_is_finished(fe,0); fe->xine_close(fe); firsttry = 0; /* HUP reconnects */ if (last_signal == SIGHUP) last_signal = 0; } while (!last_signal && xine_finished != FE_XINE_EXIT && reconnect); /* Clean up */ PRINTF("Terminating...\n"); fe->send_event(fe, "QUIT"); /* stop input threads */ lirc_stop(); cec_stop(); if (!nokbd) kbd_stop(); fe->fe_free(fe); free(static_post_plugins); free(mrl); free(audio_driver); free(video_driver); free(lirc_dev); return xine_finished==FE_XINE_EXIT ? 0 : 1; }