mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-27 09:38:17 +00:00
gst/net/: Use the timepacket stuff in the provider, include it from gstnet.h, and add it to the build.
Original commit message from CVS: 2005-11-16 Andy Wingo <wingo@pobox.com> * gst/net/Makefile.am: * gst/net/gstnet.h: * gst/net/gstnettimeprovider.c: * gst/net/gstnettimeprovider.h: Use the timepacket stuff in the provider, include it from gstnet.h, and add it to the build. * gst/net/gstnettimepacket.h: * gst/net/gstnettimepacket.c: New files, abstracts out the packet sending and receiving.
This commit is contained in:
parent
578f2ae633
commit
fec8e1db7d
13 changed files with 534 additions and 88 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2005-11-16 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* gst/net/Makefile.am:
|
||||||
|
* gst/net/gstnet.h:
|
||||||
|
* gst/net/gstnettimeprovider.c:
|
||||||
|
* gst/net/gstnettimeprovider.h: Use the timepacket stuff in the
|
||||||
|
provider, include it from gstnet.h, and add it to the build.
|
||||||
|
|
||||||
|
* gst/net/gstnettimepacket.h:
|
||||||
|
* gst/net/gstnettimepacket.c: New files, abstracts out the packet
|
||||||
|
sending and receiving.
|
||||||
|
|
||||||
2005-11-16 Wim Taymans <wim@fluendo.com>
|
2005-11-16 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* check/Makefile.am:
|
* check/Makefile.am:
|
||||||
|
|
|
@ -49,6 +49,26 @@ GST_START_TEST (test_refcounts)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
GST_START_TEST (test_functioning)
|
||||||
|
{
|
||||||
|
GstNetTimeProvider *ntp;
|
||||||
|
GstClock *clock;
|
||||||
|
|
||||||
|
clock = gst_system_clock_obtain ();
|
||||||
|
fail_unless (clock != NULL, "failed to get system clock");
|
||||||
|
ntp = gst_net_time_provider_new (clock, NULL, -1);
|
||||||
|
fail_unless (ntp != NULL, "failed to create net time provider");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gst_object_unref (ntp);
|
||||||
|
gst_object_unref (clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
#endif
|
||||||
|
|
||||||
Suite *
|
Suite *
|
||||||
gst_net_time_provider_suite (void)
|
gst_net_time_provider_suite (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,9 +5,11 @@ lib_LTLIBRARIES = libgstnet-tempname-@GST_MAJORMINOR@.la
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/net
|
libgstnet_tempname_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/net
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_include_HEADERS = \
|
libgstnet_tempname_@GST_MAJORMINOR@_include_HEADERS = \
|
||||||
gstnet.h \
|
gstnet.h \
|
||||||
|
gstnettimepacker.h \
|
||||||
gstnettimeprovider.h
|
gstnettimeprovider.h
|
||||||
|
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
|
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
|
||||||
|
gstnettimepacket.c \
|
||||||
gstnettimeprovider.c
|
gstnettimeprovider.c
|
||||||
|
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
|
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define __GST_NET_H__
|
#define __GST_NET_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <gst/net/gstnettimepacket.h>
|
||||||
#include <gst/net/gstnettimeprovider.h>
|
#include <gst/net/gstnettimeprovider.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
167
gst/net/gstnettimepacket.c
Normal file
167
gst/net/gstnettimepacket.c
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gstnettimepacket.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_new:
|
||||||
|
* @buffer: a buffer from which to construct the packet, or NULL
|
||||||
|
*
|
||||||
|
* Creates a new #GstNetTimePacket from a buffer received over the network. The
|
||||||
|
* caller is responsible for ensuring that @buffer is at least
|
||||||
|
* #GST_NET_TIME_PACKET_SIZE bytes long.
|
||||||
|
*
|
||||||
|
* If @buffer is #NULL, the local and remote times will be set to
|
||||||
|
* #GST_CLOCK_TIME_NONE.
|
||||||
|
*
|
||||||
|
* MT safe. Caller owns return value (g_free to free).
|
||||||
|
*
|
||||||
|
* Returns: The new #GstNetTimePacket.
|
||||||
|
*/
|
||||||
|
GstNetTimePacket *
|
||||||
|
gst_net_time_packet_new (const guint8 * buffer)
|
||||||
|
{
|
||||||
|
GstNetTimePacket *ret;
|
||||||
|
|
||||||
|
g_assert (sizeof (GstClockTime) == 8);
|
||||||
|
|
||||||
|
ret = g_new0 (GstNetTimePacket, 1);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
ret->local_time = GST_READ_UINT64_BE (buffer);
|
||||||
|
ret->remote_time = GST_READ_UINT64_BE (buffer + sizeof (GstClockTime));
|
||||||
|
} else {
|
||||||
|
ret->local_time = GST_CLOCK_TIME_NONE;
|
||||||
|
ret->remote_time = GST_CLOCK_TIME_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_serialize:
|
||||||
|
* @packet: the #GstNetTimePacket
|
||||||
|
*
|
||||||
|
* Serialized a #GstNetTimePacket into a newly-allocated sequence of
|
||||||
|
* #GST_NET_TIME_PACKET_SIZE bytes, in network byte order. The value returned is
|
||||||
|
* suitable for passing to write(2) or sendto(2) for communication over the
|
||||||
|
* network.
|
||||||
|
*
|
||||||
|
* MT safe. Caller owns return value (g_free to free).
|
||||||
|
*
|
||||||
|
* Returns: A newly allocated sequence of #GST_NET_TIME_PACKET_SIZE bytes.
|
||||||
|
*/
|
||||||
|
guint8 *
|
||||||
|
gst_net_time_packet_serialize (const GstNetTimePacket * packet)
|
||||||
|
{
|
||||||
|
guint8 *ret;
|
||||||
|
|
||||||
|
g_assert (sizeof (GstClockTime) == 8);
|
||||||
|
|
||||||
|
ret = g_new0 (guint8, GST_NET_TIME_PACKET_SIZE);
|
||||||
|
|
||||||
|
GST_WRITE_UINT64_BE (ret, packet->local_time);
|
||||||
|
GST_WRITE_UINT64_BE (ret + sizeof (GstClockTime), packet->remote_time);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_receive:
|
||||||
|
* @sockfd: a file descriptor created by socket(2)
|
||||||
|
* @addr: a pointer to a sockaddr to hold the address of the sender
|
||||||
|
* @len: a pointer to the size of the data pointed to by @addr
|
||||||
|
*
|
||||||
|
* Receives a #GstNetTimePacket over a socket. Handles interrupted system calls,
|
||||||
|
* but otherwise returns NULL on error. See recvfrom(2) for more information on
|
||||||
|
* how to interpret @sockaddr.
|
||||||
|
*
|
||||||
|
* MT safe. Caller owns return value (g_free to free).
|
||||||
|
*
|
||||||
|
* Returns: The new #GstNetTimePacket.
|
||||||
|
*/
|
||||||
|
GstNetTimePacket *
|
||||||
|
gst_net_time_packet_receive (gint fd, struct sockaddr * addr, socklen_t * len)
|
||||||
|
{
|
||||||
|
guint8 buffer[GST_NET_TIME_PACKET_SIZE];
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
ret = recvfrom (fd, buffer, GST_NET_TIME_PACKET_SIZE,
|
||||||
|
0, (struct sockaddr *) addr, len);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno != EAGAIN && errno != EINTR)
|
||||||
|
goto receive_error;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
} else if (ret < GST_NET_TIME_PACKET_SIZE) {
|
||||||
|
goto short_packet;
|
||||||
|
} else {
|
||||||
|
return gst_net_time_packet_new (buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receive_error:
|
||||||
|
{
|
||||||
|
GST_DEBUG ("receive error %d: %s (%d)", ret, g_strerror (errno), errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
short_packet:
|
||||||
|
{
|
||||||
|
GST_DEBUG ("someone sent us a short packet (%d < %d)",
|
||||||
|
ret, GST_NET_TIME_PACKET_SIZE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_send:
|
||||||
|
* @packet: the #GstNetTimePacket
|
||||||
|
* @sockfd: a file descriptor created by socket(2)
|
||||||
|
* @addr: a pointer to a sockaddr to hold the address of the sender
|
||||||
|
* @len: the size of the data pointed to by @addr
|
||||||
|
*
|
||||||
|
* Sends a #GstNetTimePacket over a socket. Essentially a thin wrapper around
|
||||||
|
* sendto(2) and gst_net_time_packet_serialize().
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Returns: The return value of sendto(2).
|
||||||
|
*/
|
||||||
|
gint
|
||||||
|
gst_net_time_packet_send (const GstNetTimePacket * packet, gint fd,
|
||||||
|
struct sockaddr * addr, socklen_t len)
|
||||||
|
{
|
||||||
|
guint8 *buffer;
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (packet != NULL, -EINVAL);
|
||||||
|
|
||||||
|
buffer = gst_net_time_packet_serialize (packet);
|
||||||
|
|
||||||
|
ret = sendto (fd, buffer, GST_NET_TIME_PACKET_SIZE, MSG_DONTWAIT, addr, len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
57
gst/net/gstnettimepacket.h
Normal file
57
gst/net/gstnettimepacket.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GST_NET_TIME_PACKET_H__
|
||||||
|
#define __GST_NET_TIME_PACKET_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define GST_NET_TIME_PACKET_SIZE 16
|
||||||
|
|
||||||
|
typedef struct _GstNetTimePacket GstNetTimePacket;
|
||||||
|
|
||||||
|
struct _GstNetTimePacket {
|
||||||
|
GstClockTime local_time;
|
||||||
|
GstClockTime remote_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
GstNetTimePacket* gst_net_time_packet_new (const guint8 *buffer);
|
||||||
|
guint8* gst_net_time_packet_serialize (const GstNetTimePacket *packet);
|
||||||
|
|
||||||
|
GstNetTimePacket* gst_net_time_packet_receive (gint fd, struct sockaddr *addr,
|
||||||
|
socklen_t *len);
|
||||||
|
gint gst_net_time_packet_send (const GstNetTimePacket *packet,
|
||||||
|
gint fd, struct sockaddr *addr,
|
||||||
|
socklen_t len);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GST_NET_TIME_PACKET_H__ */
|
|
@ -23,6 +23,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstnettimeprovider.h"
|
#include "gstnettimeprovider.h"
|
||||||
|
#include "gstnettimepacket.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
@ -55,17 +57,6 @@ G_STMT_START { \
|
||||||
#define DEFAULT_ADDRESS "0.0.0.0"
|
#define DEFAULT_ADDRESS "0.0.0.0"
|
||||||
#define DEFAULT_PORT 5637
|
#define DEFAULT_PORT 5637
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstClockTime slave_time_sent;
|
|
||||||
GstClockTime master_time_received;
|
|
||||||
} NetworkTimePacket;
|
|
||||||
|
|
||||||
/* 2 * sizeof(GstClockTime), verified in base_init */
|
|
||||||
#define NETWORK_TIME_PACKET_SIZE 16
|
|
||||||
#define NETWORK_TIME_PACKET_SET_MASTER_TIME(p, t) \
|
|
||||||
GST_WRITE_UINT64_BE(p+8, t)
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -171,7 +162,7 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
guint max_sock;
|
guint max_sock;
|
||||||
gchar *pktdata;
|
GstNetTimePacket *packet;
|
||||||
gint ret;
|
gint ret;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -218,35 +209,22 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* got data in */
|
/* got data in */
|
||||||
pktdata = g_malloc (NETWORK_TIME_PACKET_SIZE);
|
|
||||||
|
|
||||||
len = sizeof (struct sockaddr);
|
len = sizeof (struct sockaddr);
|
||||||
while (TRUE) {
|
|
||||||
ret = recvfrom (self->sock, pktdata, NETWORK_TIME_PACKET_SIZE,
|
|
||||||
0, (struct sockaddr *) &tmpaddr, &len);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno != EAGAIN && errno != EINTR)
|
|
||||||
goto receive_error;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
} else if (ret < NETWORK_TIME_PACKET_SIZE) {
|
|
||||||
goto short_packet;
|
|
||||||
} else {
|
|
||||||
GstClockTime now;
|
|
||||||
|
|
||||||
now = gst_clock_get_time (self->clock);
|
packet = gst_net_time_packet_receive (self->sock,
|
||||||
|
(struct sockaddr *) &tmpaddr, &len);
|
||||||
|
|
||||||
NETWORK_TIME_PACKET_SET_MASTER_TIME (pktdata, time);
|
if (!packet)
|
||||||
|
goto receive_error;
|
||||||
|
|
||||||
/* ignore errors */
|
/* do what we were asked to and send the packet back */
|
||||||
sendto (self->sock, pktdata, ret, MSG_DONTWAIT,
|
packet->remote_time = gst_clock_get_time (self->clock);
|
||||||
(struct sockaddr *) &tmpaddr, len);
|
|
||||||
|
|
||||||
break;
|
/* ignore errors */
|
||||||
}
|
gst_net_time_packet_send (packet, self->sock,
|
||||||
|
(struct sockaddr *) &tmpaddr, len);
|
||||||
|
|
||||||
g_assert_not_reached ();
|
g_free (packet);
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -260,12 +238,6 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
g_strerror (errno), errno);
|
g_strerror (errno), errno);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
short_packet:
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (self, "someone sent us a short packet (%d < %d)",
|
|
||||||
ret, NETWORK_TIME_PACKET_SIZE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stopped:
|
stopped:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (self, "shutting down");
|
GST_DEBUG_OBJECT (self, "shutting down");
|
||||||
|
@ -274,9 +246,7 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
}
|
}
|
||||||
receive_error:
|
receive_error:
|
||||||
{
|
{
|
||||||
g_free (pktdata);
|
GST_DEBUG_OBJECT (self, "receive error");
|
||||||
GST_DEBUG_OBJECT (self, "receive error %d: %s (%d)", ret,
|
|
||||||
g_strerror (errno), errno);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@ lib_LTLIBRARIES = libgstnet-tempname-@GST_MAJORMINOR@.la
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/net
|
libgstnet_tempname_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/net
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_include_HEADERS = \
|
libgstnet_tempname_@GST_MAJORMINOR@_include_HEADERS = \
|
||||||
gstnet.h \
|
gstnet.h \
|
||||||
|
gstnettimepacker.h \
|
||||||
gstnettimeprovider.h
|
gstnettimeprovider.h
|
||||||
|
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
|
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
|
||||||
|
gstnettimepacket.c \
|
||||||
gstnettimeprovider.c
|
gstnettimeprovider.c
|
||||||
|
|
||||||
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
|
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define __GST_NET_H__
|
#define __GST_NET_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <gst/net/gstnettimepacket.h>
|
||||||
#include <gst/net/gstnettimeprovider.h>
|
#include <gst/net/gstnettimeprovider.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
167
libs/gst/net/gstnettimepacket.c
Normal file
167
libs/gst/net/gstnettimepacket.c
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gstnettimepacket.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_new:
|
||||||
|
* @buffer: a buffer from which to construct the packet, or NULL
|
||||||
|
*
|
||||||
|
* Creates a new #GstNetTimePacket from a buffer received over the network. The
|
||||||
|
* caller is responsible for ensuring that @buffer is at least
|
||||||
|
* #GST_NET_TIME_PACKET_SIZE bytes long.
|
||||||
|
*
|
||||||
|
* If @buffer is #NULL, the local and remote times will be set to
|
||||||
|
* #GST_CLOCK_TIME_NONE.
|
||||||
|
*
|
||||||
|
* MT safe. Caller owns return value (g_free to free).
|
||||||
|
*
|
||||||
|
* Returns: The new #GstNetTimePacket.
|
||||||
|
*/
|
||||||
|
GstNetTimePacket *
|
||||||
|
gst_net_time_packet_new (const guint8 * buffer)
|
||||||
|
{
|
||||||
|
GstNetTimePacket *ret;
|
||||||
|
|
||||||
|
g_assert (sizeof (GstClockTime) == 8);
|
||||||
|
|
||||||
|
ret = g_new0 (GstNetTimePacket, 1);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
ret->local_time = GST_READ_UINT64_BE (buffer);
|
||||||
|
ret->remote_time = GST_READ_UINT64_BE (buffer + sizeof (GstClockTime));
|
||||||
|
} else {
|
||||||
|
ret->local_time = GST_CLOCK_TIME_NONE;
|
||||||
|
ret->remote_time = GST_CLOCK_TIME_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_serialize:
|
||||||
|
* @packet: the #GstNetTimePacket
|
||||||
|
*
|
||||||
|
* Serialized a #GstNetTimePacket into a newly-allocated sequence of
|
||||||
|
* #GST_NET_TIME_PACKET_SIZE bytes, in network byte order. The value returned is
|
||||||
|
* suitable for passing to write(2) or sendto(2) for communication over the
|
||||||
|
* network.
|
||||||
|
*
|
||||||
|
* MT safe. Caller owns return value (g_free to free).
|
||||||
|
*
|
||||||
|
* Returns: A newly allocated sequence of #GST_NET_TIME_PACKET_SIZE bytes.
|
||||||
|
*/
|
||||||
|
guint8 *
|
||||||
|
gst_net_time_packet_serialize (const GstNetTimePacket * packet)
|
||||||
|
{
|
||||||
|
guint8 *ret;
|
||||||
|
|
||||||
|
g_assert (sizeof (GstClockTime) == 8);
|
||||||
|
|
||||||
|
ret = g_new0 (guint8, GST_NET_TIME_PACKET_SIZE);
|
||||||
|
|
||||||
|
GST_WRITE_UINT64_BE (ret, packet->local_time);
|
||||||
|
GST_WRITE_UINT64_BE (ret + sizeof (GstClockTime), packet->remote_time);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_receive:
|
||||||
|
* @sockfd: a file descriptor created by socket(2)
|
||||||
|
* @addr: a pointer to a sockaddr to hold the address of the sender
|
||||||
|
* @len: a pointer to the size of the data pointed to by @addr
|
||||||
|
*
|
||||||
|
* Receives a #GstNetTimePacket over a socket. Handles interrupted system calls,
|
||||||
|
* but otherwise returns NULL on error. See recvfrom(2) for more information on
|
||||||
|
* how to interpret @sockaddr.
|
||||||
|
*
|
||||||
|
* MT safe. Caller owns return value (g_free to free).
|
||||||
|
*
|
||||||
|
* Returns: The new #GstNetTimePacket.
|
||||||
|
*/
|
||||||
|
GstNetTimePacket *
|
||||||
|
gst_net_time_packet_receive (gint fd, struct sockaddr * addr, socklen_t * len)
|
||||||
|
{
|
||||||
|
guint8 buffer[GST_NET_TIME_PACKET_SIZE];
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
ret = recvfrom (fd, buffer, GST_NET_TIME_PACKET_SIZE,
|
||||||
|
0, (struct sockaddr *) addr, len);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno != EAGAIN && errno != EINTR)
|
||||||
|
goto receive_error;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
} else if (ret < GST_NET_TIME_PACKET_SIZE) {
|
||||||
|
goto short_packet;
|
||||||
|
} else {
|
||||||
|
return gst_net_time_packet_new (buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receive_error:
|
||||||
|
{
|
||||||
|
GST_DEBUG ("receive error %d: %s (%d)", ret, g_strerror (errno), errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
short_packet:
|
||||||
|
{
|
||||||
|
GST_DEBUG ("someone sent us a short packet (%d < %d)",
|
||||||
|
ret, GST_NET_TIME_PACKET_SIZE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_net_time_packet_send:
|
||||||
|
* @packet: the #GstNetTimePacket
|
||||||
|
* @sockfd: a file descriptor created by socket(2)
|
||||||
|
* @addr: a pointer to a sockaddr to hold the address of the sender
|
||||||
|
* @len: the size of the data pointed to by @addr
|
||||||
|
*
|
||||||
|
* Sends a #GstNetTimePacket over a socket. Essentially a thin wrapper around
|
||||||
|
* sendto(2) and gst_net_time_packet_serialize().
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Returns: The return value of sendto(2).
|
||||||
|
*/
|
||||||
|
gint
|
||||||
|
gst_net_time_packet_send (const GstNetTimePacket * packet, gint fd,
|
||||||
|
struct sockaddr * addr, socklen_t len)
|
||||||
|
{
|
||||||
|
guint8 *buffer;
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (packet != NULL, -EINVAL);
|
||||||
|
|
||||||
|
buffer = gst_net_time_packet_serialize (packet);
|
||||||
|
|
||||||
|
ret = sendto (fd, buffer, GST_NET_TIME_PACKET_SIZE, MSG_DONTWAIT, addr, len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
57
libs/gst/net/gstnettimepacket.h
Normal file
57
libs/gst/net/gstnettimepacket.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GST_NET_TIME_PACKET_H__
|
||||||
|
#define __GST_NET_TIME_PACKET_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define GST_NET_TIME_PACKET_SIZE 16
|
||||||
|
|
||||||
|
typedef struct _GstNetTimePacket GstNetTimePacket;
|
||||||
|
|
||||||
|
struct _GstNetTimePacket {
|
||||||
|
GstClockTime local_time;
|
||||||
|
GstClockTime remote_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
GstNetTimePacket* gst_net_time_packet_new (const guint8 *buffer);
|
||||||
|
guint8* gst_net_time_packet_serialize (const GstNetTimePacket *packet);
|
||||||
|
|
||||||
|
GstNetTimePacket* gst_net_time_packet_receive (gint fd, struct sockaddr *addr,
|
||||||
|
socklen_t *len);
|
||||||
|
gint gst_net_time_packet_send (const GstNetTimePacket *packet,
|
||||||
|
gint fd, struct sockaddr *addr,
|
||||||
|
socklen_t len);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GST_NET_TIME_PACKET_H__ */
|
|
@ -23,6 +23,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstnettimeprovider.h"
|
#include "gstnettimeprovider.h"
|
||||||
|
#include "gstnettimepacket.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
@ -55,17 +57,6 @@ G_STMT_START { \
|
||||||
#define DEFAULT_ADDRESS "0.0.0.0"
|
#define DEFAULT_ADDRESS "0.0.0.0"
|
||||||
#define DEFAULT_PORT 5637
|
#define DEFAULT_PORT 5637
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstClockTime slave_time_sent;
|
|
||||||
GstClockTime master_time_received;
|
|
||||||
} NetworkTimePacket;
|
|
||||||
|
|
||||||
/* 2 * sizeof(GstClockTime), verified in base_init */
|
|
||||||
#define NETWORK_TIME_PACKET_SIZE 16
|
|
||||||
#define NETWORK_TIME_PACKET_SET_MASTER_TIME(p, t) \
|
|
||||||
GST_WRITE_UINT64_BE(p+8, t)
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -171,7 +162,7 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
guint max_sock;
|
guint max_sock;
|
||||||
gchar *pktdata;
|
GstNetTimePacket *packet;
|
||||||
gint ret;
|
gint ret;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -218,35 +209,22 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* got data in */
|
/* got data in */
|
||||||
pktdata = g_malloc (NETWORK_TIME_PACKET_SIZE);
|
|
||||||
|
|
||||||
len = sizeof (struct sockaddr);
|
len = sizeof (struct sockaddr);
|
||||||
while (TRUE) {
|
|
||||||
ret = recvfrom (self->sock, pktdata, NETWORK_TIME_PACKET_SIZE,
|
|
||||||
0, (struct sockaddr *) &tmpaddr, &len);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno != EAGAIN && errno != EINTR)
|
|
||||||
goto receive_error;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
} else if (ret < NETWORK_TIME_PACKET_SIZE) {
|
|
||||||
goto short_packet;
|
|
||||||
} else {
|
|
||||||
GstClockTime now;
|
|
||||||
|
|
||||||
now = gst_clock_get_time (self->clock);
|
packet = gst_net_time_packet_receive (self->sock,
|
||||||
|
(struct sockaddr *) &tmpaddr, &len);
|
||||||
|
|
||||||
NETWORK_TIME_PACKET_SET_MASTER_TIME (pktdata, time);
|
if (!packet)
|
||||||
|
goto receive_error;
|
||||||
|
|
||||||
/* ignore errors */
|
/* do what we were asked to and send the packet back */
|
||||||
sendto (self->sock, pktdata, ret, MSG_DONTWAIT,
|
packet->remote_time = gst_clock_get_time (self->clock);
|
||||||
(struct sockaddr *) &tmpaddr, len);
|
|
||||||
|
|
||||||
break;
|
/* ignore errors */
|
||||||
}
|
gst_net_time_packet_send (packet, self->sock,
|
||||||
|
(struct sockaddr *) &tmpaddr, len);
|
||||||
|
|
||||||
g_assert_not_reached ();
|
g_free (packet);
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -260,12 +238,6 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
g_strerror (errno), errno);
|
g_strerror (errno), errno);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
short_packet:
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (self, "someone sent us a short packet (%d < %d)",
|
|
||||||
ret, NETWORK_TIME_PACKET_SIZE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stopped:
|
stopped:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (self, "shutting down");
|
GST_DEBUG_OBJECT (self, "shutting down");
|
||||||
|
@ -274,9 +246,7 @@ gst_net_time_provider_thread (gpointer data)
|
||||||
}
|
}
|
||||||
receive_error:
|
receive_error:
|
||||||
{
|
{
|
||||||
g_free (pktdata);
|
GST_DEBUG_OBJECT (self, "receive error");
|
||||||
GST_DEBUG_OBJECT (self, "receive error %d: %s (%d)", ret,
|
|
||||||
g_strerror (errno), errno);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,26 @@ GST_START_TEST (test_refcounts)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
GST_START_TEST (test_functioning)
|
||||||
|
{
|
||||||
|
GstNetTimeProvider *ntp;
|
||||||
|
GstClock *clock;
|
||||||
|
|
||||||
|
clock = gst_system_clock_obtain ();
|
||||||
|
fail_unless (clock != NULL, "failed to get system clock");
|
||||||
|
ntp = gst_net_time_provider_new (clock, NULL, -1);
|
||||||
|
fail_unless (ntp != NULL, "failed to create net time provider");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gst_object_unref (ntp);
|
||||||
|
gst_object_unref (clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
#endif
|
||||||
|
|
||||||
Suite *
|
Suite *
|
||||||
gst_net_time_provider_suite (void)
|
gst_net_time_provider_suite (void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue