⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gstnetclientclock.c

📁 gnash 在pc和嵌入式下开发需要的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> *                    2005 Wim Taymans <wim@fluendo.com> *                    2005 Andy Wingo <wingo@pobox.com> * * gstnetclientclock.h: clock that synchronizes itself to a time provider over * the network * * 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. *//** * SECTION:gstnetclientclock * @short_description: Special clock that synchronizes to a remote time *                     provider. * @see_also: #GstClock, #GstNetTimeProvider, #GstPipeline * * This object implements a custom #GstClock that synchronizes its time * to a remote time provider such as #GstNetTimeProvider. * * A new clock is created with gst_net_client_clock_new() which takes the * address and port of the remote time provider along with a name and * an initial time. * * This clock will poll the time provider and will update its calibration * parameters based on the local and remote observations. * * Various parameters of the clock can be configured with the parent #GstClock * "timeout", "window-size" and "window-threshold" object properties. * * A #GstNetClientClock is typically set on a #GstPipeline with  * gst_pipeline_use_clock(). * * Last reviewed on 2005-11-23 (0.9.5) */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "gstnettimepacket.h"#include "gstnetclientclock.h"#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#if defined (_MSC_VER) && _MSC_VER >= 1400#include <io.h>#endifGST_DEBUG_CATEGORY_STATIC (ncc_debug);#define GST_CAT_DEFAULT (ncc_debug)/* the select call is also performed on the control sockets, that way * we can send special commands to unblock or restart the select call */#define CONTROL_RESTART        'R'      /* restart the select call */#define CONTROL_STOP           'S'      /* stop the select call */#define CONTROL_SOCKETS(self)   self->control_sock#define WRITE_SOCKET(self)      self->control_sock[1]#define READ_SOCKET(self)       self->control_sock[0]#define SEND_COMMAND(self, command)                     \G_STMT_START {                                  \  unsigned char c; c = command;                 \  write (WRITE_SOCKET(self), &c, 1);            \} G_STMT_END#define READ_COMMAND(self, command, res)                \G_STMT_START {                                  \  res = read(READ_SOCKET(self), &command, 1);    \} G_STMT_END#define DEFAULT_ADDRESS         "127.0.0.1"#define DEFAULT_PORT            5637#define DEFAULT_TIMEOUT         GST_SECOND#ifdef G_OS_WIN32#define getsockname(sock,addr,len) getsockname(sock,addr,(int *)len)#endifenum{  PROP_0,  PROP_ADDRESS,  PROP_PORT,};#define _do_init(type) \  GST_DEBUG_CATEGORY_INIT (ncc_debug, "netclock", 0, "Network client clock");GST_BOILERPLATE_FULL (GstNetClientClock, gst_net_client_clock,    GstSystemClock, GST_TYPE_SYSTEM_CLOCK, _do_init);static void gst_net_client_clock_finalize (GObject * object);static void gst_net_client_clock_set_property (GObject * object, guint prop_id,    const GValue * value, GParamSpec * pspec);static void gst_net_client_clock_get_property (GObject * object, guint prop_id,    GValue * value, GParamSpec * pspec);static void gst_net_client_clock_stop (GstNetClientClock * self);#ifdef G_OS_WIN32static intinet_aton (const char *c, struct in_addr *paddr){  /* note that inet_addr is deprecated on unix because   * inet_addr returns -1 (INADDR_NONE) for the valid 255.255.255.255   * address. */  paddr->s_addr = inet_addr (c);  if (paddr->s_addr == INADDR_NONE)    return 0;  return 1;}#endifstatic voidgst_net_client_clock_base_init (gpointer g_class){  /* nop */}static voidgst_net_client_clock_class_init (GstNetClientClockClass * klass){  GObjectClass *gobject_class;  gobject_class = G_OBJECT_CLASS (klass);  gobject_class->finalize = gst_net_client_clock_finalize;  gobject_class->get_property = gst_net_client_clock_get_property;  gobject_class->set_property = gst_net_client_clock_set_property;  g_object_class_install_property (gobject_class, PROP_ADDRESS,      g_param_spec_string ("address", "address",          "The address of the machine providing a time server, "          "as a dotted quad (x.x.x.x)", DEFAULT_ADDRESS, G_PARAM_READWRITE));  g_object_class_install_property (gobject_class, PROP_PORT,      g_param_spec_int ("port", "port",          "The port on which the remote server is listening", 0, G_MAXUINT16,          DEFAULT_PORT, G_PARAM_READWRITE));}static voidgst_net_client_clock_init (GstNetClientClock * self,    GstNetClientClockClass * g_class){  GstClock *clock = GST_CLOCK_CAST (self);#ifdef G_OS_WIN32  WSADATA w;  int error = WSAStartup (0x0202, &w);  if (error) {    GST_DEBUG_OBJECT (self, "Error on WSAStartup");  }  if (w.wVersion != 0x0202) {    WSACleanup ();  }#endif  self->port = DEFAULT_PORT;  self->address = g_strdup (DEFAULT_ADDRESS);  clock->timeout = DEFAULT_TIMEOUT;  self->sock = -1;  self->thread = NULL;  self->servaddr = NULL;  READ_SOCKET (self) = -1;  WRITE_SOCKET (self) = -1;}static voidgst_net_client_clock_finalize (GObject * object){  GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object);  if (self->thread) {    gst_net_client_clock_stop (self);    g_assert (self->thread == NULL);  }  if (READ_SOCKET (self) != -1) {    close (READ_SOCKET (self));    close (WRITE_SOCKET (self));    READ_SOCKET (self) = -1;    WRITE_SOCKET (self) = -1;  }  g_free (self->address);  self->address = NULL;  g_free (self->servaddr);  self->servaddr = NULL;#ifdef G_OS_WIN32  WSACleanup ();#endif  G_OBJECT_CLASS (parent_class)->finalize (object);}static voidgst_net_client_clock_set_property (GObject * object, guint prop_id,    const GValue * value, GParamSpec * pspec){  GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object);  switch (prop_id) {    case PROP_ADDRESS:      g_free (self->address);      if (g_value_get_string (value) == NULL)        self->address = g_strdup (DEFAULT_ADDRESS);      else        self->address = g_strdup (g_value_get_string (value));      break;    case PROP_PORT:      self->port = g_value_get_int (value);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static voidgst_net_client_clock_get_property (GObject * object, guint prop_id,    GValue * value, GParamSpec * pspec){  GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object);  switch (prop_id) {    case PROP_ADDRESS:      g_value_set_string (value, self->address);      break;    case PROP_PORT:      g_value_set_int (value, self->port);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static voidgst_net_client_clock_observe_times (GstNetClientClock * self,    GstClockTime local_1, GstClockTime remote, GstClockTime local_2){  GstClockTime local_avg;  gdouble r_squared;  GstClock *clock;  if (local_2 < local_1)    goto bogus_observation;  local_avg = (local_2 + local_1) / 2;  clock = GST_CLOCK_CAST (self);  gst_clock_add_observation (GST_CLOCK (self), local_avg, remote, &r_squared);  GST_CLOCK_SLAVE_LOCK (self);  if (clock->filling) {    self->current_timeout = 0;  } else {    /* geto formula */    self->current_timeout =        (1e-3 / (1 - MIN (r_squared, 0.99999))) * GST_SECOND;    self->current_timeout = MIN (self->current_timeout, clock->timeout);  }  GST_CLOCK_SLAVE_UNLOCK (clock);  return;bogus_observation:  {    GST_WARNING_OBJECT (self, "time packet receive time < send time (%"        GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", GST_TIME_ARGS (local_1),        GST_TIME_ARGS (local_2));    return;  }}static gintgst_net_client_clock_do_select (GstNetClientClock * self, fd_set * readfds){  gint max_sock;  gint ret;  while (TRUE) {    FD_ZERO (readfds);    FD_SET (self->sock, readfds);    FD_SET (READ_SOCKET (self), readfds);    max_sock = MAX (self->sock, READ_SOCKET (self));    GST_LOG_OBJECT (self, "doing select");    {      GstClockTime diff;      GTimeVal tv, *ptv = &tv;      diff = gst_clock_get_internal_time (GST_CLOCK (self));      GST_TIME_TO_TIMEVAL (self->current_timeout, tv);#ifdef G_OS_WIN32      if (((max_sock + 1) != READ_SOCKET (self)) ||          ((max_sock + 1) != WRITE_SOCKET (self))) {        ret =            select (max_sock + 1, readfds, NULL, NULL, (struct timeval *) ptv);      } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -