コード例 #1
0
int channelscan_advance(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result)
{
	memset(result, 0, sizeof(struct hdhomerun_channelscan_result_t));

	struct hdhomerun_channel_entry_t *entry = scan->next_channel;
	if (!entry) {
		return 0;
	}

	/* Combine channels with same frequency. */
	result->frequency = hdhomerun_channel_entry_frequency(entry);

	char *ptr = result->channel_str;
	char *end = result->channel_str + sizeof(result->channel_str);
	hdhomerun_sprintf(ptr, end, hdhomerun_channel_entry_name(entry));

	while (1) {
		entry = hdhomerun_channel_list_prev(scan->channel_list, entry);
		if (!entry) {
			scan->next_channel = NULL;
			break;
		}

		if (hdhomerun_channel_entry_frequency(entry) != result->frequency) {
			scan->next_channel = entry;
			break;
		}

		ptr = strchr(ptr, 0);
		hdhomerun_sprintf(ptr, end, ", %s", hdhomerun_channel_entry_name(entry));
	}

	return 1;
}
コード例 #2
0
int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource)
{
	HKEY tuners_key;
	LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Silicondust\\HDHomeRun\\Tuners", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &tuners_key);
	if (ret != ERROR_SUCCESS) {
		hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_load_from_windows_registry: failed to open tuners registry key (%ld)\n", (long)ret);
		return 0;
	}

	int count = 0;
	DWORD index = 0;
	while (1) {
		/* Next tuner device. */
		wchar_t wdevice_str[32];
		DWORD size = sizeof(wdevice_str);
		ret = RegEnumKeyEx(tuners_key, index++, wdevice_str, &size, NULL, NULL, NULL, NULL);
		if (ret != ERROR_SUCCESS) {
			break;
		}

		/* Check device configuation. */
		HKEY device_key;
		ret = RegOpenKeyEx(tuners_key, wdevice_str, 0, KEY_QUERY_VALUE, &device_key);
		if (ret != ERROR_SUCCESS) {
			hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_load_from_windows_registry: failed to open registry key for %S (%ld)\n", wdevice_str, (long)ret);
			continue;
		}

		wchar_t wsource_test[32];
		size = sizeof(wsource_test);
		if (RegQueryValueEx(device_key, L"Source", NULL, NULL, (LPBYTE)&wsource_test, &size) != ERROR_SUCCESS) {
			wsprintf(wsource_test, L"Unknown");
		}

		RegCloseKey(device_key);

		if (_wcsicmp(wsource_test, wsource) != 0) {
			continue;
		}

		/* Create and add device. */
		char device_str[32];
		hdhomerun_sprintf(device_str, device_str + sizeof(device_str), "%S", wdevice_str);
		count += hdhomerun_device_selector_load_from_str(hds, device_str);
	}

	RegCloseKey(tuners_key);
	return count;
}
コード例 #3
0
ファイル: hdhomerun_channels.c プロジェクト: JREkiwi/sagetv
static void hdhomerun_channel_list_build_range(struct hdhomerun_channel_list_t *channel_list, const char *channelmap, const struct hdhomerun_channelmap_range_t *range)
{
	uint16_t channel_number;
	for (channel_number = range->channel_range_start; channel_number <= range->channel_range_end; channel_number++) {
		struct hdhomerun_channel_entry_t *entry = (struct hdhomerun_channel_entry_t *)calloc(1, sizeof(struct hdhomerun_channel_entry_t));
		if (!entry) {
			return;
		}

		entry->channel_number = channel_number;
		entry->frequency = range->frequency + ((uint32_t)(channel_number - range->channel_range_start) * range->spacing);
		entry->frequency = hdhomerun_channel_frequency_round_normal(entry->frequency);
		hdhomerun_sprintf(entry->name, entry->name + sizeof(entry->name), "%s:%u", channelmap, entry->channel_number);

		hdhomerun_channel_list_build_insert(channel_list, entry);
	}
}
コード例 #4
0
static int channelscan_find_lock(struct hdhomerun_channelscan_t *scan, uint32_t frequency, struct hdhomerun_channelscan_result_t *result)
{
	/* Set channel. */
	char channel_str[64];
	hdhomerun_sprintf(channel_str, channel_str + sizeof(channel_str), "auto:%u", (unsigned int)frequency);

	int ret = hdhomerun_device_set_tuner_channel(scan->hd, channel_str);
	if (ret <= 0) {
		return ret;
	}

	/* Wait for lock. */
	ret = hdhomerun_device_wait_for_lock(scan->hd, &result->status);
	if (ret <= 0) {
		return ret;
	}
	if (!result->status.lock_supported) {
		return 1;
	}

	/* Wait for symbol quality = 100%. */
	uint64_t timeout = getcurrenttime() + 5000;
	while (1) {
		ret = hdhomerun_device_get_tuner_status(scan->hd, NULL, &result->status);
		if (ret <= 0) {
			return ret;
		}

		if (result->status.symbol_error_quality == 100) {
			return 1;
		}

		if (getcurrenttime() >= timeout) {
			return 1;
		}

		msleep_approx(250);
	}
}
コード例 #5
0
static int channelscan_detect_programs(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result, bool_t *pchanged, bool_t *pincomplete)
{
	*pchanged = FALSE;
	*pincomplete = FALSE;

	char *streaminfo;
	int ret = hdhomerun_device_get_tuner_streaminfo(scan->hd, &streaminfo);
	if (ret <= 0) {
		return ret;
	}

	char *next_line = streaminfo;
	int program_count = 0;

	while (1) {
		char *line = next_line;

		next_line = strchr(line, '\n');
		if (!next_line) {
			break;
		}
		*next_line++ = 0;

		unsigned int transport_stream_id;
		if (sscanf(line, "tsid=0x%x", &transport_stream_id) == 1) {
			result->transport_stream_id = transport_stream_id;
			result->transport_stream_id_detected = TRUE;
			continue;
		}

		unsigned int original_network_id;
		if (sscanf(line, "onid=0x%x", &original_network_id) == 1) {
			result->original_network_id = original_network_id;
			result->original_network_id_detected = TRUE;
			continue;
		}

		if (program_count >= HDHOMERUN_CHANNELSCAN_MAX_PROGRAM_COUNT) {
			continue;
		}

		struct hdhomerun_channelscan_program_t program;
		memset(&program, 0, sizeof(program));

		hdhomerun_sprintf(program.program_str, program.program_str + sizeof(program.program_str), "%s", line);

		unsigned int program_number;
		unsigned int virtual_major, virtual_minor;
		if (sscanf(line, "%u: %u.%u", &program_number, &virtual_major, &virtual_minor) != 3) {
			if (sscanf(line, "%u: %u", &program_number, &virtual_major) != 2) {
				continue;
			}
			virtual_minor = 0;
		}

		program.program_number = program_number;
		program.virtual_major = virtual_major;
		program.virtual_minor = virtual_minor;

		channelscan_extract_name(&program, line);

		if (strstr(line, "(control)")) {
			program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_CONTROL;
		} else if (strstr(line, "(encrypted)")) {
			program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_ENCRYPTED;
		} else if (strstr(line, "(no data)")) {
			program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_NODATA;
			*pincomplete = TRUE;
		} else {
			program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_NORMAL;
			if ((program.virtual_major == 0) || (program.name[0] == 0)) {
				*pincomplete = TRUE;
			}
		}

		if (memcmp(&result->programs[program_count], &program, sizeof(program)) != 0) {
			memcpy(&result->programs[program_count], &program, sizeof(program));
			*pchanged = TRUE;
		}

		program_count++;
	}

	if (program_count == 0) {
		*pincomplete = TRUE;
	}
	if (result->program_count != program_count) {
		result->program_count = program_count;
		*pchanged = TRUE;
	}

	return 1;
}
コード例 #6
0
void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args)
{
	if (!dbg) {
		return;
	}
	if (!dbg->enabled) {
		return;
	}

	struct hdhomerun_debug_message_t *message = (struct hdhomerun_debug_message_t *)malloc(sizeof(struct hdhomerun_debug_message_t));
	if (!message) {
		return;
	}

	char *ptr = message->buffer;
	char *end = message->buffer + sizeof(message->buffer) - 2;
	*end = 0;

	/*
	 * Timestamp.
	 */
	time_t current_time = time(NULL);
	ptr += strftime(ptr, end - ptr, "%Y%m%d-%H:%M:%S ", localtime(&current_time));
	if (ptr > end) {
		ptr = end;
	}

	/*
	 * Debug prefix.
	 */
	pthread_mutex_lock(&dbg->print_lock);

	if (dbg->prefix) {
		hdhomerun_sprintf(ptr, end, "%s ", dbg->prefix);
		ptr = strchr(ptr, 0);
	}

	pthread_mutex_unlock(&dbg->print_lock);

	/*
	 * Message text.
	 */
	hdhomerun_vsprintf(ptr, end, fmt, args);
	ptr = strchr(ptr, 0);

	/*
	 * Force newline.
	 */
	if (ptr[-1] != '\n') {
		hdhomerun_sprintf(ptr, end, "\n");
	}

	/*
	 * Enqueue.
	 */
	pthread_mutex_lock(&dbg->queue_lock);

	message->prev = NULL;
	message->next = dbg->queue_head;
	dbg->queue_head = message;
	if (message->next) {
		message->next->prev = message;
	} else {
		dbg->queue_tail = message;
	}
	dbg->queue_depth++;

	pthread_mutex_unlock(&dbg->queue_lock);
}