mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 08:25:33 +00:00
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:
parent
8fc4794bcc
commit
6ff8fdfc47
6 changed files with 485 additions and 108 deletions
docs
gst
tests/check/gst
win32/common
|
@ -101,8 +101,13 @@ The following transformation to running_time exist:
|
|||
|
||||
if (S.rate > 0.0)
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
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,
|
||||
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
|
||||
the current stream_time.
|
||||
|
|
|
@ -2569,10 +2569,13 @@ gst_segment_copy
|
|||
gst_segment_free
|
||||
gst_segment_do_seek
|
||||
gst_segment_position_from_stream_time
|
||||
gst_segment_position_from_stream_time_full
|
||||
gst_segment_to_running_time
|
||||
gst_segment_to_running_time_full
|
||||
gst_segment_to_stream_time
|
||||
gst_segment_to_stream_time_full
|
||||
gst_segment_position_from_running_time
|
||||
gst_segment_position_from_running_time_full
|
||||
gst_segment_to_position
|
||||
gst_segment_set_running_time
|
||||
gst_segment_copy_into
|
||||
|
|
466
gst/gstsegment.c
466
gst/gstsegment.c
|
@ -374,6 +374,114 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
|
|||
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:
|
||||
* @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
|
||||
* was given.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
guint64
|
||||
gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
|
||||
guint64 position)
|
||||
{
|
||||
guint64 stream_time, start, stop, time;
|
||||
gdouble abs_applied_rate;
|
||||
|
||||
/* format does not matter for -1 */
|
||||
if (G_UNLIKELY (position == -1))
|
||||
return -1;
|
||||
guint64 result;
|
||||
|
||||
g_return_val_if_fail (segment != NULL, -1);
|
||||
g_return_val_if_fail (segment->format == format, -1);
|
||||
|
||||
stop = segment->stop;
|
||||
|
||||
/* outside of the segment boundary stop */
|
||||
if (G_UNLIKELY (stop != -1 && position > stop))
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* before the segment boundary */
|
||||
if (G_UNLIKELY (position < start))
|
||||
return -1;
|
||||
|
||||
time = segment->time;
|
||||
|
||||
/* time must be known */
|
||||
if (G_UNLIKELY (time == -1))
|
||||
return -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_UNLIKELY (position < start))
|
||||
return -1;
|
||||
/* bring to uncorrected position in segment */
|
||||
stream_time = position - start;
|
||||
if (G_LIKELY (stream_time > time)) {
|
||||
res = 1;
|
||||
*position = stream_time - time;
|
||||
} else {
|
||||
res = -1;
|
||||
*position = time - stream_time;
|
||||
}
|
||||
/* 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;
|
||||
*position /= abs_applied_rate;
|
||||
|
||||
if (G_UNLIKELY (res == -1)) {
|
||||
if (*position > start) {
|
||||
*position -= start;
|
||||
} else {
|
||||
*position = start - *position;
|
||||
res = 1;
|
||||
}
|
||||
} else {
|
||||
*position += start;
|
||||
}
|
||||
} else {
|
||||
/* correct for segment time, clamp at 0. Streams with a negative
|
||||
* applied_rate have timestamps between start and stop, as usual, but have
|
||||
* the time member starting high and going backwards. */
|
||||
if (G_UNLIKELY (position > stop))
|
||||
return -1;
|
||||
stream_time = stop - position;
|
||||
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))
|
||||
stream_time *= abs_applied_rate;
|
||||
stream_time += time;
|
||||
*position /= abs_applied_rate;
|
||||
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,
|
||||
GstFormat format, guint64 stream_time)
|
||||
{
|
||||
guint64 position, start, stop, time;
|
||||
gdouble abs_applied_rate;
|
||||
|
||||
/* format does not matter for -1 */
|
||||
if (G_UNLIKELY (stream_time == -1))
|
||||
return -1;
|
||||
guint64 position;
|
||||
gint res;
|
||||
|
||||
g_return_val_if_fail (segment != NULL, -1);
|
||||
g_return_val_if_fail (segment->format == format, -1);
|
||||
|
||||
start = segment->start;
|
||||
time = segment->time;
|
||||
/* this stream time was for a previous segment */
|
||||
if (G_UNLIKELY (stream_time < segment->time))
|
||||
res =
|
||||
gst_segment_position_from_stream_time_full (segment, format, stream_time,
|
||||
&position);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* time must be known */
|
||||
if (G_UNLIKELY (time == -1))
|
||||
return -1;
|
||||
|
||||
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 position;
|
||||
/* 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 -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -766,50 +933,139 @@ guint64
|
|||
gst_segment_position_from_running_time (const GstSegment * segment,
|
||||
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;
|
||||
gdouble abs_rate;
|
||||
|
||||
if (G_UNLIKELY (running_time == -1))
|
||||
return -1;
|
||||
if (G_UNLIKELY (running_time == -1)) {
|
||||
*position = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_return_val_if_fail (segment != NULL, -1);
|
||||
g_return_val_if_fail (segment->format == format, FALSE);
|
||||
g_return_val_if_fail (segment != NULL, 0);
|
||||
g_return_val_if_fail (segment->format == format, 0);
|
||||
|
||||
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);
|
||||
if (G_UNLIKELY (abs_rate != 1.0))
|
||||
result = ceil (result * abs_rate);
|
||||
|
||||
start = segment->start;
|
||||
stop = segment->stop;
|
||||
|
||||
if (G_LIKELY (segment->rate > 0.0)) {
|
||||
/* bring to corrected position in segment */
|
||||
result += start + segment->offset;
|
||||
|
||||
/* outside of the segment boundary stop */
|
||||
if (G_UNLIKELY (stop != -1 && result > stop))
|
||||
return -1;
|
||||
/* 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 */
|
||||
*position += start + segment->offset;
|
||||
res = 1;
|
||||
} else {
|
||||
*position = base - running_time;
|
||||
if (G_UNLIKELY (abs_rate != 1.0))
|
||||
*position = ceil (*position * abs_rate);
|
||||
if (start + segment->offset > *position) {
|
||||
*position -= start + segment->offset;
|
||||
res = -1;
|
||||
} else {
|
||||
*position = start + segment->offset - *position;
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* cannot continue if no stop position set or outside of
|
||||
* the segment. */
|
||||
if (G_UNLIKELY (stop == -1 || result + start > stop))
|
||||
return -1;
|
||||
|
||||
/* bring to corrected position in segment */
|
||||
result = stop - result - segment->offset;
|
||||
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 result;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -218,7 +218,9 @@ void gst_segment_free (GstSegment *segment);
|
|||
|
||||
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);
|
||||
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_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
|
||||
guint64 gst_segment_to_position (const GstSegment *segment, GstFormat format, guint64 running_time);
|
||||
#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);
|
||||
|
||||
gboolean gst_segment_set_running_time (GstSegment *segment, GstFormat format, guint64 running_time);
|
||||
|
|
|
@ -755,7 +755,7 @@ GST_END_TEST;
|
|||
GST_START_TEST (segment_full)
|
||||
{
|
||||
GstSegment segment;
|
||||
guint64 rt;
|
||||
guint64 rt, pos;
|
||||
|
||||
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,
|
||||
50, &rt) == 1);
|
||||
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,
|
||||
200, &rt) == 1);
|
||||
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,
|
||||
NULL));
|
||||
fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40,
|
||||
|
@ -785,6 +791,9 @@ GST_START_TEST (segment_full)
|
|||
NULL));
|
||||
fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201,
|
||||
&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,
|
||||
-50) == TRUE);
|
||||
|
@ -794,6 +803,99 @@ GST_START_TEST (segment_full)
|
|||
50, &rt) == -1);
|
||||
GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
|
||||
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;
|
||||
|
@ -897,6 +999,7 @@ gst_segment_suite (void)
|
|||
tcase_add_test (tc_chain, segment_full);
|
||||
tcase_add_test (tc_chain, segment_negative_rate);
|
||||
tcase_add_test (tc_chain, segment_negative_applied_rate);
|
||||
tcase_add_test (tc_chain, segment_stream_time_full);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -1158,12 +1158,15 @@ EXPORTS
|
|||
gst_segment_new
|
||||
gst_segment_offset_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_full
|
||||
gst_segment_set_running_time
|
||||
gst_segment_to_position
|
||||
gst_segment_to_running_time
|
||||
gst_segment_to_running_time_full
|
||||
gst_segment_to_stream_time
|
||||
gst_segment_to_stream_time_full
|
||||
gst_segtrap_is_enabled
|
||||
gst_segtrap_set_enabled
|
||||
gst_state_change_get_type
|
||||
|
|
Loading…
Reference in a new issue