Example #1
0
int main(int argc, char **argv)
{
	int rc;
	int result = EXIT_FAILURE;
	struct device *upnp_renderer;

	if (!g_thread_supported()) {
		g_thread_init(NULL);
	}

	rc = process_cmdline(argc, argv);
	if (rc != 0) {
		goto out;
	}

	if (show_version) {
		do_show_version();
		exit(EXIT_SUCCESS);
	}
	if (show_connmgr_scpd) {
		upnp_renderer_dump_connmgr_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_control_scpd) {
		upnp_renderer_dump_control_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_transport_scpd) {
		upnp_renderer_dump_transport_scpd();
		exit(EXIT_SUCCESS);
	}

	upnp_renderer = upnp_renderer_new(friendly_name, uuid);
	if (upnp_renderer == NULL) {
		goto out;
	}

	if (show_devicedesc) {
		fputs(upnp_get_device_desc(upnp_renderer), stdout);
		exit(EXIT_SUCCESS);
	}

	rc = output_gstreamer_init();
	if (rc != 0) {
		goto out;
	}

	rc = upnp_device_init(upnp_renderer, ip_address);
	if (rc != 0) {
		goto out;
	}

	printf("Ready for rendering..\n");
	output_loop();
	result = EXIT_SUCCESS;

out:
	return result;
}
Example #2
0
int main(int argc, char **argv)
{
	int rc;
	struct upnp_device_descriptor *upnp_renderer;

	if (!process_cmdline(argc, argv)) {
		return EXIT_FAILURE;
	}

	if (show_version) {
		do_show_version();
		exit(EXIT_SUCCESS);
	}
	if (show_connmgr_scpd) {
		upnp_renderer_dump_connmgr_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_control_scpd) {
		upnp_renderer_dump_control_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_transport_scpd) {
		upnp_renderer_dump_transport_scpd();
		exit(EXIT_SUCCESS);
	}

	if (show_outputs) {
		output_dump_modules();
		exit(EXIT_SUCCESS);
	}

	init_logging(log_file);

	// Now we're going to start threads etc, which means we need
	// to become a daemon before that.

	// We need to open the pid-file now because relative filenames will
	// break if we're becoming a daemon and cwd changes.
	FILE *pid_file_stream = NULL;
	if (pid_file) {
		pid_file_stream = fopen(pid_file, "w");
	}
	if (daemon_mode) {
		daemon(0, 0);  // TODO: check for daemon() in configure.
	}
	if (pid_file_stream) {
		fprintf(pid_file_stream, "%d\n", getpid());
		fclose(pid_file_stream);
	}

#if !GLIB_CHECK_VERSION(2, 32, 0)
	// Only older version of glib require this.
	if (!g_thread_get_initialized()) {
		g_thread_init(NULL);
	}
#endif

	upnp_renderer = upnp_renderer_descriptor(friendly_name, uuid);
	if (upnp_renderer == NULL) {
		return EXIT_FAILURE;
	}

	rc = output_init(output);
	if (rc != 0) {
		Log_error("main",
			  "ERROR: Failed to initialize Output subsystem");
		return EXIT_FAILURE;
	}

	struct upnp_device *device;
	if (listen_port != 0 &&
	    (listen_port < 49152 || listen_port > 65535)) {
		// Somewhere obscure internally in libupnp, they clamp the
		// port to be outside of the IANA range, so at least 49152.
		// Instead of surprising the user by ignoring lower port
		// numbers, complain loudly.
		Log_error("main", "Parameter error: --port needs to be in "
			  "range [49152..65535] (but was set to %d)",
			  listen_port);
		return EXIT_FAILURE;
	}
	device = upnp_device_init(upnp_renderer, ip_address, listen_port);
	if (device == NULL) {
		Log_error("main", "ERROR: Failed to initialize UPnP device");
		return EXIT_FAILURE;
	}

	upnp_transport_init(device);
	upnp_control_init(device);

	if (show_devicedesc) {
		// This can only be run after all services have been
		// initialized.
		char *buf = upnp_create_device_desc(upnp_renderer);
		assert(buf != NULL);
		fputs(buf, stdout);
		exit(EXIT_SUCCESS);
	}

	if (Log_info_enabled()) {
		upnp_transport_register_variable_listener(log_variable_change,
							  (void*) "transport");
		upnp_control_register_variable_listener(log_variable_change,
							(void*) "control");
	}

	// Write both to the log (which might be disabled) and console.
	Log_info("main", "Ready for rendering.");
	fprintf(stderr, "Ready for rendering.\n");

	output_loop();

	// We're here, because the loop exited. Probably due to catching
	// a signal.
	Log_info("main", "Exiting.");
	upnp_device_shutdown(device);

	return EXIT_SUCCESS;
}
Example #3
0
int main(int argc, char **argv)
{
	int rc;
	struct upnp_device_descriptor *upnp_renderer;

#if !GLIB_CHECK_VERSION(2,32,0)
	g_thread_init (NULL);  // Was necessary < glib 2.32, deprecated since.
#endif

	if (!process_cmdline(argc, argv)) {
		return EXIT_FAILURE;
	}

	if (show_version) {
		do_show_version();
		exit(EXIT_SUCCESS);
	}
	if (show_connmgr_scpd) {
		upnp_renderer_dump_connmgr_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_control_scpd) {
		upnp_renderer_dump_control_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_transport_scpd) {
		upnp_renderer_dump_transport_scpd();
		exit(EXIT_SUCCESS);
	}

	if (show_outputs) {
		output_dump_modules();
		exit(EXIT_SUCCESS);
	}

	init_logging(log_file);

	// Now we're going to start threads etc, which means we need
	// to become a daemon before that.

	// We need to open the pid-file now because relative filenames will
	// break if we're becoming a daemon and cwd changes.
	FILE *pid_file_stream = NULL;
	if (pid_file) {
		pid_file_stream = fopen(pid_file, "w");
	}
	if (daemon_mode) {
		daemon(0, 0);  // TODO: check for daemon() in configure.
	}
	if (pid_file_stream) {
		fprintf(pid_file_stream, "%d\n", getpid());
		fclose(pid_file_stream);
	}

	if (show_devicedesc) {
		// This can only be run after all services have been
		// initialized.
		char *buf = upnp_create_device_desc(upnp_renderer);
		assert(buf != NULL);
		fputs(buf, stdout);
		exit(EXIT_SUCCESS);
	}
	struct upnp *upnp = upnp_start(friendly_name, uuid, "1234", ip_address, listen_port, output);
	if (upnp == NULL) {
		Log_error("main", "ERROR: Failed to initialize UPnP device");
		return EXIT_FAILURE;
	}

	// Write both to the log (which might be disabled) and console.
	Log_info("main", "Ready for rendering.");
	fprintf(stderr, "Ready for rendering.\n");

	output_loop();

	// We're here, because the loop exited. Probably due to catching
	// a signal.
	Log_info("main", "Exiting.");
	upnp_stop(upnp);

	return EXIT_SUCCESS;
}
Example #4
0
int main(int argc, char **argv)
{
	int rc;
	int result = EXIT_FAILURE;
	struct device *upnp_renderer;

	rc = process_cmdline(argc, argv);
	if (rc != 0) {
		goto out;
	}

	if (show_version) {
		do_show_version();
		exit(EXIT_SUCCESS);
	}
	if (show_connmgr_scpd) {
		upnp_renderer_dump_connmgr_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_control_scpd) {
		upnp_renderer_dump_control_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_transport_scpd) {
		upnp_renderer_dump_transport_scpd();
		exit(EXIT_SUCCESS);
	}

	if (show_outputs) {
		output_dump_modules();
		exit(EXIT_SUCCESS);
	}

	if (pid_file && pid_file[0] != '/') {
		// We need to canonicalize the filename because our
		// cwd will change after becoming a daemon.
		char *buf = (char*) malloc(PATH_MAX);  // will leak. Ok.
		char *result = getcwd(buf, PATH_MAX);
		result = strcat(result, "/");
		pid_file = strcat(result, pid_file);
	}
	if (daemon_mode) {
		daemon(0, 0);  // TODO: check for daemon() in configure.
	}
	if (pid_file) {
		FILE *p = fopen(pid_file, "w+");
		if (p) {
			fprintf(p, "%d\n", getpid());
			fclose(p);
		} else {
			perror("Failed to write pid file");
		}
	}
	if (!g_thread_get_initialized()) {
		g_thread_init(NULL);
	}

	upnp_renderer = upnp_renderer_new(friendly_name, uuid);
	if (upnp_renderer == NULL) {
		goto out;
	}

	if (show_devicedesc) {
		char *buf;
		buf = upnp_get_device_desc(upnp_renderer);
		assert(buf != NULL);
		fputs(buf, stdout);
		exit(EXIT_SUCCESS);
	}

	rc = output_init(output);
	if (rc != 0) {
		fprintf(stderr,"ERROR: Failed to initialize Output subsystem\n");
		goto out;
	}

	struct device_private *device;
	device = upnp_device_init(upnp_renderer, ip_address);
	if (device == NULL) {
		fprintf(stderr,"ERROR: Failed to initialize UPnP device\n");
		goto out;
	}

	upnp_transport_init(device);
	upnp_control_init();

	printf("Ready for rendering..\n");
	output_loop();
	result = EXIT_SUCCESS;

out:
	return result;
}
Example #5
0
File: main.c Project: thess/UPnPMPD
int main(int argc, char **argv)
{
	int rc, cnt;
	struct device *upnp_renderer;
	char mac_addr[18];
	char eth_name[sizeof(ether_tmpl) + 10];
	char **eth;
	FILE *fh = NULL;

#if defined(__i386__) && defined(DEBUG)
	struct sigaction sigact;

	sigact.sa_sigaction = crit_err_hdlr;
	sigact.sa_flags = SA_RESTART | SA_SIGINFO;

	if (sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL) != 0)
	{
		fprintf(stderr, "error setting signal handler for %d (%s)\n",
			SIGSEGV, strsignal(SIGSEGV));

		exit(EXIT_FAILURE);
	}
#endif
	// Init glib threads
	if (!g_thread_supported())
	{
		g_thread_init(NULL);
	}

	// Parse args early (may set debug-level)
	rc = process_cmdline(argc, argv);
	if (rc != 0)
	{
		exit(EXIT_FAILURE);
	}

	// Some commands are valid only if interactive
	if (!run_as_daemon)
	{
		// Info commenads (non-daemon)
		if (show_version)
		{
			do_show_version();
			return EXIT_SUCCESS;
		}

		if (show_connmgr_scpd)
		{
			upnp_renderer_dump_connmgr_scpd();
			return EXIT_SUCCESS;
		}

		if (show_control_scpd)
		{
			upnp_renderer_dump_control_scpd();
			return EXIT_SUCCESS;
		}

		if (show_transport_scpd)
		{
			upnp_renderer_dump_transport_scpd();
			return EXIT_SUCCESS;
		}
	}
	else
	{
		if (show_version || show_control_scpd || show_connmgr_scpd ||
				show_transport_scpd || show_devicedesc)
		{
			// Info commands not allow in daemon mode
			fprintf(stderr, "Info options incompatible with daemon\n");
			exit(EXIT_FAILURE);
		}

		rc = daemon(0, 0);
		if (rc != 0)
		{
			fprintf(stderr, "Failed to detach process\n");
			exit(EXIT_FAILURE);
		}
	}

	// Read and parse config file, OK if none
	if (config_file == NULL)
		config_file = CFG_FILE_NAME;


	config_init(&upnpmpd_cfg);
	rc = config_read_file(&upnpmpd_cfg, (config_file) ? config_file : CFG_FILE_NAME);
	if (rc != CONFIG_TRUE)
	{
		if (config_error_line(&upnpmpd_cfg) == 0)
		{
			printf("Config not found (%s), continuing...\n", config_file);
		}
		else
		{
			printf ("Error parsing config file: %s\nLine %d: %s", config_file,
				config_error_line(&upnpmpd_cfg), config_error_text(&upnpmpd_cfg));
			exit(EXIT_FAILURE);
		}
	}

	// Use bound interface if given
	if (if_name[0])
		eth = &if_name[0];
	else
		eth = &ethers[0];

	while (*eth)
	{
		sprintf(eth_name, ether_tmpl, *eth);
		// Obtain MAC address from interface
		fh = fopen(eth_name, "r");
		if (fh)
			break;
		// Try next
		eth++;
	}

	// anything?
	if (fh == NULL)
	{
		fprintf(stderr, "No usable network interface found\n");
		exit(EXIT_FAILURE);
	}
	// Read 6 groups of 3 chars
	cnt = fread(mac_addr, 3, 6, fh);
	fclose(fh);

	// Valid looking MAC?
	if (cnt != 6)
	{
		fprintf(stderr, "Bad MAC address %d\n", cnt);
		exit(EXIT_FAILURE);
	}

	mac_addr[17] = '\0';
	DBG_PRINT(DBG_LVL2, "Found MAC at %s: %s\n", eth_name, mac_addr);

	upnp_renderer = upnp_renderer_new(friendly_name, mac_addr, serial, &upnpmpd_cfg);
	if (upnp_renderer == NULL)
		exit(EXIT_FAILURE);

	if (show_devicedesc)
	{
		fputs(upnp_get_device_desc(upnp_renderer), stdout);
		return EXIT_SUCCESS;
	}

	// Connect to MPD
	rc = output_mpd_init(&upnpmpd_cfg);
	if (rc != 0)
		exit(EXIT_FAILURE);

	// Create UPnP device and broadcast
	rc = getIfInfo(if_name[0]);
	if (rc != 0)
		exit(EXIT_FAILURE);

	rc = upnp_device_init(upnp_renderer, gIF_IPV4);
	if (rc != 0)
		exit(EXIT_FAILURE);

	printf("UPnPMPD ready at IP: %s\n", gIF_IPV4);

	// Run main event loop
	// Process glib evnets
	output_loop();

	return EXIT_SUCCESS;
}
static GstFlowReturn collected_pads(GstCollectPads *pads, GstOmxBaseFilter21 *self)
{
    GSList *item;
    GstCollectData *collectdata;
    GstFlowReturn ret = GST_FLOW_OK;
    GOmxCore *gomx = self->gomx;
    gint sink_number;
    GstBuffer *buffers[2];
    gboolean eos = FALSE;

    GST_DEBUG_OBJECT(self, "Collected pads !");

    // Collect buffers
    for( item = pads->data ; item != NULL ; item = item->next ) {
        collectdata = (GstCollectData *) item->data;
        
        //FIXME Use collect data
        if(strcmp(GST_PAD_NAME(collectdata->pad), "sink_00") == 0){
    		sink_number=0;
	    }
	    else{
		    sink_number=1;
	    }
	    
	    buffers[sink_number] = gst_collect_pads_pop(pads, collectdata);
	    
	    if( buffers[sink_number] == NULL ) {
	        eos = TRUE;
	    }
    }

    // Detect EOS
    if( eos == TRUE ) {
        GST_INFO_OBJECT(self, "EOS");
        for( sink_number=0 ; sink_number<2 ; sink_number++ ) {
            if( buffers[sink_number] ) {
                gst_buffer_unref(buffers[sink_number]);
            }
        }
        gst_pad_push_event(self->srcpad, gst_event_new_eos());
        return GST_FLOW_UNEXPECTED;
    }

    // Setup input ports if not done yet
    if (G_LIKELY (gomx->omx_state != OMX_StateExecuting)) {
      for( sink_number=0 ; sink_number<2 ; sink_number++ ) {
        GST_INFO_OBJECT(self, "Setup port %d", sink_number);
        setup_input_buffer (self, buffers[sink_number], sink_number);
      }
    }
    
    // Call chain foreach buffer
    for( sink_number=0 ; sink_number<2 ; sink_number++ ) {
        ret = pad_chain(self->sinkpad[sink_number], buffers[sink_number]);
    }
    
    // Call output_loop after pad_chain
    output_loop(self->srcpad);
    
    return ret;
}