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

📄 gstbasesrc.c

📁 gnash 在pc和嵌入式下开发需要的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      gst_segment_set_duration (&src->segment, GST_FORMAT_BYTES, size);      /* make sure we don't exceed the configured segment stop       * if it was set */      if (src->segment.stop != -1)        maxsize = MIN (size, src->segment.stop);      else        maxsize = size;      /* if we are at or past the end, EOS */      if (G_UNLIKELY (offset >= maxsize))        goto unexpected_length;      /* else we can clip to the end */      if (G_UNLIKELY (offset + *length >= maxsize))        *length = maxsize - offset;    }  }  /* keep track of current position. segment is in bytes, we checked    * that above. */  gst_segment_set_last_stop (&src->segment, GST_FORMAT_BYTES, offset);  return TRUE;  /* ERRORS */unexpected_length:  {    return FALSE;  }}/* must be called with LIVE_LOCK */static GstFlowReturngst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,    GstBuffer ** buf){  GstFlowReturn ret;  GstBaseSrcClass *bclass;  GstClockReturn status;  bclass = GST_BASE_SRC_GET_CLASS (src);  ret = gst_base_src_wait_playing (src);  if (ret != GST_FLOW_OK)    goto stopped;  if (G_UNLIKELY (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)))    goto not_started;  if (G_UNLIKELY (!bclass->create))    goto no_function;  if (G_UNLIKELY (!gst_base_src_update_length (src, offset, &length)))    goto unexpected_length;  /* normally we don't count buffers */  if (G_UNLIKELY (src->num_buffers_left >= 0)) {    if (src->num_buffers_left == 0)      goto reached_num_buffers;    else      src->num_buffers_left--;  }  GST_DEBUG_OBJECT (src,      "calling create offset %" G_GUINT64_FORMAT " length %u, time %"      G_GINT64_FORMAT, offset, length, src->segment.time);  ret = bclass->create (src, offset, length, buf);  if (G_UNLIKELY (ret != GST_FLOW_OK))    goto not_ok;  /* no timestamp set and we are at offset 0, we can timestamp with 0 */  if (offset == 0 && src->segment.time == 0      && GST_BUFFER_TIMESTAMP (*buf) == -1)    GST_BUFFER_TIMESTAMP (*buf) = 0;  /* now sync before pushing the buffer */  status = gst_base_src_do_sync (src, *buf);  /* waiting for the clock could have made us flushing */  if (src->priv->flushing)    goto flushing;  switch (status) {    case GST_CLOCK_EARLY:      /* the buffer is too late. We currently don't drop the buffer. */      GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");      break;    case GST_CLOCK_OK:      /* buffer synchronised properly */      GST_DEBUG_OBJECT (src, "buffer ok");      break;    case GST_CLOCK_UNSCHEDULED:      /* this case is triggered when we were waiting for the clock and       * it got unlocked because we did a state change. We return        * WRONG_STATE in this case to stop the dataflow also get rid of the       * produced buffer. */      GST_DEBUG_OBJECT (src,          "clock was unscheduled (%d), returning WRONG_STATE", status);      gst_buffer_unref (*buf);      *buf = NULL;      ret = GST_FLOW_WRONG_STATE;      break;    default:      /* all other result values are unexpected and errors */      GST_ELEMENT_ERROR (src, CORE, CLOCK,          (_("Internal clock error.")),          ("clock returned unexpected return value %d", status));      gst_buffer_unref (*buf);      *buf = NULL;      ret = GST_FLOW_ERROR;      break;  }  return ret;  /* ERROR */stopped:  {    GST_DEBUG_OBJECT (src, "wait_playing returned %d (%s)", ret,        gst_flow_get_name (ret));    return ret;  }not_ok:  {    GST_DEBUG_OBJECT (src, "create returned %d (%s)", ret,        gst_flow_get_name (ret));    return ret;  }not_started:  {    GST_DEBUG_OBJECT (src, "getrange but not started");    return GST_FLOW_WRONG_STATE;  }no_function:  {    GST_DEBUG_OBJECT (src, "no create function");    return GST_FLOW_ERROR;  }unexpected_length:  {    GST_DEBUG_OBJECT (src, "unexpected length %u (offset=%" G_GUINT64_FORMAT        ", size=%" G_GINT64_FORMAT ")", length, offset, src->segment.duration);    return GST_FLOW_UNEXPECTED;  }reached_num_buffers:  {    GST_DEBUG_OBJECT (src, "sent all buffers");    return GST_FLOW_UNEXPECTED;  }flushing:  {    GST_DEBUG_OBJECT (src, "we are flushing");    gst_buffer_unref (*buf);    *buf = NULL;    return GST_FLOW_WRONG_STATE;  }}static GstFlowReturngst_base_src_pad_get_range (GstPad * pad, guint64 offset, guint length,    GstBuffer ** buf){  GstBaseSrc *src;  GstFlowReturn res;  src = GST_BASE_SRC (gst_pad_get_parent (pad));  GST_LIVE_LOCK (src);  if (src->priv->flushing)    goto flushing;  res = gst_base_src_get_range (src, offset, length, buf);done:  GST_LIVE_UNLOCK (src);  gst_object_unref (src);  return res;  /* ERRORS */flushing:  {    GST_DEBUG_OBJECT (src, "we are flushing");    res = GST_FLOW_WRONG_STATE;    goto done;  }}static gbooleangst_base_src_default_check_get_range (GstBaseSrc * src){  gboolean res;  if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {    GST_LOG_OBJECT (src, "doing start/stop to check get_range support");    if (G_LIKELY (gst_base_src_start (src)))      gst_base_src_stop (src);  }  /* we can operate in getrange mode if the native format is bytes   * and we are seekable, this condition is set in the random_access   * flag and is set in the _start() method. */  res = src->random_access;  return res;}static gbooleangst_base_src_check_get_range (GstBaseSrc * src){  GstBaseSrcClass *bclass;  gboolean res;  bclass = GST_BASE_SRC_GET_CLASS (src);  if (bclass->check_get_range == NULL)    goto no_function;  res = bclass->check_get_range (src);  GST_LOG_OBJECT (src, "%s() returned %d",      GST_DEBUG_FUNCPTR_NAME (bclass->check_get_range), (gint) res);  return res;  /* ERRORS */no_function:  {    GST_WARNING_OBJECT (src, "no check_get_range function set");    return FALSE;  }}static gbooleangst_base_src_pad_check_get_range (GstPad * pad){  GstBaseSrc *src;  gboolean res;  src = GST_BASE_SRC (gst_pad_get_parent (pad));  res = gst_base_src_check_get_range (src);  gst_object_unref (src);  return res;}static voidgst_base_src_loop (GstPad * pad){  GstBaseSrc *src;  GstBuffer *buf = NULL;  GstFlowReturn ret;  gint64 position;  gboolean eos;  eos = FALSE;  src = GST_BASE_SRC (gst_pad_get_parent (pad));  GST_LIVE_LOCK (src);  if (src->priv->flushing)    goto flushing;  src->priv->last_sent_eos = FALSE;  /* if we operate in bytes, we can calculate an offset */  if (src->segment.format == GST_FORMAT_BYTES)    position = src->segment.last_stop;  else    position = -1;  ret = gst_base_src_get_range (src, position, src->blocksize, &buf);  if (G_UNLIKELY (ret != GST_FLOW_OK)) {    GST_INFO_OBJECT (src, "pausing after gst_base_src_get_range() = %s",        gst_flow_get_name (ret));    GST_LIVE_UNLOCK (src);    goto pause;  }  /* this should not happen */  if (G_UNLIKELY (buf == NULL))    goto null_buffer;  /* push events to close/start our segment before we push the buffer. */  if (src->priv->close_segment) {    gst_pad_push_event (pad, src->priv->close_segment);    src->priv->close_segment = NULL;  }  if (src->priv->start_segment) {    gst_pad_push_event (pad, src->priv->start_segment);    src->priv->start_segment = NULL;  }  /* figure out the new position */  switch (src->segment.format) {    case GST_FORMAT_BYTES:      position += GST_BUFFER_SIZE (buf);      break;    case GST_FORMAT_TIME:    {      GstClockTime start, duration;      start = GST_BUFFER_TIMESTAMP (buf);      duration = GST_BUFFER_DURATION (buf);      if (GST_CLOCK_TIME_IS_VALID (start))        position = start;      else        position = src->segment.last_stop;      if (GST_CLOCK_TIME_IS_VALID (duration))        position += duration;      break;    }    case GST_FORMAT_DEFAULT:      position = GST_BUFFER_OFFSET_END (buf);      break;    default:      position = -1;      break;  }  if (position != -1) {    if (src->segment.stop != -1) {      if (position >= src->segment.stop) {        eos = TRUE;        position = src->segment.stop;      }    }    gst_segment_set_last_stop (&src->segment, src->segment.format, position);  }  if (G_UNLIKELY (src->priv->discont)) {    buf = gst_buffer_make_metadata_writable (buf);    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);    src->priv->discont = FALSE;  }  GST_LIVE_UNLOCK (src);  ret = gst_pad_push (pad, buf);  if (G_UNLIKELY (ret != GST_FLOW_OK)) {    GST_INFO_OBJECT (src, "pausing after gst_pad_push() = %s",        gst_flow_get_name (ret));    goto pause;  }  if (eos) {    GST_INFO_OBJECT (src, "pausing after EOS");    ret = GST_FLOW_UNEXPECTED;    goto pause;  }done:  gst_object_unref (src);  return;  /* special cases */flushing:  {    GST_DEBUG_OBJECT (src, "we are flushing");    GST_LIVE_UNLOCK (src);    ret = GST_FLOW_WRONG_STATE;    goto pause;  }pause:  {    const gchar *reason = gst_flow_get_name (ret);    GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);    src->data.ABI.running = FALSE;    gst_pad_pause_task (pad);    if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {      if (ret == GST_FLOW_UNEXPECTED) {        /* perform EOS logic */        if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) {          gst_element_post_message (GST_ELEMENT_CAST (src),              gst_message_new_segment_done (GST_OBJECT_CAST (src),                  src->segment.format, src->segment.last_stop));        } else {          gst_pad_push_event (pad, gst_event_new_eos ());          src->priv->last_sent_eos = TRUE;        }      } else {        /* for fatal errors we post an error message, post the error         * first so the app knows about the error first. */        GST_ELEMENT_ERROR (src, STREAM, FAILED,            (_("Internal data flow error.")),            ("streaming task paused, reason %s (%d)", reason, ret));        gst_pad_push_event (pad, gst_event_new_eos ());        src->priv->last_sent_eos = TRUE;      }    }    goto done;  }null_buffer:  {    GST_ELEMENT_ERROR (src, STREAM, FAILED,        (_("Internal data flow error.")), ("element returned NULL buffer"));    GST_LIVE_UNLOCK (src);    /* we finished the segment on error */    ret = GST_FLOW_ERROR;    goto done;  }}/* default negotiation code.  * * Take intersection between src and sink pads, take first * caps and fixate.  */static gbooleangst_base_src_default_negotiate (GstBaseSrc * basesrc){  GstCaps *thiscaps;  GstCaps *caps = NULL;  GstCaps *peercaps = NULL;  gboolean result = FALSE;  /* first see what is possible on our source pad */  thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));  GST_DEBUG_OBJECT (base

⌨️ 快捷键说明

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