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); }
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)); }
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; } }
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; }
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. }