Пример #1
0
static void
gst_videorate_update_duration (GstVideoRate * videorate)
{
  GstMessage *m;

  m = gst_message_new_duration_changed (GST_OBJECT (videorate));
  gst_element_post_message (GST_ELEMENT (videorate), m);
}
Пример #2
0
static void
avrcp_metadata_cb (GstAvrcpConnection * avrcp, GstTagList * taglist,
    gpointer user_data)
{
  GstAvdtpSrc *src = GST_AVDTP_SRC (user_data);
  guint64 duration;

  if (gst_tag_list_get_uint64 (taglist, GST_TAG_DURATION, &duration)) {
    src->duration = duration;
    gst_element_post_message (GST_ELEMENT (src),
        gst_message_new_duration_changed (GST_OBJECT (src)));
  }

  gst_pad_push_event (GST_BASE_SRC_PAD (src),
      gst_event_new_tag (gst_tag_list_copy (taglist)));
  gst_element_post_message (GST_ELEMENT (src),
      gst_message_new_tag (GST_OBJECT (src), taglist));
}
Пример #3
0
static GstFlowReturn
gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
    GstBuffer ** buf)
{
  GstAppSrc *appsrc = GST_APP_SRC_CAST (bsrc);
  GstAppSrcPrivate *priv = appsrc->priv;
  GstFlowReturn ret;

  GST_OBJECT_LOCK (appsrc);
  if (G_UNLIKELY (priv->size != bsrc->segment.duration &&
          bsrc->segment.format == GST_FORMAT_BYTES)) {
    GST_DEBUG_OBJECT (appsrc,
        "Size changed from %" G_GINT64_FORMAT " to %" G_GINT64_FORMAT,
        bsrc->segment.duration, priv->size);
    bsrc->segment.duration = priv->size;
    GST_OBJECT_UNLOCK (appsrc);

    gst_element_post_message (GST_ELEMENT (appsrc),
        gst_message_new_duration_changed (GST_OBJECT (appsrc)));
  } else {
    GST_OBJECT_UNLOCK (appsrc);
  }

  g_mutex_lock (&priv->mutex);
  /* check flushing first */
  if (G_UNLIKELY (priv->flushing))
    goto flushing;

  if (priv->stream_type == GST_APP_STREAM_TYPE_RANDOM_ACCESS) {
    /* if we are dealing with a random-access stream, issue a seek if the offset
     * changed. */
    if (G_UNLIKELY (priv->offset != offset)) {
      gboolean res;

      /* do the seek */
      res = gst_app_src_emit_seek (appsrc, offset);

      if (G_UNLIKELY (!res))
        /* failing to seek is fatal */
        goto seek_error;

      priv->offset = offset;
      priv->is_eos = FALSE;
    }
  }

  while (TRUE) {
    /* return data as long as we have some */
    if (!g_queue_is_empty (priv->queue)) {
      guint buf_size;

      if (priv->new_caps) {
        gst_app_src_do_negotiate (bsrc);
        priv->new_caps = FALSE;
      }

      *buf = g_queue_pop_head (priv->queue);
      buf_size = gst_buffer_get_size (*buf);

      GST_DEBUG_OBJECT (appsrc, "we have buffer %p of size %u", *buf, buf_size);

      priv->queued_bytes -= buf_size;

      /* only update the offset when in random_access mode */
      if (priv->stream_type == GST_APP_STREAM_TYPE_RANDOM_ACCESS)
        priv->offset += buf_size;

      /* signal that we removed an item */
      g_cond_broadcast (&priv->cond);

      /* see if we go lower than the empty-percent */
      if (priv->min_percent && priv->max_bytes) {
        if (priv->queued_bytes * 100 / priv->max_bytes <= priv->min_percent)
          /* ignore flushing state, we got a buffer and we will return it now.
           * Errors will be handled in the next round */
          gst_app_src_emit_need_data (appsrc, size);
      }
      ret = GST_FLOW_OK;
      break;
    } else {
      gst_app_src_emit_need_data (appsrc, size);

      /* we can be flushing now because we released the lock above */
      if (G_UNLIKELY (priv->flushing))
        goto flushing;

      /* if we have a buffer now, continue the loop and try to return it. In
       * random-access mode (where a buffer is normally pushed in the above
       * signal) we can still be empty because the pushed buffer got flushed or
       * when the application pushes the requested buffer later, we support both
       * possibilities. */
      if (!g_queue_is_empty (priv->queue))
        continue;

      /* no buffer yet, maybe we are EOS, if not, block for more data. */
    }

    /* check EOS */
    if (G_UNLIKELY (priv->is_eos))
      goto eos;

    /* nothing to return, wait a while for new data or flushing. */
    g_cond_wait (&priv->cond, &priv->mutex);
  }
  g_mutex_unlock (&priv->mutex);
  return ret;

  /* ERRORS */
flushing:
  {
    GST_DEBUG_OBJECT (appsrc, "we are flushing");
    g_mutex_unlock (&priv->mutex);
    return GST_FLOW_FLUSHING;
  }
eos:
  {
    GST_DEBUG_OBJECT (appsrc, "we are EOS");
    g_mutex_unlock (&priv->mutex);
    return GST_FLOW_EOS;
  }
seek_error:
  {
    g_mutex_unlock (&priv->mutex);
    GST_ELEMENT_ERROR (appsrc, RESOURCE, READ, ("failed to seek"),
        GST_ERROR_SYSTEM);
    return GST_FLOW_ERROR;
  }
}
Пример #4
0
static GstFlowReturn
gst_test_http_src_create (GstBaseSrc * basesrc, guint64 offset,
    guint length, GstBuffer ** retbuf)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (basesrc);
  guint bytes_read;
  GstFlowReturn ret = GST_FLOW_OK;
  guint blocksize;

  fail_unless (gst_test_http_src_callbacks != NULL);
  fail_unless (gst_test_http_src_callbacks->src_create != NULL);

  GST_OBJECT_LOCK (src);
  blocksize = basesrc->blocksize;
  GST_OBJECT_UNLOCK (src);

  g_mutex_lock (&src->mutex);
  GST_DEBUG ("gst_test_http_src_create feeding from %" G_GUINT64_FORMAT,
      src->position);
  if (src->uri == NULL) {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    g_mutex_unlock (&src->mutex);
    return GST_FLOW_ERROR;
  }
  if (src->input.status_code < 200 || src->input.status_code >= 300) {
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s",
            "Generated requested error"), ("%s (%d), URL: %s, Redirect to: %s",
            "Generated requested error", src->input.status_code, src->uri,
            GST_STR_NULL (NULL)));
    g_mutex_unlock (&src->mutex);
    return GST_FLOW_ERROR;
  }
  if (src->http_method == METHOD_INVALID) {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, ("%s",
            "Invalid HTTP method"), ("%s (%s), URL: %s",
            "Invalid HTTP method", src->http_method_name, src->uri));
    g_mutex_unlock (&src->mutex);
    return GST_FLOW_ERROR;
  } else if (src->http_method == METHOD_HEAD) {
    ret = GST_FLOW_EOS;
    goto http_events;
  }
  fail_unless_equals_uint64 (offset, src->position);
  bytes_read = MIN ((src->segment_end - src->position), blocksize);
  if (bytes_read == 0) {
    ret = GST_FLOW_EOS;
    goto http_events;
  }
  ret = gst_test_http_src_callbacks->src_create (src,
      offset, bytes_read, retbuf,
      src->input.context, gst_test_http_src_callback_user_data);
  if (ret != GST_FLOW_OK) {
    goto http_events;
  }

  GST_BUFFER_OFFSET (*retbuf) = src->position;
  GST_BUFFER_OFFSET_END (*retbuf) = src->position + bytes_read;

  src->position += bytes_read;
http_events:
  if (src->http_headers_event) {
    gst_pad_push_event (GST_BASE_SRC_PAD (src), src->http_headers_event);
    src->http_headers_event = NULL;
  }
  if (src->duration_changed) {
    src->duration_changed = FALSE;
    gst_element_post_message (GST_ELEMENT (src),
        gst_message_new_duration_changed (GST_OBJECT (src)));
  }

  g_mutex_unlock (&src->mutex);
  return ret;
}
Пример #5
0
void PlaybackPipeline::notifyDurationChanged()
{
    gst_element_post_message(GST_ELEMENT(m_webKitMediaSrc.get()), gst_message_new_duration_changed(GST_OBJECT(m_webKitMediaSrc.get())));
    // WebKitMediaSrc will ask MediaPlayerPrivateGStreamerMSE for the new duration later, when somebody asks for it.
}