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

📄 gstbasesrc.c

📁 gnash 在pc和嵌入式下开发需要的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
       * especially sync since all segment info will get flushed */      break;      /* downstream serialized events */    case GST_EVENT_EOS:      /* FIXME, queue EOS and make sure the task or pull function        * perform the EOS actions. */      break;    case GST_EVENT_NEWSEGMENT:      /* sending random NEWSEGMENT downstream can break sync. */      break;    case GST_EVENT_TAG:      /* sending tags could be useful, FIXME insert in dataflow */      break;    case GST_EVENT_BUFFERSIZE:      /* does not seem to make much sense currently */      break;      /* upstream events */    case GST_EVENT_QOS:      /* elements should override send_event and do something */      break;    case GST_EVENT_SEEK:    {      gboolean started;      GST_OBJECT_LOCK (src->srcpad);      if (GST_PAD_ACTIVATE_MODE (src->srcpad) == GST_ACTIVATE_PULL)        goto wrong_mode;      started = GST_PAD_ACTIVATE_MODE (src->srcpad) == GST_ACTIVATE_PUSH;      GST_OBJECT_UNLOCK (src->srcpad);      if (started) {        /* when we are running in push mode, we can execute the         * seek right now, we need to unlock. */        result = gst_base_src_perform_seek (src, event, TRUE);      } else {        GstEvent **event_p;        /* else we store the event and execute the seek when we         * get activated */        GST_OBJECT_LOCK (src);        event_p = &src->data.ABI.pending_seek;        gst_event_replace ((GstEvent **) event_p, event);        GST_OBJECT_UNLOCK (src);        /* assume the seek will work */        result = TRUE;      }      break;    }    case GST_EVENT_NAVIGATION:      /* could make sense for elements that do something with navigation events       * but then they would need to override the send_event function */      break;    case GST_EVENT_LATENCY:      /* does not seem to make sense currently */      break;      /* custom events */    case GST_EVENT_CUSTOM_UPSTREAM:      /* override send_event if you want this */      break;    case GST_EVENT_CUSTOM_DOWNSTREAM:    case GST_EVENT_CUSTOM_BOTH:      /* FIXME, insert event in the dataflow */      break;    case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:    case GST_EVENT_CUSTOM_BOTH_OOB:      /* insert a random custom event into the pipeline */      GST_DEBUG_OBJECT (src, "pushing custom OOB event downstream");      result = gst_pad_push_event (src->srcpad, event);      /* we gave away the ref to the event in the push */      event = NULL;      break;    default:      break;  }done:  /* if we still have a ref to the event, unref it now */  if (event)    gst_event_unref (event);  return result;  /* ERRORS */wrong_mode:  {    GST_DEBUG_OBJECT (src, "cannot perform seek when operating in pull mode");    GST_OBJECT_UNLOCK (src->srcpad);    result = FALSE;    goto done;  }}static gbooleangst_base_src_default_event (GstBaseSrc * src, GstEvent * event){  gboolean result;  switch (GST_EVENT_TYPE (event)) {    case GST_EVENT_SEEK:      /* is normally called when in push mode */      if (!src->seekable)        goto not_seekable;      result = gst_base_src_perform_seek (src, event, TRUE);      break;    case GST_EVENT_FLUSH_START:      /* cancel any blocking getrange, is normally called       * when in pull mode. */      result = gst_base_src_set_flushing (src, TRUE, FALSE, TRUE, NULL);      break;    case GST_EVENT_FLUSH_STOP:      result = gst_base_src_set_flushing (src, FALSE, TRUE, TRUE, NULL);      break;    default:      result = TRUE;      break;  }  return result;  /* ERRORS */not_seekable:  {    GST_DEBUG_OBJECT (src, "is not seekable");    return FALSE;  }}static gbooleangst_base_src_event_handler (GstPad * pad, GstEvent * event){  GstBaseSrc *src;  GstBaseSrcClass *bclass;  gboolean result = FALSE;  src = GST_BASE_SRC (gst_pad_get_parent (pad));  bclass = GST_BASE_SRC_GET_CLASS (src);  if (bclass->event) {    if (!(result = bclass->event (src, event)))      goto subclass_failed;  }done:  gst_event_unref (event);  gst_object_unref (src);  return result;  /* ERRORS */subclass_failed:  {    GST_DEBUG_OBJECT (src, "subclass refused event");    goto done;  }}static voidgst_base_src_set_property (GObject * object, guint prop_id,    const GValue * value, GParamSpec * pspec){  GstBaseSrc *src;  src = GST_BASE_SRC (object);  switch (prop_id) {    case PROP_BLOCKSIZE:      src->blocksize = g_value_get_ulong (value);      break;    case PROP_NUM_BUFFERS:      src->num_buffers = g_value_get_int (value);      break;    case PROP_TYPEFIND:      src->data.ABI.typefind = g_value_get_boolean (value);      break;    case PROP_DO_TIMESTAMP:      src->priv->do_timestamp = g_value_get_boolean (value);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static voidgst_base_src_get_property (GObject * object, guint prop_id, GValue * value,    GParamSpec * pspec){  GstBaseSrc *src;  src = GST_BASE_SRC (object);  switch (prop_id) {    case PROP_BLOCKSIZE:      g_value_set_ulong (value, src->blocksize);      break;    case PROP_NUM_BUFFERS:      g_value_set_int (value, src->num_buffers);      break;    case PROP_TYPEFIND:      g_value_set_boolean (value, src->data.ABI.typefind);      break;    case PROP_DO_TIMESTAMP:      g_value_set_boolean (value, src->priv->do_timestamp);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}/* with STREAM_LOCK and LOCK */static GstClockReturngst_base_src_wait (GstBaseSrc * basesrc, GstClock * clock, GstClockTime time){  GstClockReturn ret;  GstClockID id;  id = gst_clock_new_single_shot_id (clock, time);  basesrc->clock_id = id;  /* release the live lock while waiting */  GST_LIVE_UNLOCK (basesrc);  ret = gst_clock_id_wait (id, NULL);  GST_LIVE_LOCK (basesrc);  gst_clock_id_unref (id);  basesrc->clock_id = NULL;  return ret;}/* perform synchronisation on a buffer.  * with STREAM_LOCK. */static GstClockReturngst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer){  GstClockReturn result;  GstClockTime start, end;  GstBaseSrcClass *bclass;  GstClockTime base_time;  GstClock *clock;  GstClockTime now = GST_CLOCK_TIME_NONE, timestamp;  gboolean do_timestamp, first, pseudo_live;  bclass = GST_BASE_SRC_GET_CLASS (basesrc);  start = end = -1;  if (bclass->get_times)    bclass->get_times (basesrc, buffer, &start, &end);  /* get buffer timestamp */  timestamp = GST_BUFFER_TIMESTAMP (buffer);  /* grab the lock to prepare for clocking and calculate the startup    * latency. */  GST_OBJECT_LOCK (basesrc);  /* if we are asked to sync against the clock we are a pseudo live element */  pseudo_live = (start != -1 && basesrc->is_live);  /* check for the first buffer */  first = (basesrc->priv->latency == -1);  if (timestamp != -1 && pseudo_live) {    GstClockTime latency;    /* we have a timestamp and a sync time, latency is the diff */    if (timestamp <= start)      latency = start - timestamp;    else      latency = 0;    if (first) {      GST_DEBUG_OBJECT (basesrc, "pseudo_live with latency %" GST_TIME_FORMAT,          GST_TIME_ARGS (latency));      /* first time we calculate latency, just configure */      basesrc->priv->latency = latency;    } else {      if (basesrc->priv->latency != latency) {        /* we have a new latency, FIXME post latency message */        basesrc->priv->latency = latency;        GST_DEBUG_OBJECT (basesrc, "latency changed to %" GST_TIME_FORMAT,            GST_TIME_ARGS (latency));      }    }  } else if (first) {    GST_DEBUG_OBJECT (basesrc, "no latency needed, live %d, sync %d",        basesrc->is_live, start != -1);    basesrc->priv->latency = 0;  }  /* get clock, if no clock, we can't sync or do timestamps */  if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)    goto no_clock;  base_time = GST_ELEMENT_CAST (basesrc)->base_time;  do_timestamp = basesrc->priv->do_timestamp;  /* first buffer, calculate the timestamp offset */  if (first) {    GstClockTime running_time;    now = gst_clock_get_time (clock);    running_time = now - base_time;    GST_LOG_OBJECT (basesrc,        "startup timestamp: %" GST_TIME_FORMAT ", running_time %"        GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),        GST_TIME_ARGS (running_time));    if (pseudo_live && timestamp != -1) {      /* live source and we need to sync, add startup latency to all timestamps       * to get the real running_time. Live sources should always timestamp       * according to the current running time. */      basesrc->priv->ts_offset = GST_CLOCK_DIFF (timestamp, running_time);      GST_LOG_OBJECT (basesrc, "live with sync, ts_offset %" GST_TIME_FORMAT,          GST_TIME_ARGS (basesrc->priv->ts_offset));    } else {      basesrc->priv->ts_offset = 0;      GST_LOG_OBJECT (basesrc, "no timestamp offset needed");    }    if (!GST_CLOCK_TIME_IS_VALID (timestamp)) {      if (do_timestamp)        timestamp = running_time;      else        timestamp = 0;      GST_BUFFER_TIMESTAMP (buffer) = timestamp;      GST_LOG_OBJECT (basesrc, "created timestamp: %" GST_TIME_FORMAT,          GST_TIME_ARGS (timestamp));    }    /* add the timestamp offset we need for sync */    timestamp += basesrc->priv->ts_offset;  } else {    /* not the first buffer, the timestamp is the diff between the clock and     * base_time */    if (do_timestamp && !GST_CLOCK_TIME_IS_VALID (timestamp)) {      now = gst_clock_get_time (clock);      GST_BUFFER_TIMESTAMP (buffer) = now - base_time;      GST_LOG_OBJECT (basesrc, "created timestamp: %" GST_TIME_FORMAT,          GST_TIME_ARGS (now - base_time));    }  }  /* if we don't have a buffer timestamp, we don't sync */  if (!GST_CLOCK_TIME_IS_VALID (start))    goto no_sync;  if (basesrc->is_live && GST_CLOCK_TIME_IS_VALID (timestamp)) {    /* for pseudo live sources, add our ts_offset to the timestamp */    GST_BUFFER_TIMESTAMP (buffer) += basesrc->priv->ts_offset;    start += basesrc->priv->ts_offset;  }  GST_LOG_OBJECT (basesrc,      "waiting for clock, base time %" GST_TIME_FORMAT      ", stream_start %" GST_TIME_FORMAT,      GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));  GST_OBJECT_UNLOCK (basesrc);  result = gst_base_src_wait (basesrc, clock, start + base_time);  GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);  return result;  /* special cases */no_clock:  {    GST_DEBUG_OBJECT (basesrc, "we have no clock");    GST_OBJECT_UNLOCK (basesrc);    return GST_CLOCK_OK;  }no_sync:  {    GST_DEBUG_OBJECT (basesrc, "no sync needed");    GST_OBJECT_UNLOCK (basesrc);    return GST_CLOCK_OK;  }}static gbooleangst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length){  guint64 size, maxsize;  GstBaseSrcClass *bclass;  bclass = GST_BASE_SRC_GET_CLASS (src);  /* only operate if we are working with bytes */  if (src->segment.format != GST_FORMAT_BYTES)    return TRUE;  /* get total file size */  size = (guint64) src->segment.duration;  /* the max amount of bytes to read is the total size or   * up to the segment.stop if present. */  if (src->segment.stop != -1)    maxsize = MIN (size, src->segment.stop);  else    maxsize = size;  GST_DEBUG_OBJECT (src,      "reading offset %" G_GUINT64_FORMAT ", length %u, size %" G_GINT64_FORMAT      ", segment.stop %" G_GINT64_FORMAT ", maxsize %" G_GINT64_FORMAT, offset,      *length, size, src->segment.stop, maxsize);  /* check size if we have one */  if (maxsize != -1) {    /* if we run past the end, check if the file became bigger and      * retry. */    if (G_UNLIKELY (offset + *length >= maxsize)) {      /* see if length of the file changed */      if (bclass->get_size)        if (!bclass->get_size (src, &size))          size = -1;

⌨️ 快捷键说明

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