mirror of
https://github.com/Silicondust/libhdhomerun
synced 2025-08-21 14:03:25 -07:00
support sending keepalive packets when streaming udp/rtp
This commit is contained in:
parent
7671e9862b
commit
3bfae366c3
3 changed files with 63 additions and 8 deletions
|
@ -1145,6 +1145,8 @@ int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdhomerun_video_set_keepalive(hd->vs, 0, 0, 0);
|
||||||
|
|
||||||
/* Set target. */
|
/* Set target. */
|
||||||
if (hd->multicast_ip != 0) {
|
if (hd->multicast_ip != 0) {
|
||||||
int ret = hdhomerun_video_join_multicast_group(hd->vs, hd->multicast_ip, 0);
|
int ret = hdhomerun_video_join_multicast_group(hd->vs, hd->multicast_ip, 0);
|
||||||
|
@ -1159,6 +1161,9 @@ int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd)
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t remote_ip = hdhomerun_control_get_device_ip(hd->cs);
|
||||||
|
hdhomerun_video_set_keepalive(hd->vs, remote_ip, 5004, hd->lockkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush video buffer. */
|
/* Flush video buffer. */
|
||||||
|
|
|
@ -25,6 +25,11 @@ struct hdhomerun_video_sock_t {
|
||||||
struct hdhomerun_debug_t *dbg;
|
struct hdhomerun_debug_t *dbg;
|
||||||
struct hdhomerun_sock_t *sock;
|
struct hdhomerun_sock_t *sock;
|
||||||
|
|
||||||
|
uint32_t keepalive_lockkey;
|
||||||
|
uint32_t keepalive_addr;
|
||||||
|
uint16_t keepalive_port;
|
||||||
|
volatile bool_t keepalive_start;
|
||||||
|
|
||||||
volatile size_t head;
|
volatile size_t head;
|
||||||
volatile size_t tail;
|
volatile size_t tail;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
|
@ -128,6 +133,21 @@ void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs)
|
||||||
free(vs);
|
free(vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hdhomerun_video_set_keepalive(struct hdhomerun_video_sock_t *vs, uint32_t remote_addr, uint32_t remote_port, uint32_t lockkey)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&vs->lock);
|
||||||
|
|
||||||
|
vs->keepalive_addr = remote_addr;
|
||||||
|
vs->keepalive_port = remote_port;
|
||||||
|
vs->keepalive_lockkey = lockkey;
|
||||||
|
|
||||||
|
if ((remote_addr != 0) && (remote_port != 0)) {
|
||||||
|
vs->keepalive_start = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&vs->lock);
|
||||||
|
}
|
||||||
|
|
||||||
struct hdhomerun_sock_t *hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs)
|
struct hdhomerun_sock_t *hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs)
|
||||||
{
|
{
|
||||||
return vs->sock;
|
return vs->sock;
|
||||||
|
@ -222,26 +242,51 @@ static void hdhomerun_video_parse_rtp(struct hdhomerun_video_sock_t *vs, struct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hdhomerun_video_thread_send_keepalive(struct hdhomerun_video_sock_t *vs)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&vs->lock);
|
||||||
|
uint32_t keepalive_lockkey = vs->keepalive_lockkey;
|
||||||
|
uint32_t keepalive_addr = vs->keepalive_addr;
|
||||||
|
uint16_t keepalive_port = vs->keepalive_port;
|
||||||
|
vs->keepalive_start = FALSE;
|
||||||
|
pthread_mutex_unlock(&vs->lock);
|
||||||
|
|
||||||
|
if ((keepalive_addr == 0) || (keepalive_port == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hdhomerun_pkt_t pkt;
|
||||||
|
hdhomerun_pkt_reset(&pkt);
|
||||||
|
hdhomerun_pkt_write_u32(&pkt, keepalive_lockkey);
|
||||||
|
hdhomerun_sock_sendto(vs->sock, keepalive_addr, keepalive_port, pkt.start, pkt.end - pkt.start, 25);
|
||||||
|
}
|
||||||
|
|
||||||
static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg)
|
static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg)
|
||||||
{
|
{
|
||||||
struct hdhomerun_video_sock_t *vs = (struct hdhomerun_video_sock_t *)arg;
|
struct hdhomerun_video_sock_t *vs = (struct hdhomerun_video_sock_t *)arg;
|
||||||
struct hdhomerun_pkt_t pkt_inst;
|
uint64_t send_time = getcurrenttime();
|
||||||
|
|
||||||
while (!vs->terminate) {
|
while (!vs->terminate) {
|
||||||
struct hdhomerun_pkt_t *pkt = &pkt_inst;
|
uint64_t current_time = getcurrenttime();
|
||||||
hdhomerun_pkt_reset(pkt);
|
if (vs->keepalive_start || (current_time >= send_time)) {
|
||||||
|
hdhomerun_video_thread_send_keepalive(vs);
|
||||||
|
send_time = current_time + 1000;
|
||||||
|
}
|
||||||
|
|
||||||
/* Receive. */
|
/* Receive. */
|
||||||
|
struct hdhomerun_pkt_t pkt;
|
||||||
|
hdhomerun_pkt_reset(&pkt);
|
||||||
|
|
||||||
size_t length = VIDEO_RTP_DATA_PACKET_SIZE;
|
size_t length = VIDEO_RTP_DATA_PACKET_SIZE;
|
||||||
if (!hdhomerun_sock_recv(vs->sock, pkt->end, &length, 25)) {
|
if (!hdhomerun_sock_recv(vs->sock, pkt.end, &length, 25)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt->end += length;
|
pkt.end += length;
|
||||||
|
|
||||||
if (length == VIDEO_RTP_DATA_PACKET_SIZE) {
|
if (length == VIDEO_RTP_DATA_PACKET_SIZE) {
|
||||||
hdhomerun_video_parse_rtp(vs, pkt);
|
hdhomerun_video_parse_rtp(vs, &pkt);
|
||||||
length = pkt->end - pkt->pos;
|
length = pkt.end - pkt.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length != VIDEO_DATA_PACKET_SIZE) {
|
if (length != VIDEO_DATA_PACKET_SIZE) {
|
||||||
|
@ -254,7 +299,7 @@ static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg)
|
||||||
/* Store in ring buffer. */
|
/* Store in ring buffer. */
|
||||||
size_t head = vs->head;
|
size_t head = vs->head;
|
||||||
uint8_t *ptr = vs->buffer + head;
|
uint8_t *ptr = vs->buffer + head;
|
||||||
memcpy(ptr, pkt->pos, length);
|
memcpy(ptr, pkt.pos, length);
|
||||||
|
|
||||||
/* Stats. */
|
/* Stats. */
|
||||||
vs->packet_count++;
|
vs->packet_count++;
|
||||||
|
|
|
@ -51,6 +51,11 @@ struct hdhomerun_video_stats_t {
|
||||||
extern LIBHDHOMERUN_API struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool_t allow_port_reuse, size_t buffer_size, struct hdhomerun_debug_t *dbg);
|
extern LIBHDHOMERUN_API struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool_t allow_port_reuse, size_t buffer_size, struct hdhomerun_debug_t *dbg);
|
||||||
extern LIBHDHOMERUN_API void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs);
|
extern LIBHDHOMERUN_API void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure to send a keepalive packet every second.
|
||||||
|
*/
|
||||||
|
extern LIBHDHOMERUN_API void hdhomerun_video_set_keepalive(struct hdhomerun_video_sock_t *vs, uint32_t remote_addr, uint32_t remote_port, uint32_t lockkey);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the port the socket is listening on.
|
* Get the port the socket is listening on.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue