/** * gst_segment_to_running_time: * @segment: a #GstSegment structure. * @format: the format of the segment. * @position: the position in the segment * * Translate @position to the total running time using the currently configured * segment. Position is a value between @segment start and stop time. * * This function is typically used by elements that need to synchronize to the * global clock in a pipeline. The running time is a constantly increasing value * starting from 0. When gst_segment_init() is called, this value will reset to * 0. * * This function returns -1 if the position is outside of @segment start and stop. * * Returns: the position as the total running time or -1 when an invalid position * was given. */ guint64 gst_segment_to_running_time (const GstSegment * segment, GstFormat format, guint64 position) { guint64 result; 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; }
static GstFlowReturn gst_timecodewait_asink_chain (GstPad * pad, GstObject * parent, GstBuffer * inbuf) { GstClockTime timestamp; GstTimeCodeWait *self = GST_TIMECODEWAIT (parent); GstClockTime current_running_time; GstClockTime video_running_time = GST_CLOCK_TIME_NONE; GstClockTime duration; GstClockTime running_time_at_end = GST_CLOCK_TIME_NONE; gint asign, vsign = 1, esign = 1; timestamp = GST_BUFFER_TIMESTAMP (inbuf); if (timestamp == GST_CLOCK_TIME_NONE) { gst_buffer_unref (inbuf); return GST_FLOW_ERROR; } g_mutex_lock (&self->mutex); self->asegment.position = timestamp; asign = gst_segment_to_running_time_full (&self->asegment, GST_FORMAT_TIME, self->asegment.position, ¤t_running_time); if (asign == 0) { g_mutex_unlock (&self->mutex); gst_buffer_unref (inbuf); GST_ERROR_OBJECT (self, "Could not get current running time"); return GST_FLOW_ERROR; } if (self->vsegment.format == GST_FORMAT_TIME) { vsign = gst_segment_to_running_time_full (&self->vsegment, GST_FORMAT_TIME, self->vsegment.position, &video_running_time); if (vsign == 0) { video_running_time = GST_CLOCK_TIME_NONE; } } while (!(self->video_eos_flag || self->audio_flush_flag || self->shutdown_flag) && (video_running_time == GST_CLOCK_TIME_NONE || gst_timecodewait_compare_guint64_with_signs (asign, current_running_time, vsign, video_running_time) == 1) && self->running_time_of_timecode == GST_CLOCK_TIME_NONE) { g_cond_wait (&self->cond, &self->mutex); vsign = gst_segment_to_running_time_full (&self->vsegment, GST_FORMAT_TIME, self->vsegment.position, &video_running_time); if (vsign == 0) { video_running_time = GST_CLOCK_TIME_NONE; } } if (self->audio_flush_flag || self->shutdown_flag) { GST_DEBUG_OBJECT (self, "Shutting down, ignoring frame"); gst_buffer_unref (inbuf); return GST_FLOW_FLUSHING; } duration = GST_BUFFER_DURATION (inbuf); if (duration != GST_CLOCK_TIME_NONE) { esign = gst_segment_to_running_time_full (&self->asegment, GST_FORMAT_TIME, self->asegment.position + duration, &running_time_at_end); if (esign == 0) { g_mutex_unlock (&self->mutex); GST_ERROR_OBJECT (self, "Could not get running time at end"); gst_buffer_unref (inbuf); return GST_FLOW_ERROR; } } if (self->running_time_of_timecode == GST_CLOCK_TIME_NONE || gst_timecodewait_compare_guint64_with_signs (esign, running_time_at_end, 1, self->running_time_of_timecode) == -1) { GST_DEBUG_OBJECT (self, "Dropped an audio buf at %" GST_TIME_FORMAT " with timecode %" GST_TIME_FORMAT " video timecode %" GST_TIME_FORMAT, GST_TIME_ARGS (current_running_time), GST_TIME_ARGS (self->running_time_of_timecode), GST_TIME_ARGS (video_running_time)); gst_buffer_unref (inbuf); inbuf = NULL; } else if (current_running_time < self->running_time_of_timecode && running_time_at_end > self->running_time_of_timecode) { GstSegment asegment2 = self->asegment; gst_segment_set_running_time (&asegment2, GST_FORMAT_TIME, self->running_time_of_timecode); inbuf = gst_audio_buffer_clip (inbuf, &asegment2, self->ainfo.rate, self->ainfo.bpf); } g_mutex_unlock (&self->mutex); if (inbuf) return gst_pad_push (self->asrcpad, inbuf); else return GST_FLOW_OK; }