goto no_framerate;
if (pad == videorate->srcpad) {
+ /* out_frame_count is scaled by the frame rate caps when calculating next_ts.
+ * when the frame rate caps change, we must update base_ts and reset
+ * out_frame_count */
+ if (videorate->to_rate_numerator) {
+ videorate->base_ts +=
+ gst_util_uint64_scale (videorate->out_frame_count,
+ videorate->to_rate_denominator * GST_SECOND,
+ videorate->to_rate_numerator);
+ }
+ videorate->out_frame_count = 0;
videorate->to_rate_numerator = rate_numerator;
videorate->to_rate_denominator = rate_denominator;
otherpad = videorate->sinkpad;
videorate->in = 0;
videorate->out = 0;
- videorate->segment_out = 0;
+ videorate->base_ts = 0;
+ videorate->out_frame_count = 0;
videorate->drop = 0;
videorate->dup = 0;
videorate->next_ts = GST_CLOCK_TIME_NONE;
push_ts = videorate->next_ts;
videorate->out++;
- videorate->segment_out++;
+ videorate->out_frame_count++;
if (videorate->to_rate_numerator) {
/* interpolate next expected timestamp in the segment */
- videorate->next_ts = videorate->segment.accum + videorate->segment.start +
- gst_util_uint64_scale (videorate->segment_out,
+ videorate->next_ts =
+ videorate->segment.accum + videorate->segment.start +
+ videorate->base_ts + gst_util_uint64_scale (videorate->out_frame_count,
videorate->to_rate_denominator * GST_SECOND,
videorate->to_rate_numerator);
GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
gst_video_rate_notify_drop (videorate);
}
/* clean up for the new one; _chain will resume from the new start */
- videorate->segment_out = 0;
+ videorate->base_ts = 0;
+ videorate->out_frame_count = 0;
gst_video_rate_swap_prev (videorate, NULL, 0);
videorate->next_ts = GST_CLOCK_TIME_NONE;
}
* timestamp in the segment */
if (videorate->skip_to_first) {
videorate->next_ts = in_ts;
- videorate->segment_out = gst_util_uint64_scale (in_ts,
+ videorate->out_frame_count = gst_util_uint64_scale (in_ts,
videorate->to_rate_numerator,
videorate->to_rate_denominator * GST_SECOND) -
(videorate->segment.accum + videorate->segment.start);
guint64 next_ts; /* Timestamp of next buffer to output */
GstBuffer *prevbuf;
guint64 prev_ts; /* Previous buffer timestamp */
- guint64 segment_out; /* in-segment counting */
+ guint64 out_frame_count; /* number of frames output since the beginning
+ * of the segment or the last frame rate caps
+ * change, whichever was later */
+ guint64 base_ts; /* used in next_ts calculation after a
+ * frame rate caps change */
gboolean discont;
guint64 last_ts; /* Timestamp of last input buffer */