segment: Add _full variants of all stream/running_time from/to segment position functions

See formula clarifications in design docs for calculation details.

https://bugzilla.gnome.org/show_bug.cgi?id=756564
This commit is contained in:
Vivia Nikolaidou 2015-10-15 14:49:37 +03:00 committed by Sebastian Dröge
parent 8fc4794bcc
commit 6ff8fdfc47
6 changed files with 485 additions and 108 deletions

View file

@ -101,8 +101,13 @@ The following transformation to running_time exist:
if (S.rate > 0.0) if (S.rate > 0.0)
B.running_time = (B.timestamp - (S.start + S.offset)) / ABS (S.rate) + S.base B.running_time = (B.timestamp - (S.start + S.offset)) / ABS (S.rate) + S.base
=>
B.timestamp = (B.running_time - S.base) * ABS (S.rate) + S.start + S.offset
else else
B.running_time = ((S.stop - S.offset) - B.timestamp) / ABS (S.rate) + S.base B.running_time = ((S.stop - S.offset) - B.timestamp) / ABS (S.rate) + S.base
=>
B.timestamp = S.stop - S.offset - ((B.running_time - S.base) * ABS (S.rate))
We write B.running_time as the running_time obtained from the SEGMENT event We write B.running_time as the running_time obtained from the SEGMENT event
and the buffers of that segment. and the buffers of that segment.
@ -191,9 +196,13 @@ Stream time is calculated using the buffer times and the preceding SEGMENT
event as follows: event as follows:
stream_time = (B.timestamp - S.start) * ABS (S.applied_rate) + S.time stream_time = (B.timestamp - S.start) * ABS (S.applied_rate) + S.time
=> B.timestamp = (stream_time - S.time) / ABS(S.applied_rate) + S.start
For negative rates, B.timestamp will go backwards from S.stop to S.start, For negative rates, B.timestamp will go backwards from S.stop to S.start,
making the stream time go backwards. making the stream time go backwards:
stream_time = (S.stop - B.timestamp) * ABS(S.applied_rate) + S.time
=> B.timestamp = S.stop - (stream_time - S.time) / ABS(S.applied_rate)
In the PLAYING state, it is also possible to use the pipeline clock to derive In the PLAYING state, it is also possible to use the pipeline clock to derive
the current stream_time. the current stream_time.

View file

@ -2569,10 +2569,13 @@ gst_segment_copy
gst_segment_free gst_segment_free
gst_segment_do_seek gst_segment_do_seek
gst_segment_position_from_stream_time gst_segment_position_from_stream_time
gst_segment_position_from_stream_time_full
gst_segment_to_running_time gst_segment_to_running_time
gst_segment_to_running_time_full gst_segment_to_running_time_full
gst_segment_to_stream_time gst_segment_to_stream_time
gst_segment_to_stream_time_full
gst_segment_position_from_running_time gst_segment_position_from_running_time
gst_segment_position_from_running_time_full
gst_segment_to_position gst_segment_to_position
gst_segment_set_running_time gst_segment_set_running_time
gst_segment_copy_into gst_segment_copy_into

View file

@ -374,6 +374,114 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
return TRUE; return TRUE;
} }
/**
* gst_segment_to_stream_time_full:
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @position: the position in the segment
* @stream_time: result stream-time
*
* Translate @position to the total stream time using the currently configured
* segment. Compared to gst_segment_to_stream_time() this function can return
* negative stream-time.
*
* This function is typically used by elements that need to synchronize buffers
* against the clock or eachother.
*
* @position can be any value and the result of this function for values outside
* of the segment is extrapolated.
*
* When 1 is returned, @position resulted in a positive stream-time returned
* in @stream_time.
*
* When this function returns -1, the returned @stream_time should be negated
* to get the real negative stream time.
*
* Returns: a 1 or -1 on success, 0 on failure.
*
* Since: 1.8
*/
gint
gst_segment_to_stream_time_full (const GstSegment * segment, GstFormat format,
guint64 position, guint64 * stream_time)
{
guint64 start, stop, time;
gdouble abs_applied_rate;
gint res;
/* format does not matter for -1 */
if (G_UNLIKELY (position == -1)) {
*stream_time = -1;
return 0;
}
g_return_val_if_fail (segment != NULL, 0);
g_return_val_if_fail (segment->format == format, 0);
stop = segment->stop;
start = segment->start;
time = segment->time;
/* time must be known */
if (G_UNLIKELY (time == -1))
return 0;
abs_applied_rate = ABS (segment->applied_rate);
/* add or subtract from segment time based on applied rate */
if (G_LIKELY (segment->applied_rate > 0.0)) {
if (G_LIKELY (position > start)) {
/* bring to uncorrected position in segment */
*stream_time = position - start;
/* correct for applied rate if needed */
if (G_UNLIKELY (abs_applied_rate != 1.0))
*stream_time *= abs_applied_rate;
/* correct for segment time */
*stream_time += time;
res = 1;
} else {
*stream_time = start - position;
if (G_UNLIKELY (abs_applied_rate != 1.0))
*stream_time *= abs_applied_rate;
if (*stream_time > time) {
*stream_time -= time;
res = -1;
} else {
*stream_time = time - *stream_time;
res = 1;
}
}
} else {
/* correct for segment time. Streams with a negative applied_rate
* have timestamps between start and stop, as usual, but have the
* time member starting high and going backwards. */
/* cannot continue without a known segment stop */
if (G_UNLIKELY (stop == -1))
return 0;
if (G_UNLIKELY (position > stop)) {
*stream_time = position - stop;
if (G_UNLIKELY (abs_applied_rate != 1.0))
*stream_time *= abs_applied_rate;
if (*stream_time > time) {
*stream_time -= time;
res = -1;
} else {
*stream_time = time - *stream_time;
res = 1;
}
} else {
*stream_time = stop - position;
if (G_UNLIKELY (abs_applied_rate != 1.0))
*stream_time *= abs_applied_rate;
*stream_time += time;
res = 1;
}
}
return res;
}
/** /**
* gst_segment_to_stream_time: * gst_segment_to_stream_time:
* @segment: a #GstSegment structure. * @segment: a #GstSegment structure.
@ -393,65 +501,146 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
* *
* Returns: the position in stream_time or -1 when an invalid position * Returns: the position in stream_time or -1 when an invalid position
* was given. * was given.
*
* Since: 1.8
*/ */
guint64 guint64
gst_segment_to_stream_time (const GstSegment * segment, GstFormat format, gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
guint64 position) guint64 position)
{ {
guint64 stream_time, start, stop, time; guint64 result;
gdouble abs_applied_rate;
/* format does not matter for -1 */
if (G_UNLIKELY (position == -1))
return -1;
g_return_val_if_fail (segment != NULL, -1); g_return_val_if_fail (segment != NULL, -1);
g_return_val_if_fail (segment->format == format, -1); g_return_val_if_fail (segment->format == format, -1);
stop = segment->stop; /* before the segment boundary */
if (G_UNLIKELY (position < segment->start)) {
/* outside of the segment boundary stop */ GST_DEBUG ("position(%" G_GUINT64_FORMAT ") < start(%" G_GUINT64_FORMAT
if (G_UNLIKELY (stop != -1 && position > stop)) ")", position, segment->start);
return -1; return -1;
}
/* after the segment boundary */
if (G_UNLIKELY (segment->stop != -1 && position > segment->stop)) {
GST_DEBUG ("position(%" G_GUINT64_FORMAT ") > stop(%" G_GUINT64_FORMAT
")", position, segment->stop);
return -1;
}
if (gst_segment_to_stream_time_full (segment, format, position, &result) == 1)
return result;
return 0;
}
/**
* gst_segment_position_from_stream_time_full:
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @stream_time: the stream-time
* @position: the resulting position in the segment
*
* Translate @stream_time to the segment position using the currently configured
* segment. Compared to gst_segment_position_from_stream_time() this function can
* return negative segment position.
*
* This function is typically used by elements that need to synchronize buffers
* against the clock or each other.
*
* @stream_time can be any value and the result of this function for values outside
* of the segment is extrapolated.
*
* When 1 is returned, @stream_time resulted in a positive position returned
* in @position.
*
* When this function returns -1, the returned @position should be negated
* to get the real negative segment position.
*
* Returns: a 1 or -1 on success, 0 on failure.
*
* Since: 1.8
*/
gint
gst_segment_position_from_stream_time_full (const GstSegment * segment,
GstFormat format, guint64 stream_time, guint64 * position)
{
guint64 start, time;
gdouble abs_applied_rate;
gint res;
/* format does not matter for -1 */
if (G_UNLIKELY (stream_time == -1)) {
*position = -1;
return 0;
}
g_return_val_if_fail (segment != NULL, -1);
g_return_val_if_fail (segment->format == format, -1);
start = segment->start; start = segment->start;
/* before the segment boundary */
if (G_UNLIKELY (position < start))
return -1;
time = segment->time; time = segment->time;
/* time must be known */ /* time must be known */
if (G_UNLIKELY (time == -1)) if (G_UNLIKELY (time == -1))
return -1; return 0;
abs_applied_rate = ABS (segment->applied_rate); abs_applied_rate = ABS (segment->applied_rate);
/* add or subtract from segment time based on applied rate */
if (G_LIKELY (segment->applied_rate > 0.0)) { if (G_LIKELY (segment->applied_rate > 0.0)) {
if (G_UNLIKELY (position < start)) if (G_LIKELY (stream_time > time)) {
return -1; res = 1;
/* bring to uncorrected position in segment */ *position = stream_time - time;
stream_time = position - start; } else {
res = -1;
*position = time - stream_time;
}
/* correct for applied rate if needed */ /* correct for applied rate if needed */
if (G_UNLIKELY (abs_applied_rate != 1.0)) if (G_UNLIKELY (abs_applied_rate != 1.0))
stream_time *= abs_applied_rate; *position /= abs_applied_rate;
/* correct for segment time */
stream_time += time; if (G_UNLIKELY (res == -1)) {
if (*position > start) {
*position -= start;
} else { } else {
/* correct for segment time, clamp at 0. Streams with a negative *position = start - *position;
* applied_rate have timestamps between start and stop, as usual, but have res = 1;
* the time member starting high and going backwards. */ }
if (G_UNLIKELY (position > stop)) } else {
return -1; *position += start;
stream_time = stop - position; }
} else {
GstClockTime stop = segment->stop;
/* cannot continue without a known segment stop */
if (G_UNLIKELY (stop == -1))
return 0;
if (G_UNLIKELY (time > stream_time)) {
res = -1;
*position = time - stream_time;
} else {
res = 1;
*position = stream_time - time;
}
if (G_UNLIKELY (abs_applied_rate != 1.0)) if (G_UNLIKELY (abs_applied_rate != 1.0))
stream_time *= abs_applied_rate; *position /= abs_applied_rate;
stream_time += time; if (G_UNLIKELY (stop < *position)) {
if (G_LIKELY (res == 1)) {
*position -= stop;
res = -1;
} else {
*position += stop;
res = 1;
}
} else {
if (G_LIKELY (res == 1)) {
*position = stop - *position;
res = 1;
} else {
*position += stop;
res = 1;
}
}
} }
return stream_time; return res;
} }
/** /**
@ -472,56 +661,34 @@ guint64
gst_segment_position_from_stream_time (const GstSegment * segment, gst_segment_position_from_stream_time (const GstSegment * segment,
GstFormat format, guint64 stream_time) GstFormat format, guint64 stream_time)
{ {
guint64 position, start, stop, time; guint64 position;
gdouble abs_applied_rate; gint res;
/* format does not matter for -1 */
if (G_UNLIKELY (stream_time == -1))
return -1;
g_return_val_if_fail (segment != NULL, -1); g_return_val_if_fail (segment != NULL, -1);
g_return_val_if_fail (segment->format == format, -1); g_return_val_if_fail (segment->format == format, -1);
start = segment->start; res =
time = segment->time; gst_segment_position_from_stream_time_full (segment, format, stream_time,
/* this stream time was for a previous segment */ &position);
if (G_UNLIKELY (stream_time < segment->time))
return -1;
/* time must be known */ /* before the segment boundary */
if (G_UNLIKELY (time == -1)) if (G_UNLIKELY (position < segment->start)) {
return -1; GST_DEBUG ("position(%" G_GUINT64_FORMAT ") < start(%" G_GUINT64_FORMAT
")", position, segment->start);
position = stream_time - time;
abs_applied_rate = ABS (segment->applied_rate);
stop = segment->stop;
/* correct for applied rate if needed */
if (G_UNLIKELY (abs_applied_rate != 1.0))
position /= abs_applied_rate;
if (G_LIKELY (segment->applied_rate > 0.0)) {
position += start;
/* outside of the segment boundary stop */
if (G_UNLIKELY (stop != -1 && position > stop))
return -1;
} else {
/* cannot calculate without known boundary stop */
if (G_UNLIKELY (stop == -1))
return -1;
/* outside segment boundary */
if (G_UNLIKELY (position > stop))
return -1;
position = stop - position;
/* position before segment start */
if (G_UNLIKELY (position < start))
return -1; return -1;
} }
/* after the segment boundary */
if (G_UNLIKELY (segment->stop != -1 && position > segment->stop)) {
GST_DEBUG ("position(%" G_GUINT64_FORMAT ") > stop(%" G_GUINT64_FORMAT
")", position, segment->stop);
return -1;
}
if (res == 1)
return position; return position;
return -1;
} }
/** /**
@ -766,50 +933,139 @@ guint64
gst_segment_position_from_running_time (const GstSegment * segment, gst_segment_position_from_running_time (const GstSegment * segment,
GstFormat format, guint64 running_time) GstFormat format, guint64 running_time)
{ {
guint64 result; guint64 position;
gint res;
g_return_val_if_fail (segment != NULL, -1);
g_return_val_if_fail (segment->format == format, -1);
res =
gst_segment_position_from_running_time_full (segment, format,
running_time, &position);
if (res != 1) {
g_print
("here with start %lu stop %lu base %lu rate %f offset %lu running_time %lu position %lu\n",
segment->start, segment->stop, segment->base, segment->rate,
segment->offset, running_time, position);
return -1;
}
/* before the segment boundary */
if (G_UNLIKELY (position < segment->start)) {
GST_DEBUG ("position(%" G_GUINT64_FORMAT ") < start(%" G_GUINT64_FORMAT
")", position, segment->start);
return -1;
}
/* after the segment boundary */
if (G_UNLIKELY (segment->stop != -1 && position > segment->stop)) {
GST_DEBUG ("position(%" G_GUINT64_FORMAT ") > stop(%" G_GUINT64_FORMAT
")", position, segment->stop);
return -1;
}
return position;
}
/**
* gst_segment_position_from_running_time_full:
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @running_time: the running-time
* @position: the resulting position in the segment
*
* Translate @running_time to the segment position using the currently configured
* segment. Compared to gst_segment_position_from_running_time() this function can
* return negative segment position.
*
* This function is typically used by elements that need to synchronize buffers
* against the clock or each other.
*
* @running_time can be any value and the result of this function for values
* outside of the segment is extrapolated.
*
* When 1 is returned, @running_time resulted in a positive position returned
* in @position.
*
* When this function returns -1, the returned @position should be negated
* to get the real negative segment position.
*
* Returns: a 1 or -1 on success, 0 on failure.
*
* Since: 1.8
*/
gint
gst_segment_position_from_running_time_full (const GstSegment * segment,
GstFormat format, guint64 running_time, guint64 * position)
{
gint res;
guint64 start, stop, base; guint64 start, stop, base;
gdouble abs_rate; gdouble abs_rate;
if (G_UNLIKELY (running_time == -1)) if (G_UNLIKELY (running_time == -1)) {
return -1; *position = -1;
return 0;
}
g_return_val_if_fail (segment != NULL, -1); g_return_val_if_fail (segment != NULL, 0);
g_return_val_if_fail (segment->format == format, FALSE); g_return_val_if_fail (segment->format == format, 0);
base = segment->base; base = segment->base;
/* this running_time was for a previous segment */
if (running_time < base)
return -1;
/* start by subtracting the base time */
result = running_time - base;
/* move into the segment at the right rate */
abs_rate = ABS (segment->rate); abs_rate = ABS (segment->rate);
if (G_UNLIKELY (abs_rate != 1.0))
result = ceil (result * abs_rate);
start = segment->start; start = segment->start;
stop = segment->stop; stop = segment->stop;
if (G_LIKELY (segment->rate > 0.0)) { if (G_LIKELY (segment->rate > 0.0)) {
/* start by subtracting the base time */
if (G_LIKELY (running_time >= base)) {
*position = running_time - base;
/* move into the segment at the right rate */
if (G_UNLIKELY (abs_rate != 1.0))
*position = ceil (*position * abs_rate);
/* bring to corrected position in segment */ /* bring to corrected position in segment */
result += start + segment->offset; *position += start + segment->offset;
res = 1;
/* outside of the segment boundary stop */
if (G_UNLIKELY (stop != -1 && result > stop))
return -1;
} else { } else {
/* cannot continue if no stop position set or outside of *position = base - running_time;
* the segment. */ if (G_UNLIKELY (abs_rate != 1.0))
if (G_UNLIKELY (stop == -1 || result + start > stop)) *position = ceil (*position * abs_rate);
return -1; if (start + segment->offset > *position) {
*position -= start + segment->offset;
/* bring to corrected position in segment */ res = -1;
result = stop - result - segment->offset; } else {
*position = start + segment->offset - *position;
res = 1;
} }
return result; }
} else {
if (G_LIKELY (running_time >= base)) {
*position = running_time - base;
if (G_UNLIKELY (abs_rate != 1.0))
*position = ceil (*position * abs_rate);
if (G_UNLIKELY (stop < *position + segment->offset)) {
*position += segment->offset - stop;
res = -1;
} else {
*position = stop - *position - segment->offset;
res = 1;
}
} else {
*position = base - running_time;
if (G_UNLIKELY (abs_rate != 1.0))
*position = ceil (*position * abs_rate);
if (G_UNLIKELY (stop < segment->offset - *position)) {
*position -= segment->offset - stop;
res = -1;
} else {
*position = stop + *position - segment->offset;
res = 1;
}
}
}
return res;
} }
/** /**

View file

@ -218,7 +218,9 @@ void gst_segment_free (GstSegment *segment);
void gst_segment_init (GstSegment *segment, GstFormat format); void gst_segment_init (GstSegment *segment, GstFormat format);
gint gst_segment_to_stream_time_full (const GstSegment *segment, GstFormat format, guint64 position, guint64 * stream_time);
guint64 gst_segment_to_stream_time (const GstSegment *segment, GstFormat format, guint64 position); guint64 gst_segment_to_stream_time (const GstSegment *segment, GstFormat format, guint64 position);
gint gst_segment_position_from_stream_time_full (const GstSegment * segment, GstFormat format, guint64 stream_time, guint64 * position);
guint64 gst_segment_position_from_stream_time (const GstSegment * segment, GstFormat format, guint64 stream_time); guint64 gst_segment_position_from_stream_time (const GstSegment * segment, GstFormat format, guint64 stream_time);
guint64 gst_segment_to_running_time (const GstSegment *segment, GstFormat format, guint64 position); guint64 gst_segment_to_running_time (const GstSegment *segment, GstFormat format, guint64 position);
@ -227,6 +229,7 @@ gint gst_segment_to_running_time_full (const GstSegment *segment, GstFor
#ifndef GST_DISABLE_DEPRECATED #ifndef GST_DISABLE_DEPRECATED
guint64 gst_segment_to_position (const GstSegment *segment, GstFormat format, guint64 running_time); guint64 gst_segment_to_position (const GstSegment *segment, GstFormat format, guint64 running_time);
#endif #endif
gint gst_segment_position_from_running_time_full (const GstSegment *segment, GstFormat format, guint64 running_time, guint64 * position);
guint64 gst_segment_position_from_running_time (const GstSegment *segment, GstFormat format, guint64 running_time); guint64 gst_segment_position_from_running_time (const GstSegment *segment, GstFormat format, guint64 running_time);
gboolean gst_segment_set_running_time (GstSegment *segment, GstFormat format, guint64 running_time); gboolean gst_segment_set_running_time (GstSegment *segment, GstFormat format, guint64 running_time);

View file

@ -755,7 +755,7 @@ GST_END_TEST;
GST_START_TEST (segment_full) GST_START_TEST (segment_full)
{ {
GstSegment segment; GstSegment segment;
guint64 rt; guint64 rt, pos;
gst_segment_init (&segment, GST_FORMAT_TIME); gst_segment_init (&segment, GST_FORMAT_TIME);
@ -770,9 +770,15 @@ GST_START_TEST (segment_full)
fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
50, &rt) == 1); 50, &rt) == 1);
fail_unless (rt == 0); fail_unless (rt == 0);
fail_unless (gst_segment_position_from_running_time_full (&segment,
GST_FORMAT_TIME, rt, &pos) == 1);
fail_unless (pos == 50);
fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
200, &rt) == 1); 200, &rt) == 1);
fail_unless (rt == 150); fail_unless (rt == 150);
fail_unless (gst_segment_position_from_running_time_full (&segment,
GST_FORMAT_TIME, rt, &pos) == 1);
fail_unless (pos == 200);
fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 40, 40, NULL, fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 40, 40, NULL,
NULL)); NULL));
fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40, fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40,
@ -785,6 +791,9 @@ GST_START_TEST (segment_full)
NULL)); NULL));
fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201, fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201,
&rt) == 1); &rt) == 1);
fail_unless (gst_segment_position_from_running_time_full (&segment,
GST_FORMAT_TIME, rt, &pos) == 1);
fail_unless (pos == 201);
fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME, fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
-50) == TRUE); -50) == TRUE);
@ -794,6 +803,99 @@ GST_START_TEST (segment_full)
50, &rt) == -1); 50, &rt) == -1);
GST_DEBUG ("%" G_GUINT64_FORMAT, rt); GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
fail_unless (rt == 50); fail_unless (rt == 50);
segment.start = 50;
segment.stop = 300;
segment.position = 150;
segment.time = 0;
segment.offset = 0;
gst_segment_set_running_time (&segment, GST_FORMAT_TIME, 100);
fail_unless_equals_int (segment.base, 100);
fail_unless (gst_segment_position_from_running_time_full (&segment,
GST_FORMAT_TIME, 70, &pos) == -1);
fail_unless (gst_segment_position_from_running_time_full (&segment,
GST_FORMAT_TIME, 140, &pos) == 1);
fail_unless_equals_int (pos, 190);
}
GST_END_TEST;
GST_START_TEST (segment_stream_time_full)
{
GstSegment segment;
guint64 st, pos;
gst_segment_init (&segment, GST_FORMAT_TIME);
segment.start = 50;
segment.stop = 200;
segment.time = 30;
segment.position = 0;
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
0, &st) == -1);
fail_unless_equals_int (st, 20);
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
20, &st) == 1);
fail_unless_equals_int (st, 0);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 0, &pos) == 1);
fail_unless_equals_int (pos, 20);
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
10, &st) == -1);
fail_unless_equals_int (st, 10);
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
40, &st) == 1);
fail_unless_equals_int (st, 20);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, st, &pos) == 1);
fail_unless_equals_int (pos, 40);
segment.time = 100;
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 40, &pos) == -1);
fail_unless_equals_int (pos, 10);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 60, &pos) == 1);
fail_unless_equals_int (pos, 10);
segment.start = 50;
segment.position = 150;
segment.stop = 200;
segment.time = 0;
segment.applied_rate = -1;
segment.rate = -1;
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
0, &st) == 1);
fail_unless_equals_int (st, 200);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 200, &pos) == 1);
fail_unless_equals_int (pos, 0);
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
250, &st) == -1);
fail_unless_equals_int (st, 50);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 200, &pos) == 1);
fail_unless_equals_int (pos, 0);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 250, &pos) == -1);
fail_unless_equals_int (pos, 50);
segment.time = 70;
fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
250, &st) == 1);
fail_unless_equals_int (st, 20);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 50, &pos) == 1);
fail_unless_equals_int (pos, 220);
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 90, &pos) == 1);
fail_unless_equals_int (pos, 180);
segment.stop = 60;
fail_unless (gst_segment_position_from_stream_time_full (&segment,
GST_FORMAT_TIME, 5, &pos) == 1);
fail_unless_equals_int (pos, 125);
} }
GST_END_TEST; GST_END_TEST;
@ -897,6 +999,7 @@ gst_segment_suite (void)
tcase_add_test (tc_chain, segment_full); tcase_add_test (tc_chain, segment_full);
tcase_add_test (tc_chain, segment_negative_rate); tcase_add_test (tc_chain, segment_negative_rate);
tcase_add_test (tc_chain, segment_negative_applied_rate); tcase_add_test (tc_chain, segment_negative_applied_rate);
tcase_add_test (tc_chain, segment_stream_time_full);
return s; return s;
} }

View file

@ -1158,12 +1158,15 @@ EXPORTS
gst_segment_new gst_segment_new
gst_segment_offset_running_time gst_segment_offset_running_time
gst_segment_position_from_running_time gst_segment_position_from_running_time
gst_segment_position_from_running_time_full
gst_segment_position_from_stream_time gst_segment_position_from_stream_time
gst_segment_position_from_stream_time_full
gst_segment_set_running_time gst_segment_set_running_time
gst_segment_to_position gst_segment_to_position
gst_segment_to_running_time gst_segment_to_running_time
gst_segment_to_running_time_full gst_segment_to_running_time_full
gst_segment_to_stream_time gst_segment_to_stream_time
gst_segment_to_stream_time_full
gst_segtrap_is_enabled gst_segtrap_is_enabled
gst_segtrap_set_enabled gst_segtrap_set_enabled
gst_state_change_get_type gst_state_change_get_type