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:
Andy Wingo 2005-11-16 17:52:04 +00:00
parent 578f2ae633
commit fec8e1db7d
13 changed files with 534 additions and 88 deletions

View file

@ -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>
* check/Makefile.am:

View file

@ -49,6 +49,26 @@ GST_START_TEST (test_refcounts)
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 *
gst_net_time_provider_suite (void)
{

View file

@ -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@_include_HEADERS = \
gstnet.h \
gstnettimepacker.h \
gstnettimeprovider.h
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
gstnettimepacket.c \
gstnettimeprovider.c
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)

View file

@ -22,6 +22,7 @@
#define __GST_NET_H__
#include <gst/net/gstnettimepacket.h>
#include <gst/net/gstnettimeprovider.h>

167
gst/net/gstnettimepacket.c Normal file
View 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;
}

View 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__ */

View file

@ -23,6 +23,8 @@
#endif
#include "gstnettimeprovider.h"
#include "gstnettimepacket.h"
#include <unistd.h>
#include <sys/ioctl.h>
@ -55,17 +57,6 @@ G_STMT_START { \
#define DEFAULT_ADDRESS "0.0.0.0"
#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
{
PROP_0,
@ -171,7 +162,7 @@ gst_net_time_provider_thread (gpointer data)
socklen_t len;
fd_set read_fds;
guint max_sock;
gchar *pktdata;
GstNetTimePacket *packet;
gint ret;
while (TRUE) {
@ -218,35 +209,22 @@ gst_net_time_provider_thread (gpointer data)
continue;
} else {
/* got data in */
pktdata = g_malloc (NETWORK_TIME_PACKET_SIZE);
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 */
sendto (self->sock, pktdata, ret, MSG_DONTWAIT,
(struct sockaddr *) &tmpaddr, len);
/* do what we were asked to and send the packet back */
packet->remote_time = gst_clock_get_time (self->clock);
break;
}
/* ignore errors */
gst_net_time_packet_send (packet, self->sock,
(struct sockaddr *) &tmpaddr, len);
g_assert_not_reached ();
}
g_free (packet);
continue;
}
@ -260,12 +238,6 @@ gst_net_time_provider_thread (gpointer data)
g_strerror (errno), errno);
continue;
}
short_packet:
{
GST_DEBUG_OBJECT (self, "someone sent us a short packet (%d < %d)",
ret, NETWORK_TIME_PACKET_SIZE);
continue;
}
stopped:
{
GST_DEBUG_OBJECT (self, "shutting down");
@ -274,9 +246,7 @@ gst_net_time_provider_thread (gpointer data)
}
receive_error:
{
g_free (pktdata);
GST_DEBUG_OBJECT (self, "receive error %d: %s (%d)", ret,
g_strerror (errno), errno);
GST_DEBUG_OBJECT (self, "receive error");
continue;
}

View file

@ -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@_include_HEADERS = \
gstnet.h \
gstnettimepacker.h \
gstnettimeprovider.h
libgstnet_tempname_@GST_MAJORMINOR@_la_SOURCES = \
gstnettimepacket.c \
gstnettimeprovider.c
libgstnet_tempname_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)

View file

@ -22,6 +22,7 @@
#define __GST_NET_H__
#include <gst/net/gstnettimepacket.h>
#include <gst/net/gstnettimeprovider.h>

View 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;
}

View 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__ */

View file

@ -23,6 +23,8 @@
#endif
#include "gstnettimeprovider.h"
#include "gstnettimepacket.h"
#include <unistd.h>
#include <sys/ioctl.h>
@ -55,17 +57,6 @@ G_STMT_START { \
#define DEFAULT_ADDRESS "0.0.0.0"
#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
{
PROP_0,
@ -171,7 +162,7 @@ gst_net_time_provider_thread (gpointer data)
socklen_t len;
fd_set read_fds;
guint max_sock;
gchar *pktdata;
GstNetTimePacket *packet;
gint ret;
while (TRUE) {
@ -218,35 +209,22 @@ gst_net_time_provider_thread (gpointer data)
continue;
} else {
/* got data in */
pktdata = g_malloc (NETWORK_TIME_PACKET_SIZE);
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 */
sendto (self->sock, pktdata, ret, MSG_DONTWAIT,
(struct sockaddr *) &tmpaddr, len);
/* do what we were asked to and send the packet back */
packet->remote_time = gst_clock_get_time (self->clock);
break;
}
/* ignore errors */
gst_net_time_packet_send (packet, self->sock,
(struct sockaddr *) &tmpaddr, len);
g_assert_not_reached ();
}
g_free (packet);
continue;
}
@ -260,12 +238,6 @@ gst_net_time_provider_thread (gpointer data)
g_strerror (errno), errno);
continue;
}
short_packet:
{
GST_DEBUG_OBJECT (self, "someone sent us a short packet (%d < %d)",
ret, NETWORK_TIME_PACKET_SIZE);
continue;
}
stopped:
{
GST_DEBUG_OBJECT (self, "shutting down");
@ -274,9 +246,7 @@ gst_net_time_provider_thread (gpointer data)
}
receive_error:
{
g_free (pktdata);
GST_DEBUG_OBJECT (self, "receive error %d: %s (%d)", ret,
g_strerror (errno), errno);
GST_DEBUG_OBJECT (self, "receive error");
continue;
}

View file

@ -49,6 +49,26 @@ GST_START_TEST (test_refcounts)
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 *
gst_net_time_provider_suite (void)
{