mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +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>
|
||||
|
||||
* check/Makefile.am:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
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
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define __GST_NET_H__
|
||||
|
||||
|
||||
#include <gst/net/gstnettimepacket.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
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue