mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
imagefreeze: Implement reverse playback and set buffer offsets
This commit is contained in:
parent
e71c7ecc93
commit
0c170d9107
1 changed files with 62 additions and 29 deletions
|
@ -569,10 +569,22 @@ gst_image_freeze_src_event (GstPad * pad, GstEvent * event)
|
|||
|
||||
GST_OBJECT_LOCK (self);
|
||||
gst_event_replace (&self->close_segment, NULL);
|
||||
self->close_segment =
|
||||
gst_event_new_new_segment_full (TRUE, self->segment.rate,
|
||||
self->segment.applied_rate, self->segment.format, self->segment.start,
|
||||
self->segment.last_stop, self->segment.time);
|
||||
if (self->segment.rate >= 0) {
|
||||
self->close_segment =
|
||||
gst_event_new_new_segment_full (TRUE, self->segment.rate,
|
||||
self->segment.applied_rate, self->segment.format,
|
||||
self->segment.start, self->segment.last_stop, self->segment.time);
|
||||
} else {
|
||||
gint64 stop;
|
||||
|
||||
if ((stop = self->segment.stop) == -1)
|
||||
stop = self->segment.duration;
|
||||
|
||||
self->close_segment =
|
||||
gst_event_new_new_segment_full (TRUE, self->segment.rate,
|
||||
self->segment.applied_rate, self->segment.format,
|
||||
self->segment.last_stop, stop, self->segment.last_stop);
|
||||
}
|
||||
|
||||
gst_segment_set_seek (&self->segment, rate, format, flags, start_type,
|
||||
start, stop_type, stop, NULL);
|
||||
|
@ -644,6 +656,7 @@ gst_image_freeze_src_loop (GstPad * pad)
|
|||
{
|
||||
GstImageFreeze *self = GST_IMAGE_FREEZE (GST_PAD_PARENT (pad));
|
||||
GstBuffer *buffer;
|
||||
guint64 offset;
|
||||
GstClockTime timestamp, duration;
|
||||
gint64 cstart, cstop;
|
||||
gboolean in_seg, eos;
|
||||
|
@ -675,9 +688,15 @@ gst_image_freeze_src_loop (GstPad * pad)
|
|||
self->segment.stop, self->segment.start);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
self->offset =
|
||||
gst_util_uint64_scale (self->segment.start, self->fps_n,
|
||||
self->fps_d * GST_SECOND);
|
||||
if (self->segment.rate >= 0) {
|
||||
self->offset =
|
||||
gst_util_uint64_scale (self->segment.start, self->fps_n,
|
||||
self->fps_d * GST_SECOND);
|
||||
} else {
|
||||
self->offset =
|
||||
gst_util_uint64_scale (self->segment.stop, self->fps_n,
|
||||
self->fps_d * GST_SECOND);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
self->need_segment = FALSE;
|
||||
|
@ -686,19 +705,24 @@ gst_image_freeze_src_loop (GstPad * pad)
|
|||
}
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
offset = self->offset;
|
||||
|
||||
if (self->fps_n != 0) {
|
||||
timestamp =
|
||||
gst_util_uint64_scale (self->offset, self->fps_d * GST_SECOND,
|
||||
self->fps_n);
|
||||
gst_util_uint64_scale (offset, self->fps_d * GST_SECOND, self->fps_n);
|
||||
duration = gst_util_uint64_scale_int (GST_SECOND, self->fps_d, self->fps_n);
|
||||
} else {
|
||||
timestamp = 0;
|
||||
timestamp = self->segment.start;
|
||||
duration = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
eos = (self->segment.stop != -1 && timestamp > self->segment.stop) ||
|
||||
(self->fps_n == 0 && self->offset > 0);
|
||||
eos = (self->fps_n == 0 && offset > 0) ||
|
||||
(self->segment.rate >= 0 && self->segment.stop != -1
|
||||
&& timestamp > self->segment.stop) || (self->segment.rate < 0
|
||||
&& offset == 0) || (self->segment.rate < 0
|
||||
&& self->segment.start != -1
|
||||
&& timestamp + duration < self->segment.start);
|
||||
|
||||
if (self->fps_n == 0 && self->offset > 0)
|
||||
if (self->fps_n == 0 && offset > 0)
|
||||
in_seg = FALSE;
|
||||
else
|
||||
in_seg =
|
||||
|
@ -708,32 +732,22 @@ gst_image_freeze_src_loop (GstPad * pad)
|
|||
if (in_seg)
|
||||
gst_segment_set_last_stop (&self->segment, GST_FORMAT_TIME, cstart);
|
||||
|
||||
self->offset++;
|
||||
if (self->segment.rate >= 0)
|
||||
self->offset++;
|
||||
else
|
||||
self->offset--;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Handling buffer with timestamp %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (timestamp));
|
||||
|
||||
if (eos) {
|
||||
if ((self->segment.flags & GST_SEEK_FLAG_SEGMENT)) {
|
||||
GstMessage *m;
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Sending segment done at end of segment");
|
||||
m = gst_message_new_segment_done (GST_OBJECT_CAST (self),
|
||||
GST_FORMAT_TIME, self->segment.stop);
|
||||
gst_element_post_message (GST_ELEMENT_CAST (self), m);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "Sending EOS at end of segment");
|
||||
gst_pad_push_event (self->srcpad, gst_event_new_eos ());
|
||||
}
|
||||
gst_pad_pause_task (self->srcpad);
|
||||
}
|
||||
|
||||
if (in_seg) {
|
||||
GstFlowReturn ret;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (buffer) = cstart;
|
||||
GST_BUFFER_DURATION (buffer) = cstop - cstart;
|
||||
GST_BUFFER_OFFSET (buffer) = offset;
|
||||
GST_BUFFER_OFFSET_END (buffer) = offset + 1;
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (self->srcpad));
|
||||
ret = gst_pad_push (self->srcpad, buffer);
|
||||
GST_DEBUG_OBJECT (pad, "Pushing buffer resulted in %s",
|
||||
|
@ -743,6 +757,25 @@ gst_image_freeze_src_loop (GstPad * pad)
|
|||
} else {
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
if (eos) {
|
||||
if ((self->segment.flags & GST_SEEK_FLAG_SEGMENT)) {
|
||||
GstMessage *m;
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Sending segment done at end of segment");
|
||||
if (self->segment.rate >= 0)
|
||||
m = gst_message_new_segment_done (GST_OBJECT_CAST (self),
|
||||
GST_FORMAT_TIME, self->segment.stop);
|
||||
else
|
||||
m = gst_message_new_segment_done (GST_OBJECT_CAST (self),
|
||||
GST_FORMAT_TIME, self->segment.start);
|
||||
gst_element_post_message (GST_ELEMENT_CAST (self), m);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "Sending EOS at end of segment");
|
||||
gst_pad_push_event (self->srcpad, gst_event_new_eos ());
|
||||
}
|
||||
gst_pad_pause_task (self->srcpad);
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
|
|
Loading…
Reference in a new issue