diff --git a/ChangeLog b/ChangeLog index 8b0765fc4d..807f543aeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2006-10-09 Wim Taymans + + * 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 * gst/gsttaglist.c: (gst_tag_list_is_empty): diff --git a/docs/design/part-qos.txt b/docs/design/part-qos.txt index a39d404b5d..91f16a8f73 100644 --- a/docs/design/part-qos.txt +++ b/docs/design/part-qos.txt @@ -32,9 +32,9 @@ The QoS event travels upstream and contains the following fields: - 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. diff --git a/gst/gstevent.c b/gst/gstevent.c index 52cedd2110..09644804e2 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -785,33 +785,34 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion, * @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 diff --git a/gst/gstevent.h b/gst/gstevent.h index cd6b330682..5f00700330 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -411,11 +411,11 @@ void gst_event_parse_qos (GstEvent *event, gdouble *proportion, GstClockTimeDi 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); diff --git a/gst/gstsegment.c b/gst/gstsegment.c index 2f33afda2b..641631e966 100644 --- a/gst/gstsegment.c +++ b/gst/gstsegment.c @@ -172,11 +172,11 @@ gst_segment_init (GstSegment * segment, GstFormat format) * 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. @@ -226,19 +226,31 @@ gst_segment_set_last_stop (GstSegment * segment, GstFormat format, * @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 @@ -247,7 +259,7 @@ gst_segment_set_last_stop (GstSegment * segment, GstFormat format, 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; @@ -263,35 +275,35 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate, 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) { @@ -328,15 +340,18 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate, /* 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; diff --git a/gst/gstsegment.h b/gst/gstsegment.h index f983230e08..ce5e4706e5 100644 --- a/gst/gstsegment.h +++ b/gst/gstsegment.h @@ -83,7 +83,7 @@ void gst_segment_set_last_stop (GstSegment *segment, GstFormat for 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); diff --git a/tests/check/gst/gstpad.c b/tests/check/gst/gstpad.c index b6d3cd0830..15bc8a8e3a 100644 --- a/tests/check/gst/gstpad.c +++ b/tests/check/gst/gstpad.c @@ -333,9 +333,21 @@ GST_START_TEST (test_push_linked) 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); diff --git a/tests/check/gst/gstsegment.c b/tests/check/gst/gstsegment.c index c0a728ed92..98f38f2079 100644 --- a/tests/check/gst/gstsegment.c +++ b/tests/check/gst/gstsegment.c @@ -380,6 +380,43 @@ GST_START_TEST (segment_seek_size) 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) { @@ -1289,6 +1326,7 @@ gst_segment_suite (void) 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);