+2006-10-09 Wim Taymans <wim@fluendo.com>
+
+ * docs/design/part-qos.txt:
+ Fix typo.
+
+ * gst/gstevent.c:
+ * gst/gstevent.h:
+ Update seek event docs regarding negative rates.
+ Rename @cur to @start.
+
+ * gst/gstsegment.c: (gst_segment_set_seek):
+ * gst/gstsegment.h:
+ Update set_seek docs regarding negative rates.
+ Correctly update last_stop to @stop when dealing with negative
+ rates.
+ Rename @cur to @start.
+
+ * tests/check/gst/gstpad.c: (GST_START_TEST):
+ Activate pads before trying to use them.
+
+ * tests/check/gst/gstsegment.c: (GST_START_TEST),
+ (gst_segment_suite):
+ Add simple check for segments and negative rates.
+
2006-10-09 Tim-Philipp Müller <tim at centricular dot net>
* gst/gsttaglist.c: (gst_tag_list_is_empty):
- timestamp: The timestamp on the buffer that generated the QoS
event. These timestamps are expressed in total running time in
- the sink so that the value is every increasing.
+ the sink so that the value is ever increasing.
- - jitter: The difference of that timestamp against the currentl clock time.
+ - jitter: The difference of that timestamp against the current clock time.
Negative values mean the timestamp was on time. Positive values
indicate the timestamp was late by that amount.
* @rate: The new playback rate
* @format: The format of the seek values
* @flags: The optional seek flags
- * @cur_type: The type and flags for the new current position
- * @cur: The value of the new current position
+ * @start_type: The type and flags for the new start position
+ * @start: The value of the new start position
* @stop_type: The type and flags for the new stop position
* @stop: The value of the new stop position
*
* Allocate a new seek event with the given parameters.
*
- * The seek event configures playback of the pipeline from
- * @cur to @stop at the speed given in @rate, also called a playback segment.
- * The @cur and @stop values are expressed in format @format.
+ * The seek event configures playback of the pipeline between @start to @stop
+ * at the speed given in @rate, also called a playback segment.
+ * The @start and @stop values are expressed in @format.
*
* A @rate of 1.0 means normal playback rate, 2.0 means double speed.
* Negatives values means backwards playback. A value of 0.0 for the
* rate is not allowed and should be accomplished instead by PAUSING the
* pipeline.
*
- * A pipeline has a default playback segment configured with a current
- * position of 0, a stop position of the total duration of the stream(s) and
- * a rate of 1.0. The currently configured playback segment can be queried
- * with #GST_QUERY_SEGMENT.
+ * A pipeline has a default playback segment configured with a start
+ * position of 0, a stop position of -1 and a rate of 1.0. The currently
+ * configured playback segment can be queried with #GST_QUERY_SEGMENT.
*
- * @cur_type and @stop_type specify how to adjust the current and stop
- * time, relative or absolute to the last configured playback segment. A type
- * of #GST_SEEK_TYPE_NONE means that the position should not be updated.
+ * @start_type and @stop_type specify how to adjust the currently configured
+ * start and stop fields in @segment. Adjustments can be made relative or
+ * absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE means
+ * that the position should not be updated.
*
- * Updating the @cur position will actually move the current playback position
- * to that new position.
+ * When the rate is positive and @start has been updated, playback will start
+ * from the newly configured start position. For negative rates, playback will
+ * start from the newly configured stop position.
*
* It is not possible to seek relative to the current playback position, to do
* this, PAUSE the pipeline, query the current playback position with
GstClockTime *timestamp);
/* seek event */
GstEvent* gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
- GstSeekType cur_type, gint64 cur,
+ GstSeekType start_type, gint64 start,
GstSeekType stop_type, gint64 stop);
void gst_event_parse_seek (GstEvent *event, gdouble *rate, GstFormat *format,
GstSeekFlags *flags,
- GstSeekType *cur_type, gint64 *cur,
+ GstSeekType *start_type, gint64 *start,
GstSeekType *stop_type, gint64 *stop);
/* navigation event */
GstEvent* gst_event_new_navigation (GstStructure *structure);
* gst_segment_set_duration:
* @segment: a #GstSegment structure.
* @format: the format of the segment.
- * @duration: the duration of the segment info.
+ * @duration: the duration of the segment info or -1 if unknown.
*
* Set the duration of the segment to @duration. This function is mainly
* used by elements that perform seeking and know the total duration of the
- * segment.
+ * segment.
*
* This field should be set to allow seeking requests relative to the
* duration.
* @rate: the rate of the segment.
* @format: the format of the segment.
* @flags: the seek flags for the segment
- * @cur_type: the seek method
- * @cur: the seek start value
+ * @start_type: the seek method
+ * @start: the seek start value
* @stop_type: the seek method
* @stop: the seek stop value
* @update: boolean holding whether start or stop were updated.
*
- * Update the segment structure with the field values of a seek event.
+ * Update the segment structure with the field values of a seek event (see
+ * gst_event_new_seek()).
*
- * After calling this method, the segment field last_stop will contain
- * the requested new position in the segment. If the cur_type is different
- * from GST_SEEK_TYPE_NONE, the current position is not updated and
- * streaming should continue from the last position, possibly with
- * updated rate, flags or stop position.
+ * After calling this method, the segment field last_stop and time will
+ * contain the requested new position in the segment. The new requested
+ * position in the segment depends on @rate and @start_type and @stop_type.
+ *
+ * For positive @rate, the new position in the segment is the new @segment
+ * start field when it was updated with a @start_type different from
+ * #GST_SEEK_TYPE_NONE. If no update was performed on @segment start position
+ * (#GST_SEEK_TYPE_NONE), @start is ignored and @segment last_stop is
+ * unmodified.
+ *
+ * For negative @rate, the new position in the segment is the new @segment
+ * stop field when it was updated with a @stop_type different from
+ * #GST_SEEK_TYPE_NONE. If no stop was previously configured in the segment, the
+ * duration of the segment will be used to update the stop position.
+ * If no update was performed on @segment stop position (#GST_SEEK_TYPE_NONE),
+ * @stop is ignored and @segment last_stop is unmodified.
*
* The applied rate of the segment will be set to 1.0 by default.
* If the caller can apply a rate change, it should update @segment
void
gst_segment_set_seek (GstSegment * segment, gdouble rate,
GstFormat format, GstSeekFlags flags,
- GstSeekType cur_type, gint64 cur,
+ GstSeekType start_type, gint64 start,
GstSeekType stop_type, gint64 stop, gboolean * update)
{
gboolean update_stop, update_start;
update_stop = update_start = TRUE;
/* start is never invalid */
- switch (cur_type) {
+ switch (start_type) {
case GST_SEEK_TYPE_NONE:
/* no update to segment */
- cur = segment->start;
+ start = segment->start;
update_start = FALSE;
break;
case GST_SEEK_TYPE_SET:
- /* cur holds desired position */
+ /* start holds desired position */
break;
case GST_SEEK_TYPE_CUR:
- /* add cur to currently configure segment */
- cur = segment->start + cur;
+ /* add start to currently configure segment */
+ start = segment->start + start;
break;
case GST_SEEK_TYPE_END:
if (segment->duration != -1) {
- /* add cur to total length */
- cur = segment->duration + cur;
+ /* add start to total length */
+ start = segment->duration + start;
} else {
/* no update if duration unknown */
- cur = segment->start;
+ start = segment->start;
update_start = FALSE;
}
break;
}
/* bring in sane range */
if (segment->duration != -1)
- cur = CLAMP (cur, 0, segment->duration);
+ start = CLAMP (start, 0, segment->duration);
else
- cur = MAX (cur, 0);
+ start = MAX (start, 0);
/* stop can be -1 if we have not configured a stop. */
switch (stop_type) {
/* we can't have stop before start */
if (stop != -1)
- g_return_if_fail (cur <= stop);
+ g_return_if_fail (start <= stop);
segment->rate = rate;
segment->abs_rate = ABS (rate);
segment->applied_rate = 1.0;
segment->flags = flags;
- segment->start = cur;
- if (update_start) {
- segment->last_stop = cur;
+ segment->start = start;
+ if (update_start && rate > 0.0) {
+ segment->last_stop = start;
+ }
+ if (update_stop && rate < 0.0) {
+ segment->last_stop = stop;
}
segment->time = segment->last_stop;
segment->stop = stop;
void gst_segment_set_seek (GstSegment *segment, gdouble rate,
GstFormat format, GstSeekFlags flags,
- GstSeekType cur_type, gint64 cur,
+ GstSeekType start_type, gint64 start,
GstSeekType stop_type, gint64 stop,
gboolean *update);
fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
+ buffer = gst_buffer_new ();
+#if 0
+ /* FIXME, new pad should be flushing */
+ gst_buffer_ref (buffer);
+ fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
+ gst_buffer_ref (buffer);
+ fail_unless (gst_pad_chain (sink, buffer) == GST_FLOW_WRONG_STATE);
+#endif
+
+ /* activate pads */
+ gst_pad_set_active (src, TRUE);
+ gst_pad_set_active (sink, TRUE);
+
/* test */
/* pushing on a linked pad will drop the ref to the buffer */
- buffer = gst_buffer_new ();
gst_buffer_ref (buffer);
fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
GST_END_TEST;
+GST_START_TEST (segment_seek_reverse)
+{
+ GstSegment segment;
+ gboolean update;
+
+ gst_segment_init (&segment, GST_FORMAT_BYTES);
+ gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
+
+ /* configure segment to stop 100 */
+ gst_segment_set_seek (&segment, -1.0,
+ GST_FORMAT_BYTES,
+ GST_SEEK_FLAG_NONE,
+ GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
+ fail_unless (segment.start == 0);
+ fail_unless (segment.stop == 100);
+ fail_unless (segment.last_stop == 100);
+
+ /* update */
+ gst_segment_set_seek (&segment, -1.0,
+ GST_FORMAT_BYTES,
+ GST_SEEK_FLAG_NONE,
+ GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_CUR, -20, &update);
+ fail_unless (segment.start == 10);
+ fail_unless (segment.stop == 80);
+ fail_unless (segment.last_stop == 80);
+
+ gst_segment_set_seek (&segment, -1.0,
+ GST_FORMAT_BYTES,
+ GST_SEEK_FLAG_NONE,
+ GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
+ fail_unless (segment.start == 20);
+ fail_unless (segment.stop == 80);
+ fail_unless (segment.last_stop == 80);
+}
+
+GST_END_TEST;
+
/* mess with the segment structure in the bytes format */
GST_START_TEST (segment_newsegment_open)
{
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, segment_seek_nosize);
tcase_add_test (tc_chain, segment_seek_size);
+ tcase_add_test (tc_chain, segment_seek_reverse);
tcase_add_test (tc_chain, segment_newsegment_open);
tcase_add_test (tc_chain, segment_newsegment_closed);
tcase_add_test (tc_chain, segment_newsegment_streamtime);