Index: mythtv/libs/libmythhdhomerun/hdhomerun.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun.h	(working copy)
@@ -3,7 +3,7 @@
 /*
  * hdhomerun.h
  *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -35,7 +35,6 @@
 #include "hdhomerun_os.h"
 #include "hdhomerun_types.h"
 #include "hdhomerun_pkt.h"
-#include "hdhomerun_sock.h"
 #include "hdhomerun_debug.h"
 #include "hdhomerun_discover.h"
 #include "hdhomerun_control.h"
Index: mythtv/libs/libmythhdhomerun/hdhomerun_debug.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_debug.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_debug.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_debug.c
  *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -44,13 +44,9 @@
 #define HDHOMERUN_DEBUG_HOST "debug.silicondust.com"
 #endif
 #if !defined(HDHOMERUN_DEBUG_PORT)
-#define HDHOMERUN_DEBUG_PORT 8002
+#define HDHOMERUN_DEBUG_PORT "8002"
 #endif
 
-#define HDHOMERUN_DEBUG_CONNECT_RETRY_TIME 30000
-#define HDHOMERUN_DEBUG_CONNECT_TIMEOUT 10000
-#define HDHOMERUN_DEBUG_SEND_TIMEOUT 10000
-
 struct hdhomerun_debug_message_t
 {
 	struct hdhomerun_debug_message_t *next;
@@ -77,7 +73,7 @@
 
 	char *file_name;
 	FILE *file_fp;
-	hdhomerun_sock_t sock;
+	int sock;
 };
 
 static THREAD_FUNC_PREFIX hdhomerun_debug_thread_execute(void *arg);
@@ -89,7 +85,7 @@
 		return NULL;
 	}
 
-	dbg->sock = HDHOMERUN_SOCK_INVALID;
+	dbg->sock = -1;
 
 	pthread_mutex_init(&dbg->print_lock, NULL);
 	pthread_mutex_init(&dbg->queue_lock, NULL);
@@ -121,8 +117,8 @@
 	if (dbg->file_fp) {
 		fclose(dbg->file_fp);
 	}
-	if (dbg->sock != HDHOMERUN_SOCK_INVALID) {
-		hdhomerun_sock_destroy(dbg->sock);
+	if (dbg->sock != -1) {
+		close(dbg->sock);
 	}
 
 	free(dbg);
@@ -136,9 +132,9 @@
 		dbg->file_fp = NULL;
 	}
 
-	if (dbg->sock != HDHOMERUN_SOCK_INVALID) {
-		hdhomerun_sock_destroy(dbg->sock);
-		dbg->sock = HDHOMERUN_SOCK_INVALID;
+	if (dbg->sock != -1) {
+		close(dbg->sock);
+		dbg->sock = -1;
 	}
 }
 
@@ -255,7 +251,7 @@
 			return;
 		}
 
-		msleep_approx(10);
+		msleep(10);
 	}
 }
 
@@ -376,40 +372,54 @@
 }
 
 /* Send lock held by caller */
+#if defined(__CYGWIN__)
 static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message)
 {
-	if (dbg->sock == HDHOMERUN_SOCK_INVALID) {
+	return TRUE;
+}
+#else
+static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message)
+{
+	if (dbg->sock == -1) {
 		uint64_t current_time = getcurrenttime();
 		if (current_time < dbg->connect_delay) {
 			return FALSE;
 		}
-		dbg->connect_delay = current_time + HDHOMERUN_DEBUG_CONNECT_RETRY_TIME;
+		dbg->connect_delay = current_time + 30*1000;
 
-		dbg->sock = hdhomerun_sock_create_tcp();
-		if (dbg->sock == HDHOMERUN_SOCK_INVALID) {
+		dbg->sock = (int)socket(AF_INET, SOCK_STREAM, 0);
+		if (dbg->sock == -1) {
 			return FALSE;
 		}
 
-		uint32_t remote_addr = hdhomerun_sock_getaddrinfo_addr(dbg->sock, HDHOMERUN_DEBUG_HOST);
-		if (remote_addr == 0) {
+		struct addrinfo hints;
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = AF_INET;
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_protocol = IPPROTO_TCP;
+
+		struct addrinfo *sock_info;
+		if (getaddrinfo(HDHOMERUN_DEBUG_HOST, HDHOMERUN_DEBUG_PORT, &hints, &sock_info) != 0) {
 			hdhomerun_debug_close_internal(dbg);
 			return FALSE;
 		}
-
-		if (!hdhomerun_sock_connect(dbg->sock, remote_addr, HDHOMERUN_DEBUG_PORT, HDHOMERUN_DEBUG_CONNECT_TIMEOUT)) {
+		if (connect(dbg->sock, sock_info->ai_addr, (int)sock_info->ai_addrlen) != 0) {
+			freeaddrinfo(sock_info);
 			hdhomerun_debug_close_internal(dbg);
 			return FALSE;
 		}
+		freeaddrinfo(sock_info);
 	}
 
 	size_t length = strlen(message->buffer);
-	if (!hdhomerun_sock_send(dbg->sock, message->buffer, length, HDHOMERUN_DEBUG_SEND_TIMEOUT)) {
+	if (send(dbg->sock, (char *)message->buffer, (int)length, 0) != length) {
 		hdhomerun_debug_close_internal(dbg);
 		return FALSE;
 	}
 
 	return TRUE;
 }
+#endif
 
 static bool_t hdhomerun_debug_output_message(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message)
 {
@@ -456,7 +466,7 @@
 		pthread_mutex_unlock(&dbg->queue_lock);
 
 		if (!message) {
-			msleep_approx(250);
+			msleep(250);
 			continue;
 		}
 
@@ -466,7 +476,7 @@
 		}
 
 		if (!hdhomerun_debug_output_message(dbg, message)) {
-			msleep_approx(250);
+			msleep(250);
 			continue;
 		}
 
Index: mythtv/libs/libmythhdhomerun/libmythhdhomerun.pro
===================================================================
--- mythtv/libs/libmythhdhomerun/libmythhdhomerun.pro	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/libmythhdhomerun.pro	(working copy)
@@ -10,33 +10,21 @@
 
 QMAKE_CLEAN += $(TARGET) $(TARGETA) $(TARGETD) $(TARGET0) $(TARGET1) $(TARGET2)
 
-HEADERS += hdhomerun.h  hdhomerun_os.h  hdhomerun_sock.h  hdhomerun_types.h
+HEADERS += hdhomerun.h  hdhomerun_os.h  hdhomerun_types.h
 
 HEADERS += hdhomerun_channels.h  hdhomerun_channelscan.h  hdhomerun_control.h
-HEADERS += hdhomerun_debug.h     hdhomerun_device.h
+HEADERS += hdhomerun_debug.h     hdhomerun_device.h       hdhomerun_dhcp.h
+HEADERS += hdhomerun_discover.h  hdhomerun_pkt.h          hdhomerun_video.h 
 HEADERS += hdhomerun_device_selector.h
-HEADERS += hdhomerun_discover.h  hdhomerun_os_posix.h
-HEADERS += hdhomerun_pkt.h       hdhomerun_video.h 
 
-SOURCES += hdhomerun_config.c
-
 SOURCES += hdhomerun_channels.c  hdhomerun_channelscan.c  hdhomerun_control.c
-SOURCES += hdhomerun_debug.c     hdhomerun_device.c
+SOURCES += hdhomerun_debug.c     hdhomerun_device.c       hdhomerun_dhcp.c
+SOURCES += hdhomerun_discover.c  hdhomerun_pkt.c          hdhomerun_video.c
 SOURCES += hdhomerun_device_selector.c
-SOURCES += hdhomerun_discover.c  hdhomerun_os_posix.c
-SOURCES += hdhomerun_pkt.c       hdhomerun_video.c
 
-
-unix:SOURCES += hdhomerun_sock_posix.c
-
 mingw {
     HEADERS += hdhomerun_os_windows.h
-    SOURCES += hdhomerun_os_windows.c
-    SOURCES -= hdhomerun_os_posix.c
-    SOURCES += hdhomerun_sock_windows.c
     LIBS += -lws2_32 -liphlpapi -lpthread
 }
 
-LIBS += $$EXTRALIBS
-
 include ( ../libs-targetfix.pro )
Index: mythtv/libs/libmythhdhomerun/hdhomerun_os_posix.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_os_posix.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_os_posix.c	(working copy)
@@ -1,89 +0,0 @@
-/*
- * hdhomerun_os_posix.c
- *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * As a special exception to the GNU Lesser General Public License,
- * you may link, statically or dynamically, an application with a
- * publicly distributed version of the Library to produce an
- * executable file containing portions of the Library, and
- * distribute that executable file under terms of your choice,
- * without any of the additional requirements listed in clause 4 of
- * the GNU Lesser General Public License.
- * 
- * By "a publicly distributed version of the Library", we mean
- * either the unmodified Library as distributed by Silicondust, or a
- * modified version of the Library that is distributed under the
- * conditions defined in the GNU Lesser General Public License.
- */
-
-#include "hdhomerun_os.h"
-
-uint64_t getcurrenttime(void)
-{
-	static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-	static uint64_t result = 0;
-	static uint64_t previous_time = 0;
-
-	pthread_mutex_lock(&lock);
-
-#if defined(CLOCK_MONOTONIC)
-	struct timespec tp;
-	clock_gettime(CLOCK_MONOTONIC, &tp);
-	uint64_t current_time = ((uint64_t)tp.tv_sec * 1000) + (tp.tv_nsec / 1000000);
-#else
-	struct timeval t;
-	gettimeofday(&t, NULL);
-	uint64_t current_time = ((uint64_t)t.tv_sec * 1000) + (t.tv_usec / 1000);
-#endif
-
-	if (current_time > previous_time) {
-		result += current_time - previous_time;
-	}
-
-	previous_time = current_time;
-
-	pthread_mutex_unlock(&lock);
-	return result;
-}
-
-void msleep_approx(uint64_t ms)
-{
-	unsigned int delay_s = ms / 1000;
-	if (delay_s > 0) {
-		sleep(delay_s);
-		ms -= delay_s * 1000;
-	}
-
-	unsigned int delay_us = ms * 1000;
-	if (delay_us > 0) {
-		usleep(delay_us);
-	}
-}
-
-void msleep_minimum(uint64_t ms)
-{
-	uint64_t stop_time = getcurrenttime() + ms;
-
-	while (1) {
-		uint64_t current_time = getcurrenttime();
-		if (current_time >= stop_time) {
-			return;
-		}
-
-		msleep_approx(stop_time - current_time);
-	}
-}
Index: mythtv/libs/libmythhdhomerun/hdhomerun_sock.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_sock.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_sock.h	(working copy)
@@ -1,62 +0,0 @@
-/*
- * hdhomerun_sock.h
- *
- * Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>.
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * As a special exception to the GNU Lesser General Public License,
- * you may link, statically or dynamically, an application with a
- * publicly distributed version of the Library to produce an
- * executable file containing portions of the Library, and
- * distribute that executable file under terms of your choice,
- * without any of the additional requirements listed in clause 4 of
- * the GNU Lesser General Public License.
- * 
- * By "a publicly distributed version of the Library", we mean
- * either the unmodified Library as distributed by Silicondust, or a
- * modified version of the Library that is distributed under the
- * conditions defined in the GNU Lesser General Public License.
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define HDHOMERUN_SOCK_INVALID -1
-
-typedef int hdhomerun_sock_t;
-
-extern LIBTYPE hdhomerun_sock_t hdhomerun_sock_create_udp(void);
-extern LIBTYPE hdhomerun_sock_t hdhomerun_sock_create_tcp(void);
-extern LIBTYPE void hdhomerun_sock_destroy(hdhomerun_sock_t sock);
-
-extern LIBTYPE int hdhomerun_sock_getlasterror(void);
-extern LIBTYPE uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock);
-extern LIBTYPE uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock);
-extern LIBTYPE uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock);
-extern LIBTYPE uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name);
-
-extern LIBTYPE bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port);
-extern LIBTYPE bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout);
-
-extern LIBTYPE bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout);
-extern LIBTYPE bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout);
-
-extern LIBTYPE bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout);
-extern LIBTYPE bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout);
-
-
-#ifdef __cplusplus
-}
-#endif
Index: mythtv/libs/libmythhdhomerun/hdhomerun_config.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_config.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_config.c	(working copy)
@@ -286,7 +286,7 @@
 		}
 
 		cmd_scan_printf(fp, "SCANNING: %lu (%s)\n",
-			(unsigned long)result.frequency, result.channel_str
+			result.frequency, result.channel_str
 		);
 
 		ret = hdhomerun_device_channelscan_detect(hd, &result);
@@ -364,7 +364,7 @@
 		size_t actual_size;
 		uint8_t *ptr = hdhomerun_device_stream_recv(hd, VIDEO_DATA_BUFFER_SIZE_1S, &actual_size);
 		if (!ptr) {
-			msleep_approx(64);
+			msleep(64);
 			continue;
 		}
 
@@ -381,12 +381,6 @@
 				next_progress = loop_start_time + 1000;
 			}
 
-			/* Windows - indicate activity to suppress auto sleep mode. */
-			#if defined(__WINDOWS__)
-			SetThreadExecutionState(ES_SYSTEM_REQUIRED);
-			#endif
-
-			/* Video stats. */
 			hdhomerun_device_get_video_stats(hd, &stats_cur);
 
 			if (stats_cur.overflow_error_count > stats_old.overflow_error_count) {
@@ -410,7 +404,7 @@
 			continue;
 		}
 
-		msleep_approx(delay);
+		msleep(delay);
 	}
 
 	if (fp) {
@@ -446,10 +440,10 @@
 		fclose(fp);
 		return -1;
 	}
-	msleep_minimum(2000);
+	sleep(2);
 
 	printf("upgrading firmware...\n");
-	msleep_minimum(8000);
+	sleep(8);
 
 	printf("rebooting...\n");
 	int count = 0;
@@ -466,7 +460,7 @@
 			return -1;
 		}
 
-		msleep_minimum(1000);
+		sleep(1);
 	}
 
 	printf("upgrade complete - now running firmware %s\n", version_str);
Index: mythtv/libs/libmythhdhomerun/hdhomerun_video.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_video.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_video.c	(working copy)
@@ -34,27 +34,21 @@
 
 struct hdhomerun_video_sock_t {
 	pthread_mutex_t lock;
-	struct hdhomerun_debug_t *dbg;
-
-	int sock;
-	uint32_t multicast_ip;
-
-	volatile size_t head;
-	volatile size_t tail;
 	uint8_t *buffer;
 	size_t buffer_size;
+	volatile size_t head;
+	volatile size_t tail;
 	size_t advance;
-
-	pthread_t thread;
 	volatile bool_t terminate;
-
+	pthread_t thread;
+	int sock;
+	uint32_t rtp_sequence;
+	struct hdhomerun_debug_t *dbg;
 	volatile uint32_t packet_count;
 	volatile uint32_t transport_error_count;
 	volatile uint32_t network_error_count;
 	volatile uint32_t sequence_error_count;
 	volatile uint32_t overflow_error_count;
-
-	volatile uint32_t rtp_sequence;
 	volatile uint8_t sequence[0x2000];
 };
 
@@ -70,7 +64,7 @@
 	}
 
 	vs->dbg = dbg;
-	vs->sock = HDHOMERUN_SOCK_INVALID;
+	vs->sock = -1;
 	pthread_mutex_init(&vs->lock, NULL);
 
 	/* Reset sequence tracking. */
@@ -92,8 +86,8 @@
 	}
 	
 	/* Create socket. */
-	vs->sock = hdhomerun_sock_create_udp();
-	if (vs->sock == HDHOMERUN_SOCK_INVALID) {
+	vs->sock = (int)socket(AF_INET, SOCK_DGRAM, 0);
+	if (vs->sock == -1) {
 		hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to allocate socket\n");
 		goto error;
 	}
@@ -102,8 +96,17 @@
 	int rx_size = 1024 * 1024;
 	setsockopt(vs->sock, SOL_SOCKET, SO_RCVBUF, (char *)&rx_size, sizeof(rx_size));
 
+	/* Set timeouts. */
+	setsocktimeout(vs->sock, SOL_SOCKET, SO_SNDTIMEO, 1000);
+	setsocktimeout(vs->sock, SOL_SOCKET, SO_RCVTIMEO, 1000);
+
 	/* Bind socket. */
-	if (!hdhomerun_sock_bind(vs->sock, INADDR_ANY, listen_port)) {
+	struct sockaddr_in sock_addr;
+	memset(&sock_addr, 0, sizeof(sock_addr));
+	sock_addr.sin_family = AF_INET;
+	sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	sock_addr.sin_port = htons(listen_port);
+	if (bind(vs->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
 		hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to bind socket (port %u)\n", listen_port);
 		goto error;
 	}
@@ -118,8 +121,8 @@
 	return vs;
 
 error:
-	if (vs->sock != HDHOMERUN_SOCK_INVALID) {
-		hdhomerun_sock_destroy(vs->sock);
+	if (vs->sock != -1) {
+		close(vs->sock);
 	}
 	if (vs->buffer) {
 		free(vs->buffer);
@@ -133,7 +136,7 @@
 	vs->terminate = TRUE;
 	pthread_join(vs->thread, NULL);
 
-	hdhomerun_sock_destroy(vs->sock);
+	close(vs->sock);
 	free(vs->buffer);
 
 	free(vs);
@@ -141,54 +144,16 @@
 
 uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs)
 {
-	uint16_t port = hdhomerun_sock_getsockname_port(vs->sock);
-	if (port == 0) {
-		hdhomerun_debug_printf(vs->dbg, "hdhomerun_video_get_local_port: getsockname failed (%d)\n", hdhomerun_sock_getlasterror());
+	struct sockaddr_in sock_addr;
+	socklen_t sockaddr_size = sizeof(sock_addr);
+	if (getsockname(vs->sock, (struct sockaddr*)&sock_addr, &sockaddr_size) != 0) {
+		hdhomerun_debug_printf(vs->dbg, "hdhomerun_video_get_local_port: getsockname failed (%d)\n", sock_getlasterror);
 		return 0;
 	}
 
-	return port;
+	return ntohs(sock_addr.sin_port);
 }
 
-int hdhomerun_video_join_multicast_group(struct hdhomerun_video_sock_t *vs, uint32_t multicast_ip, uint32_t local_ip)
-{
-	if (vs->multicast_ip != 0) {
-		hdhomerun_video_leave_multicast_group(vs);
-	}
-
-	struct ip_mreq imr;
-	memset(&imr, 0, sizeof(imr));
-	imr.imr_multiaddr.s_addr  = htonl(multicast_ip);
-	imr.imr_interface.s_addr  = htonl(local_ip);
-
-	if (setsockopt(vs->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
-		hdhomerun_debug_printf(vs->dbg, "hdhomerun_video_join_multicast_group: setsockopt failed (%d)\n", hdhomerun_sock_getlasterror());
-		return -1;
-	}
-
-	vs->multicast_ip = multicast_ip;
-	return 1;
-}
-
-int hdhomerun_video_leave_multicast_group(struct hdhomerun_video_sock_t *vs)
-{
-	if (vs->multicast_ip == 0) {
-		return 1;
-	}
-
-	struct ip_mreq imr;
-	memset(&imr, 0, sizeof(imr));
-	imr.imr_multiaddr.s_addr  = htonl(vs->multicast_ip);
-	imr.imr_interface.s_addr  = htonl(INADDR_ANY);
-
-	if (setsockopt(vs->sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
-		hdhomerun_debug_printf(vs->dbg, "hdhomerun_video_leave_multicast_group: setsockopt failed (%d)\n", hdhomerun_sock_getlasterror());
-	}
-
-	vs->multicast_ip = 0;
-	return 1;
-}
-
 static void hdhomerun_video_stats_ts_pkt(struct hdhomerun_video_sock_t *vs, uint8_t *ptr)
 {
 	uint16_t packet_identifier = ((uint16_t)(ptr[1] & 0x1F) << 8) | (uint16_t)ptr[2];
@@ -203,22 +168,23 @@
 		return;
 	}
 
-	uint8_t sequence = ptr[3] & 0x0F;
-
+	uint8_t continuity_counter = ptr[3] & 0x0F;
 	uint8_t previous_sequence = vs->sequence[packet_identifier];
-	vs->sequence[packet_identifier] = sequence;
 
-	if (previous_sequence == 0xFF) {
+	if (continuity_counter == ((previous_sequence + 1) & 0x0F)) {
+		vs->sequence[packet_identifier] = continuity_counter;
 		return;
 	}
-	if (sequence == ((previous_sequence + 1) & 0x0F)) {
+	if (previous_sequence == 0xFF) {
+		vs->sequence[packet_identifier] = continuity_counter;
 		return;
 	}
-	if (sequence == previous_sequence) {
+	if (continuity_counter == previous_sequence) {
 		return;
 	}
 
 	vs->sequence_error_count++;
+	vs->sequence[packet_identifier] = continuity_counter;
 }
 
 static void hdhomerun_video_parse_rtp(struct hdhomerun_video_sock_t *vs, struct hdhomerun_pkt_t *pkt)
@@ -227,27 +193,19 @@
 	uint32_t rtp_sequence = hdhomerun_pkt_read_u16(pkt);
 	pkt->pos += 8;
 
-	uint32_t previous_rtp_sequence = vs->rtp_sequence;
-	vs->rtp_sequence = rtp_sequence;
+	if (rtp_sequence != ((vs->rtp_sequence + 1) & 0xFFFF)) {
+		if (vs->rtp_sequence != 0xFFFFFFFF) {
+			vs->network_error_count++;
 
-	/* Initial case - first packet received. */
-	if (previous_rtp_sequence == 0xFFFFFFFF) {
-		return;
+			/* restart pid sequence check */
+			/* can't use memset bcs sequence is volatile */
+			int i;
+			for (i = 0; i < sizeof(vs->sequence) / sizeof(uint8_t) ; i++)
+				vs->sequence[i] = 0xFF;
+		}
 	}
 
-	/* Normal case - next sequence number. */
-	if (rtp_sequence == ((previous_rtp_sequence + 1) & 0xFFFF)) {
-		return;
-	}
-
-	/* Error case - sequence missed. */
-	vs->network_error_count++;
-
-	/* Restart pid sequence check after packet loss. */
-	int i;
-	for (i = 0; i < 0x2000; i++) {
-		vs->sequence[i] = 0xFF;
-	}
+	vs->rtp_sequence = rtp_sequence;
 }
 
 static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg)
@@ -260,11 +218,7 @@
 		hdhomerun_pkt_reset(pkt);
 
 		/* Receive. */
-		size_t length = VIDEO_RTP_DATA_PACKET_SIZE;
-		if (!hdhomerun_sock_recv(vs->sock, pkt->end, &length, 25)) {
-			continue;
-		}
-
+		int length = recv(vs->sock, (char *)pkt->end, VIDEO_RTP_DATA_PACKET_SIZE, 0);
 		pkt->end += length;
 
 		if (length == VIDEO_RTP_DATA_PACKET_SIZE) {
@@ -273,8 +227,16 @@
 		}
 
 		if (length != VIDEO_DATA_PACKET_SIZE) {
-			/* Data received but not valid - ignore. */
-			continue;
+			if (length > 0) {
+				/* Data received but not valid - ignore. */
+				continue;
+			}
+			if (sock_getlasterror_socktimeout) {
+				/* Wait for more data. */
+				continue;
+			}
+			vs->terminate = TRUE;
+			return NULL;
 		}
 
 		pthread_mutex_lock(&vs->lock);
@@ -307,6 +269,7 @@
 			continue;
 		}
 
+		/* Atomic update. */
 		vs->head = head;
 
 		pthread_mutex_unlock(&vs->lock);
@@ -328,6 +291,7 @@
 			tail -= vs->buffer_size;
 		}
 	
+		/* Atomic update. */
 		vs->tail = tail;
 	}
 
@@ -370,12 +334,13 @@
 	vs->tail = vs->head;
 	vs->advance = 0;
 
-	vs->rtp_sequence = 0xFFFFFFFF;
+	/* can't use memset bcs sequence is volatile */
 	int i;
-	for (i = 0; i < 0x2000; i++) {
+	for (i = 0; i < sizeof(vs->sequence) / sizeof(uint8_t) ; i++)
 		vs->sequence[i] = 0xFF;
-	}
 
+	vs->rtp_sequence = 0xFFFFFFFF;
+
 	vs->packet_count = 0;
 	vs->transport_error_count = 0;
 	vs->network_error_count = 0;
@@ -390,10 +355,10 @@
 	struct hdhomerun_video_stats_t stats;
 	hdhomerun_video_get_stats(vs, &stats);
 
-	hdhomerun_debug_printf(vs->dbg, "video sock: pkt=%lu net=%lu te=%lu miss=%lu drop=%lu\n",
-		(unsigned long)stats.packet_count, (unsigned long)stats.network_error_count,
-		(unsigned long)stats.transport_error_count, (unsigned long)stats.sequence_error_count,
-		(unsigned long)stats.overflow_error_count
+	hdhomerun_debug_printf(vs->dbg, "video sock: pkt=%ld net=%ld te=%ld miss=%ld drop=%ld\n",
+		stats.packet_count, stats.network_error_count,
+		stats.transport_error_count, stats.sequence_error_count,
+		stats.overflow_error_count
 	);
 }
 
Index: mythtv/libs/libmythhdhomerun/hdhomerun_os_posix.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_os_posix.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_os_posix.h	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_os_posix.h
  *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -52,18 +52,44 @@
 typedef int bool_t;
 
 #define LIBTYPE
+#define sock_getlasterror errno
+#define sock_getlasterror_socktimeout (errno == EAGAIN)
 #define console_vprintf vprintf
 #define console_printf printf
 #define THREAD_FUNC_PREFIX void *
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+static inline uint64_t getcurrenttime(void)
+{
+	struct timeval t;
+	gettimeofday(&t, NULL);
+	return ((uint64_t)t.tv_sec * 1000) + (t.tv_usec / 1000);
+}
 
-extern LIBTYPE uint64_t getcurrenttime(void);
-extern LIBTYPE void msleep_approx(uint64_t ms);
-extern LIBTYPE void msleep_minimum(uint64_t ms);
+static inline int msleep(unsigned int ms)
+{
+	uint64_t stop_time = getcurrenttime() + ms;
 
-#ifdef __cplusplus
+	while (1) {
+		uint64_t current_time = getcurrenttime();
+		if (current_time >= stop_time) {
+			return 0;
+		}
+
+		uint64_t delay_s = (stop_time - current_time) / 1000;
+		if (delay_s > 0) {
+			sleep((unsigned int)delay_s);
+			continue;
+		}
+
+		uint64_t delay_us = (stop_time - current_time) * 1000;
+		usleep((unsigned int)delay_us);
+	}
 }
-#endif
+
+static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout)
+{
+	struct timeval t;
+	t.tv_sec = timeout / 1000;
+	t.tv_usec = (timeout % 1000) * 1000;
+	return setsockopt(s, level, optname, (char *)&t, sizeof(t));
+}
Index: mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c	(working copy)
@@ -1,347 +0,0 @@
-/*
- * hdhomerun_sock_windows.c
- *
- * Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>.
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * As a special exception to the GNU Lesser General Public License,
- * you may link, statically or dynamically, an application with a
- * publicly distributed version of the Library to produce an
- * executable file containing portions of the Library, and
- * distribute that executable file under terms of your choice,
- * without any of the additional requirements listed in clause 4 of
- * the GNU Lesser General Public License.
- * 
- * By "a publicly distributed version of the Library", we mean
- * either the unmodified Library as distributed by Silicondust, or a
- * modified version of the Library that is distributed under the
- * conditions defined in the GNU Lesser General Public License.
- */
-
-/*
- * Implementation notes:
- *
- * API specifies timeout for each operation (or zero for non-blocking).
- *
- * It is not possible to rely on the OS socket timeout as this will fail to
- * detect the command-response situation where data is sent successfully and
- * the other end chooses not to send a response (other than the TCP ack).
- *
- * Windows supports select() however native WSA events are used to:
- * - avoid problems with socket numbers above 1024.
- * - wait without allowing other events handlers to run (important for use
- *   with win7 WMC).
- */
-
-#include "hdhomerun.h"
-
-hdhomerun_sock_t hdhomerun_sock_create_udp(void)
-{
-	/* Create socket. */
-	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0);
-	if (sock == -1) {
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Set non-blocking */
-	unsigned long mode = 1;
-	if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
-		closesocket(sock);
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Allow broadcast. */
-	int sock_opt = 1;
-	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));
-
-	/* Success. */
-	return sock;
-}
-
-hdhomerun_sock_t hdhomerun_sock_create_tcp(void)
-{
-	/* Create socket. */
-	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_STREAM, 0);
-	if (sock == -1) {
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Set non-blocking */
-	unsigned long mode = 1;
-	if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
-		closesocket(sock);
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Success. */
-	return sock;
-}
-
-void hdhomerun_sock_destroy(hdhomerun_sock_t sock)
-{
-	closesocket(sock);
-}
-
-int hdhomerun_sock_getlasterror(void)
-{
-	return WSAGetLastError();
-}
-
-uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock)
-{
-	struct sockaddr_in sock_addr;
-	int sockaddr_size = sizeof(sock_addr);
-
-	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return 0;
-	}
-
-	return ntohl(sock_addr.sin_addr.s_addr);
-}
-
-uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock)
-{
-	struct sockaddr_in sock_addr;
-	int sockaddr_size = sizeof(sock_addr);
-
-	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return 0;
-	}
-
-	return ntohs(sock_addr.sin_port);
-}
-
-uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock)
-{
-	struct sockaddr_in sock_addr;
-	int sockaddr_size = sizeof(sock_addr);
-
-	if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return 0;
-	}
-
-	return ntohl(sock_addr.sin_addr.s_addr);
-}
-
-uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name)
-{
-	struct addrinfo hints;
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_protocol = IPPROTO_TCP;
-
-	struct addrinfo *sock_info;
-	if (getaddrinfo(name, "", &hints, &sock_info) != 0) {
-		return 0;
-	}
-
-	struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr;
-	uint32_t addr = ntohl(sock_addr->sin_addr.s_addr);
-
-	freeaddrinfo(sock_info);
-	return addr;
-}
-
-bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port)
-{
-	struct sockaddr_in sock_addr;
-	memset(&sock_addr, 0, sizeof(sock_addr));
-	sock_addr.sin_family = AF_INET;
-	sock_addr.sin_addr.s_addr = htonl(local_addr);
-	sock_addr.sin_port = htons(local_port);
-
-	if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
-{
-	WSAEVENT wsa_event = WSACreateEvent();
-	if (wsa_event == WSA_INVALID_EVENT) {
-		return FALSE;
-	}
-
-	if (WSAEventSelect(sock, wsa_event, FD_CONNECT) == SOCKET_ERROR) {
-		WSACloseEvent(wsa_event);
-		return FALSE;
-	}
-
-	/* Connect (non-blocking). */
-	struct sockaddr_in sock_addr;
-	memset(&sock_addr, 0, sizeof(sock_addr));
-	sock_addr.sin_family = AF_INET;
-	sock_addr.sin_addr.s_addr = htonl(remote_addr);
-	sock_addr.sin_port = htons(remote_port);
-
-	if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
-		if (WSAGetLastError() != WSAEWOULDBLOCK) {
-			WSACloseEvent(wsa_event);
-			return FALSE;
-		}
-	}
-
-	/* Wait for connect to complete (both success and failure will signal). */
-	DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)timeout, FALSE);
-	WSACloseEvent(wsa_event);
-
-	if (ret != WAIT_OBJECT_0) {
-		return FALSE;
-	}
-
-	/* Detect success/failure. */
-	int sockaddr_size = sizeof(sock_addr);
-	if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static bool_t hdhomerun_sock_wait_for_event(hdhomerun_sock_t sock, long event_type, uint64_t stop_time)
-{
-	uint64_t current_time = getcurrenttime();
-	if (current_time >= stop_time) {
-		return FALSE;
-	}
-
-	WSAEVENT wsa_event = WSACreateEvent();
-	if (wsa_event == WSA_INVALID_EVENT) {
-		return FALSE;
-	}
-
-	if (WSAEventSelect(sock, wsa_event, event_type) == SOCKET_ERROR) {
-		WSACloseEvent(wsa_event);
-		return FALSE;
-	}
-
-	DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)(stop_time - current_time), FALSE);
-	WSACloseEvent(wsa_event);
-
-	if (ret != WAIT_OBJECT_0) {
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-	const uint8_t *ptr = (uint8_t *)data;
-
-	while (1) {
-		int ret = send(sock, (char *)ptr, (int)length, 0);
-		if (ret >= (int)length) {
-			return TRUE;
-		}
-
-		if (ret > 0) {
-			ptr += ret;
-			length -= ret;
-		}
-
-		if (WSAGetLastError() != WSAEWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-	const uint8_t *ptr = (uint8_t *)data;
-
-	while (1) {
-		struct sockaddr_in sock_addr;
-		memset(&sock_addr, 0, sizeof(sock_addr));
-		sock_addr.sin_family = AF_INET;
-		sock_addr.sin_addr.s_addr = htonl(remote_addr);
-		sock_addr.sin_port = htons(remote_port);
-
-		int ret = sendto(sock, (char *)ptr, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
-		if (ret >= (int)length) {
-			return TRUE;
-		}
-
-		if (ret > 0) {
-			ptr += ret;
-			length -= ret;
-		}
-
-		if (WSAGetLastError() != WSAEWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-
-	while (1) {
-		int ret = recv(sock, (char *)data, (int)(*length), 0);
-		if (ret > 0) {
-			*length = ret;
-			return TRUE;
-		}
-
-		if (WSAGetLastError() != WSAEWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-
-	while (1) {
-		struct sockaddr_in sock_addr;
-		memset(&sock_addr, 0, sizeof(sock_addr));
-		int sockaddr_size = sizeof(sock_addr);
-
-		int ret = recvfrom(sock, (char *)data, (int)(*length), 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
-		if (ret > 0) {
-			*remote_addr = ntohl(sock_addr.sin_addr.s_addr);
-			*remote_port = ntohs(sock_addr.sin_port);
-			*length = ret;
-			return TRUE;
-		}
-
-		if (WSAGetLastError() != WSAEWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) {
-			return FALSE;
-		}
-	}
-}
Index: mythtv/libs/libmythhdhomerun/hdhomerun_video.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_video.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_video.h	(working copy)
@@ -71,12 +71,6 @@
 extern LIBTYPE uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs);
 
 /*
- * Join/leave multicast group.
- */
-extern LIBTYPE int hdhomerun_video_join_multicast_group(struct hdhomerun_video_sock_t *vs, uint32_t multicast_ip, uint32_t local_ip);
-extern LIBTYPE int hdhomerun_video_leave_multicast_group(struct hdhomerun_video_sock_t *vs);
-
-/*
  * Read data from buffer.
  *
  * size_t max_size: The maximum amount of data to be returned.
Index: mythtv/libs/libmythhdhomerun/hdhomerun_channelscan.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_channelscan.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_channelscan.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_channelscan.c
  *
- * Copyright © 2007-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2007-2008 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -99,7 +99,7 @@
 			return 1;
 		}
 
-		msleep_approx(250);
+		msleep(250);
 	}
 }
 
@@ -303,7 +303,7 @@
 			break;
 		}
 
-		msleep_approx(250);
+		msleep(250);
 	}
 
 	/* Lock => skip overlapping channels. */
Index: mythtv/libs/libmythhdhomerun/hdhomerun_discover.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_discover.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_discover.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_discover.c
  *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006-2007 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -44,11 +44,17 @@
 #endif
 #endif
 
+#include <sys/param.h>  // Defines BSD on FreeBSD and Mac OS X
+#if defined(__linux__) || defined(__APPLE__) || defined(BSD)
+#  include <ifaddrs.h>
+#  define USE_IFADDRS 1
+#  include <sys/select.h>
+#endif
+
 #define HDHOMERUN_DISOCVER_MAX_SOCK_COUNT 16
 
 struct hdhomerun_discover_sock_t {
-	hdhomerun_sock_t sock;
-	bool_t detected;
+	int sock;
 	uint32_t local_ip;
 	uint32_t subnet_mask;
 };
@@ -60,74 +66,48 @@
 	struct hdhomerun_pkt_t rx_pkt;
 };
 
-static bool_t hdhomerun_discover_sock_add(struct hdhomerun_discover_t *ds, uint32_t local_ip, uint32_t subnet_mask)
+static bool_t hdhomerun_discover_sock_create(struct hdhomerun_discover_t *ds, uint32_t local_ip, uint32_t subnet_mask)
 {
-	unsigned int i;
-	for (i = 1; i < ds->sock_count; i++) {
-		struct hdhomerun_discover_sock_t *dss = &ds->socks[i];
-
-		if ((dss->local_ip == local_ip) && (dss->subnet_mask == subnet_mask)) {
-			dss->detected = TRUE;
-			return TRUE;
-		}
-	}
-
 	if (ds->sock_count >= HDHOMERUN_DISOCVER_MAX_SOCK_COUNT) {
 		return FALSE;
 	}
 
 	/* Create socket. */
-	hdhomerun_sock_t sock = hdhomerun_sock_create_udp();
-	if (sock == HDHOMERUN_SOCK_INVALID) {
+	int sock = (int)socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock == -1) {
 		return FALSE;
 	}
 
+	/* Set timeouts. */
+	setsocktimeout(sock, SOL_SOCKET, SO_SNDTIMEO, 1000);
+	setsocktimeout(sock, SOL_SOCKET, SO_RCVTIMEO, 1000);
+
+	/* Allow broadcast. */
+	int sock_opt = 1;
+	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));
+
 	/* Bind socket. */
-	if (!hdhomerun_sock_bind(sock, local_ip, 0)) {
-		hdhomerun_sock_destroy(sock);
+	struct sockaddr_in sock_addr;
+	memset(&sock_addr, 0, sizeof(sock_addr));
+	sock_addr.sin_family = AF_INET;
+	sock_addr.sin_addr.s_addr = htonl(local_ip);
+	sock_addr.sin_port = htons(0);
+	if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
+		close(sock);
 		return FALSE;
 	}
 
 	/* Write sock entry. */
 	struct hdhomerun_discover_sock_t *dss = &ds->socks[ds->sock_count++];
 	dss->sock = sock;
-	dss->detected = TRUE;
 	dss->local_ip = local_ip;
 	dss->subnet_mask = subnet_mask;
 
 	return TRUE;
 }
 
-struct hdhomerun_discover_t *hdhomerun_discover_create(void)
-{
-	struct hdhomerun_discover_t *ds = (struct hdhomerun_discover_t *)calloc(1, sizeof(struct hdhomerun_discover_t));
-	if (!ds) {
-		return NULL;
-	}
-
-	/* Create a routable socket (always first entry). */
-	if (!hdhomerun_discover_sock_add(ds, 0, 0)) {
-		free(ds);
-		return NULL;
-	}
-
-	/* Success. */
-	return ds;
-}
-
-void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds)
-{
-	unsigned int i;
-	for (i = 0; i < ds->sock_count; i++) {
-		struct hdhomerun_discover_sock_t *dss = &ds->socks[i];
-		hdhomerun_sock_destroy(dss->sock);
-	}
-
-	free(ds);
-}
-
 #if defined(USE_IPHLPAPI)
-static void hdhomerun_discover_sock_detect_internal(struct hdhomerun_discover_t *ds)
+static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds)
 {
 	PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
 	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
@@ -158,7 +138,7 @@
 				continue;
 			}
 
-			hdhomerun_discover_sock_add(ds, local_ip, mask);
+			hdhomerun_discover_sock_create(ds, local_ip, mask);
 			pIPAddr = pIPAddr->Next;
 		}
 
@@ -170,9 +150,12 @@
 
 #else
 
-static void hdhomerun_discover_sock_detect_internal(struct hdhomerun_discover_t *ds)
+static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds)
 {
-	int sock = ds->socks[0].sock;
+	int fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (fd == -1) {
+		return;
+	}
 
 	struct ifconf ifc;
 	uint8_t buf[8192];
@@ -181,7 +164,8 @@
 
 	memset(buf, 0, sizeof(buf));
 
-	if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) {
+	if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
+		close(fd);
 		return;
 	}
 
@@ -192,7 +176,7 @@
 		struct ifreq *ifr = (struct ifreq *)ptr;
 		ptr += _SIZEOF_ADDR_IFREQ(*ifr);
 
-		if (ioctl(sock, SIOCGIFADDR, ifr) != 0) {
+		if (ioctl(fd, SIOCGIFADDR, ifr) != 0) {
 			continue;
 		}
 		struct sockaddr_in *addr_in = (struct sockaddr_in *)&(ifr->ifr_addr);
@@ -201,45 +185,48 @@
 			continue;
 		}
 
-		if (ioctl(sock, SIOCGIFNETMASK, ifr) != 0) {
+		if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) {
 			continue;
 		}
 		struct sockaddr_in *mask_in = (struct sockaddr_in *)&(ifr->ifr_addr);
 		uint32_t mask = ntohl(mask_in->sin_addr.s_addr);
 
-		hdhomerun_discover_sock_add(ds, local_ip, mask);
+		hdhomerun_discover_sock_create(ds, local_ip, mask);
 	}
+
+	close(fd);
 }
 #endif
 
-static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds)
+static struct hdhomerun_discover_t *hdhomerun_discover_create(void)
 {
-	unsigned int i;
-	for (i = 1; i < ds->sock_count; i++) {
-		struct hdhomerun_discover_sock_t *dss = &ds->socks[i];
-		dss->detected = FALSE;
+	struct hdhomerun_discover_t *ds = (struct hdhomerun_discover_t *)calloc(1, sizeof(struct hdhomerun_discover_t));
+	if (!ds) {
+		return NULL;
 	}
 
-	hdhomerun_discover_sock_detect_internal(ds);
+	/* Create a routable socket. */
+	if (!hdhomerun_discover_sock_create(ds, 0, 0)) {
+		free(ds);
+		return NULL;
+	}
 
-	struct hdhomerun_discover_sock_t *src = &ds->socks[1];
-	struct hdhomerun_discover_sock_t *dst = &ds->socks[1];
-	unsigned int count = 1;
-	for (i = 1; i < ds->sock_count; i++) {
-		if (!src->detected) {
-			hdhomerun_sock_destroy(src->sock);
-			src++;
-			continue;
-		}
-		if (dst != src) {
-			*dst = *src;
-		}
-		src++;
-		dst++;
-		count++;
+	/* Detect & create local sockets. */
+	hdhomerun_discover_sock_detect(ds);
+
+	/* Success. */
+	return ds;
+}
+
+static void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds)
+{
+	unsigned int i;
+	for (i = 0; i < ds->sock_count; i++) {
+		struct hdhomerun_discover_sock_t *dss = &ds->socks[i];
+		close(dss->sock);
 	}
 
-	ds->sock_count = count;
+	free(ds);
 }
 
 static bool_t hdhomerun_discover_send_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, uint32_t target_ip, uint32_t device_type, uint32_t device_id)
@@ -255,7 +242,18 @@
 	hdhomerun_pkt_write_u32(tx_pkt, device_id);
 	hdhomerun_pkt_seal_frame(tx_pkt, HDHOMERUN_TYPE_DISCOVER_REQ);
 
-	return hdhomerun_sock_sendto(dss->sock, target_ip, HDHOMERUN_DISCOVER_UDP_PORT, tx_pkt->start, tx_pkt->end - tx_pkt->start, 0);
+	struct sockaddr_in sock_addr;
+	memset(&sock_addr, 0, sizeof(sock_addr));
+	sock_addr.sin_family = AF_INET;
+	sock_addr.sin_addr.s_addr = htonl(target_ip);
+	sock_addr.sin_port = htons(HDHOMERUN_DISCOVER_UDP_PORT);
+
+	int length = (int)(tx_pkt->end - tx_pkt->start);
+	if (sendto(dss->sock, (char *)tx_pkt->start, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != length) {
+		return FALSE;
+	}
+
+	return TRUE;
 }
 
 static bool_t hdhomerun_discover_send_wildcard_ip(struct hdhomerun_discover_t *ds, uint32_t device_type, uint32_t device_id)
@@ -315,36 +313,38 @@
 
 static bool_t hdhomerun_discover_send(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id)
 {
-	if (target_ip == 0) {
-		return hdhomerun_discover_send_wildcard_ip(ds, device_type, device_id);
-	} else {
+	if (target_ip != 0) {
 		return hdhomerun_discover_send_target_ip(ds, target_ip, device_type, device_id);
 	}
+
+	return hdhomerun_discover_send_wildcard_ip(ds, device_type, device_id);
 }
 
-static bool_t hdhomerun_discover_recv_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, struct hdhomerun_discover_device_t *result)
+static int hdhomerun_discover_recv_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, struct hdhomerun_discover_device_t *result)
 {
 	struct hdhomerun_pkt_t *rx_pkt = &ds->rx_pkt;
 	hdhomerun_pkt_reset(rx_pkt);
 
-	uint32_t remote_addr;
-	uint16_t remote_port;
-	size_t length = rx_pkt->limit - rx_pkt->end;
-	if (!hdhomerun_sock_recvfrom(dss->sock, &remote_addr, &remote_port, rx_pkt->end, &length, 0)) {
-		return FALSE;
+	struct sockaddr_in sock_addr;
+	memset(&sock_addr, 0, sizeof(sock_addr));
+	socklen_t sockaddr_size = sizeof(sock_addr);
+
+	int rx_length = recvfrom(dss->sock, (char *)rx_pkt->end, (int)(rx_pkt->limit - rx_pkt->end), 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
+	if (rx_length <= 0) {
+		/* Don't return error - windows machine on VPN can sometimes cause a sock error here but otherwise works. */
+		return 0;
 	}
+	rx_pkt->end += rx_length;
 
-	rx_pkt->end += length;
-
 	uint16_t type;
 	if (hdhomerun_pkt_open_frame(rx_pkt, &type) <= 0) {
-		return FALSE;
+		return 0;
 	}
 	if (type != HDHOMERUN_TYPE_DISCOVER_RPY) {
-		return FALSE;
+		return 0;
 	}
 
-	result->ip_addr = remote_addr;
+	result->ip_addr = ntohl(sock_addr.sin_addr.s_addr);
 	result->device_type = 0;
 	result->device_id = 0;
 
@@ -378,40 +378,63 @@
 		rx_pkt->pos = next;
 	}
 
-	return TRUE;
+	return 1;
 }
 
-static bool_t hdhomerun_discover_recv(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_device_t *result)
+static int hdhomerun_discover_recv(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_device_t *result)
 {
+	struct timeval t;
+	t.tv_sec = 0;
+	t.tv_usec = 250000;
+
+	fd_set readfds;
+	FD_ZERO(&readfds);
+	int max_sock = -1;
+
 	unsigned int i;
 	for (i = 0; i < ds->sock_count; i++) {
 		struct hdhomerun_discover_sock_t *dss = &ds->socks[i];
+		FD_SET(dss->sock, &readfds);
+		if (dss->sock > max_sock) {
+			max_sock = dss->sock;
+		}
+	}
 
-		if (hdhomerun_discover_recv_internal(ds, dss, result)) {
-			return TRUE;
+	if (select(max_sock+1, &readfds, NULL, NULL, &t) < 0) {
+		return -1;
+	}
+
+	for (i = 0; i < ds->sock_count; i++) {
+		struct hdhomerun_discover_sock_t *dss = &ds->socks[i];
+		if (!FD_ISSET(dss->sock, &readfds)) {
+			continue;
 		}
+
+		if (hdhomerun_discover_recv_internal(ds, dss, result) <= 0) {
+			continue;
+		}
+
+		return 1;
 	}
 
-	return FALSE;
+	return 0;
 }
 
-static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, struct hdhomerun_discover_device_t *lookup)
+static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, uint32_t ip_addr)
 {
 	int index;
 	for (index = 0; index < count; index++) {
-		struct hdhomerun_discover_device_t *entry = &result_list[index];
-		if (memcmp(lookup, entry, sizeof(struct hdhomerun_discover_device_t)) == 0) {
-			return entry;
+		struct hdhomerun_discover_device_t *result = &result_list[index];
+		if (result->ip_addr == ip_addr) {
+			return result;
 		}
 	}
 
 	return NULL;
 }
 
-int hdhomerun_discover_find_devices(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count)
+static int hdhomerun_discover_find_devices_internal(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count)
 {
-	hdhomerun_discover_sock_detect(ds);
-
 	int count = 0;
 	int attempt;
 	for (attempt = 0; attempt < 2; attempt++) {
@@ -420,14 +443,14 @@
 		}
 
 		uint64_t timeout = getcurrenttime() + 200;
-		while (1) {
+		while (getcurrenttime() < timeout) {
 			struct hdhomerun_discover_device_t *result = &result_list[count];
 
-			if (!hdhomerun_discover_recv(ds, result)) {
-				if (getcurrenttime() >= timeout) {
-					break;
-				}
-				msleep_approx(10);
+			int ret = hdhomerun_discover_recv(ds, result);
+			if (ret < 0) {
+				return -1;
+			}
+			if (ret == 0) {
 				continue;
 			}
 
@@ -444,7 +467,7 @@
 			}
 
 			/* Ensure not already in list. */
-			if (hdhomerun_discover_find_in_list(result_list, count, result)) {
+			if (hdhomerun_discover_find_in_list(result_list, count, result->ip_addr)) {
 				continue;
 			}
 
@@ -461,16 +484,12 @@
 
 int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count)
 {
-	if (hdhomerun_discover_is_ip_multicast(target_ip)) {
-		return 0;
-	}
-
 	struct hdhomerun_discover_t *ds = hdhomerun_discover_create();
 	if (!ds) {
 		return -1;
 	}
 
-	int ret = hdhomerun_discover_find_devices(ds, target_ip, device_type, device_id, result_list, max_count);
+	int ret = hdhomerun_discover_find_devices_internal(ds, target_ip, device_type, device_id, result_list, max_count);
 
 	hdhomerun_discover_destroy(ds);
 	return ret;
@@ -494,7 +513,3 @@
 	return (checksum == 0);
 }
 
-bool_t hdhomerun_discover_is_ip_multicast(uint32_t ip_addr)
-{
-	return (ip_addr >= 0xE0000000) && (ip_addr < 0xF0000000);
-}
Index: mythtv/libs/libmythhdhomerun/hdhomerun_discover.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_discover.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_discover.h	(working copy)
@@ -44,11 +44,9 @@
  *
  * The device information is stored in caller-supplied array of hdhomerun_discover_device_t vars.
  * Multiple attempts are made to find devices.
- * Execution time is typically 400ms if max_count is not reached.
+ * Execution time is 1 second.
  *
  * Set target_ip to zero to auto-detect IP address.
- * Set device_type to HDHOMERUN_DEVICE_TYPE_TUNER to detect HDHomeRun tuner devices.
- * Set device_id to HDHOMERUN_DEVICE_ID_WILDCARD to detect all device ids.
  *
  * Returns the number of devices found.
  * Retruns -1 on error.
@@ -56,13 +54,6 @@
 extern LIBTYPE int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count);
 
 /*
- * Optional: persistent discover instance available for discover polling use.
- */
-extern LIBTYPE struct hdhomerun_discover_t *hdhomerun_discover_create(void);
-extern LIBTYPE void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds);
-extern LIBTYPE int hdhomerun_discover_find_devices(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count);
-
-/*
  * Verify that the device ID given is valid.
  *
  * The device ID contains a self-check sequence that detects common user input errors including
@@ -73,14 +64,6 @@
  */
 extern LIBTYPE bool_t hdhomerun_discover_validate_device_id(uint32_t device_id);
 
-/*
- * Detect if an IP address is multicast.
- *
- * Returns TRUE if multicast.
- * Returns FALSE if zero, unicast, expermental, or broadcast.
- */
-extern LIBTYPE bool_t hdhomerun_discover_is_ip_multicast(uint32_t ip_addr);
-
 #ifdef __cplusplus
 }
 #endif
Index: mythtv/libs/libmythhdhomerun/Makefile.bin
===================================================================
--- mythtv/libs/libmythhdhomerun/Makefile.bin	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/Makefile.bin	(working copy)
@@ -1,15 +1,12 @@
-
+LIBSRCS += hdhomerun_pkt.c
+LIBSRCS += hdhomerun_debug.c
+LIBSRCS += hdhomerun_discover.c
 LIBSRCS += hdhomerun_channels.c
 LIBSRCS += hdhomerun_channelscan.c
 LIBSRCS += hdhomerun_control.c
-LIBSRCS += hdhomerun_debug.c
+LIBSRCS += hdhomerun_video.c
 LIBSRCS += hdhomerun_device.c
 LIBSRCS += hdhomerun_device_selector.c
-LIBSRCS += hdhomerun_discover.c
-LIBSRCS += hdhomerun_os_posix.c
-LIBSRCS += hdhomerun_pkt.c
-LIBSRCS += hdhomerun_sock_posix.c
-LIBSRCS += hdhomerun_video.c
 
 CC    := $(CROSS_COMPILE)gcc
 STRIP := $(CROSS_COMPILE)strip
@@ -23,15 +20,11 @@
   LIBEXT := .dll
   LDFLAGS += -liphlpapi
 else
-  OS := $(shell uname -s)
   LIBEXT := .so
-  ifeq ($(OS),Linux)
-    LDFLAGS += -lrt
-  endif
-  ifeq ($(OS),SunOS)
+  ifneq ($(findstring solaris,$(shell echo $$OSTYPE)),)
     LDFLAGS += -lns -lsocket
   endif
-  ifeq ($(OS),Darwin)
+  ifneq ($(findstring darwin,$(shell echo $$OSTYPE)),)
     CFLAGS += -arch i386 -arch ppc
     LIBEXT := .dylib
     SHARED := -dynamiclib -install_name libhdhomerun$(LIBEXT)
Index: mythtv/libs/libmythhdhomerun/hdhomerun_os_windows.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_os_windows.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_os_windows.c	(working copy)
@@ -1,137 +0,0 @@
-/*
- * hdhomerun_os_windows.c
- *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * As a special exception to the GNU Lesser General Public License,
- * you may link, statically or dynamically, an application with a
- * publicly distributed version of the Library to produce an
- * executable file containing portions of the Library, and
- * distribute that executable file under terms of your choice,
- * without any of the additional requirements listed in clause 4 of
- * the GNU Lesser General Public License.
- * 
- * By "a publicly distributed version of the Library", we mean
- * either the unmodified Library as distributed by Silicondust, or a
- * modified version of the Library that is distributed under the
- * conditions defined in the GNU Lesser General Public License.
- */
-
-#include "hdhomerun_os.h"
-
-uint64_t getcurrenttime(void)
-{
-	static pthread_mutex_t lock = INVALID_HANDLE_VALUE;
-	static uint64_t result = 0;
-	static uint32_t previous_time = 0;
-
-	/* Initialization is not thread safe. */
-	if (lock == INVALID_HANDLE_VALUE) {
-		pthread_mutex_init(&lock, NULL);
-	}
-
-	pthread_mutex_lock(&lock);
-
-	uint32_t current_time = GetTickCount();
-
-	if (current_time > previous_time) {
-		result += current_time - previous_time;
-	}
-
-	previous_time = current_time;
-
-	pthread_mutex_unlock(&lock);
-	return result;
-}
-
-void msleep_approx(uint64_t ms)
-{
-	Sleep((DWORD)ms);
-}
-
-void msleep_minimum(uint64_t ms)
-{
-	uint64_t stop_time = getcurrenttime() + ms;
-
-	while (1) {
-		uint64_t current_time = getcurrenttime();
-		if (current_time >= stop_time) {
-			return;
-		}
-
-		msleep_approx(stop_time - current_time);
-	}
-}
-
-#if !defined(PTHREAD_H)
-int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg)
-{
-	*tid = CreateThread(NULL, 0, start, arg, 0, NULL);
-	if (!*tid) {
-		return (int)GetLastError();
-	}
-	return 0;
-}
-
-int pthread_join(pthread_t tid, void **value_ptr)
-{
-	while (1) {
-		DWORD ExitCode = 0;
-		if (!GetExitCodeThread(tid, &ExitCode)) {
-			return (int)GetLastError();
-		}
-		if (ExitCode != STILL_ACTIVE) {
-			return 0;
-		}
-	}
-}
-
-void pthread_mutex_init(pthread_mutex_t *mutex, void *attr)
-{
-	*mutex = CreateMutex(NULL, FALSE, NULL);
-}
-
-void pthread_mutex_lock(pthread_mutex_t *mutex)
-{
-	WaitForSingleObject(*mutex, INFINITE);
-}
-
-void pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
-	ReleaseMutex(*mutex);
-}
-#endif
-
-/*
- * The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing.
- * Attempting to restore on exit fails to restore if the program is terminated by the user.
- * Solution - set the output format each printf.
- */
-void console_vprintf(const char *fmt, va_list ap)
-{
-	UINT cp = GetConsoleOutputCP();
-	SetConsoleOutputCP(CP_UTF8);
-	vprintf(fmt, ap);
-	SetConsoleOutputCP(cp);
-}
-
-void console_printf(const char *fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	console_vprintf(fmt, ap);
-	va_end(ap);
-}
Index: mythtv/libs/libmythhdhomerun/hdhomerun_device_selector.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_device_selector.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_device_selector.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_device_selector.c
  *
- * Copyright Â© 2009-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright Â© 2009 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -68,11 +68,6 @@
 	free(hds);
 }
 
-LIBTYPE int hdhomerun_device_selector_get_device_count(struct hdhomerun_device_selector_t *hds)
-{
-	return (int)hds->hd_count;
-}
-
 void hdhomerun_device_selector_add_device(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *hd)
 {
 	size_t index;
@@ -134,11 +129,11 @@
 	return NULL;
 }
 
-int hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t *hds, char *filename)
+void hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t *hds, char *filename)
 {
 	FILE *fp = fopen(filename, "r");
 	if (!fp) {
-		return 0;
+		return;
 	}
 
 	while(1) {
@@ -156,17 +151,16 @@
 	}
 
 	fclose(fp);
-	return (int)hds->hd_count;
 }
 
 #if defined(__WINDOWS__)
-int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource)
+void 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;
+		hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_load_from_windows_registry: failed to open tuners registry key (%ld)\n", ret);
+		return;
 	}
 
 	DWORD index = 0;
@@ -183,7 +177,7 @@
 		HKEY device_key;
 		ret = RegOpenKeyEx(tuners_key, wdevice_name, 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_name, (long)ret);
+			hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_load_from_windows_registry: failed to open registry key for %S (%ld)\n", wdevice_name, ret);
 			continue;
 		}
 
@@ -213,7 +207,6 @@
 	}
 
 	RegCloseKey(tuners_key);
-	return (int)hds->hd_count;
 }
 #endif
 
@@ -275,16 +268,21 @@
 	/*
 	 * Test local port.
 	 */
-	hdhomerun_sock_t test_sock = hdhomerun_sock_create_udp();
-	if (test_sock == HDHOMERUN_SOCK_INVALID) {
+	int test_sock = (int)socket(AF_INET, SOCK_DGRAM, 0);
+	if (test_sock == -1) {
 		hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to create test sock\n", name);
 		return FALSE;
 	}
 
-	bool_t inuse = (hdhomerun_sock_bind(test_sock, INADDR_ANY, (uint16_t)target_port) == FALSE);
-	hdhomerun_sock_destroy(test_sock);
+	struct sockaddr_in sock_addr;
+	memset(&sock_addr, 0, sizeof(sock_addr));
+	sock_addr.sin_family = AF_INET;
+	sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	sock_addr.sin_port = htons((uint16_t)target_port);
+	ret = bind(test_sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
+	close(test_sock);
 
-	if (inuse) {
+	if (ret != 0) {
 		hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine\n", name);
 		return FALSE;
 	}
Index: mythtv/libs/libmythhdhomerun/hdhomerun_device.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_device.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_device.c	(working copy)
@@ -37,8 +37,6 @@
 	struct hdhomerun_video_sock_t *vs;
 	struct hdhomerun_debug_t *dbg;
 	struct hdhomerun_channelscan_t *scan;
-	uint32_t multicast_ip;
-	uint16_t multicast_port;
 	uint32_t device_id;
 	unsigned int tuner;
 	uint32_t lockkey;
@@ -46,108 +44,53 @@
 	char model[32];
 };
 
-static int hdhomerun_device_set_device_normal(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip)
+static void hdhomerun_device_set_update(struct hdhomerun_device_t *hd)
 {
-	if (!hd->cs) {
-		hd->cs = hdhomerun_control_create(0, 0, hd->dbg);
-		if (!hd->cs) {
-			hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_device: failed to create control object\n");
-			return -1;
-		}
-	}
+	/* Clear cached information. */
+	*hd->model = 0;
 
+	/* New name. */
+	sprintf(hd->name, "%08lX-%u", (unsigned long)hd->device_id, hd->tuner);
+}
+
+void hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip)
+{
 	hdhomerun_control_set_device(hd->cs, device_id, device_ip);
 
 	if ((device_id == 0) || (device_id == HDHOMERUN_DEVICE_ID_WILDCARD)) {
 		device_id = hdhomerun_control_get_device_id(hd->cs);
 	}
 
-	hd->multicast_ip = 0;
-	hd->multicast_port = 0;
 	hd->device_id = device_id;
-	hd->tuner = 0;
-	hd->lockkey = 0;
-
-	sprintf(hd->name, "%08lX-%u", (unsigned long)hd->device_id, hd->tuner);
-	hd->model[0] = 0; /* clear cached model string */
-
-	return 1;
+	hdhomerun_device_set_update(hd);
 }
 
-static int hdhomerun_device_set_device_multicast(struct hdhomerun_device_t *hd, uint32_t multicast_ip)
+void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner)
 {
-	if (hd->cs) {
-		hdhomerun_control_destroy(hd->cs);
-		hd->cs = NULL;
-	}
-
-	hd->multicast_ip = multicast_ip;
-	hd->multicast_port = 0;
-	hd->device_id = 0;
-	hd->tuner = 0;
-	hd->lockkey = 0;
-
-	unsigned long ip = multicast_ip;
-	sprintf(hd->name, "%lu.%lu.%lu.%lu", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, (ip >> 0) & 0xFF);
-	sprintf(hd->model, "multicast");
-
-	return 1;
-}
-
-int hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip)
-{
-	if ((device_id == 0) && (device_ip == 0)) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_device: device not specified\n");
-		return -1;
-	}
-
-	if (hdhomerun_discover_is_ip_multicast(device_ip)) {
-		return hdhomerun_device_set_device_multicast(hd, device_ip);
-	}
-
-	return hdhomerun_device_set_device_normal(hd, device_id, device_ip);
-}
-
-int hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner)
-{
-	if (hd->multicast_ip != 0) {
-		if (tuner != 0) {
-			hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner: tuner cannot be specified in multicast mode\n");
-			return -1;
-		}
-
-		return 1;
-	}
-
 	hd->tuner = tuner;
-	sprintf(hd->name, "%08lX-%u", (unsigned long)hd->device_id, hd->tuner);
-
-	return 1;
+	hdhomerun_device_set_update(hd);
 }
 
 struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner, struct hdhomerun_debug_t *dbg)
 {
 	struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)calloc(1, sizeof(struct hdhomerun_device_t));
 	if (!hd) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_create: failed to allocate device object\n");
+		hdhomerun_debug_printf(dbg, "hdhomerun_device_create: failed to allocate device object\n");
 		return NULL;
 	}
 
 	hd->dbg = dbg;
 
-	if ((device_id == 0) && (device_ip == 0) && (tuner == 0)) {
-		return hd;
-	}
-
-	if (hdhomerun_device_set_device(hd, device_id, device_ip) <= 0) {
+	hd->cs = hdhomerun_control_create(0, 0, hd->dbg);
+	if (!hd->cs) {
+		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_create: failed to create control object\n");
 		free(hd);
 		return NULL;
 	}
-	if (hdhomerun_device_set_tuner(hd, tuner) <= 0) {
-		free(hd);
-		return NULL;
-	}
 
+	hdhomerun_device_set_device(hd, device_id, device_ip);
+	hdhomerun_device_set_tuner(hd, tuner);
+
 	return hd;
 }
 
@@ -161,9 +104,7 @@
 		hdhomerun_video_destroy(hd->vs);
 	}
 
-	if (hd->cs) {
-		hdhomerun_control_destroy(hd->cs);
-	}
+	hdhomerun_control_destroy(hd->cs);
 
 	free(hd);
 }
@@ -215,24 +156,17 @@
 static struct hdhomerun_device_t *hdhomerun_device_create_from_str_ip(const char *device_str, struct hdhomerun_debug_t *dbg)
 {
 	unsigned long a[4];
-	unsigned int port = 0;
-	if (sscanf(device_str, "%lu.%lu.%lu.%lu:%u", &a[0], &a[1], &a[2], &a[3], &port) != 5) {
+	unsigned int tuner;
+
+	if (sscanf(device_str, "%lu.%lu.%lu.%lu-%u", &a[0], &a[1], &a[2], &a[3], &tuner) != 5) {
+		tuner = 0;
 		if (sscanf(device_str, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) != 4) {
 			return NULL;
 		}
 	}
 
 	unsigned long device_ip = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0);
-	struct hdhomerun_device_t *hd = hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, (uint32_t)device_ip, 0, dbg);
-	if (!hd) {
-		return NULL;
-	}
-
-	if (hd->multicast_ip != 0) {
-		hd->multicast_port = port;
-	}
-
-	return hd;
+	return hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, (uint32_t)device_ip, tuner, dbg);
 }
 
 static struct hdhomerun_device_t *hdhomerun_device_create_from_str_dns(const char *device_str, struct hdhomerun_debug_t *dbg)
@@ -305,43 +239,22 @@
 
 uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd)
 {
-	return hd->device_id;
+	return hdhomerun_control_get_device_id(hd->cs);
 }
 
 uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd)
 {
-	if (hd->multicast_ip != 0) {
-		return hd->multicast_ip;
-	}
-	if (hd->cs) {
-		return hdhomerun_control_get_device_ip(hd->cs);
-	}
-
-	return 0;
+	return hdhomerun_control_get_device_ip(hd->cs);
 }
 
 uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd)
 {
-	if (hd->multicast_ip != 0) {
-		return 0;
-	}
-	if (hd->cs) {
-		return hdhomerun_control_get_device_id_requested(hd->cs);
-	}
-
-	return 0;
+	return hdhomerun_control_get_device_id_requested(hd->cs);
 }
 
 uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd)
 {
-	if (hd->multicast_ip != 0) {
-		return hd->multicast_ip;
-	}
-	if (hd->cs) {
-		return hdhomerun_control_get_device_ip_requested(hd->cs);
-	}
-
-	return 0;
+	return hdhomerun_control_get_device_ip_requested(hd->cs);
 }
 
 unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd)
@@ -360,7 +273,7 @@
 		return hd->vs;
 	}
 
-	hd->vs = hdhomerun_video_create(hd->multicast_port, VIDEO_DATA_BUFFER_SIZE_1S * 2, hd->dbg);
+	hd->vs = hdhomerun_video_create(0, VIDEO_DATA_BUFFER_SIZE_1S * 2, hd->dbg);
 	if (!hd->vs) {
 		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_video_sock: failed to create video object\n");
 		return NULL;
@@ -371,11 +284,7 @@
 
 uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun_device_t *hd)
 {
-	if (hd->cs) {
-		return hdhomerun_control_get_local_addr(hd->cs);
-	}
-
-	return 0;
+	return hdhomerun_control_get_local_addr(hd->cs);
 }
 
 static uint32_t hdhomerun_device_get_status_parse(const char *status_str, const char *tag)
@@ -459,11 +368,6 @@
 
 int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_status: device not set\n");
-		return -1;
-	}
-
 	memset(status, 0, sizeof(struct hdhomerun_tuner_status_t));
 
 	char name[32];
@@ -510,11 +414,6 @@
 
 int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_streaminfo: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/streaminfo", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, pstreaminfo, NULL);
@@ -522,11 +421,6 @@
 
 int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_channel: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/channel", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, pchannel, NULL);
@@ -534,11 +428,6 @@
 
 int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_channelmap: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/channelmap", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, pchannelmap, NULL);
@@ -546,11 +435,6 @@
 
 int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_filter: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/filter", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, pfilter, NULL);
@@ -558,11 +442,6 @@
 
 int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_program: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/program", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, pprogram, NULL);
@@ -570,11 +449,6 @@
 
 int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_target: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/target", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, ptarget, NULL);
@@ -582,11 +456,6 @@
 
 int hdhomerun_device_get_tuner_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_plotsample: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/plotsample", hd->tuner);
 
@@ -636,11 +505,6 @@
 
 int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_lockkey_owner: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/lockkey", hd->tuner);
 	return hdhomerun_control_get(hd->cs, name, powner, NULL);
@@ -648,31 +512,16 @@
 
 int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_ir_target: device not set\n");
-		return -1;
-	}
-
 	return hdhomerun_control_get(hd->cs, "/ir/target", ptarget, NULL);
 }
 
 int hdhomerun_device_get_lineup_location(struct hdhomerun_device_t *hd, char **plocation)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_lineup_location: device not set\n");
-		return -1;
-	}
-
 	return hdhomerun_control_get(hd->cs, "/lineup/location", plocation, NULL);
 }
 
 int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_version: device not set\n");
-		return -1;
-	}
-
 	char *version_str;
 	int ret = hdhomerun_control_get(hd->cs, "/sys/version", &version_str, NULL);
 	if (ret <= 0) {
@@ -697,11 +546,6 @@
 
 int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_channel: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/channel", hd->tuner);
 	return hdhomerun_control_set_with_lockkey(hd->cs, name, channel, hd->lockkey, NULL, NULL);
@@ -709,11 +553,6 @@
 
 int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_channelmap: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/channelmap", hd->tuner);
 	return hdhomerun_control_set_with_lockkey(hd->cs, name, channelmap, hd->lockkey, NULL, NULL);
@@ -721,11 +560,6 @@
 
 int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_filter: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/filter", hd->tuner);
 	return hdhomerun_control_set_with_lockkey(hd->cs, name, filter, hd->lockkey, NULL, NULL);
@@ -801,11 +635,6 @@
 
 int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_program: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/program", hd->tuner);
 	return hdhomerun_control_set_with_lockkey(hd->cs, name, program, hd->lockkey, NULL, NULL);
@@ -813,24 +642,16 @@
 
 int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, const char *target)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_target: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/target", hd->tuner);
 	return hdhomerun_control_set_with_lockkey(hd->cs, name, target, hd->lockkey, NULL, NULL);
 }
 
-static int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd, const char *protocol)
+int hdhomerun_device_set_tuner_target_to_local_protocol(struct hdhomerun_device_t *hd, const char *protocol)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_target_to_local: device not set\n");
-		return -1;
-	}
+	/* Create video socket. */
+	hdhomerun_device_get_video_sock(hd);
 	if (!hd->vs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_target_to_local: video not initialized\n");
 		return -1;
 	}
 
@@ -848,66 +669,33 @@
 	return hdhomerun_device_set_tuner_target(hd, target);
 }
 
-int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target)
+int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_ir_target: device not set\n");
-		return -1;
-	}
+	return hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_UDP); 
+}
 
+int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target)
+{
 	return hdhomerun_control_set(hd->cs, "/ir/target", target, NULL, NULL);
 }
 
 int hdhomerun_device_set_lineup_location(struct hdhomerun_device_t *hd, const char *location)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_lineup_location: device not set\n");
-		return -1;
-	}
-
 	return hdhomerun_control_set(hd->cs, "/lineup/location", location, NULL, NULL);
 }
 
-int hdhomerun_device_set_sys_dvbc_modulation(struct hdhomerun_device_t *hd, const char *modulation_list)
-{
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_sys_dvbc_modulation: device not set\n");
-		return -1;
-	}
-
-	return hdhomerun_control_set(hd->cs, "/sys/dvbc_modulation", modulation_list, NULL, NULL);
-}
-
 int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_var: device not set\n");
-		return -1;
-	}
-
 	return hdhomerun_control_get(hd->cs, name, pvalue, perror);
 }
 
 int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_var: device not set\n");
-		return -1;
-	}
-
 	return hdhomerun_control_set_with_lockkey(hd->cs, name, value, hd->lockkey, pvalue, perror);
 }
 
 int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd, char **perror)
 {
-	if (hd->multicast_ip != 0) {
-		return 1;
-	}
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_tuner_lockkey_request: device not set\n");
-		return -1;
-	}
-
 	uint32_t new_lockkey = (uint32_t)getcurrenttime();
 
 	char name[32];
@@ -928,14 +716,6 @@
 
 int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd)
 {
-	if (hd->multicast_ip != 0) {
-		return 1;
-	}
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_tuner_lockkey_release: device not set\n");
-		return -1;
-	}
-
 	if (hd->lockkey == 0) {
 		return 1;
 	}
@@ -950,14 +730,6 @@
 
 int hdhomerun_device_tuner_lockkey_force(struct hdhomerun_device_t *hd)
 {
-	if (hd->multicast_ip != 0) {
-		return 1;
-	}
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_tuner_lockkey_force: device not set\n");
-		return -1;
-	}
-
 	char name[32];
 	sprintf(name, "/tuner%u/lockkey", hd->tuner);
 	int ret = hdhomerun_control_set(hd->cs, name, "force", NULL, NULL);
@@ -968,17 +740,13 @@
 
 void hdhomerun_device_tuner_lockkey_use_value(struct hdhomerun_device_t *hd, uint32_t lockkey)
 {
-	if (hd->multicast_ip != 0) {
-		return;
-	}
-
 	hd->lockkey = lockkey;
 }
 
 int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status)
 {
 	/* Delay for SS reading to be valid (signal present). */
-	msleep_minimum(250);
+	msleep(250);
 
 	/* Wait for up to 2.5 seconds for lock. */
 	uint64_t timeout = getcurrenttime() + 2500;
@@ -1000,73 +768,51 @@
 			return 1;
 		}
 
-		msleep_approx(250);
+		msleep(250);
 	}
 }
 
 int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd)
 {
-	hdhomerun_device_get_video_sock(hd);
-	if (!hd->vs) {
-		return -1;
-	}
-
 	/* Set target. */
-	if (hd->multicast_ip != 0) {
-		int ret = hdhomerun_video_join_multicast_group(hd->vs, hd->multicast_ip, 0);
-		if (ret <= 0) {
-			return ret;
-		}
-	} else {
-		int ret = hdhomerun_device_set_tuner_target_to_local(hd, HDHOMERUN_TARGET_PROTOCOL_RTP);
-		if (ret == 0) {
-			ret = hdhomerun_device_set_tuner_target_to_local(hd, HDHOMERUN_TARGET_PROTOCOL_UDP);
-		}
-		if (ret <= 0) {
-			return ret;
-		}
+	int ret = hdhomerun_device_stream_refresh_target(hd);
+	if (ret <= 0) {
+		return ret;
 	}
 
 	/* Flush video buffer. */
-	msleep_minimum(64);
+	msleep(64);
 	hdhomerun_video_flush(hd->vs);
 
 	/* Success. */
 	return 1;
 }
 
+int hdhomerun_device_stream_refresh_target(struct hdhomerun_device_t *hd)
+{
+	int ret = hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_RTP);
+	if (ret == 0) {
+		ret = hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_UDP);
+	}
+	return ret;
+}
+
 uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size)
 {
 	if (!hd->vs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_stream_recv: video not initialized\n");
 		return NULL;
 	}
-
 	return hdhomerun_video_recv(hd->vs, max_size, pactual_size);
 }
 
 void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd)
 {
-	if (!hd->vs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_stream_flush: video not initialized\n");
-		return;
-	}
-
 	hdhomerun_video_flush(hd->vs);
 }
 
 void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd)
 {
-	if (!hd->vs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_stream_stop: video not initialized\n");
-		return;
-	}
-
-	if (hd->multicast_ip != 0) {
-		hdhomerun_video_leave_multicast_group(hd->vs);
-	} else {
-		hdhomerun_device_set_tuner_target(hd, "none");
-	}
+	hdhomerun_device_set_tuner_target(hd, "none");
 }
 
 int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap)
@@ -1077,7 +823,6 @@
 
 	hd->scan = channelscan_create(hd, channelmap);
 	if (!hd->scan) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_channelscan_init: failed to create scan object\n");
 		return -1;
 	}
 
@@ -1087,7 +832,6 @@
 int hdhomerun_device_channelscan_advance(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result)
 {
 	if (!hd->scan) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_channelscan_advance: scan not initialized\n");
 		return 0;
 	}
 
@@ -1103,7 +847,6 @@
 int hdhomerun_device_channelscan_detect(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result)
 {
 	if (!hd->scan) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_channelscan_detect: scan not initialized\n");
 		return 0;
 	}
 
@@ -1119,46 +862,52 @@
 uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd)
 {
 	if (!hd->scan) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_channelscan_get_progress: scan not initialized\n");
 		return 0;
 	}
 
 	return channelscan_get_progress(hd->scan);
 }
 
+int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features)
+{
+	uint32_t version;
+	if (hdhomerun_device_get_version(hd, NULL, &version) <= 0) {
+		return -1;
+	}
+
+	if (version < 20070219) {
+		return 0;
+	}
+
+	return 1;
+}
+
 const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd)
 {
 	if (*hd->model) {
 		return hd->model;
 	}
 
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_model_str: device not set\n");
-		return NULL;
-	}
-
 	char *model_str;
 	int ret = hdhomerun_control_get(hd->cs, "/sys/model", &model_str, NULL);
 	if (ret < 0) {
 		return NULL;
 	}
 	if (ret == 0) {
-		model_str = "hdhomerun_atsc";
+		strncpy(hd->model, "hdhomerun_atsc", sizeof(hd->model) - 1);
+		hd->model[sizeof(hd->model) - 1] = 0;
 	}
+	else
+	{
+		strncpy(hd->model, model_str, sizeof(hd->model) - 1);
+		hd->model[sizeof(hd->model) - 1] = 0;
+	}
 
-	strncpy(hd->model, model_str, sizeof(hd->model) - 1);
-	hd->model[sizeof(hd->model) - 1] = 0;
-
 	return hd->model;
 }
 
 int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file)
 {
-	if (!hd->cs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_upgrade: device not set\n");
-		return -1;
-	}
-
 	hdhomerun_control_set(hd->cs, "/tuner0/lockkey", "force", NULL, NULL);
 	hdhomerun_control_set(hd->cs, "/tuner0/channel", "none", NULL, NULL);
 
@@ -1174,23 +923,21 @@
 		return;
 	}
 
-	if (hd->cs) {
-		char name[32];
-		sprintf(name, "/tuner%u/debug", hd->tuner);
+	char name[32];
+	sprintf(name, "/tuner%u/debug", hd->tuner);
 
-		char *debug_str;
-		char *error_str;
-		int ret = hdhomerun_control_get(hd->cs, name, &debug_str, &error_str);
-		if (ret < 0) {
-			hdhomerun_debug_printf(hd->dbg, "video dev: communication error getting debug stats\n");
-			return;
-		}
+	char *debug_str;
+	char *error_str;
+	int ret = hdhomerun_control_get(hd->cs, name, &debug_str, &error_str);
+	if (ret < 0) {
+		hdhomerun_debug_printf(hd->dbg, "video dev: communication error getting debug stats\n");
+		return;
+	}
 
-		if (error_str) {
-			hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", error_str);
-		} else {
-			hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", debug_str);
-		}
+	if (error_str) {
+		hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", error_str);
+	} else {
+		hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", debug_str);
 	}
 
 	if (hd->vs) {
@@ -1200,11 +947,5 @@
 
 void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats)
 {
-	if (!hd->vs) {
-		hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_stream_flush: video not initialized\n");
-		memset(stats, 0, sizeof(struct hdhomerun_video_stats_t));
-		return;
-	}
-
 	hdhomerun_video_get_stats(hd->vs, stats);
 }
Index: mythtv/libs/libmythhdhomerun/hdhomerun_os_windows.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_os_windows.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_os_windows.h	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_os_windows.h
  *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -31,16 +31,12 @@
  */
 
 #define _WINSOCKAPI_
-#if defined(USING_MINGW)
-/* MinGW lacks wspiapi.h; set minimum WINVER to WinXP to remove dependency */
+// MinGW lacks wspiapi, so remove dependency by setting minimum WINVER to WinXP
 #define WINVER 0x0501
-#endif
 #include <windows.h>
 #include <winsock2.h>
 #include <ws2tcpip.h>
-#if !defined(USING_MINGW)
-#include <wspiapi.h>
-#endif
+//#include <wspiapi.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -59,10 +55,7 @@
 #endif
 
 typedef int bool_t;
-#if defined(USING_MINGW)
-#include <stdint.h>
-#include <pthread.h>
-#else
+/* Use MinGW includes instead
 typedef signed __int8 int8_t;
 typedef signed __int16 int16_t;
 typedef signed __int32 int32_t;
@@ -73,9 +66,17 @@
 typedef unsigned __int64 uint64_t;
 typedef HANDLE pthread_t;
 typedef HANDLE pthread_mutex_t;
-#endif
+*/
+#include <stdint.h>
+#include <pthread.h>
 
-#define va_copy(x, y) x = y
+// Avoid #define conflicts by limiting scope to non-c++
+#ifndef __cplusplus
+#define socklen_t int
+#define close closesocket
+#define sock_getlasterror WSAGetLastError()
+#define sock_getlasterror_socktimeout (WSAGetLastError() == WSAETIMEDOUT)
+//#define va_copy(x, y) x = y
 #define atoll _atoi64
 #define strdup _strdup
 #define strcasecmp _stricmp
@@ -84,31 +85,100 @@
 #define ftello _ftelli64
 #define THREAD_FUNC_PREFIX DWORD WINAPI
 #define SIGPIPE SIGABRT
-
-#ifdef __cplusplus
-extern "C" {
 #endif
 
-extern LIBTYPE uint64_t getcurrenttime(void);
-extern LIBTYPE void msleep_approx(uint64_t ms);
-extern LIBTYPE void msleep_minimum(uint64_t ms);
+static inline uint64_t getcurrenttime(void)
+{
+	struct timeb tb;
+	ftime(&tb);
+	return ((uint64_t)tb.time * 1000) + tb.millitm;
+}
 
-#if !defined(PTHREAD_H)
-extern LIBTYPE int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg);
-extern LIBTYPE int pthread_join(pthread_t tid, void **value_ptr);
-extern LIBTYPE void pthread_mutex_init(pthread_mutex_t *mutex, void *attr);
-extern LIBTYPE void pthread_mutex_lock(pthread_mutex_t *mutex);
-extern LIBTYPE void pthread_mutex_unlock(pthread_mutex_t *mutex);
-#endif
+static inline int msleep(unsigned int ms)
+{
+	uint64_t stop_time = getcurrenttime() + ms;
 
+	while (1) {
+		uint64_t current_time = getcurrenttime();
+		if (current_time >= stop_time) {
+			return 0;
+		}
+
+		uint64_t delay_ms = stop_time - current_time;
+		Sleep((DWORD)delay_ms);
+	}
+}
+
+// Avoid a define conflict
+/*static inline int sleep(unsigned int sec)
+{
+	msleep(sec * 1000);
+	return 0;
+}
+*/
+
+static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout)
+{
+	int t = (int)timeout;
+	return setsockopt(s, level, optname, (char *)&t, sizeof(t));
+}
+
+/* MythTV uses pthreads lib instead
+static inline int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg)
+{
+	*tid = CreateThread(NULL, 0, start, arg, 0, NULL);
+	if (!*tid) {
+		return (int)GetLastError();
+	}
+	return 0;
+}
+
+static inline int pthread_join(pthread_t tid, void **value_ptr)
+{
+	while (1) {
+		DWORD ExitCode = 0;
+		if (!GetExitCodeThread(tid, &ExitCode)) {
+			return (int)GetLastError();
+		}
+		if (ExitCode != STILL_ACTIVE) {
+			return 0;
+		}
+	}
+}
+
+static inline void pthread_mutex_init(pthread_mutex_t *mutex, void *attr)
+{
+	*mutex = CreateMutex(NULL, FALSE, NULL);
+}
+
+static inline void pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+	WaitForSingleObject(*mutex, INFINITE);
+}
+
+static inline void pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+	ReleaseMutex(*mutex);
+}
+*/
+
 /*
  * The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing.
  * Attempting to restore on exit fails to restore if the program is terminated by the user.
  * Solution - set the output format each printf.
  */
-extern LIBTYPE void console_vprintf(const char *fmt, va_list ap);
-extern LIBTYPE void console_printf(const char *fmt, ...);
+static inline void console_vprintf(const char *fmt, va_list ap)
+{
+	UINT cp = GetConsoleOutputCP();
+	SetConsoleOutputCP(CP_UTF8);
+	vprintf(fmt, ap);
+	SetConsoleOutputCP(cp);
+}
 
-#ifdef __cplusplus
+static inline void console_printf(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	console_vprintf(fmt, ap);
+	va_end(ap);
 }
-#endif
Index: mythtv/libs/libmythhdhomerun/hdhomerun_device_selector.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_device_selector.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_device_selector.h	(working copy)
@@ -43,17 +43,11 @@
 extern LIBTYPE void hdhomerun_device_selector_destroy(struct hdhomerun_device_selector_t *hds, bool_t destroy_devices);
 
 /*
- * Get the number of devices in the list.
- */
-extern LIBTYPE int hdhomerun_device_selector_get_device_count(struct hdhomerun_device_selector_t *hds);
-
-/*
  * Populate device selector with devices from given source.
- * Returns the number of devices populated.
  */
-extern LIBTYPE int hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t *hds, char *filename);
+extern LIBTYPE void hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t *hds, char *filename);
 #if defined(__WINDOWS__)
-extern LIBTYPE int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource);
+extern LIBTYPE void hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource);
 #endif
 
 /*
Index: mythtv/libs/libmythhdhomerun/hdhomerun_device.h
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_device.h	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_device.h	(working copy)
@@ -90,8 +90,8 @@
 extern LIBTYPE uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd);
 extern LIBTYPE unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd);
 
-extern LIBTYPE int hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip);
-extern LIBTYPE int hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner);
+extern LIBTYPE void hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip);
+extern LIBTYPE void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner);
 extern LIBTYPE int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str);
 
 /*
@@ -148,9 +148,10 @@
 extern LIBTYPE int hdhomerun_device_set_tuner_filter_by_array(struct hdhomerun_device_t *hd, unsigned char filter_array[0x2000]);
 extern LIBTYPE int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program);
 extern LIBTYPE int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, const char *target);
+extern LIBTYPE int hdhomerun_device_set_tuner_target_to_local_protocol(struct hdhomerun_device_t *hd, const char *protocol);
+extern LIBTYPE int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd);
 extern LIBTYPE int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target);
 extern LIBTYPE int hdhomerun_device_set_lineup_location(struct hdhomerun_device_t *hd, const char *location);
-extern LIBTYPE int hdhomerun_device_set_sys_dvbc_modulation(struct hdhomerun_device_t *hd, const char *modulation_list);
 
 /*
  * Get/set a named control variable on the device.
@@ -223,6 +224,7 @@
  * The hdhomerun_device_stream_stop function tells the device to stop streaming data.
  */
 extern LIBTYPE int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd);
+extern LIBTYPE int hdhomerun_device_stream_refresh_target(struct hdhomerun_device_t *hd);
 extern LIBTYPE uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size);
 extern LIBTYPE void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd);
 extern LIBTYPE void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd);
@@ -236,6 +238,17 @@
 extern LIBTYPE uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd);
 
 /*
+ * Check that the device is running the recommended firmware.
+ *
+ * uint32_t features: Reserved for future use. Set to zero.
+ *
+ * Returns 1 if the firmware meets the minimum requriements for all operations.
+ * Returns 0 if th firmware does not meet the minimum requriements for all operations.
+ * Returns -1 if an error occurs.
+ */
+extern LIBTYPE int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features);
+
+/*
  * Upload new firmware to the device.
  *
  * FILE *upgrade_file: File pointer to read from. The file must have been opened in binary mode for reading.
Index: mythtv/libs/libmythhdhomerun/hdhomerun_control.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_control.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_control.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_control.c
  *
- * Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public
@@ -32,9 +32,8 @@
 
 #include "hdhomerun.h"
 
-#define HDHOMERUN_CONTROL_CONNECT_TIMEOUT 2500
-#define HDHOMERUN_CONTROL_SEND_TIMEOUT 2500
-#define HDHOMERUN_CONTROL_RECV_TIMEOUT 2500
+#define HDHOMERUN_CONTROL_SEND_TIMEOUT 5000
+#define HDHOMERUN_CONTROL_RECV_TIMEOUT 5000
 #define HDHOMERUN_CONTROL_UPGRADE_TIMEOUT 20000
 
 struct hdhomerun_control_sock_t {
@@ -50,12 +49,12 @@
 
 static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs)
 {
-	if (cs->sock == HDHOMERUN_SOCK_INVALID) {
+	if (cs->sock == -1) {
 		return;
 	}
 
-	hdhomerun_sock_destroy(cs->sock);
-	cs->sock = HDHOMERUN_SOCK_INVALID;
+	close(cs->sock);
+	cs->sock = -1;
 }
 
 void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip)
@@ -77,7 +76,7 @@
 	}
 
 	cs->dbg = dbg;
-	cs->sock = HDHOMERUN_SOCK_INVALID;
+	cs->sock = -1;
 	hdhomerun_control_set_device(cs, device_id, device_ip);
 
 	return cs;
@@ -91,7 +90,7 @@
 
 static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs)
 {
-	if (cs->sock != HDHOMERUN_SOCK_INVALID) {
+	if (cs->sock != -1) {
 		return TRUE;
 	}
 
@@ -99,10 +98,6 @@
 		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: no device specified\n");
 		return FALSE;
 	}
-	if (hdhomerun_discover_is_ip_multicast(cs->desired_device_ip)) {
-		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: cannot use multicast ip address for device operations\n");
-		return FALSE;
-	}
 
 	/* Find device. */
 	struct hdhomerun_discover_device_t result;
@@ -114,15 +109,24 @@
 	cs->actual_device_id = result.device_id;
 
 	/* Create socket. */
-	cs->sock = hdhomerun_sock_create_tcp();
-	if (cs->sock == HDHOMERUN_SOCK_INVALID) {
-		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to create socket (%d)\n", hdhomerun_sock_getlasterror());
+	cs->sock = (int)socket(AF_INET, SOCK_STREAM, 0);
+	if (cs->sock == -1) {
+		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to create socket (%d)\n", sock_getlasterror);
 		return FALSE;
 	}
 
+	/* Set timeouts. */
+	setsocktimeout(cs->sock, SOL_SOCKET, SO_SNDTIMEO, HDHOMERUN_CONTROL_SEND_TIMEOUT);
+	setsocktimeout(cs->sock, SOL_SOCKET, SO_RCVTIMEO, HDHOMERUN_CONTROL_RECV_TIMEOUT);
+
 	/* Initiate connection. */
-	if (!hdhomerun_sock_connect(cs->sock, cs->actual_device_ip, HDHOMERUN_CONTROL_TCP_PORT, HDHOMERUN_CONTROL_CONNECT_TIMEOUT)) {
-		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to connect (%d)\n", hdhomerun_sock_getlasterror());
+	struct sockaddr_in sock_addr;
+	memset(&sock_addr, 0, sizeof(sock_addr));
+	sock_addr.sin_family = AF_INET;
+	sock_addr.sin_addr.s_addr = htonl(cs->actual_device_ip);
+	sock_addr.sin_port = htons(HDHOMERUN_CONTROL_TCP_PORT);
+	if (connect(cs->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
+		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to connect (%d)\n", sock_getlasterror);
 		hdhomerun_control_close_sock(cs);
 		return FALSE;
 	}
@@ -168,58 +172,76 @@
 		return 0;
 	}
 
-	uint32_t addr = hdhomerun_sock_getsockname_addr(cs->sock);
-	if (addr == 0) {
-		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_local_addr: getsockname failed (%d)\n", hdhomerun_sock_getlasterror());
+	struct sockaddr_in sock_addr;
+	socklen_t sockaddr_size = sizeof(sock_addr);
+	if (getsockname(cs->sock, (struct sockaddr*)&sock_addr, &sockaddr_size) != 0) {
+		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_local_addr: getsockname failed (%d)\n", sock_getlasterror);
 		return 0;
 	}
 
-	return addr;
+	return ntohl(sock_addr.sin_addr.s_addr);
 }
 
-static bool_t hdhomerun_control_send_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt)
+static int hdhomerun_control_send_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt)
 {
-	if (!hdhomerun_sock_send(cs->sock, tx_pkt->start, tx_pkt->end - tx_pkt->start, HDHOMERUN_CONTROL_SEND_TIMEOUT)) {
-		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_sock: send failed (%d)\n", hdhomerun_sock_getlasterror());
+	int length = (int)(tx_pkt->end - tx_pkt->start);
+	if (send(cs->sock, (char *)tx_pkt->start, (int)length, 0) != length) {
+		hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_sock: send failed (%d)\n", sock_getlasterror);
 		hdhomerun_control_close_sock(cs);
-		return FALSE;
+		return -1;
 	}
 
-	return TRUE;
+	return 1;
 }
 
-static bool_t hdhomerun_control_recv_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *rx_pkt, uint16_t *ptype, uint64_t recv_timeout)
+static int hdhomerun_control_recv_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *rx_pkt, uint16_t *ptype, uint64_t recv_timeout)
 {
 	uint64_t stop_time = getcurrenttime() + recv_timeout;
 	hdhomerun_pkt_reset(rx_pkt);
 
-	while (1) {
-		uint64_t current_time = getcurrenttime();
-		if (current_time >= stop_time) {
-			hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: timeout\n");
+	while (getcurrenttime() < stop_time) {
+		struct timeval t;
+		t.tv_sec = 0;
+		t.tv_usec = 250000;
+	
+		fd_set readfds;
+		FD_ZERO(&readfds);
+		FD_SET(cs->sock, &readfds);
+	
+		if (select(cs->sock+1, &readfds, NULL, NULL, &t) < 0) {
+			hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: select failed (%d)\n", sock_getlasterror);
 			hdhomerun_control_close_sock(cs);
-			return FALSE;
+			return -1;
 		}
-
-		size_t length = rx_pkt->limit - rx_pkt->end;
-		if (!hdhomerun_sock_recv(cs->sock, rx_pkt->end, &length, stop_time - current_time)) {
-			hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: recv failed (%d)\n", hdhomerun_sock_getlasterror());
+	
+		if (!FD_ISSET(cs->sock, &readfds)) {
+			continue;
+		}
+	
+		int rx_length = recv(cs->sock, (char *)rx_pkt->end, (int)(rx_pkt->limit - rx_pkt->end), 0);
+		if (rx_length <= 0) {
+			hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: recv failed (%d)\n", sock_getlasterror);
 			hdhomerun_control_close_sock(cs);
-			return FALSE;
+			return -1;
 		}
+		rx_pkt->end += rx_length;
 
-		rx_pkt->end += length;
-
 		int ret = hdhomerun_pkt_open_frame(rx_pkt, ptype);
 		if (ret < 0) {
 			hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: frame error\n");
 			hdhomerun_control_close_sock(cs);
-			return FALSE;
+			return -1;
 		}
-		if (ret > 0) {
-			return TRUE;
+		if (ret == 0) {
+			continue;
 		}
+
+		return 1;
 	}
+
+	hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: timeout\n");
+	hdhomerun_control_close_sock(cs);
+	return -1;
 }
 
 static int hdhomerun_control_send_recv_internal(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type, uint64_t recv_timeout)
@@ -228,14 +250,14 @@
 
 	int i;
 	for (i = 0; i < 2; i++) {
-		if (cs->sock == HDHOMERUN_SOCK_INVALID) {
+		if (cs->sock == -1) {
 			if (!hdhomerun_control_connect_sock(cs)) {
 				hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: connect failed\n");
 				return -1;
 			}
 		}
 
-		if (!hdhomerun_control_send_sock(cs, tx_pkt)) {
+		if (hdhomerun_control_send_sock(cs, tx_pkt) < 0) {
 			continue;
 		}
 		if (!rx_pkt) {
@@ -243,7 +265,7 @@
 		}
 
 		uint16_t rsp_type;
-		if (!hdhomerun_control_recv_sock(cs, rx_pkt, &rsp_type, recv_timeout)) {
+		if (hdhomerun_control_recv_sock(cs, rx_pkt, &rsp_type, recv_timeout) < 0) {
 			continue;
 		}
 		if (rsp_type != type + 1) {
@@ -279,7 +301,7 @@
 	}
 	hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_NAME);
 	hdhomerun_pkt_write_var_length(tx_pkt, name_len);
-	hdhomerun_pkt_write_mem(tx_pkt, (void *)name, name_len);
+	hdhomerun_pkt_write_mem(tx_pkt, (const void *)name, name_len);
 
 	if (value) {
 		int value_len = (int)strlen(value) + 1;
@@ -289,7 +311,7 @@
 		}
 		hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_VALUE);
 		hdhomerun_pkt_write_var_length(tx_pkt, value_len);
-		hdhomerun_pkt_write_mem(tx_pkt, (void *)value, value_len);
+		hdhomerun_pkt_write_mem(tx_pkt, (const void *)value, value_len);
 	}
 
 	if (lockkey != 0) {
Index: mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c
===================================================================
--- mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c	(revision 24016)
+++ mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c	(working copy)
@@ -1,402 +0,0 @@
-/*
- * hdhomerun_sock_posix.c
- *
- * Copyright Â© 2010 Silicondust USA Inc. <www.silicondust.com>.
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * As a special exception to the GNU Lesser General Public License,
- * you may link, statically or dynamically, an application with a
- * publicly distributed version of the Library to produce an
- * executable file containing portions of the Library, and
- * distribute that executable file under terms of your choice,
- * without any of the additional requirements listed in clause 4 of
- * the GNU Lesser General Public License.
- * 
- * By "a publicly distributed version of the Library", we mean
- * either the unmodified Library as distributed by Silicondust, or a
- * modified version of the Library that is distributed under the
- * conditions defined in the GNU Lesser General Public License.
- */
-
-/*
- * Implementation notes:
- *
- * API specifies timeout for each operation (or zero for non-blocking).
- *
- * It is not possible to rely on the OS socket timeout as this will fail to
- * detect the command-response situation where data is sent successfully and
- * the other end chooses not to send a response (other than the TCP ack).
- *
- * The select() cannot be used with high socket numbers (typically max 1024)
- * so the code works as follows:
- * - Use non-blocking sockets to allow operation without select.
- * - Use select where safe (low socket numbers).
- * - Poll with short sleep when select cannot be used safely.
- */
-
-#include "hdhomerun.h"
-
-hdhomerun_sock_t hdhomerun_sock_create_udp(void)
-{
-	/* Create socket. */
-	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0);
-	if (sock == -1) {
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Set non-blocking */
-	if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
-		close(sock);
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Allow broadcast. */
-	int sock_opt = 1;
-	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));
-
-	/* Success. */
-	return sock;
-}
-
-hdhomerun_sock_t hdhomerun_sock_create_tcp(void)
-{
-	/* Create socket. */
-	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_STREAM, 0);
-	if (sock == -1) {
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Set non-blocking */
-	if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
-		close(sock);
-		return HDHOMERUN_SOCK_INVALID;
-	}
-
-	/* Success. */
-	return sock;
-}
-
-void hdhomerun_sock_destroy(hdhomerun_sock_t sock)
-{
-	close(sock);
-}
-
-int hdhomerun_sock_getlasterror(void)
-{
-	return errno;
-}
-
-uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock)
-{
-	struct sockaddr_in sock_addr;
-	socklen_t sockaddr_size = sizeof(sock_addr);
-
-	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return 0;
-	}
-
-	return ntohl(sock_addr.sin_addr.s_addr);
-}
-
-uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock)
-{
-	struct sockaddr_in sock_addr;
-	socklen_t sockaddr_size = sizeof(sock_addr);
-
-	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return 0;
-	}
-
-	return ntohs(sock_addr.sin_port);
-}
-
-uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock)
-{
-	struct sockaddr_in sock_addr;
-	socklen_t sockaddr_size = sizeof(sock_addr);
-
-	if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
-		return 0;
-	}
-
-	return ntohl(sock_addr.sin_addr.s_addr);
-}
-
-#if defined(__CYGWIN__)
-uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name)
-{
-	return 0;
-}
-#else
-uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name)
-{
-	struct addrinfo hints;
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_protocol = IPPROTO_TCP;
-
-	struct addrinfo *sock_info;
-	if (getaddrinfo(name, "", &hints, &sock_info) != 0) {
-		return 0;
-	}
-
-	struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr;
-	uint32_t addr = ntohl(sock_addr->sin_addr.s_addr);
-
-	freeaddrinfo(sock_info);
-	return addr;
-}
-#endif
-
-bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port)
-{
-	struct sockaddr_in sock_addr;
-	memset(&sock_addr, 0, sizeof(sock_addr));
-	sock_addr.sin_family = AF_INET;
-	sock_addr.sin_addr.s_addr = htonl(local_addr);
-	sock_addr.sin_port = htons(local_port);
-
-	if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static bool_t hdhomerun_sock_wait_for_read_event(hdhomerun_sock_t sock, uint64_t stop_time)
-{
-	uint64_t current_time = getcurrenttime();
-	if (current_time >= stop_time) {
-		return FALSE;
-	}
-
-	if (sock < FD_SETSIZE) {
-		uint64_t timeout = stop_time - current_time;
-		struct timeval t;
-		t.tv_sec = timeout / 1000;
-		t.tv_usec = (timeout % 1000) * 1000;
-
-		fd_set readfds;
-		FD_ZERO(&readfds);
-		FD_SET(sock, &readfds);
-
-		fd_set errorfds;
-		FD_ZERO(&errorfds);
-		FD_SET(sock, &errorfds);
-
-		if (select(sock + 1, &readfds, NULL, &errorfds, &t) <= 0) {
-			return FALSE;
-		}
-		if (!FD_ISSET(sock, &readfds)) {
-			return FALSE;
-		}
-	} else {
-		uint64_t delay = stop_time - current_time;
-		if (delay > 5) {
-			delay = 5;
-		}
-
-		msleep_approx(delay);
-	}
-
-	return TRUE;
-}
-
-static bool_t hdhomerun_sock_wait_for_write_event(hdhomerun_sock_t sock, uint64_t stop_time)
-{
-	uint64_t current_time = getcurrenttime();
-	if (current_time >= stop_time) {
-		return FALSE;
-	}
-
-	if (sock < FD_SETSIZE) {
-		uint64_t timeout = stop_time - current_time;
-		struct timeval t;
-		t.tv_sec = timeout / 1000;
-		t.tv_usec = (timeout % 1000) * 1000;
-
-		fd_set writefds;
-		FD_ZERO(&writefds);
-		FD_SET(sock, &writefds);
-
-		fd_set errorfds;
-		FD_ZERO(&errorfds);
-		FD_SET(sock, &errorfds);
-
-		if (select(sock + 1, NULL, &writefds, &errorfds, &t) <= 0) {
-			return FALSE;
-		}
-		if (!FD_ISSET(sock, &writefds)) {
-			return FALSE;
-		}
-	} else {
-		uint64_t delay = stop_time - current_time;
-		if (delay > 5) {
-			delay = 5;
-		}
-
-		msleep_approx(delay);
-	}
-
-	return TRUE;
-}
-
-bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
-{
-	struct sockaddr_in sock_addr;
-	memset(&sock_addr, 0, sizeof(sock_addr));
-	sock_addr.sin_family = AF_INET;
-	sock_addr.sin_addr.s_addr = htonl(remote_addr);
-	sock_addr.sin_port = htons(remote_port);
-
-	if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) == 0) {
-		return TRUE;
-	}
-
-	uint64_t stop_time = getcurrenttime() + timeout;
-
-	/*
-	 * getpeername() is used to detect if connect succeeded. Bug - cygwin
-	 * will return getpeername success even if the connect process hasn't
-	 * completed. This first call to select is used to work around the
-	 * problem (at least for low numbered sockets where select is used).
-	 */
-	if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
-		return FALSE;
-	}
-
-	while (1) {
-		struct sockaddr_in sock_addr;
-		socklen_t sockaddr_size = sizeof(sock_addr);
-		if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) == 0) {
-			return TRUE;
-		}
-
-		if (errno != ENOTCONN) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-	const uint8_t *ptr = (uint8_t *)data;
-
-	while (1) {
-		int ret = send(sock, ptr, length, 0);
-		if (ret >= (int)length) {
-			return TRUE;
-		}
-
-		if (ret > 0) {
-			ptr += ret;
-			length -= ret;
-		}
-
-		if (errno != EWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-	const uint8_t *ptr = (uint8_t *)data;
-
-	while (1) {
-		struct sockaddr_in sock_addr;
-		memset(&sock_addr, 0, sizeof(sock_addr));
-		sock_addr.sin_family = AF_INET;
-		sock_addr.sin_addr.s_addr = htonl(remote_addr);
-		sock_addr.sin_port = htons(remote_port);
-
-		int ret = sendto(sock, ptr, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
-		if (ret >= (int)length) {
-			return TRUE;
-		}
-
-		if (ret > 0) {
-			ptr += ret;
-			length -= ret;
-		}
-
-		if (errno != EWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-
-	while (1) {
-		int ret = recv(sock, data, *length, 0);
-		if (ret > 0) {
-			*length = ret;
-			return TRUE;
-		}
-
-		if (errno != EWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_read_event(sock, stop_time)) {
-			return FALSE;
-		}
-	}
-}
-
-bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout)
-{
-	uint64_t stop_time = getcurrenttime() + timeout;
-
-	while (1) {
-		struct sockaddr_in sock_addr;
-		memset(&sock_addr, 0, sizeof(sock_addr));
-		socklen_t sockaddr_size = sizeof(sock_addr);
-
-		int ret = recvfrom(sock, data, *length, 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
-		if (ret > 0) {
-			*remote_addr = ntohl(sock_addr.sin_addr.s_addr);
-			*remote_port = ntohs(sock_addr.sin_port);
-			*length = ret;
-			return TRUE;
-		}
-
-		if (errno != EWOULDBLOCK) {
-			return FALSE;
-		}
-
-		if (!hdhomerun_sock_wait_for_read_event(sock, stop_time)) {
-			return FALSE;
-		}
-	}
-}
