gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
guint64 position)
{
- guint64 result, start, stop, time;
+ guint64 stream_time, start, stop, time;
gdouble abs_applied_rate;
/* format does not matter for -1 */
if (G_UNLIKELY (time == -1))
return -1;
- /* bring to uncorrected position in segment */
- result = position - start;
-
abs_applied_rate = ABS (segment->applied_rate);
- /* correct for applied rate if needed */
- if (G_UNLIKELY (abs_applied_rate != 1.0))
- result *= abs_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;
+ /* correct for applied rate if needed */
+ if (G_UNLIKELY (abs_applied_rate != 1.0))
+ stream_time *= abs_applied_rate;
/* correct for segment time */
- result += time;
+ stream_time += time;
} 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_LIKELY (time > result))
- result = time - result;
- else
- result = 0;
+ if (G_UNLIKELY (position > stop))
+ return -1;
+ stream_time = stop - position;
+ if (G_UNLIKELY (abs_applied_rate != 1.0))
+ stream_time *= abs_applied_rate;
+ stream_time += time;
}
- return result;
+ return stream_time;
}
/**
* @running_time: result running-time
*
* Translate @position to the total running time using the currently configured
- * segment. Position is a value between @segment start and stop time. Compared to
- * gst_segment_to_running_time() this function can return negative running-time
- * and specify if the position was before or after the segment incase it is outside
- * of the segment.
+ * segment. Compared to gst_segment_to_running_time() this function can return
+ * negative running-time.
*
* This function is typically used by elements that need to synchronize buffers
* against the clock or eachother.
*
- * When #GST_SEGMENT_RESULT_OK is returned, @position is between start and stop of
- * @segment and thus resulted in a positive running-time returned in @running_time.
+ * @position can be any value and the result of this function for values outside
+ * of the segment is extrapolated.
*
- * When @position is outside of the segment start and stop values,
- * #GST_SEGMENT_RESULT_BEFORE or #GST_SEGMENT_RESULT_AFTER is returned depending
- * if @position is respectively before or after the segment.
+ * When 1 is returned, @position resulted in a positive running-time returned
+ * in @running_time.
*
- * When this function returns #GST_SEGMENT_RESULT_NEGATIVE, the returned
- * @running_time should be negated to get the real negative running time.
+ * When this function returns -1, the returned @running_time should be negated
+ * to get the real negative running time.
*
- * Returns: a #GstSegmentResult
+ * Returns: a 1 or -1 on success, 0 on failure.
*
* Since: 1.6
*/
-GstSegmentResult
+gint
gst_segment_to_running_time_full (const GstSegment * segment, GstFormat format,
guint64 position, guint64 * running_time)
{
- GstSegmentResult res;
+ gint res = 0;
guint64 result;
guint64 start, stop, offset;
gdouble abs_rate;
if (G_UNLIKELY (position == -1)) {
GST_DEBUG ("invalid position (-1)");
- res = GST_SEGMENT_RESULT_INVALID;
goto done;
}
- g_return_val_if_fail (segment != NULL, GST_SEGMENT_RESULT_INVALID);
- g_return_val_if_fail (segment->format == format, GST_SEGMENT_RESULT_INVALID);
-
- start = segment->start;
- /* before the segment boundary */
- if (G_UNLIKELY (position < start)) {
- GST_DEBUG ("position(%" G_GUINT64_FORMAT ") < start(%" G_GUINT64_FORMAT
- ")", position, start);
- if (G_LIKELY (segment->rate > 0.0))
- res = GST_SEGMENT_RESULT_BEFORE;
- else
- res = GST_SEGMENT_RESULT_AFTER;
- goto done;
- }
-
- stop = segment->stop;
- /* after the segment boundary */
- if (G_UNLIKELY (stop != -1 && position > stop)) {
- GST_DEBUG ("position(%" G_GUINT64_FORMAT ") > stop(%" G_GUINT64_FORMAT
- ")", position, stop);
- if (G_LIKELY (segment->rate > 0.0))
- res = GST_SEGMENT_RESULT_AFTER;
- else
- res = GST_SEGMENT_RESULT_BEFORE;
- goto done;
- }
+ g_return_val_if_fail (segment != NULL, 0);
+ g_return_val_if_fail (segment->format == format, 0);
offset = segment->offset;
if (G_LIKELY (segment->rate > 0.0)) {
+ start = segment->start + offset;
+
/* bring to uncorrected position in segment */
- if (position < start + offset) {
+ if (position < start) {
/* negative value */
- result = (start + offset) - position;
- res = GST_SEGMENT_RESULT_NEGATIVE;
+ result = start - position;
+ res = -1;
} else {
- result = position - (start + offset);
- res = GST_SEGMENT_RESULT_OK;
+ result = position - start;
+ res = 1;
}
} else {
+ stop = segment->stop;
+
/* cannot continue if no stop position set or invalid offset */
- g_return_val_if_fail (stop != -1, GST_SEGMENT_RESULT_INVALID);
- g_return_val_if_fail (stop >= segment->offset, GST_SEGMENT_RESULT_INVALID);
+ g_return_val_if_fail (stop != -1, 0);
+ g_return_val_if_fail (stop >= offset, 0);
+
+ stop -= offset;
/* bring to uncorrected position in segment */
- if (position > stop - offset) {
+ if (position > stop) {
/* negative value */
- result = position - (stop - offset);
- res = GST_SEGMENT_RESULT_NEGATIVE;
+ result = position - stop;
+ res = -1;
} else {
- result = (stop - offset) - position;
- res = GST_SEGMENT_RESULT_OK;
+ result = stop - position;
+ res = 1;
}
}
result /= abs_rate;
/* correct for base of the segment */
- if (res == GST_SEGMENT_RESULT_OK)
+ if (res == 1)
/* positive, add base */
*running_time = result + segment->base;
else if (segment->base >= result) {
/* negative and base is bigger, subtract from base and we have a
* positive value again */
*running_time = segment->base - result;
- res = GST_SEGMENT_RESULT_OK;
+ res = 1;
} else {
/* negative and base is smaller, subtract base and remainder is
* negative */
{
if (running_time)
*running_time = -1;
- return res;
+ return 0;
}
}
guint64 position)
{
guint64 result;
- GstSegmentResult res;
- res = gst_segment_to_running_time_full (segment, format, position, &result);
- if (res == GST_SEGMENT_RESULT_OK)
+ g_return_val_if_fail (segment != NULL, -1);
+ g_return_val_if_fail (segment->format == format, -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;
+ }
+
+ if (gst_segment_to_running_time_full (segment, format, position,
+ &result) == 1)
return result;
return -1;
}
return TRUE;
}
+
+/**
+ * gst_segment_is_equal:
+ * @s0: a #GstSegment structure.
+ * @s1: a #GstSegment structure.
+ *
+ * Checks for two segments being equal. Equality here is defined
+ * as perfect equality, including floating point values.
+ *
+ * Since: 1.6
+ *
+ * Returns: %TRUE if the segments are equal, %FALSE otherwise.
+ */
+gboolean
+gst_segment_is_equal (const GstSegment * s0, const GstSegment * s1)
+{
+ if (s0->flags != s1->flags)
+ return FALSE;
+ if (s0->rate != s1->rate)
+ return FALSE;
+ if (s0->applied_rate != s1->applied_rate)
+ return FALSE;
+ if (s0->format != s1->format)
+ return FALSE;
+ if (s0->base != s1->base)
+ return FALSE;
+ if (s0->offset != s1->offset)
+ return FALSE;
+ if (s0->start != s1->start)
+ return FALSE;
+ if (s0->stop != s1->stop)
+ return FALSE;
+ if (s0->time != s1->time)
+ return FALSE;
+ if (s0->position != s1->position)
+ return FALSE;
+ if (s0->duration != s1->duration)
+ return FALSE;
+ return TRUE;
+}