mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
Rework GstSegment handling
Improve GstSegment, rename some fields. The idea is to have the GstSegment structure represent the timing structure of the buffers as they are generated by the source or demuxer element. gst_segment_set_seek() -> gst_segment_do_seek() Rename the NEWSEGMENT event to SEGMENT. Make parsing of the SEGMENT event into a GstSegment structure. Pass a GstSegment structure when making a new SEGMENT event. This allows us to pass the timing info directly to the next element. No accumulation is needed in the receiving element, all the info is inside the element. Remove gst_segment_set_newsegment(): This function as used to accumulate segments received from upstream, which is now not needed anymore because the segment event contains the complete timing information.
This commit is contained in:
parent
ddf2489be4
commit
bdbc069348
35 changed files with 920 additions and 1404 deletions
|
@ -434,7 +434,7 @@
|
||||||
<RANGE></RANGE>
|
<RANGE></RANGE>
|
||||||
<FLAGS>rw</FLAGS>
|
<FLAGS>rw</FLAGS>
|
||||||
<NICK>Single Segment</NICK>
|
<NICK>Single Segment</NICK>
|
||||||
<BLURB>Timestamp buffers and eat newsegments so as to appear as one segment.</BLURB>
|
<BLURB>Timestamp buffers and eat segments so as to appear as one segment.</BLURB>
|
||||||
<DEFAULT>FALSE</DEFAULT>
|
<DEFAULT>FALSE</DEFAULT>
|
||||||
</ARG>
|
</ARG>
|
||||||
|
|
||||||
|
|
150
gst/gstevent.c
150
gst/gstevent.c
|
@ -123,7 +123,7 @@ static GstEventQuarks event_quarks[] = {
|
||||||
{GST_EVENT_FLUSH_STOP, "flush-stop", 0},
|
{GST_EVENT_FLUSH_STOP, "flush-stop", 0},
|
||||||
{GST_EVENT_EOS, "eos", 0},
|
{GST_EVENT_EOS, "eos", 0},
|
||||||
{GST_EVENT_CAPS, "caps", 0},
|
{GST_EVENT_CAPS, "caps", 0},
|
||||||
{GST_EVENT_NEWSEGMENT, "newsegment", 0},
|
{GST_EVENT_SEGMENT, "segment", 0},
|
||||||
{GST_EVENT_TAG, "tag", 0},
|
{GST_EVENT_TAG, "tag", 0},
|
||||||
{GST_EVENT_BUFFERSIZE, "buffersize", 0},
|
{GST_EVENT_BUFFERSIZE, "buffersize", 0},
|
||||||
{GST_EVENT_SINK_MESSAGE, "sink-message", 0},
|
{GST_EVENT_SINK_MESSAGE, "sink-message", 0},
|
||||||
|
@ -580,7 +580,7 @@ gst_event_new_eos (void)
|
||||||
* @caps: a #GstCaps
|
* @caps: a #GstCaps
|
||||||
*
|
*
|
||||||
* Create a new CAPS event for @caps. The caps event can only travel downstream
|
* Create a new CAPS event for @caps. The caps event can only travel downstream
|
||||||
* synchronized with the buffer flow and contain the format of the buffers
|
* synchronized with the buffer flow and contains the format of the buffers
|
||||||
* that will follow after the event.
|
* that will follow after the event.
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): the new CAPS event.
|
* Returns: (transfer full): the new CAPS event.
|
||||||
|
@ -590,7 +590,8 @@ gst_event_new_caps (GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
|
||||||
g_return_val_if_fail (caps != NULL && gst_caps_is_fixed (caps), NULL);
|
g_return_val_if_fail (caps != NULL, NULL);
|
||||||
|
g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
|
||||||
|
|
||||||
GST_CAT_INFO (GST_CAT_EVENT, "creating caps event %" GST_PTR_FORMAT, caps);
|
GST_CAT_INFO (GST_CAT_EVENT, "creating caps event %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
@ -625,16 +626,12 @@ gst_event_parse_caps (GstEvent * event, GstCaps ** caps)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_event_new_new_segment:
|
* gst_event_new_segment:
|
||||||
* @update: Whether this segment is an update to a previous one
|
* @segment: a #GstSegment
|
||||||
* @rate: A new rate for playback
|
|
||||||
* @applied_rate: The rate factor which has already been applied
|
|
||||||
* @format: The format of the segment values
|
|
||||||
* @start: The start value of the segment
|
|
||||||
* @stop: The stop value of the segment
|
|
||||||
* @time: the time value of the segment
|
|
||||||
*
|
*
|
||||||
* Allocate a new newsegment event with the given format/values triplets.
|
* Create a new SEGMENT event for @segment. The segment event can only travel
|
||||||
|
* downstream synchronized with the buffer flow and contains timing information
|
||||||
|
* and playback properties for the buffers that will follow.
|
||||||
*
|
*
|
||||||
* The newsegment event marks the range of buffers to be processed. All
|
* The newsegment event marks the range of buffers to be processed. All
|
||||||
* data not within the segment range is not to be processed. This can be
|
* data not within the segment range is not to be processed. This can be
|
||||||
|
@ -664,110 +661,69 @@ gst_event_parse_caps (GstEvent * event, GstCaps ** caps)
|
||||||
*
|
*
|
||||||
* time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
|
* time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): a new newsegment event.
|
* Returns: (transfer full): the new SEGMENT event.
|
||||||
*
|
|
||||||
* Since: 0.10.6
|
|
||||||
*/
|
*/
|
||||||
GstEvent *
|
GstEvent *
|
||||||
gst_event_new_new_segment (gboolean update, gdouble rate,
|
gst_event_new_segment (GstSegment * segment)
|
||||||
gdouble applied_rate, GstFormat format, gint64 start, gint64 stop,
|
|
||||||
gint64 time)
|
|
||||||
{
|
{
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
GstStructure *structure;
|
|
||||||
|
|
||||||
g_return_val_if_fail (rate != 0.0, NULL);
|
g_return_val_if_fail (segment != NULL, NULL);
|
||||||
g_return_val_if_fail (applied_rate != 0.0, NULL);
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_TIME) {
|
GST_CAT_INFO (GST_CAT_EVENT, "creating segment event %" GST_PTR_FORMAT,
|
||||||
GST_CAT_INFO (GST_CAT_EVENT,
|
segment);
|
||||||
"creating newsegment update %d, rate %lf, format GST_FORMAT_TIME, "
|
|
||||||
"start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT
|
|
||||||
", time %" GST_TIME_FORMAT,
|
|
||||||
update, rate, GST_TIME_ARGS (start),
|
|
||||||
GST_TIME_ARGS (stop), GST_TIME_ARGS (time));
|
|
||||||
} else {
|
|
||||||
GST_CAT_INFO (GST_CAT_EVENT,
|
|
||||||
"creating newsegment update %d, rate %lf, format %s, "
|
|
||||||
"start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", time %"
|
|
||||||
G_GINT64_FORMAT, update, rate, gst_format_get_name (format), start,
|
|
||||||
stop, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_return_val_if_fail (time != -1, NULL);
|
event = gst_event_new_custom (GST_EVENT_SEGMENT,
|
||||||
g_return_val_if_fail (start != -1, NULL);
|
gst_structure_id_new (GST_QUARK (EVENT_SEGMENT),
|
||||||
if (stop != -1)
|
GST_QUARK (SEGMENT), GST_TYPE_SEGMENT, segment, NULL));
|
||||||
g_return_val_if_fail (start <= stop, NULL);
|
|
||||||
|
|
||||||
structure = gst_structure_id_new (GST_QUARK (EVENT_NEWSEGMENT),
|
|
||||||
GST_QUARK (UPDATE), G_TYPE_BOOLEAN, update,
|
|
||||||
GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
|
|
||||||
GST_QUARK (APPLIED_RATE), G_TYPE_DOUBLE, applied_rate,
|
|
||||||
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
|
||||||
GST_QUARK (START), G_TYPE_INT64, start,
|
|
||||||
GST_QUARK (STOP), G_TYPE_INT64, stop,
|
|
||||||
GST_QUARK (TIME), G_TYPE_INT64, time, NULL);
|
|
||||||
event = gst_event_new_custom (GST_EVENT_NEWSEGMENT, structure);
|
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_event_parse_new_segment:
|
* gst_event_get_segment:
|
||||||
* @event: The event to query
|
* @event: The event
|
||||||
* @update: (out): A pointer to the update flag of the segment
|
|
||||||
* @rate: (out): A pointer to the rate of the segment
|
|
||||||
* @applied_rate: (out): A pointer to the applied_rate of the segment
|
|
||||||
* @format: (out): A pointer to the format of the newsegment values
|
|
||||||
* @start: (out): A pointer to store the start value in
|
|
||||||
* @stop: (out): A pointer to store the stop value in
|
|
||||||
* @time: (out): A pointer to store the time value in
|
|
||||||
*
|
*
|
||||||
* Get the update, rate, applied_rate, format, start, stop and
|
* Get the segment from @event. The segment remains valid as long as @event remains
|
||||||
* time in the newsegment event. See gst_event_new_new_segment()
|
* valid.
|
||||||
* for a full description of the newsegment event.
|
|
||||||
*
|
*
|
||||||
* Since: 0.10.6
|
* Returns: the #GstSegment. The segment stays valid for as long as @event is
|
||||||
|
* valid.
|
||||||
*/
|
*/
|
||||||
void
|
const GstSegment *
|
||||||
gst_event_parse_new_segment (GstEvent * event, gboolean * update,
|
gst_event_get_segment (GstEvent * event)
|
||||||
gdouble * rate, gdouble * applied_rate, GstFormat * format,
|
|
||||||
gint64 * start, gint64 * stop, gint64 * time)
|
|
||||||
{
|
{
|
||||||
const GstStructure *structure;
|
GstStructure *structure;
|
||||||
|
GstSegment *segment;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_EVENT (event));
|
g_return_val_if_fail (GST_IS_EVENT (event), NULL);
|
||||||
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
|
g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT, NULL);
|
||||||
|
|
||||||
structure = GST_EVENT_STRUCTURE (event);
|
structure = GST_EVENT_STRUCTURE (event);
|
||||||
if (G_LIKELY (update))
|
segment = g_value_get_boxed (gst_structure_id_get_value (structure,
|
||||||
*update =
|
GST_QUARK (SEGMENT)));
|
||||||
g_value_get_boolean (gst_structure_id_get_value (structure,
|
|
||||||
GST_QUARK (UPDATE)));
|
return segment;
|
||||||
if (G_LIKELY (rate))
|
}
|
||||||
*rate =
|
|
||||||
g_value_get_double (gst_structure_id_get_value (structure,
|
/**
|
||||||
GST_QUARK (RATE)));
|
* gst_event_parse_segment:
|
||||||
if (G_LIKELY (applied_rate))
|
* @event: The event to parse
|
||||||
*applied_rate =
|
* @segment: a #GstSegment
|
||||||
g_value_get_double (gst_structure_id_get_value (structure,
|
*
|
||||||
GST_QUARK (APPLIED_RATE)));
|
* Copy the segment values from @event into @segment.
|
||||||
if (G_LIKELY (format))
|
*/
|
||||||
*format =
|
void
|
||||||
g_value_get_enum (gst_structure_id_get_value (structure,
|
gst_event_parse_segment (GstEvent * event, GstSegment * segment)
|
||||||
GST_QUARK (FORMAT)));
|
{
|
||||||
if (G_LIKELY (start))
|
const GstSegment *src;
|
||||||
*start =
|
|
||||||
g_value_get_int64 (gst_structure_id_get_value (structure,
|
g_return_if_fail (segment != NULL);
|
||||||
GST_QUARK (START)));
|
|
||||||
if (G_LIKELY (stop))
|
src = gst_event_get_segment (event);
|
||||||
*stop =
|
g_return_if_fail (src != NULL);
|
||||||
g_value_get_int64 (gst_structure_id_get_value (structure,
|
|
||||||
GST_QUARK (STOP)));
|
gst_segment_copy_into (src, segment);
|
||||||
if (G_LIKELY (time))
|
|
||||||
*time =
|
|
||||||
g_value_get_int64 (gst_structure_id_get_value (structure,
|
|
||||||
GST_QUARK (TIME)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <gst/gstclock.h>
|
#include <gst/gstclock.h>
|
||||||
#include <gst/gststructure.h>
|
#include <gst/gststructure.h>
|
||||||
#include <gst/gsttaglist.h>
|
#include <gst/gsttaglist.h>
|
||||||
|
#include <gst/gstsegment.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -107,8 +108,8 @@ typedef enum {
|
||||||
* @GST_EVENT_FLUSH_STOP: Stop a flush operation. This event resets the
|
* @GST_EVENT_FLUSH_STOP: Stop a flush operation. This event resets the
|
||||||
* running-time of the pipeline.
|
* running-time of the pipeline.
|
||||||
* @GST_EVENT_EOS: End-Of-Stream. No more data is to be expected to follow
|
* @GST_EVENT_EOS: End-Of-Stream. No more data is to be expected to follow
|
||||||
* without a NEWSEGMENT event.
|
* without a SEGMENT event.
|
||||||
* @GST_EVENT_NEWSEGMENT: A new media segment follows in the dataflow. The
|
* @GST_EVENT_SEGMENT: A new media segment follows in the dataflow. The
|
||||||
* segment events contains information for clipping buffers and
|
* segment events contains information for clipping buffers and
|
||||||
* converting buffer timestamps to running-time and
|
* converting buffer timestamps to running-time and
|
||||||
* stream-time.
|
* stream-time.
|
||||||
|
@ -157,11 +158,12 @@ typedef enum {
|
||||||
GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
|
GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
|
||||||
/* downstream serialized events */
|
/* downstream serialized events */
|
||||||
GST_EVENT_CAPS = GST_EVENT_MAKE_TYPE (5, 1, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
GST_EVENT_CAPS = GST_EVENT_MAKE_TYPE (5, 1, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
||||||
GST_EVENT_NEWSEGMENT = GST_EVENT_MAKE_TYPE (6, 2, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
GST_EVENT_SEGMENT = GST_EVENT_MAKE_TYPE (6, 2, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
||||||
GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, 3, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, 3, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
||||||
GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, 4, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, 4, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
||||||
GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, 5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, 5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
||||||
GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (10, 6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (10, 6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
|
||||||
|
|
||||||
/* upstream events */
|
/* upstream events */
|
||||||
GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, 0, FLAG(UPSTREAM)),
|
GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, 0, FLAG(UPSTREAM)),
|
||||||
GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, 0, FLAG(UPSTREAM)),
|
GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, 0, FLAG(UPSTREAM)),
|
||||||
|
@ -280,77 +282,6 @@ typedef enum {
|
||||||
#define gst_event_replace(old_event,new_event) \
|
#define gst_event_replace(old_event,new_event) \
|
||||||
gst_mini_object_replace ((GstMiniObject **)(old_event), GST_MINI_OBJECT_CAST (new_event))
|
gst_mini_object_replace ((GstMiniObject **)(old_event), GST_MINI_OBJECT_CAST (new_event))
|
||||||
|
|
||||||
/**
|
|
||||||
* GstSeekType:
|
|
||||||
* @GST_SEEK_TYPE_NONE: no change in position is required
|
|
||||||
* @GST_SEEK_TYPE_CUR: change relative to currently configured segment. This
|
|
||||||
* can't be used to seek relative to the current playback position - do a
|
|
||||||
* position query, calculate the desired position and then do an absolute
|
|
||||||
* position seek instead if that's what you want to do.
|
|
||||||
* @GST_SEEK_TYPE_SET: absolute position is requested
|
|
||||||
* @GST_SEEK_TYPE_END: relative position to duration is requested
|
|
||||||
*
|
|
||||||
* The different types of seek events. When constructing a seek event with
|
|
||||||
* gst_event_new_seek(), a format, a seek method and optional flags are to
|
|
||||||
* be provided. The seek event is then inserted into the graph with
|
|
||||||
* gst_pad_send_event() or gst_element_send_event().
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
/* one of these */
|
|
||||||
GST_SEEK_TYPE_NONE = 0,
|
|
||||||
GST_SEEK_TYPE_CUR = 1,
|
|
||||||
GST_SEEK_TYPE_SET = 2,
|
|
||||||
GST_SEEK_TYPE_END = 3
|
|
||||||
} GstSeekType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstSeekFlags:
|
|
||||||
* @GST_SEEK_FLAG_NONE: no flag
|
|
||||||
* @GST_SEEK_FLAG_FLUSH: flush pipeline
|
|
||||||
* @GST_SEEK_FLAG_ACCURATE: accurate position is requested, this might
|
|
||||||
* be considerably slower for some formats.
|
|
||||||
* @GST_SEEK_FLAG_KEY_UNIT: seek to the nearest keyframe. This might be
|
|
||||||
* faster but less accurate.
|
|
||||||
* @GST_SEEK_FLAG_SEGMENT: perform a segment seek.
|
|
||||||
* @GST_SEEK_FLAG_SKIP: when doing fast foward or fast reverse playback, allow
|
|
||||||
* elements to skip frames instead of generating all
|
|
||||||
* frames. Since 0.10.22.
|
|
||||||
*
|
|
||||||
* Flags to be used with gst_element_seek() or gst_event_new_seek(). All flags
|
|
||||||
* can be used together.
|
|
||||||
*
|
|
||||||
* A non flushing seek might take some time to perform as the currently
|
|
||||||
* playing data in the pipeline will not be cleared.
|
|
||||||
*
|
|
||||||
* An accurate seek might be slower for formats that don't have any indexes
|
|
||||||
* or timestamp markers in the stream. Specifying this flag might require a
|
|
||||||
* complete scan of the file in those cases.
|
|
||||||
*
|
|
||||||
* When performing a segment seek: after the playback of the segment completes,
|
|
||||||
* no EOS will be emmited by the element that performed the seek, but a
|
|
||||||
* #GST_MESSAGE_SEGMENT_DONE message will be posted on the bus by the element.
|
|
||||||
* When this message is posted, it is possible to send a new seek event to
|
|
||||||
* continue playback. With this seek method it is possible to perform seemless
|
|
||||||
* looping or simple linear editing.
|
|
||||||
*
|
|
||||||
* When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode
|
|
||||||
* playback, the @GST_SEEK_FLAG_SKIP flag can be used to instruct decoders
|
|
||||||
* and demuxers to adjust the playback rate by skipping frames. This can improve
|
|
||||||
* performance and decrease CPU usage because not all frames need to be decoded.
|
|
||||||
*
|
|
||||||
* Also see part-seeking.txt in the GStreamer design documentation for more
|
|
||||||
* details on the meaning of these flags and the behaviour expected of
|
|
||||||
* elements that handle them.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
GST_SEEK_FLAG_NONE = 0,
|
|
||||||
GST_SEEK_FLAG_FLUSH = (1 << 0),
|
|
||||||
GST_SEEK_FLAG_ACCURATE = (1 << 1),
|
|
||||||
GST_SEEK_FLAG_KEY_UNIT = (1 << 2),
|
|
||||||
GST_SEEK_FLAG_SEGMENT = (1 << 3),
|
|
||||||
GST_SEEK_FLAG_SKIP = (1 << 4)
|
|
||||||
} GstSeekFlags;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstQOSType:
|
* GstQOSType:
|
||||||
* @GST_QOS_TYPE_OVERFLOW: The QoS event type that is produced when downstream
|
* @GST_QOS_TYPE_OVERFLOW: The QoS event type that is produced when downstream
|
||||||
|
@ -477,19 +408,11 @@ GstEvent * gst_event_new_eos (void);
|
||||||
GstEvent * gst_event_new_caps (GstCaps *caps);
|
GstEvent * gst_event_new_caps (GstCaps *caps);
|
||||||
void gst_event_parse_caps (GstEvent *event, GstCaps **caps);
|
void gst_event_parse_caps (GstEvent *event, GstCaps **caps);
|
||||||
|
|
||||||
/* newsegment events */
|
/* segment event */
|
||||||
GstEvent* gst_event_new_new_segment (gboolean update, gdouble rate,
|
GstEvent* gst_event_new_segment (GstSegment *segment);
|
||||||
gdouble applied_rate,
|
const GstSegment *
|
||||||
GstFormat format,
|
gst_event_get_segment (GstEvent *event);
|
||||||
gint64 start, gint64 stop,
|
void gst_event_parse_segment (GstEvent *event, GstSegment *segment);
|
||||||
gint64 time);
|
|
||||||
void gst_event_parse_new_segment (GstEvent *event,
|
|
||||||
gboolean *update,
|
|
||||||
gdouble *rate,
|
|
||||||
gdouble *applied_rate,
|
|
||||||
GstFormat *format,
|
|
||||||
gint64 *start, gint64 *stop,
|
|
||||||
gint64 *time);
|
|
||||||
|
|
||||||
/* tag event */
|
/* tag event */
|
||||||
GstEvent* gst_event_new_tag (GstTagList *taglist);
|
GstEvent* gst_event_new_tag (GstTagList *taglist);
|
||||||
|
@ -515,6 +438,7 @@ void gst_event_parse_seek (GstEvent *event, gdouble *rate,
|
||||||
GstSeekFlags *flags,
|
GstSeekFlags *flags,
|
||||||
GstSeekType *start_type, gint64 *start,
|
GstSeekType *start_type, gint64 *start,
|
||||||
GstSeekType *stop_type, gint64 *stop);
|
GstSeekType *stop_type, gint64 *stop);
|
||||||
|
|
||||||
/* navigation event */
|
/* navigation event */
|
||||||
GstEvent* gst_event_new_navigation (GstStructure *structure);
|
GstEvent* gst_event_new_navigation (GstStructure *structure);
|
||||||
|
|
||||||
|
|
|
@ -724,13 +724,11 @@ gst_debug_print_segment (gpointer ptr)
|
||||||
}
|
}
|
||||||
case GST_FORMAT_TIME:{
|
case GST_FORMAT_TIME:{
|
||||||
return g_strdup_printf ("time segment start=%" GST_TIME_FORMAT
|
return g_strdup_printf ("time segment start=%" GST_TIME_FORMAT
|
||||||
", stop=%" GST_TIME_FORMAT ", last_stop=%" GST_TIME_FORMAT
|
", stop=%" GST_TIME_FORMAT ", rate=%f, applied_rate=%f"
|
||||||
", duration=%" GST_TIME_FORMAT ", rate=%f, applied_rate=%f"
|
", flags=0x%02x, time=%" GST_TIME_FORMAT ", base=%" GST_TIME_FORMAT,
|
||||||
", flags=0x%02x, time=%" GST_TIME_FORMAT ", accum=%" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop),
|
GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop),
|
||||||
GST_TIME_ARGS (segment->last_stop), GST_TIME_ARGS (segment->duration),
|
|
||||||
segment->rate, segment->applied_rate, (guint) segment->flags,
|
segment->rate, segment->applied_rate, (guint) segment->flags,
|
||||||
GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->accum));
|
GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->base));
|
||||||
}
|
}
|
||||||
default:{
|
default:{
|
||||||
const gchar *format_name;
|
const gchar *format_name;
|
||||||
|
@ -739,13 +737,11 @@ gst_debug_print_segment (gpointer ptr)
|
||||||
if (G_UNLIKELY (format_name == NULL))
|
if (G_UNLIKELY (format_name == NULL))
|
||||||
format_name = "(UNKNOWN FORMAT)";
|
format_name = "(UNKNOWN FORMAT)";
|
||||||
return g_strdup_printf ("%s segment start=%" G_GINT64_FORMAT
|
return g_strdup_printf ("%s segment start=%" G_GINT64_FORMAT
|
||||||
", stop=%" G_GINT64_FORMAT ", last_stop=%" G_GINT64_FORMAT
|
", stop=%" G_GINT64_FORMAT ", rate=%f, applied_rate=%f"
|
||||||
", duration=%" G_GINT64_FORMAT ", rate=%f, applied_rate=%f"
|
", flags=0x%02x, time=%" GST_TIME_FORMAT ", base=%" GST_TIME_FORMAT,
|
||||||
", flags=0x%02x, time=%" GST_TIME_FORMAT ", accum=%" GST_TIME_FORMAT,
|
format_name, segment->start, segment->stop, segment->rate,
|
||||||
format_name, segment->start, segment->stop, segment->last_stop,
|
segment->applied_rate, (guint) segment->flags,
|
||||||
segment->duration, segment->rate, segment->applied_rate,
|
GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->base));
|
||||||
(guint) segment->flags, GST_TIME_ARGS (segment->time),
|
|
||||||
GST_TIME_ARGS (segment->accum));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ static const gchar *_quark_strings[] = {
|
||||||
"max-latency", "busy", "type", "owner", "update", "applied-rate",
|
"max-latency", "busy", "type", "owner", "update", "applied-rate",
|
||||||
"start", "stop", "minsize", "maxsize", "async", "proportion",
|
"start", "stop", "minsize", "maxsize", "async", "proportion",
|
||||||
"diff", "timestamp", "flags", "cur-type", "cur", "stop-type",
|
"diff", "timestamp", "flags", "cur-type", "cur", "stop-type",
|
||||||
"latency", "uri", "object", "taglist", "GstEventNewsegment",
|
"latency", "uri", "object", "taglist", "GstEventSegment",
|
||||||
"GstEventBufferSize", "GstEventQOS", "GstEventSeek", "GstEventLatency",
|
"GstEventBufferSize", "GstEventQOS", "GstEventSeek", "GstEventLatency",
|
||||||
"GstMessageError", "GstMessageWarning", "GstMessageInfo",
|
"GstMessageError", "GstMessageWarning", "GstMessageInfo",
|
||||||
"GstMessageBuffering", "GstMessageState", "GstMessageClockProvide",
|
"GstMessageBuffering", "GstMessageState", "GstMessageClockProvide",
|
||||||
|
@ -52,7 +52,9 @@ static const gchar *_quark_strings[] = {
|
||||||
"quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress",
|
"quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress",
|
||||||
"code", "text", "percent", "timeout", "GstBufferPoolConfig", "caps", "size",
|
"code", "text", "percent", "timeout", "GstBufferPoolConfig", "caps", "size",
|
||||||
"min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
|
"min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
|
||||||
"GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps", "GstEventReconfigure"
|
"GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps",
|
||||||
|
"GstEventReconfigure",
|
||||||
|
"segment"
|
||||||
};
|
};
|
||||||
|
|
||||||
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||||
|
|
|
@ -80,7 +80,7 @@ typedef enum _GstQuarkId
|
||||||
GST_QUARK_URI = 51,
|
GST_QUARK_URI = 51,
|
||||||
GST_QUARK_OBJECT = 52,
|
GST_QUARK_OBJECT = 52,
|
||||||
GST_QUARK_TAGLIST = 53,
|
GST_QUARK_TAGLIST = 53,
|
||||||
GST_QUARK_EVENT_NEWSEGMENT = 54,
|
GST_QUARK_EVENT_SEGMENT = 54,
|
||||||
GST_QUARK_EVENT_BUFFER_SIZE = 55,
|
GST_QUARK_EVENT_BUFFER_SIZE = 55,
|
||||||
GST_QUARK_EVENT_QOS = 56,
|
GST_QUARK_EVENT_QOS = 56,
|
||||||
GST_QUARK_EVENT_SEEK = 57,
|
GST_QUARK_EVENT_SEEK = 57,
|
||||||
|
@ -147,8 +147,9 @@ typedef enum _GstQuarkId
|
||||||
GST_QUARK_POOL = 118,
|
GST_QUARK_POOL = 118,
|
||||||
GST_QUARK_EVENT_CAPS = 119,
|
GST_QUARK_EVENT_CAPS = 119,
|
||||||
GST_QUARK_EVENT_RECONFIGURE = 120,
|
GST_QUARK_EVENT_RECONFIGURE = 120,
|
||||||
|
GST_QUARK_SEGMENT = 121,
|
||||||
|
|
||||||
GST_QUARK_MAX = 121
|
GST_QUARK_MAX = 122
|
||||||
} GstQuarkId;
|
} GstQuarkId;
|
||||||
|
|
||||||
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||||
|
|
344
gst/gstsegment.c
344
gst/gstsegment.c
|
@ -97,7 +97,7 @@
|
||||||
* Since: 0.10.20
|
* Since: 0.10.20
|
||||||
*/
|
*/
|
||||||
GstSegment *
|
GstSegment *
|
||||||
gst_segment_copy (GstSegment * segment)
|
gst_segment_copy (const GstSegment * segment)
|
||||||
{
|
{
|
||||||
GstSegment *result = NULL;
|
GstSegment *result = NULL;
|
||||||
|
|
||||||
|
@ -107,6 +107,12 @@ gst_segment_copy (GstSegment * segment)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_segment_copy_into (const GstSegment * src, GstSegment * dest)
|
||||||
|
{
|
||||||
|
memcpy (dest, src, sizeof (GstSegment));
|
||||||
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gst_segment_get_type (void)
|
gst_segment_get_type (void)
|
||||||
{
|
{
|
||||||
|
@ -169,93 +175,41 @@ gst_segment_init (GstSegment * segment, GstFormat format)
|
||||||
{
|
{
|
||||||
g_return_if_fail (segment != NULL);
|
g_return_if_fail (segment != NULL);
|
||||||
|
|
||||||
|
segment->flags = 0;
|
||||||
segment->rate = 1.0;
|
segment->rate = 1.0;
|
||||||
segment->applied_rate = 1.0;
|
segment->applied_rate = 1.0;
|
||||||
segment->format = format;
|
segment->format = format;
|
||||||
segment->flags = 0;
|
segment->base = 0;
|
||||||
segment->start = 0;
|
segment->start = 0;
|
||||||
segment->stop = -1;
|
segment->stop = -1;
|
||||||
segment->time = 0;
|
segment->time = 0;
|
||||||
segment->accum = 0;
|
segment->position = 0;
|
||||||
segment->last_stop = 0;
|
|
||||||
segment->duration = -1;
|
segment->duration = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_segment_set_duration:
|
* gst_segment_do_seek:
|
||||||
* @segment: a #GstSegment structure.
|
|
||||||
* @format: the format of the segment.
|
|
||||||
* @duration: the duration of the segment info or -1 if unknown.
|
|
||||||
*
|
|
||||||
* Set the duration of the segment to @duration. This function is mainly
|
|
||||||
* used by elements that perform seeking and know the total duration of the
|
|
||||||
* segment.
|
|
||||||
*
|
|
||||||
* This field should be set to allow seeking requests relative to the
|
|
||||||
* duration.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_segment_set_duration (GstSegment * segment, GstFormat format,
|
|
||||||
gint64 duration)
|
|
||||||
{
|
|
||||||
g_return_if_fail (segment != NULL);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
else
|
|
||||||
g_return_if_fail (segment->format == format);
|
|
||||||
|
|
||||||
segment->duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_segment_set_last_stop:
|
|
||||||
* @segment: a #GstSegment structure.
|
|
||||||
* @format: the format of the segment.
|
|
||||||
* @position: the position
|
|
||||||
*
|
|
||||||
* Set the last observed stop position in the segment to @position.
|
|
||||||
*
|
|
||||||
* This field should be set to allow seeking requests relative to the
|
|
||||||
* current playing position.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_segment_set_last_stop (GstSegment * segment, GstFormat format,
|
|
||||||
gint64 position)
|
|
||||||
{
|
|
||||||
g_return_if_fail (segment != NULL);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
else
|
|
||||||
g_return_if_fail (segment->format == format);
|
|
||||||
|
|
||||||
segment->last_stop = MAX (segment->start, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_segment_set_seek:
|
|
||||||
* @segment: a #GstSegment structure.
|
* @segment: a #GstSegment structure.
|
||||||
* @rate: the rate of the segment.
|
* @rate: the rate of the segment.
|
||||||
* @format: the format of the segment.
|
* @format: the format of the segment.
|
||||||
* @flags: the seek flags for the segment
|
* @flags: the segment flags for the segment
|
||||||
* @start_type: the seek method
|
* @start_type: the seek method
|
||||||
* @start: the seek start value
|
* @start: the seek start value
|
||||||
* @stop_type: the seek method
|
* @stop_type: the seek method
|
||||||
* @stop: the seek stop value
|
* @stop: the seek stop value
|
||||||
* @update: boolean holding whether last_stop was updated.
|
* @update: boolean holding whether position was updated.
|
||||||
*
|
*
|
||||||
* Update the segment structure with the field values of a seek event (see
|
* Update the segment structure with the field values of a seek event (see
|
||||||
* gst_event_new_seek()).
|
* gst_event_new_seek()).
|
||||||
*
|
*
|
||||||
* After calling this method, the segment field last_stop and time will
|
* After calling this method, the segment field position and time will
|
||||||
* contain the requested new position in the segment. The new requested
|
* contain the requested new position in the segment. The new requested
|
||||||
* position in the segment depends on @rate and @start_type and @stop_type.
|
* position in the segment depends on @rate and @start_type and @stop_type.
|
||||||
*
|
*
|
||||||
* For positive @rate, the new position in the segment is the new @segment
|
* For positive @rate, the new position in the segment is the new @segment
|
||||||
* start field when it was updated with a @start_type different from
|
* start field when it was updated with a @start_type different from
|
||||||
* #GST_SEEK_TYPE_NONE. If no update was performed on @segment start position
|
* #GST_SEEK_TYPE_NONE. If no update was performed on @segment start position
|
||||||
* (#GST_SEEK_TYPE_NONE), @start is ignored and @segment last_stop is
|
* (#GST_SEEK_TYPE_NONE), @start is ignored and @segment position is
|
||||||
* unmodified.
|
* unmodified.
|
||||||
*
|
*
|
||||||
* For negative @rate, the new position in the segment is the new @segment
|
* For negative @rate, the new position in the segment is the new @segment
|
||||||
|
@ -263,33 +217,43 @@ gst_segment_set_last_stop (GstSegment * segment, GstFormat format,
|
||||||
* #GST_SEEK_TYPE_NONE. If no stop was previously configured in the segment, the
|
* #GST_SEEK_TYPE_NONE. If no stop was previously configured in the segment, the
|
||||||
* duration of the segment will be used to update the stop position.
|
* duration of the segment will be used to update the stop position.
|
||||||
* If no update was performed on @segment stop position (#GST_SEEK_TYPE_NONE),
|
* If no update was performed on @segment stop position (#GST_SEEK_TYPE_NONE),
|
||||||
* @stop is ignored and @segment last_stop is unmodified.
|
* @stop is ignored and @segment position is unmodified.
|
||||||
*
|
*
|
||||||
* The applied rate of the segment will be set to 1.0 by default.
|
* The applied rate of the segment will be set to 1.0 by default.
|
||||||
* If the caller can apply a rate change, it should update @segment
|
* If the caller can apply a rate change, it should update @segment
|
||||||
* rate and applied_rate after calling this function.
|
* rate and applied_rate after calling this function.
|
||||||
*
|
*
|
||||||
* @update will be set to TRUE if a seek should be performed to the segment
|
* @update will be set to TRUE if a seek should be performed to the segment
|
||||||
* last_stop field. This field can be FALSE if, for example, only the @rate
|
* position field. This field can be FALSE if, for example, only the @rate
|
||||||
* has been changed but not the playback position.
|
* has been changed but not the playback position.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the seek could be performed.
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_segment_set_seek (GstSegment * segment, gdouble rate,
|
gst_segment_do_seek (GstSegment * segment, gdouble rate,
|
||||||
GstFormat format, GstSeekFlags flags,
|
GstFormat format, GstSeekFlags flags,
|
||||||
GstSeekType start_type, gint64 start,
|
GstSeekType start_type, guint64 start,
|
||||||
GstSeekType stop_type, gint64 stop, gboolean * update)
|
GstSeekType stop_type, guint64 stop, gboolean * update)
|
||||||
{
|
{
|
||||||
gboolean update_stop, update_start;
|
gboolean update_stop, update_start;
|
||||||
gint64 last_stop;
|
guint64 position, base;
|
||||||
|
|
||||||
g_return_if_fail (rate != 0.0);
|
g_return_val_if_fail (rate != 0.0, FALSE);
|
||||||
g_return_if_fail (segment != NULL);
|
g_return_val_if_fail (segment != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (segment->format == format, FALSE);
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
|
|
||||||
update_start = update_stop = TRUE;
|
update_start = update_stop = TRUE;
|
||||||
|
|
||||||
|
base = segment->base;
|
||||||
|
position = segment->position;
|
||||||
|
|
||||||
|
if (flags & GST_SEEK_FLAG_FLUSH) {
|
||||||
|
/* flush resets the running_time */
|
||||||
|
base = 0;
|
||||||
|
} else {
|
||||||
|
base = gst_segment_to_running_time (segment, format, position);
|
||||||
|
}
|
||||||
|
|
||||||
/* segment->start is never invalid */
|
/* segment->start is never invalid */
|
||||||
switch (start_type) {
|
switch (start_type) {
|
||||||
case GST_SEEK_TYPE_NONE:
|
case GST_SEEK_TYPE_NONE:
|
||||||
|
@ -302,16 +266,13 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
|
||||||
if (start == -1)
|
if (start == -1)
|
||||||
start = 0;
|
start = 0;
|
||||||
/* start must be 0 or the formats must match */
|
/* start must be 0 or the formats must match */
|
||||||
g_return_if_fail (start == 0 || segment->format == format);
|
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
g_return_if_fail (start == 0 || segment->format == format);
|
|
||||||
/* add start to currently configured segment */
|
/* add start to currently configured segment */
|
||||||
start = segment->start + start;
|
start = segment->start + start;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_END:
|
case GST_SEEK_TYPE_END:
|
||||||
if (segment->duration != -1) {
|
if (segment->duration != -1) {
|
||||||
g_return_if_fail (start == 0 || segment->format == format);
|
|
||||||
/* add start to total length */
|
/* add start to total length */
|
||||||
start = segment->duration + start;
|
start = segment->duration + start;
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,12 +297,10 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
|
||||||
case GST_SEEK_TYPE_SET:
|
case GST_SEEK_TYPE_SET:
|
||||||
/* stop holds required value, if it's not -1, it must be of the same
|
/* stop holds required value, if it's not -1, it must be of the same
|
||||||
* format as the segment. */
|
* format as the segment. */
|
||||||
g_return_if_fail (stop == -1 || segment->format == format);
|
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
if (segment->stop != -1) {
|
if (segment->stop != -1) {
|
||||||
/* only add compatible formats or 0 */
|
/* only add compatible formats or 0 */
|
||||||
g_return_if_fail (stop == 0 || segment->format == format);
|
|
||||||
stop = segment->stop + stop;
|
stop = segment->stop + stop;
|
||||||
} else
|
} else
|
||||||
stop = -1;
|
stop = -1;
|
||||||
|
@ -349,7 +308,6 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
|
||||||
case GST_SEEK_TYPE_END:
|
case GST_SEEK_TYPE_END:
|
||||||
if (segment->duration != -1) {
|
if (segment->duration != -1) {
|
||||||
/* only add compatible formats or 0 */
|
/* only add compatible formats or 0 */
|
||||||
g_return_if_fail (stop == 0 || segment->format == format);
|
|
||||||
stop = segment->duration + stop;
|
stop = segment->duration + stop;
|
||||||
} else {
|
} else {
|
||||||
stop = segment->stop;
|
stop = segment->stop;
|
||||||
|
@ -367,145 +325,42 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we can't have stop before start */
|
/* we can't have stop before start */
|
||||||
if (stop != -1)
|
if (stop != -1) {
|
||||||
g_return_if_fail (start <= stop);
|
if (start > stop) {
|
||||||
|
g_return_val_if_fail (start <= stop, FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
segment->rate = rate;
|
segment->rate = rate;
|
||||||
segment->applied_rate = 1.0;
|
segment->applied_rate = 1.0;
|
||||||
|
segment->base = base;
|
||||||
segment->flags = flags;
|
segment->flags = flags;
|
||||||
segment->start = start;
|
segment->start = start;
|
||||||
segment->stop = stop;
|
segment->stop = stop;
|
||||||
segment->time = start;
|
segment->time = start;
|
||||||
|
|
||||||
last_stop = segment->last_stop;
|
|
||||||
if (update_start && rate > 0.0) {
|
if (update_start && rate > 0.0) {
|
||||||
last_stop = start;
|
position = start;
|
||||||
}
|
}
|
||||||
if (update_stop && rate < 0.0) {
|
if (update_stop && rate < 0.0) {
|
||||||
if (stop != -1)
|
if (stop != -1)
|
||||||
last_stop = stop;
|
position = stop;
|
||||||
else {
|
else {
|
||||||
if (segment->duration != -1)
|
if (segment->duration != -1)
|
||||||
last_stop = segment->duration;
|
position = segment->duration;
|
||||||
else
|
else
|
||||||
last_stop = 0;
|
position = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* set update arg to reflect update of last_stop */
|
/* set update arg to reflect update of position */
|
||||||
if (update)
|
if (update)
|
||||||
*update = last_stop != segment->last_stop;
|
*update = position != segment->position;
|
||||||
|
|
||||||
/* update new position */
|
/* update new position */
|
||||||
segment->last_stop = last_stop;
|
segment->position = position;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return TRUE;
|
||||||
* gst_segment_set_newsegment:
|
|
||||||
* @segment: a #GstSegment structure.
|
|
||||||
* @update: flag indicating a new segment is started or updated
|
|
||||||
* @rate: the rate of the segment.
|
|
||||||
* @applied_rate: the applied rate of the segment.
|
|
||||||
* @format: the format of the segment.
|
|
||||||
* @start: the new start value
|
|
||||||
* @stop: the new stop value
|
|
||||||
* @time: the new stream time
|
|
||||||
*
|
|
||||||
* Update the segment structure with the field values of a new segment event.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_segment_set_newsegment (GstSegment * segment, gboolean update,
|
|
||||||
gdouble rate, gdouble applied_rate, GstFormat format, gint64 start,
|
|
||||||
gint64 stop, gint64 time)
|
|
||||||
{
|
|
||||||
gint64 duration, last_stop;
|
|
||||||
gdouble abs_rate;
|
|
||||||
|
|
||||||
g_return_if_fail (rate != 0.0);
|
|
||||||
g_return_if_fail (applied_rate != 0.0);
|
|
||||||
g_return_if_fail (segment != NULL);
|
|
||||||
|
|
||||||
GST_DEBUG ("configuring segment update %d, rate %lf, format %s, "
|
|
||||||
"start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", position %"
|
|
||||||
G_GINT64_FORMAT, update, rate, gst_format_get_name (format), start,
|
|
||||||
stop, time);
|
|
||||||
GST_DEBUG ("old segment was: %" GST_SEGMENT_FORMAT, segment);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
|
|
||||||
/* any other format with 0 also gives time 0, the other values are
|
|
||||||
* invalid in the format though. */
|
|
||||||
if (format != segment->format && start == 0) {
|
|
||||||
format = segment->format;
|
|
||||||
if (stop != 0)
|
|
||||||
stop = -1;
|
|
||||||
if (time != 0)
|
|
||||||
time = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_return_if_fail (segment->format == format);
|
|
||||||
|
|
||||||
if (update) {
|
|
||||||
if (G_LIKELY (segment->rate > 0.0)) {
|
|
||||||
/* an update to the current segment is done, elapsed time is
|
|
||||||
* difference between the old start and new start. */
|
|
||||||
if (start > segment->start)
|
|
||||||
duration = start - segment->start;
|
|
||||||
else
|
|
||||||
duration = 0;
|
|
||||||
} else {
|
|
||||||
/* for negative rates, the elapsed duration is the diff between the stop
|
|
||||||
* positions */
|
|
||||||
if (stop != -1 && stop < segment->stop)
|
|
||||||
duration = segment->stop - stop;
|
|
||||||
else
|
|
||||||
duration = 0;
|
|
||||||
}
|
|
||||||
/* update last_stop to be a valid value in the updated segment */
|
|
||||||
if (start > segment->last_stop)
|
|
||||||
last_stop = start;
|
|
||||||
else if (stop != -1 && stop < segment->last_stop)
|
|
||||||
last_stop = stop;
|
|
||||||
else
|
|
||||||
last_stop = segment->last_stop;
|
|
||||||
} else {
|
|
||||||
/* the new segment has to be aligned with the old segment.
|
|
||||||
* We first update the accumulated time of the previous
|
|
||||||
* segment. the accumulated time is used when syncing to the
|
|
||||||
* clock. */
|
|
||||||
if (segment->stop != -1) {
|
|
||||||
duration = segment->stop - segment->start;
|
|
||||||
} else if (segment->last_stop != -1) {
|
|
||||||
/* else use last seen timestamp as segment stop */
|
|
||||||
duration = segment->last_stop - segment->start;
|
|
||||||
} else {
|
|
||||||
/* else we don't know and throw a warning.. really, this should
|
|
||||||
* be fixed in the element. */
|
|
||||||
g_warning ("closing segment of unknown duration, assuming duration of 0");
|
|
||||||
duration = 0;
|
|
||||||
}
|
|
||||||
/* position the last_stop to the next expected position in the new segment,
|
|
||||||
* which is the start or the stop of the segment */
|
|
||||||
if (rate > 0.0)
|
|
||||||
last_stop = start;
|
|
||||||
else
|
|
||||||
last_stop = stop;
|
|
||||||
}
|
|
||||||
/* use previous rate to calculate duration */
|
|
||||||
abs_rate = ABS (segment->rate);
|
|
||||||
if (G_LIKELY (abs_rate != 1.0))
|
|
||||||
duration /= abs_rate;
|
|
||||||
|
|
||||||
/* accumulate duration */
|
|
||||||
segment->accum += duration;
|
|
||||||
|
|
||||||
/* then update the current segment */
|
|
||||||
segment->rate = rate;
|
|
||||||
segment->applied_rate = applied_rate;
|
|
||||||
segment->start = start;
|
|
||||||
segment->last_stop = last_stop;
|
|
||||||
segment->stop = stop;
|
|
||||||
segment->time = time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -528,11 +383,11 @@ gst_segment_set_newsegment (GstSegment * segment, gboolean update,
|
||||||
* Returns: the position in stream_time or -1 when an invalid position
|
* Returns: the position in stream_time or -1 when an invalid position
|
||||||
* was given.
|
* was given.
|
||||||
*/
|
*/
|
||||||
gint64
|
guint64
|
||||||
gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
|
gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
|
||||||
gint64 position)
|
guint64 position)
|
||||||
{
|
{
|
||||||
gint64 result, start, stop, time;
|
guint64 result, start, stop, time;
|
||||||
gdouble abs_applied_rate;
|
gdouble abs_applied_rate;
|
||||||
|
|
||||||
/* format does not matter for -1 */
|
/* format does not matter for -1 */
|
||||||
|
@ -540,9 +395,7 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
g_return_val_if_fail (segment != NULL, -1);
|
g_return_val_if_fail (segment != NULL, -1);
|
||||||
|
g_return_val_if_fail (segment->format == format, -1);
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
|
|
||||||
/* if we have the position for the same format as the segment, we can compare
|
/* if we have the position for the same format as the segment, we can compare
|
||||||
* the start and stop values, otherwise we assume 0 and -1 */
|
* the start and stop values, otherwise we assume 0 and -1 */
|
||||||
|
@ -614,32 +467,30 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
|
||||||
* Returns: the position as the total running time or -1 when an invalid position
|
* Returns: the position as the total running time or -1 when an invalid position
|
||||||
* was given.
|
* was given.
|
||||||
*/
|
*/
|
||||||
gint64
|
guint64
|
||||||
gst_segment_to_running_time (GstSegment * segment, GstFormat format,
|
gst_segment_to_running_time (const GstSegment * segment, GstFormat format,
|
||||||
gint64 position)
|
guint64 position)
|
||||||
{
|
{
|
||||||
gint64 result;
|
guint64 result;
|
||||||
gint64 start, stop, accum;
|
guint64 start, stop, base;
|
||||||
gdouble abs_rate;
|
gdouble abs_rate;
|
||||||
|
|
||||||
if (G_UNLIKELY (position == -1))
|
if (G_UNLIKELY (position == -1))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
g_return_val_if_fail (segment != NULL, -1);
|
g_return_val_if_fail (segment != NULL, -1);
|
||||||
|
g_return_val_if_fail (segment->format == format, -1);
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
|
|
||||||
/* if we have the position for the same format as the segment, we can compare
|
/* if we have the position for the same format as the segment, we can compare
|
||||||
* the start and stop values, otherwise we assume 0 and -1 */
|
* the start and stop values, otherwise we assume 0 and -1 */
|
||||||
if (G_LIKELY (segment->format == format)) {
|
if (G_LIKELY (segment->format == format)) {
|
||||||
start = segment->start;
|
start = segment->start;
|
||||||
stop = segment->stop;
|
stop = segment->stop;
|
||||||
accum = segment->accum;
|
base = segment->base;
|
||||||
} else {
|
} else {
|
||||||
start = 0;
|
start = 0;
|
||||||
stop = -1;
|
stop = -1;
|
||||||
accum = 0;
|
base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* before the segment boundary */
|
/* before the segment boundary */
|
||||||
|
@ -669,8 +520,8 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
|
||||||
if (G_UNLIKELY (abs_rate != 1.0))
|
if (G_UNLIKELY (abs_rate != 1.0))
|
||||||
result /= abs_rate;
|
result /= abs_rate;
|
||||||
|
|
||||||
/* correct for accumulated segments */
|
/* correct for base of the segment */
|
||||||
result += accum;
|
result += base;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -703,15 +554,11 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
|
||||||
* of the segment.
|
* of the segment.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
|
gst_segment_clip (const GstSegment * segment, GstFormat format, guint64 start,
|
||||||
gint64 stop, gint64 * clip_start, gint64 * clip_stop)
|
guint64 stop, guint64 * clip_start, guint64 * clip_stop)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (segment != NULL, FALSE);
|
g_return_val_if_fail (segment != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (segment->format == format, FALSE);
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
|
||||||
segment->format = format;
|
|
||||||
else
|
|
||||||
g_return_val_if_fail (segment->format == format, FALSE);
|
|
||||||
|
|
||||||
/* if we have a stop position and a valid start and start is bigger,
|
/* if we have a stop position and a valid start and start is bigger,
|
||||||
* we're outside of the segment */
|
* we're outside of the segment */
|
||||||
|
@ -737,11 +584,11 @@ gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
|
||||||
if (stop == -1)
|
if (stop == -1)
|
||||||
*clip_stop = segment->stop;
|
*clip_stop = segment->stop;
|
||||||
else if (segment->stop == -1)
|
else if (segment->stop == -1)
|
||||||
*clip_stop = MAX (-1, stop);
|
*clip_stop = stop;
|
||||||
else
|
else
|
||||||
*clip_stop = MIN (stop, segment->stop);
|
*clip_stop = MIN (stop, segment->stop);
|
||||||
|
|
||||||
if (segment->duration != -1)
|
if (segment->duration != -1 && *clip_stop != -1)
|
||||||
*clip_stop = MIN (*clip_stop, segment->duration);
|
*clip_stop = MIN (*clip_stop, segment->duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,40 +609,38 @@ gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
|
||||||
*
|
*
|
||||||
* Since: 0.10.24
|
* Since: 0.10.24
|
||||||
*/
|
*/
|
||||||
gint64
|
guint64
|
||||||
gst_segment_to_position (GstSegment * segment, GstFormat format,
|
gst_segment_to_position (const GstSegment * segment, GstFormat format,
|
||||||
gint64 running_time)
|
guint64 running_time)
|
||||||
{
|
{
|
||||||
gint64 result;
|
guint64 result;
|
||||||
gint64 start, stop, accum;
|
guint64 start, stop, base;
|
||||||
gdouble abs_rate;
|
gdouble abs_rate;
|
||||||
|
|
||||||
g_return_val_if_fail (segment != NULL, -1);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (running_time == -1))
|
if (G_UNLIKELY (running_time == -1))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
g_return_val_if_fail (segment != NULL, -1);
|
||||||
segment->format = format;
|
g_return_val_if_fail (segment->format == format, FALSE);
|
||||||
|
|
||||||
/* if we have the position for the same format as the segment, we can compare
|
/* if we have the position for the same format as the segment, we can compare
|
||||||
* the start and stop values, otherwise we assume 0 and -1 */
|
* the start and stop values, otherwise we assume 0 and -1 */
|
||||||
if (G_LIKELY (segment->format == format)) {
|
if (G_LIKELY (segment->format == format)) {
|
||||||
start = segment->start;
|
start = segment->start;
|
||||||
stop = segment->stop;
|
stop = segment->stop;
|
||||||
accum = segment->accum;
|
base = segment->base;
|
||||||
} else {
|
} else {
|
||||||
start = 0;
|
start = 0;
|
||||||
stop = -1;
|
stop = -1;
|
||||||
accum = 0;
|
base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this running_time was for a previous segment */
|
/* this running_time was for a previous segment */
|
||||||
if (running_time < accum)
|
if (running_time < base)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* start by subtracting the accumulated time */
|
/* start by subtracting the base time */
|
||||||
result = running_time - accum;
|
result = running_time - base;
|
||||||
|
|
||||||
/* move into the segment at the right rate */
|
/* move into the segment at the right rate */
|
||||||
abs_rate = ABS (segment->rate);
|
abs_rate = ABS (segment->rate);
|
||||||
|
@ -828,7 +673,7 @@ gst_segment_to_position (GstSegment * segment, GstFormat format,
|
||||||
* @format: the format of the segment.
|
* @format: the format of the segment.
|
||||||
* @running_time: the running_time in the segment
|
* @running_time: the running_time in the segment
|
||||||
*
|
*
|
||||||
* Adjust the start/stop and accum values of @segment such that the next valid
|
* Adjust the start/stop and base values of @segment such that the next valid
|
||||||
* buffer will be one with @running_time.
|
* buffer will be one with @running_time.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the segment could be updated successfully. If %FALSE is
|
* Returns: %TRUE if the segment could be updated successfully. If %FALSE is
|
||||||
|
@ -838,10 +683,10 @@ gst_segment_to_position (GstSegment * segment, GstFormat format,
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_segment_set_running_time (GstSegment * segment, GstFormat format,
|
gst_segment_set_running_time (GstSegment * segment, GstFormat format,
|
||||||
gint64 running_time)
|
guint64 running_time)
|
||||||
{
|
{
|
||||||
gint64 position;
|
guint64 position;
|
||||||
gint64 start, stop, last_stop;
|
guint64 start, stop;
|
||||||
|
|
||||||
/* start by bringing the running_time into the segment position */
|
/* start by bringing the running_time into the segment position */
|
||||||
position = gst_segment_to_position (segment, format, running_time);
|
position = gst_segment_to_position (segment, format, running_time);
|
||||||
|
@ -852,26 +697,19 @@ gst_segment_set_running_time (GstSegment * segment, GstFormat format,
|
||||||
|
|
||||||
start = segment->start;
|
start = segment->start;
|
||||||
stop = segment->stop;
|
stop = segment->stop;
|
||||||
last_stop = segment->last_stop;
|
|
||||||
|
|
||||||
if (G_LIKELY (segment->rate > 0.0)) {
|
if (G_LIKELY (segment->rate > 0.0)) {
|
||||||
/* update the start/last_stop and time values */
|
/* update the start and time values */
|
||||||
start = position;
|
start = position;
|
||||||
if (last_stop < start)
|
|
||||||
last_stop = start;
|
|
||||||
} else {
|
} else {
|
||||||
/* reverse, update stop */
|
/* reverse, update stop */
|
||||||
stop = position;
|
stop = position;
|
||||||
/* if we were past the position, go back */
|
|
||||||
if (last_stop > stop)
|
|
||||||
last_stop = stop;
|
|
||||||
}
|
}
|
||||||
/* and accumulated time is exactly the running time */
|
/* and base time is exactly the running time */
|
||||||
segment->time = gst_segment_to_stream_time (segment, format, start);
|
segment->time = gst_segment_to_stream_time (segment, format, start);
|
||||||
segment->start = start;
|
segment->start = start;
|
||||||
segment->stop = stop;
|
segment->stop = stop;
|
||||||
segment->last_stop = last_stop;
|
segment->base = running_time;
|
||||||
segment->accum = running_time;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
134
gst/gstsegment.h
134
gst/gstsegment.h
|
@ -23,7 +23,6 @@
|
||||||
#ifndef __GST_SEGMENT_H__
|
#ifndef __GST_SEGMENT_H__
|
||||||
#define __GST_SEGMENT_H__
|
#define __GST_SEGMENT_H__
|
||||||
|
|
||||||
#include <gst/gstevent.h>
|
|
||||||
#include <gst/gstformat.h>
|
#include <gst/gstformat.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
@ -32,70 +31,129 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstSegment GstSegment;
|
typedef struct _GstSegment GstSegment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstSeekType:
|
||||||
|
* @GST_SEEK_TYPE_NONE: no change in position is required
|
||||||
|
* @GST_SEEK_TYPE_CUR: change relative to currently configured segment. This
|
||||||
|
* can't be used to seek relative to the current playback position - do a
|
||||||
|
* position query, calculate the desired position and then do an absolute
|
||||||
|
* position seek instead if that's what you want to do.
|
||||||
|
* @GST_SEEK_TYPE_SET: absolute position is requested
|
||||||
|
* @GST_SEEK_TYPE_END: relative position to duration is requested
|
||||||
|
*
|
||||||
|
* The different types of seek events. When constructing a seek event with
|
||||||
|
* gst_event_new_seek() or when doing gst_segment_do_seek ().
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/* one of these */
|
||||||
|
GST_SEEK_TYPE_NONE = 0,
|
||||||
|
GST_SEEK_TYPE_CUR = 1,
|
||||||
|
GST_SEEK_TYPE_SET = 2,
|
||||||
|
GST_SEEK_TYPE_END = 3
|
||||||
|
} GstSeekType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstSeekFlags:
|
||||||
|
* @GST_SEEK_FLAG_NONE: no flag
|
||||||
|
* @GST_SEEK_FLAG_FLUSH: flush pipeline
|
||||||
|
* @GST_SEEK_FLAG_ACCURATE: accurate position is requested, this might
|
||||||
|
* be considerably slower for some formats.
|
||||||
|
* @GST_SEEK_FLAG_KEY_UNIT: seek to the nearest keyframe. This might be
|
||||||
|
* faster but less accurate.
|
||||||
|
* @GST_SEEK_FLAG_SEGMENT: perform a segment seek.
|
||||||
|
* @GST_SEEK_FLAG_SKIP: when doing fast foward or fast reverse playback, allow
|
||||||
|
* elements to skip frames instead of generating all
|
||||||
|
* frames. Since 0.10.22.
|
||||||
|
*
|
||||||
|
* Flags to be used with gst_element_seek() or gst_event_new_seek(). All flags
|
||||||
|
* can be used together.
|
||||||
|
*
|
||||||
|
* A non flushing seek might take some time to perform as the currently
|
||||||
|
* playing data in the pipeline will not be cleared.
|
||||||
|
*
|
||||||
|
* An accurate seek might be slower for formats that don't have any indexes
|
||||||
|
* or timestamp markers in the stream. Specifying this flag might require a
|
||||||
|
* complete scan of the file in those cases.
|
||||||
|
*
|
||||||
|
* When performing a segment seek: after the playback of the segment completes,
|
||||||
|
* no EOS will be emmited by the element that performed the seek, but a
|
||||||
|
* #GST_MESSAGE_SEGMENT_DONE message will be posted on the bus by the element.
|
||||||
|
* When this message is posted, it is possible to send a new seek event to
|
||||||
|
* continue playback. With this seek method it is possible to perform seemless
|
||||||
|
* looping or simple linear editing.
|
||||||
|
*
|
||||||
|
* When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode
|
||||||
|
* playback, the @GST_SEEK_FLAG_SKIP flag can be used to instruct decoders
|
||||||
|
* and demuxers to adjust the playback rate by skipping frames. This can improve
|
||||||
|
* performance and decrease CPU usage because not all frames need to be decoded.
|
||||||
|
*
|
||||||
|
* Also see part-seeking.txt in the GStreamer design documentation for more
|
||||||
|
* details on the meaning of these flags and the behaviour expected of
|
||||||
|
* elements that handle them.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
GST_SEEK_FLAG_NONE = 0,
|
||||||
|
GST_SEEK_FLAG_FLUSH = (1 << 0),
|
||||||
|
GST_SEEK_FLAG_ACCURATE = (1 << 1),
|
||||||
|
GST_SEEK_FLAG_KEY_UNIT = (1 << 2),
|
||||||
|
GST_SEEK_FLAG_SEGMENT = (1 << 3),
|
||||||
|
GST_SEEK_FLAG_SKIP = (1 << 4)
|
||||||
|
} GstSeekFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstSegment:
|
* GstSegment:
|
||||||
|
* @flags: flags for this segment
|
||||||
* @rate: the rate of the segment
|
* @rate: the rate of the segment
|
||||||
* @applied_rate: the already applied rate to the segment
|
* @applied_rate: the already applied rate to the segment
|
||||||
* @format: the format of the segment values
|
* @format: the format of the segment values
|
||||||
* @flags: flags for this segment
|
* @base: the base time of the segment
|
||||||
* @start: the start of the segment
|
* @start: the start of the segment
|
||||||
* @stop: the stop of the segment
|
* @stop: the stop of the segment
|
||||||
* @time: the stream time of the segment
|
* @time: the stream time of the segment
|
||||||
* @accum: accumulated segment
|
|
||||||
* @last_stop: last known stop time
|
|
||||||
* @duration: total duration of segment
|
|
||||||
*
|
*
|
||||||
* A helper structure that holds the configured region of
|
* A helper structure that holds the configured region of
|
||||||
* interest in a media file.
|
* interest in a media file.
|
||||||
*/
|
*/
|
||||||
struct _GstSegment {
|
struct _GstSegment {
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
gdouble rate;
|
GstSeekFlags flags;
|
||||||
gdouble applied_rate;
|
|
||||||
GstFormat format;
|
|
||||||
GstSeekFlags flags;
|
|
||||||
gint64 start;
|
|
||||||
gint64 stop;
|
|
||||||
gint64 time;
|
|
||||||
gint64 accum;
|
|
||||||
|
|
||||||
gint64 last_stop;
|
gdouble rate;
|
||||||
gint64 duration;
|
gdouble applied_rate;
|
||||||
|
|
||||||
/*< private >*/
|
GstFormat format;
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
guint64 base;
|
||||||
|
guint64 start;
|
||||||
|
guint64 stop;
|
||||||
|
guint64 time;
|
||||||
|
|
||||||
|
guint64 position;
|
||||||
|
guint64 duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_segment_get_type (void);
|
GType gst_segment_get_type (void);
|
||||||
|
|
||||||
GstSegment * gst_segment_new (void);
|
GstSegment * gst_segment_new (void);
|
||||||
GstSegment * gst_segment_copy (GstSegment *segment);
|
GstSegment * gst_segment_copy (const GstSegment *segment);
|
||||||
|
void gst_segment_copy_into (const GstSegment *src, GstSegment *dest);
|
||||||
void gst_segment_free (GstSegment *segment);
|
void gst_segment_free (GstSegment *segment);
|
||||||
|
|
||||||
void gst_segment_init (GstSegment *segment, GstFormat format);
|
void gst_segment_init (GstSegment *segment, GstFormat format);
|
||||||
|
|
||||||
void gst_segment_set_duration (GstSegment *segment, GstFormat format, gint64 duration);
|
guint64 gst_segment_to_stream_time (const GstSegment *segment, GstFormat format, guint64 position);
|
||||||
void gst_segment_set_last_stop (GstSegment *segment, GstFormat format, gint64 position);
|
guint64 gst_segment_to_running_time (const GstSegment *segment, GstFormat format, guint64 position);
|
||||||
|
guint64 gst_segment_to_position (const GstSegment *segment, GstFormat format, guint64 running_time);
|
||||||
|
|
||||||
void gst_segment_set_seek (GstSegment *segment, gdouble rate,
|
gboolean gst_segment_set_running_time (GstSegment *segment, GstFormat format, guint64 running_time);
|
||||||
|
|
||||||
|
gboolean gst_segment_clip (const GstSegment *segment, GstFormat format, guint64 start,
|
||||||
|
guint64 stop, guint64 *clip_start, guint64 *clip_stop);
|
||||||
|
|
||||||
|
|
||||||
|
gboolean gst_segment_do_seek (GstSegment * segment, gdouble rate,
|
||||||
GstFormat format, GstSeekFlags flags,
|
GstFormat format, GstSeekFlags flags,
|
||||||
GstSeekType start_type, gint64 start,
|
GstSeekType start_type, guint64 start,
|
||||||
GstSeekType stop_type, gint64 stop,
|
GstSeekType stop_type, guint64 stop, gboolean * update);
|
||||||
gboolean *update);
|
|
||||||
|
|
||||||
void gst_segment_set_newsegment (GstSegment *segment, gboolean update, gdouble rate,
|
|
||||||
gdouble applied_rate, GstFormat format, gint64 start,
|
|
||||||
gint64 stop, gint64 time);
|
|
||||||
|
|
||||||
gint64 gst_segment_to_stream_time (GstSegment *segment, GstFormat format, gint64 position);
|
|
||||||
gint64 gst_segment_to_running_time (GstSegment *segment, GstFormat format, gint64 position);
|
|
||||||
gint64 gst_segment_to_position (GstSegment *segment, GstFormat format, gint64 running_time);
|
|
||||||
|
|
||||||
gboolean gst_segment_clip (GstSegment *segment, GstFormat format, gint64 start,
|
|
||||||
gint64 stop, gint64 *clip_start, gint64 *clip_stop);
|
|
||||||
|
|
||||||
gboolean gst_segment_set_running_time (GstSegment *segment, GstFormat format, gint64 running_time);
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -842,10 +842,10 @@ gst_base_parse_sink_event (GstPad * pad, GstEvent * event)
|
||||||
GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
|
GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
|
||||||
GST_EVENT_TYPE_NAME (event));
|
GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
/* Cache all events except EOS, NEWSEGMENT and FLUSH_STOP if we have a
|
/* Cache all events except EOS, SEGMENT and FLUSH_STOP if we have a
|
||||||
* pending segment */
|
* pending segment */
|
||||||
if (parse->priv->pending_segment && GST_EVENT_TYPE (event) != GST_EVENT_EOS
|
if (parse->priv->pending_segment && GST_EVENT_TYPE (event) != GST_EVENT_EOS
|
||||||
&& GST_EVENT_TYPE (event) != GST_EVENT_NEWSEGMENT
|
&& GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT
|
||||||
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START
|
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START
|
||||||
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) {
|
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) {
|
||||||
|
|
||||||
|
@ -897,36 +897,36 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
|
||||||
GstEvent **eventp;
|
GstEvent **eventp;
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
|
const GstSegment *in_segment;
|
||||||
|
GstSegment out_segment;
|
||||||
|
gint64 offset = 0, next_ts;
|
||||||
|
|
||||||
|
#if 0
|
||||||
gdouble rate, applied_rate;
|
gdouble rate, applied_rate;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 start, stop, pos, next_ts, offset = 0;
|
gint64 start, stop, pos, next_ts;
|
||||||
gboolean update;
|
gboolean update;
|
||||||
|
#endif
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &applied_rate,
|
in_segment = gst_event_get_segment (event);
|
||||||
&format, &start, &stop, &pos);
|
gst_segment_init (&out_segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (parse, "newseg rate %g, applied rate %g, "
|
GST_DEBUG_OBJECT (parse, "segment %" GST_SEGMENT_FORMAT, in_segment);
|
||||||
"format %d, start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
|
|
||||||
", pos = %" GST_TIME_FORMAT, rate, applied_rate, format,
|
|
||||||
GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (pos));
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_BYTES) {
|
if (in_segment->format == GST_FORMAT_BYTES) {
|
||||||
GstClockTime seg_start, seg_stop;
|
|
||||||
GstBaseParseSeek *seek = NULL;
|
GstBaseParseSeek *seek = NULL;
|
||||||
GSList *node;
|
GSList *node;
|
||||||
|
|
||||||
/* stop time is allowed to be open-ended, but not start & pos */
|
/* stop time is allowed to be open-ended, but not start & pos */
|
||||||
seg_stop = GST_CLOCK_TIME_NONE;
|
offset = in_segment->time;
|
||||||
seg_start = 0;
|
|
||||||
offset = pos;
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (parse);
|
GST_OBJECT_LOCK (parse);
|
||||||
for (node = parse->priv->pending_seeks; node; node = node->next) {
|
for (node = parse->priv->pending_seeks; node; node = node->next) {
|
||||||
GstBaseParseSeek *tmp = node->data;
|
GstBaseParseSeek *tmp = node->data;
|
||||||
|
|
||||||
if (tmp->offset == pos) {
|
if (tmp->offset == offset) {
|
||||||
seek = tmp;
|
seek = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -939,8 +939,11 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
|
||||||
GST_DEBUG_OBJECT (parse,
|
GST_DEBUG_OBJECT (parse,
|
||||||
"Matched newsegment to%s seek: %" GST_SEGMENT_FORMAT,
|
"Matched newsegment to%s seek: %" GST_SEGMENT_FORMAT,
|
||||||
seek->accurate ? " accurate" : "", &seek->segment);
|
seek->accurate ? " accurate" : "", &seek->segment);
|
||||||
seg_start = seek->segment.start;
|
|
||||||
seg_stop = seek->segment.stop;
|
out_segment.start = seek->segment.start;
|
||||||
|
out_segment.stop = seek->segment.stop;
|
||||||
|
out_segment.time = seek->segment.start;
|
||||||
|
|
||||||
next_ts = seek->start_ts;
|
next_ts = seek->start_ts;
|
||||||
parse->priv->exact_position = seek->accurate;
|
parse->priv->exact_position = seek->accurate;
|
||||||
g_free (seek);
|
g_free (seek);
|
||||||
|
@ -948,39 +951,48 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
|
||||||
/* best attempt convert */
|
/* best attempt convert */
|
||||||
/* as these are only estimates, stop is kept open-ended to avoid
|
/* as these are only estimates, stop is kept open-ended to avoid
|
||||||
* premature cutting */
|
* premature cutting */
|
||||||
gst_base_parse_convert (parse, GST_FORMAT_BYTES, start,
|
gst_base_parse_convert (parse, GST_FORMAT_BYTES, in_segment->start,
|
||||||
GST_FORMAT_TIME, (gint64 *) & seg_start);
|
GST_FORMAT_TIME, (gint64 *) & next_ts);
|
||||||
parse->priv->exact_position = (start == 0);
|
|
||||||
next_ts = seg_start;
|
out_segment.start = next_ts;
|
||||||
|
out_segment.stop = GST_CLOCK_TIME_NONE;
|
||||||
|
out_segment.time = next_ts;
|
||||||
|
|
||||||
|
parse->priv->exact_position = (in_segment->start == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
event = gst_event_new_new_segment (update, rate, applied_rate,
|
|
||||||
GST_FORMAT_TIME, seg_start, seg_stop, seg_start);
|
event = gst_event_new_segment (&out_segment);
|
||||||
format = GST_FORMAT_TIME;
|
|
||||||
start = seg_start;
|
|
||||||
stop = seg_stop;
|
|
||||||
GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. "
|
GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. "
|
||||||
"start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT,
|
GST_SEGMENT_FORMAT, in_segment);
|
||||||
GST_TIME_ARGS (seg_start), GST_TIME_ARGS (seg_stop));
|
|
||||||
} else if (format != GST_FORMAT_TIME) {
|
} else if (in_segment->format != GST_FORMAT_TIME) {
|
||||||
/* Unknown incoming segment format. Output a default open-ended
|
/* Unknown incoming segment format. Output a default open-ended
|
||||||
* TIME segment */
|
* TIME segment */
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
event = gst_event_new_new_segment (update, rate, applied_rate,
|
|
||||||
GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0);
|
out_segment.start = 0;
|
||||||
format = GST_FORMAT_TIME;
|
out_segment.stop = GST_CLOCK_TIME_NONE;;
|
||||||
next_ts = start = 0;
|
out_segment.time = 0;;
|
||||||
stop = GST_CLOCK_TIME_NONE;
|
|
||||||
|
event = gst_event_new_segment (&out_segment);
|
||||||
|
|
||||||
|
next_ts = 0;
|
||||||
} else {
|
} else {
|
||||||
/* not considered BYTE seekable if it is talking to us in TIME,
|
/* not considered BYTE seekable if it is talking to us in TIME,
|
||||||
* whatever else it might claim */
|
* whatever else it might claim */
|
||||||
parse->priv->upstream_seekable = FALSE;
|
parse->priv->upstream_seekable = FALSE;
|
||||||
next_ts = start;
|
next_ts = in_segment->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_segment_set_newsegment (&parse->segment, update, rate,
|
memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
|
||||||
applied_rate, format, start, stop, start);
|
|
||||||
|
/*
|
||||||
|
gst_segment_set_newsegment (&parse->segment, update, rate,
|
||||||
|
applied_rate, format, start, stop, start);
|
||||||
|
*/
|
||||||
|
|
||||||
/* save the segment for later, right before we push a new buffer so that
|
/* save the segment for later, right before we push a new buffer so that
|
||||||
* the caps are fixed and the next linked element can receive
|
* the caps are fixed and the next linked element can receive
|
||||||
|
@ -992,11 +1004,12 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
|
||||||
|
|
||||||
/* but finish the current segment */
|
/* but finish the current segment */
|
||||||
GST_DEBUG_OBJECT (parse, "draining current segment");
|
GST_DEBUG_OBJECT (parse, "draining current segment");
|
||||||
if (parse->segment.rate > 0.0)
|
if (in_segment->rate > 0.0)
|
||||||
gst_base_parse_drain (parse);
|
gst_base_parse_drain (parse);
|
||||||
else
|
else
|
||||||
gst_base_parse_process_fragment (parse, FALSE);
|
gst_base_parse_process_fragment (parse, FALSE);
|
||||||
gst_adapter_clear (parse->priv->adapter);
|
gst_adapter_clear (parse->priv->adapter);
|
||||||
|
|
||||||
parse->priv->offset = offset;
|
parse->priv->offset = offset;
|
||||||
parse->priv->sync_offset = offset;
|
parse->priv->sync_offset = offset;
|
||||||
parse->priv->next_ts = next_ts;
|
parse->priv->next_ts = next_ts;
|
||||||
|
@ -1767,64 +1780,46 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
gst_event_unref (parse->priv->pending_segment);
|
gst_event_unref (parse->priv->pending_segment);
|
||||||
parse->segment.start =
|
parse->segment.start =
|
||||||
MIN ((guint64) last_start, (guint64) parse->segment.stop);
|
MIN ((guint64) last_start, (guint64) parse->segment.stop);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (parse,
|
GST_DEBUG_OBJECT (parse,
|
||||||
"adjusting pending segment start to %" GST_TIME_FORMAT,
|
"adjusting pending segment start to %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (parse->segment.start));
|
GST_TIME_ARGS (parse->segment.start));
|
||||||
parse->priv->pending_segment =
|
|
||||||
gst_event_new_new_segment (FALSE, parse->segment.rate,
|
parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
|
||||||
parse->segment.applied_rate,
|
|
||||||
parse->segment.format, parse->segment.start,
|
|
||||||
parse->segment.stop, parse->segment.start);
|
|
||||||
}
|
}
|
||||||
/* handle gaps, e.g. non-zero start-time, in as much not handled by above */
|
/* handle gaps, e.g. non-zero start-time, in as much not handled by above */
|
||||||
if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
|
if (GST_CLOCK_TIME_IS_VALID (parse->segment.position) &&
|
||||||
GST_CLOCK_TIME_IS_VALID (last_start)) {
|
GST_CLOCK_TIME_IS_VALID (last_start)) {
|
||||||
GstClockTimeDiff diff;
|
GstClockTimeDiff diff;
|
||||||
|
|
||||||
/* only send newsegments with increasing start times,
|
/* only send newsegments with increasing start times,
|
||||||
* otherwise if these go back and forth downstream (sinks) increase
|
* otherwise if these go back and forth downstream (sinks) increase
|
||||||
* accumulated time and running_time */
|
* accumulated time and running_time */
|
||||||
diff = GST_CLOCK_DIFF (parse->segment.last_stop, last_start);
|
diff = GST_CLOCK_DIFF (parse->segment.position, last_start);
|
||||||
if (G_UNLIKELY (diff > 2 * GST_SECOND
|
if (G_UNLIKELY (diff > 2 * GST_SECOND
|
||||||
&& last_start > parse->segment.start
|
&& last_start > parse->segment.start
|
||||||
&& (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop)
|
&& (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop)
|
||||||
|| last_start < parse->segment.stop))) {
|
|| last_start < parse->segment.stop))) {
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (parse,
|
GST_DEBUG_OBJECT (parse,
|
||||||
"Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%"
|
"Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%"
|
||||||
GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
|
GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
|
||||||
"Sending updated NEWSEGMENT events", diff,
|
"Sending updated NEWSEGMENT events", diff,
|
||||||
GST_TIME_ARGS (parse->segment.last_stop),
|
GST_TIME_ARGS (parse->segment.position),
|
||||||
GST_TIME_ARGS (last_start));
|
GST_TIME_ARGS (last_start));
|
||||||
|
|
||||||
if (G_UNLIKELY (parse->priv->pending_segment)) {
|
if (G_UNLIKELY (parse->priv->pending_segment)) {
|
||||||
gst_event_unref (parse->priv->pending_segment);
|
gst_event_unref (parse->priv->pending_segment);
|
||||||
parse->segment.start = last_start;
|
parse->segment.start = last_start;
|
||||||
|
parse->segment.time = last_start;
|
||||||
parse->priv->pending_segment =
|
parse->priv->pending_segment =
|
||||||
gst_event_new_new_segment (FALSE, parse->segment.rate,
|
gst_event_new_segment (&parse->segment);
|
||||||
parse->segment.applied_rate,
|
|
||||||
parse->segment.format, parse->segment.start,
|
|
||||||
parse->segment.stop, parse->segment.start);
|
|
||||||
} else {
|
} else {
|
||||||
/* send newsegment events such that the gap is not accounted in
|
/* skip gap FIXME */
|
||||||
* accum time, hence running_time */
|
|
||||||
/* close ahead of gap */
|
|
||||||
gst_pad_push_event (parse->srcpad,
|
gst_pad_push_event (parse->srcpad,
|
||||||
gst_event_new_new_segment (TRUE, parse->segment.rate,
|
gst_event_new_segment (&parse->segment));
|
||||||
parse->segment.applied_rate,
|
|
||||||
parse->segment.format, parse->segment.last_stop,
|
|
||||||
parse->segment.last_stop, parse->segment.last_stop));
|
|
||||||
/* skip gap */
|
|
||||||
gst_pad_push_event (parse->srcpad,
|
|
||||||
gst_event_new_new_segment (FALSE, parse->segment.rate,
|
|
||||||
parse->segment.applied_rate,
|
|
||||||
parse->segment.format, last_start,
|
|
||||||
parse->segment.stop, last_start));
|
|
||||||
}
|
}
|
||||||
/* align segment view with downstream,
|
parse->segment.position = last_start;
|
||||||
* prevents double-counting accum when closing segment */
|
|
||||||
gst_segment_set_newsegment (&parse->segment, FALSE,
|
|
||||||
parse->segment.rate, parse->segment.applied_rate,
|
|
||||||
parse->segment.format, last_start, parse->segment.stop, last_start);
|
|
||||||
parse->segment.last_stop = last_start;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1930,8 +1925,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
|
|
||||||
/* Update current running segment position */
|
/* Update current running segment position */
|
||||||
if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE &&
|
if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE &&
|
||||||
parse->segment.last_stop < last_stop)
|
parse->segment.position < last_stop)
|
||||||
gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop);
|
parse->segment.position = last_stop;
|
||||||
|
|
||||||
gst_base_parse_frame_free (frame);
|
gst_base_parse_frame_free (frame);
|
||||||
|
|
||||||
|
@ -2048,7 +2043,7 @@ gst_base_parse_process_fragment (GstBaseParse * parse, gboolean push_only)
|
||||||
* ok if taken from subclass or upstream */
|
* ok if taken from subclass or upstream */
|
||||||
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
|
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
|
||||||
/* prevent it hanging around stop all the time */
|
/* prevent it hanging around stop all the time */
|
||||||
parse->segment.last_stop = GST_CLOCK_TIME_NONE;
|
parse->segment.position = GST_CLOCK_TIME_NONE;
|
||||||
/* mark next run */
|
/* mark next run */
|
||||||
parse->priv->discont = TRUE;
|
parse->priv->discont = TRUE;
|
||||||
|
|
||||||
|
@ -2636,7 +2631,7 @@ gst_base_parse_loop (GstPad * pad)
|
||||||
|
|
||||||
/* eat expected eos signalling past segment in reverse playback */
|
/* eat expected eos signalling past segment in reverse playback */
|
||||||
if (parse->segment.rate < 0.0 && ret == GST_FLOW_UNEXPECTED &&
|
if (parse->segment.rate < 0.0 && ret == GST_FLOW_UNEXPECTED &&
|
||||||
parse->segment.last_stop >= parse->segment.stop) {
|
parse->segment.position >= parse->segment.stop) {
|
||||||
GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
|
GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
|
||||||
/* push what was accumulated during loop run */
|
/* push what was accumulated during loop run */
|
||||||
gst_base_parse_process_fragment (parse, TRUE);
|
gst_base_parse_process_fragment (parse, TRUE);
|
||||||
|
@ -2797,10 +2792,7 @@ gst_base_parse_sink_activate_pull (GstPad * sinkpad, gboolean active)
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
if (active) {
|
if (active) {
|
||||||
parse->priv->pending_segment = gst_event_new_new_segment (FALSE,
|
parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
|
||||||
parse->segment.rate, parse->segment.applied_rate,
|
|
||||||
parse->segment.format, parse->segment.start, parse->segment.stop,
|
|
||||||
parse->segment.last_stop);
|
|
||||||
result &=
|
result &=
|
||||||
gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
|
gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
|
||||||
sinkpad);
|
sinkpad);
|
||||||
|
@ -3090,8 +3082,8 @@ gst_base_parse_query (GstPad * pad, GstQuery ** query)
|
||||||
dest_value = parse->priv->offset;
|
dest_value = parse->priv->offset;
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
} else if (format == parse->segment.format &&
|
} else if (format == parse->segment.format &&
|
||||||
GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)) {
|
GST_CLOCK_TIME_IS_VALID (parse->segment.position)) {
|
||||||
dest_value = parse->segment.last_stop;
|
dest_value = parse->segment.position;
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (parse);
|
GST_OBJECT_UNLOCK (parse);
|
||||||
|
@ -3498,10 +3490,10 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
|
|
||||||
/* copy segment, we need this because we still need the old
|
/* copy segment, we need this because we still need the old
|
||||||
* segment when we close the current segment. */
|
* segment when we close the current segment. */
|
||||||
memcpy (&seeksegment, &parse->segment, sizeof (GstSegment));
|
gst_segment_copy_into (&parse->segment, &seeksegment);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (parse, "configuring seek");
|
GST_DEBUG_OBJECT (parse, "configuring seek");
|
||||||
gst_segment_set_seek (&seeksegment, rate, format, flags,
|
gst_segment_do_seek (&seeksegment, rate, format, flags,
|
||||||
cur_type, cur, stop_type, stop, &update);
|
cur_type, cur, stop_type, stop, &update);
|
||||||
|
|
||||||
/* accurate seeking implies seek tables are used to obtain position,
|
/* accurate seeking implies seek tables are used to obtain position,
|
||||||
|
@ -3509,13 +3501,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
accurate = flags & GST_SEEK_FLAG_ACCURATE;
|
accurate = flags & GST_SEEK_FLAG_ACCURATE;
|
||||||
|
|
||||||
/* maybe we can be accurate for (almost) free */
|
/* maybe we can be accurate for (almost) free */
|
||||||
gst_base_parse_find_offset (parse, seeksegment.last_stop, TRUE, &start_ts);
|
gst_base_parse_find_offset (parse, seeksegment.position, TRUE, &start_ts);
|
||||||
if (seeksegment.last_stop <= start_ts + TARGET_DIFFERENCE) {
|
if (seeksegment.position <= start_ts + TARGET_DIFFERENCE) {
|
||||||
GST_DEBUG_OBJECT (parse, "accurate seek possible");
|
GST_DEBUG_OBJECT (parse, "accurate seek possible");
|
||||||
accurate = TRUE;
|
accurate = TRUE;
|
||||||
}
|
}
|
||||||
if (accurate) {
|
if (accurate) {
|
||||||
GstClockTime startpos = seeksegment.last_stop;
|
GstClockTime startpos = seeksegment.position;
|
||||||
|
|
||||||
/* accurate requested, so ... seek a bit before target */
|
/* accurate requested, so ... seek a bit before target */
|
||||||
if (startpos < parse->priv->lead_in_ts)
|
if (startpos < parse->priv->lead_in_ts)
|
||||||
|
@ -3526,9 +3518,9 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
|
seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
start_ts = seeksegment.last_stop;
|
start_ts = seeksegment.position;
|
||||||
dstformat = GST_FORMAT_BYTES;
|
dstformat = GST_FORMAT_BYTES;
|
||||||
if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.last_stop,
|
if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.position,
|
||||||
&dstformat, &seekpos))
|
&dstformat, &seekpos))
|
||||||
goto convert_failed;
|
goto convert_failed;
|
||||||
if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.stop,
|
if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.stop,
|
||||||
|
@ -3564,7 +3556,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
GST_PAD_STREAM_LOCK (parse->sinkpad);
|
GST_PAD_STREAM_LOCK (parse->sinkpad);
|
||||||
|
|
||||||
/* save current position */
|
/* save current position */
|
||||||
last_stop = parse->segment.last_stop;
|
last_stop = parse->segment.position;
|
||||||
GST_DEBUG_OBJECT (parse, "stopped streaming at %" G_GINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse, "stopped streaming at %" G_GINT64_FORMAT,
|
||||||
last_stop);
|
last_stop);
|
||||||
|
|
||||||
|
@ -3577,23 +3569,9 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop ());
|
gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop ());
|
||||||
gst_base_parse_clear_queues (parse);
|
gst_base_parse_clear_queues (parse);
|
||||||
} else {
|
} else {
|
||||||
if (parse->priv->close_segment)
|
/* keep track of our position */
|
||||||
gst_event_unref (parse->priv->close_segment);
|
seeksegment.base = gst_segment_to_running_time (&seeksegment,
|
||||||
|
seeksegment.format, parse->segment.position);
|
||||||
parse->priv->close_segment = gst_event_new_new_segment (TRUE,
|
|
||||||
parse->segment.rate, parse->segment.applied_rate,
|
|
||||||
parse->segment.format, parse->segment.accum, parse->segment.last_stop,
|
|
||||||
parse->segment.accum);
|
|
||||||
|
|
||||||
/* keep track of our last_stop */
|
|
||||||
seeksegment.accum = parse->segment.last_stop;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (parse, "Created close seg format %d, "
|
|
||||||
"start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
|
|
||||||
", pos = %" GST_TIME_FORMAT, format,
|
|
||||||
GST_TIME_ARGS (parse->segment.accum),
|
|
||||||
GST_TIME_ARGS (parse->segment.last_stop),
|
|
||||||
GST_TIME_ARGS (parse->segment.accum));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (&parse->segment, &seeksegment, sizeof (GstSegment));
|
memcpy (&parse->segment, &seeksegment, sizeof (GstSegment));
|
||||||
|
@ -3603,11 +3581,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
gst_event_unref (parse->priv->pending_segment);
|
gst_event_unref (parse->priv->pending_segment);
|
||||||
|
|
||||||
/* This will be sent later in _loop() */
|
/* This will be sent later in _loop() */
|
||||||
parse->priv->pending_segment =
|
parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
|
||||||
gst_event_new_new_segment (FALSE, parse->segment.rate,
|
|
||||||
parse->segment.applied_rate,
|
|
||||||
parse->segment.format, parse->segment.start,
|
|
||||||
parse->segment.stop, parse->segment.start);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (parse, "Created newseg format %d, "
|
GST_DEBUG_OBJECT (parse, "Created newseg format %d, "
|
||||||
"start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
|
"start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
|
||||||
|
@ -3620,7 +3594,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
|
||||||
* maybe scan and subclass can find where to go */
|
* maybe scan and subclass can find where to go */
|
||||||
if (!accurate) {
|
if (!accurate) {
|
||||||
gint64 scanpos;
|
gint64 scanpos;
|
||||||
GstClockTime ts = seeksegment.last_stop;
|
GstClockTime ts = seeksegment.position;
|
||||||
|
|
||||||
gst_base_parse_locate_time (parse, &ts, &scanpos);
|
gst_base_parse_locate_time (parse, &ts, &scanpos);
|
||||||
if (scanpos >= 0) {
|
if (scanpos >= 0) {
|
||||||
|
|
|
@ -1439,43 +1439,15 @@ static void
|
||||||
gst_base_sink_configure_segment (GstBaseSink * basesink, GstPad * pad,
|
gst_base_sink_configure_segment (GstBaseSink * basesink, GstPad * pad,
|
||||||
GstEvent * event, GstSegment * segment)
|
GstEvent * event, GstSegment * segment)
|
||||||
{
|
{
|
||||||
gboolean update;
|
|
||||||
gdouble rate, arate;
|
|
||||||
GstFormat format;
|
|
||||||
gint64 start;
|
|
||||||
gint64 stop;
|
|
||||||
gint64 time;
|
|
||||||
|
|
||||||
/* the newsegment event is needed to bring the buffer timestamps to the
|
|
||||||
* stream time and to drop samples outside of the playback segment. */
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate, &format,
|
|
||||||
&start, &stop, &time);
|
|
||||||
|
|
||||||
/* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.
|
/* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.
|
||||||
* We protect with the OBJECT_LOCK so that we can use the values to
|
* We protect with the OBJECT_LOCK so that we can use the values to
|
||||||
* safely answer a POSITION query. */
|
* safely answer a POSITION query. */
|
||||||
GST_OBJECT_LOCK (basesink);
|
GST_OBJECT_LOCK (basesink);
|
||||||
gst_segment_set_newsegment (segment, update, rate, arate, format, start,
|
/* the newsegment event is needed to bring the buffer timestamps to the
|
||||||
stop, time);
|
* stream time and to drop samples outside of the playback segment. */
|
||||||
|
gst_event_parse_segment (event, segment);
|
||||||
if (format == GST_FORMAT_TIME) {
|
GST_DEBUG_OBJECT (basesink, "configured NEWSEGMENT %" GST_SEGMENT_FORMAT,
|
||||||
GST_DEBUG_OBJECT (basesink,
|
segment);
|
||||||
"configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
|
||||||
"format GST_FORMAT_TIME, "
|
|
||||||
"%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
|
|
||||||
", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT,
|
|
||||||
update, rate, arate, GST_TIME_ARGS (segment->start),
|
|
||||||
GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time),
|
|
||||||
GST_TIME_ARGS (segment->accum));
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (basesink,
|
|
||||||
"configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
|
||||||
"format %d, "
|
|
||||||
"%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
|
|
||||||
G_GINT64_FORMAT ", accum %" G_GINT64_FORMAT, update, rate, arate,
|
|
||||||
segment->format, segment->start, segment->stop, segment->time,
|
|
||||||
segment->accum);
|
|
||||||
}
|
|
||||||
GST_OBJECT_UNLOCK (basesink);
|
GST_OBJECT_UNLOCK (basesink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1642,27 +1614,19 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
/* update the segment clipping regions for non-flushing seeks */
|
/* update the segment clipping regions for non-flushing seeks */
|
||||||
if (segment->rate > 0.0) {
|
if (segment->rate > 0.0) {
|
||||||
segment->stop = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
|
segment->stop = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
|
||||||
segment->last_stop = segment->stop;
|
segment->position = segment->stop;
|
||||||
} else {
|
} else {
|
||||||
gint64 position;
|
gint64 position;
|
||||||
|
|
||||||
position = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
|
position = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
|
||||||
segment->time = position;
|
segment->time = position;
|
||||||
segment->start = position;
|
segment->start = position;
|
||||||
segment->last_stop = position;
|
segment->position = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (sink,
|
GST_DEBUG_OBJECT (sink, "segment now %" GST_SEGMENT_FORMAT, segment);
|
||||||
"segment now rate %lf, applied rate %lf, "
|
|
||||||
"format GST_FORMAT_TIME, "
|
|
||||||
"%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
|
|
||||||
", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT,
|
|
||||||
segment->rate, segment->applied_rate, GST_TIME_ARGS (segment->start),
|
|
||||||
GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time),
|
|
||||||
GST_TIME_ARGS (segment->accum));
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (sink, "step started at running_time %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (sink, "step started at running_time %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (current->start));
|
GST_TIME_ARGS (current->start));
|
||||||
|
|
||||||
|
@ -1707,8 +1671,8 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
gst_segment_set_running_time (segment, GST_FORMAT_TIME, position);
|
gst_segment_set_running_time (segment, GST_FORMAT_TIME, position);
|
||||||
|
|
||||||
if (current->flush) {
|
if (current->flush) {
|
||||||
/* and remove the accumulated time we flushed, start time did not change */
|
/* and remove the time we flushed, start time did not change */
|
||||||
segment->accum = current->start;
|
segment->base = current->start;
|
||||||
} else {
|
} else {
|
||||||
/* start time is now the stepped position */
|
/* start time is now the stepped position */
|
||||||
gst_element_set_start_time (GST_ELEMENT_CAST (sink), position);
|
gst_element_set_start_time (GST_ELEMENT_CAST (sink), position);
|
||||||
|
@ -1723,7 +1687,7 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
segment->start = current->start_start;
|
segment->start = current->start_start;
|
||||||
|
|
||||||
/* the clip segment is used for position report in paused... */
|
/* the clip segment is used for position report in paused... */
|
||||||
memcpy (sink->clip_segment, segment, sizeof (GstSegment));
|
gst_segment_copy_into (segment, sink->clip_segment);
|
||||||
|
|
||||||
/* post the step done when we know the stepped duration in TIME */
|
/* post the step done when we know the stepped duration in TIME */
|
||||||
message =
|
message =
|
||||||
|
@ -1742,8 +1706,8 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_stepping (GstBaseSink * sink, GstSegment * segment,
|
handle_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
GstStepInfo * current, gint64 * cstart, gint64 * cstop, gint64 * rstart,
|
GstStepInfo * current, guint64 * cstart, guint64 * cstop, guint64 * rstart,
|
||||||
gint64 * rstop)
|
guint64 * rstop)
|
||||||
{
|
{
|
||||||
gboolean step_end = FALSE;
|
gboolean step_end = FALSE;
|
||||||
|
|
||||||
|
@ -1752,7 +1716,7 @@ handle_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
{
|
{
|
||||||
guint64 end;
|
guint64 end;
|
||||||
gint64 first, last;
|
guint64 first, last;
|
||||||
gdouble abs_rate;
|
gdouble abs_rate;
|
||||||
|
|
||||||
if (segment->rate > 0.0) {
|
if (segment->rate > 0.0) {
|
||||||
|
@ -1844,8 +1808,8 @@ gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
|
||||||
GstBaseSinkClass *bclass;
|
GstBaseSinkClass *bclass;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstClockTime start, stop; /* raw start/stop timestamps */
|
GstClockTime start, stop; /* raw start/stop timestamps */
|
||||||
gint64 cstart, cstop; /* clipped raw timestamps */
|
guint64 cstart, cstop; /* clipped raw timestamps */
|
||||||
gint64 rstart, rstop; /* clipped timestamps converted to running time */
|
guint64 rstart, rstop; /* clipped timestamps converted to running time */
|
||||||
GstClockTime sstart, sstop; /* clipped timestamps converted to stream time */
|
GstClockTime sstart, sstop; /* clipped timestamps converted to stream time */
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
GstBaseSinkPrivate *priv;
|
GstBaseSinkPrivate *priv;
|
||||||
|
@ -1890,11 +1854,6 @@ gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* other events do not need syncing */
|
/* other events do not need syncing */
|
||||||
/* FIXME, maybe NEWSEGMENT might need synchronisation
|
|
||||||
* since the POSITION query depends on accumulated times and
|
|
||||||
* we cannot accumulate the current segment before the previous
|
|
||||||
* one completed.
|
|
||||||
*/
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1940,7 +1899,7 @@ again:
|
||||||
|
|
||||||
/* clip, only when we know about time */
|
/* clip, only when we know about time */
|
||||||
if (G_UNLIKELY (!gst_segment_clip (segment, GST_FORMAT_TIME,
|
if (G_UNLIKELY (!gst_segment_clip (segment, GST_FORMAT_TIME,
|
||||||
(gint64) start, (gint64) stop, &cstart, &cstop))) {
|
start, stop, &cstart, &cstop))) {
|
||||||
if (step->valid) {
|
if (step->valid) {
|
||||||
GST_DEBUG_OBJECT (basesink, "step out of segment");
|
GST_DEBUG_OBJECT (basesink, "step out of segment");
|
||||||
/* when we are stepping, pretend we're at the end of the segment */
|
/* when we are stepping, pretend we're at the end of the segment */
|
||||||
|
@ -1964,9 +1923,9 @@ again:
|
||||||
|
|
||||||
/* set last stop position */
|
/* set last stop position */
|
||||||
if (G_LIKELY (stop != GST_CLOCK_TIME_NONE && cstop != GST_CLOCK_TIME_NONE))
|
if (G_LIKELY (stop != GST_CLOCK_TIME_NONE && cstop != GST_CLOCK_TIME_NONE))
|
||||||
gst_segment_set_last_stop (segment, GST_FORMAT_TIME, cstop);
|
segment->position = cstop;
|
||||||
else
|
else
|
||||||
gst_segment_set_last_stop (segment, GST_FORMAT_TIME, cstart);
|
segment->position = cstart;
|
||||||
|
|
||||||
do_times:
|
do_times:
|
||||||
rstart = gst_segment_to_running_time (segment, format, cstart);
|
rstart = gst_segment_to_running_time (segment, format, cstart);
|
||||||
|
@ -2735,7 +2694,7 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
|
||||||
GstClockReturn status, GstClockTimeDiff jitter)
|
GstClockReturn status, GstClockTimeDiff jitter)
|
||||||
{
|
{
|
||||||
gboolean late;
|
gboolean late;
|
||||||
gint64 max_lateness;
|
guint64 max_lateness;
|
||||||
GstBaseSinkPrivate *priv;
|
GstBaseSinkPrivate *priv;
|
||||||
|
|
||||||
priv = basesink->priv;
|
priv = basesink->priv;
|
||||||
|
@ -2989,7 +2948,7 @@ again:
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
|
gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
/* configure the segment */
|
/* configure the segment */
|
||||||
gst_base_sink_configure_segment (basesink, pad, event,
|
gst_base_sink_configure_segment (basesink, pad, event,
|
||||||
&basesink->segment);
|
&basesink->segment);
|
||||||
|
@ -3387,41 +3346,31 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gboolean update;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesink, "newsegment %p", event);
|
GST_DEBUG_OBJECT (basesink, "segment %p", event);
|
||||||
|
|
||||||
GST_BASE_SINK_PREROLL_LOCK (basesink);
|
GST_BASE_SINK_PREROLL_LOCK (basesink);
|
||||||
if (G_UNLIKELY (basesink->flushing))
|
if (G_UNLIKELY (basesink->flushing))
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, NULL, NULL, NULL, NULL,
|
/* the new segment is a non prerollable item and does not block anything,
|
||||||
NULL, NULL);
|
* we need to configure the current clipping segment and insert the event
|
||||||
|
* in the queue to serialize it with the buffers for rendering. */
|
||||||
|
gst_base_sink_configure_segment (basesink, pad, event,
|
||||||
|
basesink->clip_segment);
|
||||||
|
|
||||||
if (G_UNLIKELY (basesink->priv->received_eos && !update)) {
|
ret =
|
||||||
/* we can't accept anything when we are EOS */
|
gst_base_sink_queue_object_unlocked (basesink, pad,
|
||||||
|
_PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), FALSE);
|
||||||
|
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||||
result = FALSE;
|
result = FALSE;
|
||||||
gst_event_unref (event);
|
else {
|
||||||
} else {
|
GST_OBJECT_LOCK (basesink);
|
||||||
/* the new segment is a non prerollable item and does not block anything,
|
basesink->have_newsegment = TRUE;
|
||||||
* we need to configure the current clipping segment and insert the event
|
GST_OBJECT_UNLOCK (basesink);
|
||||||
* in the queue to serialize it with the buffers for rendering. */
|
|
||||||
gst_base_sink_configure_segment (basesink, pad, event,
|
|
||||||
basesink->clip_segment);
|
|
||||||
|
|
||||||
ret =
|
|
||||||
gst_base_sink_queue_object_unlocked (basesink, pad,
|
|
||||||
_PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), FALSE);
|
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
|
||||||
result = FALSE;
|
|
||||||
else {
|
|
||||||
GST_OBJECT_LOCK (basesink);
|
|
||||||
basesink->have_newsegment = TRUE;
|
|
||||||
GST_OBJECT_UNLOCK (basesink);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
GST_BASE_SINK_PREROLL_UNLOCK (basesink);
|
GST_BASE_SINK_PREROLL_UNLOCK (basesink);
|
||||||
break;
|
break;
|
||||||
|
@ -3589,7 +3538,7 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
|
||||||
if (GST_CLOCK_TIME_IS_VALID (start) &&
|
if (GST_CLOCK_TIME_IS_VALID (start) &&
|
||||||
(clip_segment->format == GST_FORMAT_TIME)) {
|
(clip_segment->format == GST_FORMAT_TIME)) {
|
||||||
if (G_UNLIKELY (!gst_segment_clip (clip_segment,
|
if (G_UNLIKELY (!gst_segment_clip (clip_segment,
|
||||||
GST_FORMAT_TIME, (gint64) start, (gint64) end, NULL, NULL)))
|
GST_FORMAT_TIME, start, end, NULL, NULL)))
|
||||||
goto out_of_segment;
|
goto out_of_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3744,7 +3693,7 @@ gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
|
||||||
dest_format = segment->format;
|
dest_format = segment->format;
|
||||||
|
|
||||||
if (seek_format == dest_format) {
|
if (seek_format == dest_format) {
|
||||||
gst_segment_set_seek (segment, rate, seek_format, flags,
|
gst_segment_do_seek (segment, rate, seek_format, flags,
|
||||||
cur_type, cur, stop_type, stop, &update);
|
cur_type, cur, stop_type, stop, &update);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -3766,7 +3715,7 @@ gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And finally, configure our output segment in the desired format */
|
/* And finally, configure our output segment in the desired format */
|
||||||
gst_segment_set_seek (segment, rate, dest_format, flags, cur_type, cur,
|
gst_segment_do_seek (segment, rate, dest_format, flags, cur_type, cur,
|
||||||
stop_type, stop, &update);
|
stop_type, stop, &update);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -3839,7 +3788,7 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
} else {
|
} else {
|
||||||
/* The seek format matches our processing format, no need to ask the
|
/* The seek format matches our processing format, no need to ask the
|
||||||
* the subclass to configure the segment. */
|
* the subclass to configure the segment. */
|
||||||
gst_segment_set_seek (&seeksegment, rate, seek_format, flags,
|
gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
|
||||||
cur_type, cur, stop_type, stop, &update);
|
cur_type, cur, stop_type, stop, &update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3850,9 +3799,9 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
if (res) {
|
if (res) {
|
||||||
GST_DEBUG_OBJECT (sink, "segment configured from %" G_GINT64_FORMAT
|
GST_DEBUG_OBJECT (sink, "segment configured from %" G_GINT64_FORMAT
|
||||||
" to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
" to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
||||||
seeksegment.start, seeksegment.stop, seeksegment.last_stop);
|
seeksegment.start, seeksegment.stop, seeksegment.position);
|
||||||
|
|
||||||
/* do the seek, segment.last_stop contains the new position. */
|
/* do the seek, segment.position contains the new position. */
|
||||||
res = gst_base_sink_default_do_seek (sink, &seeksegment);
|
res = gst_base_sink_default_do_seek (sink, &seeksegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3863,9 +3812,9 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
gst_base_sink_flush_stop (sink, pad);
|
gst_base_sink_flush_stop (sink, pad);
|
||||||
} else if (res && sink->running) {
|
} else if (res && sink->running) {
|
||||||
/* we are running the current segment and doing a non-flushing seek,
|
/* we are running the current segment and doing a non-flushing seek,
|
||||||
* close the segment first based on the last_stop. */
|
* close the segment first based on the position. */
|
||||||
GST_DEBUG_OBJECT (sink, "closing running segment %" G_GINT64_FORMAT
|
GST_DEBUG_OBJECT (sink, "closing running segment %" G_GINT64_FORMAT
|
||||||
" to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.last_stop);
|
" to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The subclass must have converted the segment to the processing format
|
/* The subclass must have converted the segment to the processing format
|
||||||
|
@ -3879,12 +3828,12 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
/* if successfull seek, we update our real segment and push
|
/* if successfull seek, we update our real segment and push
|
||||||
* out the new segment. */
|
* out the new segment. */
|
||||||
if (res) {
|
if (res) {
|
||||||
memcpy (&sink->segment, &seeksegment, sizeof (GstSegment));
|
gst_segment_copy_into (&seeksegment, &sink->segment);
|
||||||
|
|
||||||
if (sink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
if (sink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
||||||
gst_element_post_message (GST_ELEMENT (sink),
|
gst_element_post_message (GST_ELEMENT (sink),
|
||||||
gst_message_new_segment_start (GST_OBJECT (sink),
|
gst_message_new_segment_start (GST_OBJECT (sink),
|
||||||
sink->segment.format, sink->segment.last_stop));
|
sink->segment.format, sink->segment.position));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4016,7 +3965,7 @@ gst_base_sink_loop (GstPad * pad)
|
||||||
if ((blocksize = basesink->priv->blocksize) == 0)
|
if ((blocksize = basesink->priv->blocksize) == 0)
|
||||||
blocksize = -1;
|
blocksize = -1;
|
||||||
|
|
||||||
offset = basesink->segment.last_stop;
|
offset = basesink->segment.position;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
|
GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
|
||||||
offset, blocksize);
|
offset, blocksize);
|
||||||
|
@ -4030,7 +3979,7 @@ gst_base_sink_loop (GstPad * pad)
|
||||||
|
|
||||||
offset += gst_buffer_get_size (buf);
|
offset += gst_buffer_get_size (buf);
|
||||||
|
|
||||||
gst_segment_set_last_stop (&basesink->segment, GST_FORMAT_BYTES, offset);
|
basesink->segment.position = offset;
|
||||||
|
|
||||||
GST_BASE_SINK_PREROLL_LOCK (basesink);
|
GST_BASE_SINK_PREROLL_LOCK (basesink);
|
||||||
result = gst_base_sink_chain_unlocked (basesink, pad, _PR_IS_BUFFER, buf);
|
result = gst_base_sink_chain_unlocked (basesink, pad, _PR_IS_BUFFER, buf);
|
||||||
|
@ -4051,7 +4000,7 @@ paused:
|
||||||
if (basesink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
if (basesink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (basesink),
|
gst_element_post_message (GST_ELEMENT_CAST (basesink),
|
||||||
gst_message_new_segment_done (GST_OBJECT_CAST (basesink),
|
gst_message_new_segment_done (GST_OBJECT_CAST (basesink),
|
||||||
basesink->segment.format, basesink->segment.last_stop));
|
basesink->segment.format, basesink->segment.position));
|
||||||
} else {
|
} else {
|
||||||
gst_base_sink_event (pad, gst_event_new_eos ());
|
gst_base_sink_event (pad, gst_event_new_eos ());
|
||||||
}
|
}
|
||||||
|
@ -4335,8 +4284,8 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
|
||||||
if (result) {
|
if (result) {
|
||||||
GST_DEBUG_OBJECT (basesink,
|
GST_DEBUG_OBJECT (basesink,
|
||||||
"setting duration in bytes to %" G_GINT64_FORMAT, duration);
|
"setting duration in bytes to %" G_GINT64_FORMAT, duration);
|
||||||
gst_segment_set_duration (basesink->clip_segment, format, duration);
|
basesink->clip_segment->duration = duration;
|
||||||
gst_segment_set_duration (&basesink->segment, format, duration);
|
basesink->segment.duration = duration;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (basesink, "unknown duration");
|
GST_DEBUG_OBJECT (basesink, "unknown duration");
|
||||||
}
|
}
|
||||||
|
@ -4455,8 +4404,8 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
|
||||||
GstFormat oformat, tformat;
|
GstFormat oformat, tformat;
|
||||||
GstSegment *segment;
|
GstSegment *segment;
|
||||||
GstClockTime now, latency;
|
GstClockTime now, latency;
|
||||||
GstClockTimeDiff base;
|
GstClockTimeDiff base_time;
|
||||||
gint64 time, accum, duration;
|
gint64 time, base, duration;
|
||||||
gdouble rate;
|
gdouble rate;
|
||||||
gint64 last;
|
gint64 last;
|
||||||
gboolean last_seen, with_clock, in_paused;
|
gboolean last_seen, with_clock, in_paused;
|
||||||
|
@ -4513,7 +4462,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
|
||||||
else
|
else
|
||||||
duration = 0;
|
duration = 0;
|
||||||
|
|
||||||
accum = segment->accum;
|
base = segment->base;
|
||||||
rate = segment->rate * segment->applied_rate;
|
rate = segment->rate * segment->applied_rate;
|
||||||
latency = basesink->priv->latency;
|
latency = basesink->priv->latency;
|
||||||
|
|
||||||
|
@ -4538,28 +4487,28 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* convert last stop to stream time */
|
/* convert last stop to stream time */
|
||||||
last = gst_segment_to_stream_time (segment, oformat, segment->last_stop);
|
last = gst_segment_to_stream_time (segment, oformat, segment->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_paused) {
|
if (in_paused) {
|
||||||
/* in paused, use start_time */
|
/* in paused, use start_time */
|
||||||
base = GST_ELEMENT_START_TIME (basesink);
|
base_time = GST_ELEMENT_START_TIME (basesink);
|
||||||
GST_DEBUG_OBJECT (basesink, "in paused, using start time %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (basesink, "in paused, using start time %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (base));
|
GST_TIME_ARGS (base_time));
|
||||||
} else if (with_clock) {
|
} else if (with_clock) {
|
||||||
/* else use clock when needed */
|
/* else use clock when needed */
|
||||||
base = GST_ELEMENT_CAST (basesink)->base_time;
|
base_time = GST_ELEMENT_CAST (basesink)->base_time;
|
||||||
GST_DEBUG_OBJECT (basesink, "using clock and base time %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (basesink, "using clock and base time %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (base));
|
GST_TIME_ARGS (base_time));
|
||||||
} else {
|
} else {
|
||||||
/* else, no sync or clock -> no base time */
|
/* else, no sync or clock -> no base time */
|
||||||
GST_DEBUG_OBJECT (basesink, "no sync or no clock");
|
GST_DEBUG_OBJECT (basesink, "no sync or no clock");
|
||||||
base = -1;
|
base_time = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no base, we can't calculate running_time, use last seem timestamp to report
|
/* no base_time, we can't calculate running_time, use last seem timestamp to report
|
||||||
* time */
|
* time */
|
||||||
if (base == -1)
|
if (base_time == -1)
|
||||||
last_seen = TRUE;
|
last_seen = TRUE;
|
||||||
|
|
||||||
/* need to release the object lock before we can get the time,
|
/* need to release the object lock before we can get the time,
|
||||||
|
@ -4582,9 +4531,9 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
|
||||||
*cur = last;
|
*cur = last;
|
||||||
} else {
|
} else {
|
||||||
if (oformat != tformat) {
|
if (oformat != tformat) {
|
||||||
/* convert accum, time and duration to time */
|
/* convert base, time and duration to time */
|
||||||
if (!gst_pad_query_convert (basesink->sinkpad, oformat, accum, &tformat,
|
if (!gst_pad_query_convert (basesink->sinkpad, oformat, base, &tformat,
|
||||||
&accum))
|
&base))
|
||||||
goto convert_failed;
|
goto convert_failed;
|
||||||
if (!gst_pad_query_convert (basesink->sinkpad, oformat, duration,
|
if (!gst_pad_query_convert (basesink->sinkpad, oformat, duration,
|
||||||
&tformat, &duration))
|
&tformat, &duration))
|
||||||
|
@ -4603,25 +4552,25 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
|
||||||
if (!in_paused && with_clock) {
|
if (!in_paused && with_clock) {
|
||||||
now = gst_clock_get_time (clock);
|
now = gst_clock_get_time (clock);
|
||||||
} else {
|
} else {
|
||||||
now = base;
|
now = base_time;
|
||||||
base = 0;
|
base_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subtract base time and accumulated time from the clock time.
|
/* subtract base time and base time from the clock time.
|
||||||
* Make sure we don't go negative. This is the current time in
|
* Make sure we don't go negative. This is the current time in
|
||||||
* the segment which we need to scale with the combined
|
* the segment which we need to scale with the combined
|
||||||
* rate and applied rate. */
|
* rate and applied rate. */
|
||||||
base += accum;
|
base_time += base;
|
||||||
base += latency;
|
base_time += latency;
|
||||||
if (GST_CLOCK_DIFF (base, now) < 0)
|
if (GST_CLOCK_DIFF (base_time, now) < 0)
|
||||||
base = now;
|
base_time = now;
|
||||||
|
|
||||||
/* for negative rates we need to count back from the segment
|
/* for negative rates we need to count back from the segment
|
||||||
* duration. */
|
* duration. */
|
||||||
if (rate < 0.0)
|
if (rate < 0.0)
|
||||||
time += duration;
|
time += duration;
|
||||||
|
|
||||||
*cur = time + gst_guint64_to_gdouble (now - base) * rate;
|
*cur = time + gst_guint64_to_gdouble (now - base_time) * rate;
|
||||||
|
|
||||||
if (in_paused) {
|
if (in_paused) {
|
||||||
/* never report less than segment values in paused */
|
/* never report less than segment values in paused */
|
||||||
|
@ -4634,9 +4583,9 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesink,
|
GST_DEBUG_OBJECT (basesink,
|
||||||
"now %" GST_TIME_FORMAT " - base %" GST_TIME_FORMAT " - accum %"
|
"now %" GST_TIME_FORMAT " - base_time %" GST_TIME_FORMAT " - base %"
|
||||||
GST_TIME_FORMAT " + time %" GST_TIME_FORMAT " last %" GST_TIME_FORMAT,
|
GST_TIME_FORMAT " + time %" GST_TIME_FORMAT " last %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (now), GST_TIME_ARGS (base), GST_TIME_ARGS (accum),
|
GST_TIME_ARGS (now), GST_TIME_ARGS (base_time), GST_TIME_ARGS (base),
|
||||||
GST_TIME_ARGS (time), GST_TIME_ARGS (last));
|
GST_TIME_ARGS (time), GST_TIME_ARGS (last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4692,7 +4641,7 @@ gst_base_sink_get_duration (GstBaseSink * basesink, GstFormat format,
|
||||||
* should be done at a higher level. */
|
* should be done at a higher level. */
|
||||||
res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat, &uduration);
|
res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat, &uduration);
|
||||||
if (res) {
|
if (res) {
|
||||||
gst_segment_set_duration (&basesink->segment, uformat, uduration);
|
basesink->segment.duration = uduration;
|
||||||
if (format != uformat) {
|
if (format != uformat) {
|
||||||
/* convert to the requested format */
|
/* convert to the requested format */
|
||||||
res = gst_pad_query_convert (basesink->sinkpad, uformat, uduration,
|
res = gst_pad_query_convert (basesink->sinkpad, uformat, uduration,
|
||||||
|
|
|
@ -217,10 +217,8 @@ struct _GstBaseSrcPrivate
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
gboolean flushing;
|
gboolean flushing;
|
||||||
|
|
||||||
/* two segments to be sent in the streaming thread with STREAM_LOCK */
|
/* if segment should be sent */
|
||||||
GstEvent *close_segment;
|
gboolean segment_pending;
|
||||||
GstEvent *start_segment;
|
|
||||||
gboolean newsegment_pending;
|
|
||||||
|
|
||||||
/* if EOS is pending (atomic) */
|
/* if EOS is pending (atomic) */
|
||||||
gint pending_eos;
|
gint pending_eos;
|
||||||
|
@ -754,33 +752,15 @@ gst_base_src_new_seamless_segment (GstBaseSrc * src, gint64 start, gint64 stop,
|
||||||
GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
|
GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
|
||||||
|
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
if (src->running && !src->priv->newsegment_pending) {
|
|
||||||
if (src->priv->close_segment)
|
|
||||||
gst_event_unref (src->priv->close_segment);
|
|
||||||
src->priv->close_segment =
|
|
||||||
gst_event_new_new_segment (TRUE,
|
|
||||||
src->segment.rate, src->segment.applied_rate, src->segment.format,
|
|
||||||
src->segment.start, src->segment.last_stop, src->segment.time);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_segment_set_newsegment (&src->segment, FALSE, src->segment.rate,
|
src->segment.base = gst_segment_to_running_time (&src->segment,
|
||||||
src->segment.applied_rate, src->segment.format, start, stop, position);
|
src->segment.format, src->segment.position);
|
||||||
|
src->segment.start = start;
|
||||||
|
src->segment.stop = stop;
|
||||||
|
src->segment.position = position;
|
||||||
|
|
||||||
if (src->priv->start_segment)
|
/* forward, we send data from position to stop */
|
||||||
gst_event_unref (src->priv->start_segment);
|
src->priv->segment_pending = TRUE;
|
||||||
if (src->segment.rate >= 0.0) {
|
|
||||||
/* forward, we send data from last_stop to stop */
|
|
||||||
src->priv->start_segment =
|
|
||||||
gst_event_new_new_segment (FALSE,
|
|
||||||
src->segment.rate, src->segment.applied_rate, src->segment.format,
|
|
||||||
src->segment.last_stop, stop, src->segment.time);
|
|
||||||
} else {
|
|
||||||
/* reverse, we send data from last_stop to start */
|
|
||||||
src->priv->start_segment =
|
|
||||||
gst_event_new_new_segment (FALSE,
|
|
||||||
src->segment.rate, src->segment.applied_rate, src->segment.format,
|
|
||||||
src->segment.start, src->segment.last_stop, src->segment.time);
|
|
||||||
}
|
|
||||||
GST_OBJECT_UNLOCK (src);
|
GST_OBJECT_UNLOCK (src);
|
||||||
|
|
||||||
src->priv->discont = TRUE;
|
src->priv->discont = TRUE;
|
||||||
|
@ -867,7 +847,7 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery ** query)
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
position = src->segment.last_stop;
|
position = src->segment.position;
|
||||||
duration = src->segment.duration;
|
duration = src->segment.duration;
|
||||||
GST_OBJECT_UNLOCK (src);
|
GST_OBJECT_UNLOCK (src);
|
||||||
|
|
||||||
|
@ -892,7 +872,7 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery ** query)
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
position =
|
position =
|
||||||
gst_segment_to_stream_time (&src->segment, src->segment.format,
|
gst_segment_to_stream_time (&src->segment, src->segment.format,
|
||||||
src->segment.last_stop);
|
src->segment.position);
|
||||||
seg_format = src->segment.format;
|
seg_format = src->segment.format;
|
||||||
GST_OBJECT_UNLOCK (src);
|
GST_OBJECT_UNLOCK (src);
|
||||||
|
|
||||||
|
@ -1184,7 +1164,7 @@ gst_base_src_default_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
|
||||||
dest_format = segment->format;
|
dest_format = segment->format;
|
||||||
|
|
||||||
if (seek_format == dest_format) {
|
if (seek_format == dest_format) {
|
||||||
gst_segment_set_seek (segment, rate, seek_format, flags,
|
gst_segment_do_seek (segment, rate, seek_format, flags,
|
||||||
cur_type, cur, stop_type, stop, &update);
|
cur_type, cur, stop_type, stop, &update);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1206,7 +1186,7 @@ gst_base_src_default_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And finally, configure our output segment in the desired format */
|
/* And finally, configure our output segment in the desired format */
|
||||||
gst_segment_set_seek (segment, rate, dest_format, flags, cur_type, cur,
|
gst_segment_do_seek (segment, rate, dest_format, flags, cur_type, cur,
|
||||||
stop_type, stop, &update);
|
stop_type, stop, &update);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -1387,7 +1367,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
|
||||||
} else {
|
} else {
|
||||||
/* The seek format matches our processing format, no need to ask the
|
/* The seek format matches our processing format, no need to ask the
|
||||||
* the subclass to configure the segment. */
|
* the subclass to configure the segment. */
|
||||||
gst_segment_set_seek (&seeksegment, rate, seek_format, flags,
|
gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
|
||||||
cur_type, cur, stop_type, stop, &update);
|
cur_type, cur, stop_type, stop, &update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1398,9 +1378,9 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
|
||||||
if (res) {
|
if (res) {
|
||||||
GST_DEBUG_OBJECT (src, "segment configured from %" G_GINT64_FORMAT
|
GST_DEBUG_OBJECT (src, "segment configured from %" G_GINT64_FORMAT
|
||||||
" to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
" to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
||||||
seeksegment.start, seeksegment.stop, seeksegment.last_stop);
|
seeksegment.start, seeksegment.stop, seeksegment.position);
|
||||||
|
|
||||||
/* do the seek, segment.last_stop contains the new position. */
|
/* do the seek, segment.position contains the new position. */
|
||||||
res = gst_base_src_do_seek (src, &seeksegment);
|
res = gst_base_src_do_seek (src, &seeksegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1411,20 +1391,6 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
|
||||||
/* send flush stop, peer will accept data and events again. We
|
/* send flush stop, peer will accept data and events again. We
|
||||||
* are not yet providing data as we still have the STREAM_LOCK. */
|
* are not yet providing data as we still have the STREAM_LOCK. */
|
||||||
gst_pad_push_event (src->srcpad, tevent);
|
gst_pad_push_event (src->srcpad, tevent);
|
||||||
} else if (res && src->running) {
|
|
||||||
/* we are running the current segment and doing a non-flushing seek,
|
|
||||||
* close the segment first based on the last_stop. */
|
|
||||||
GST_DEBUG_OBJECT (src, "closing running segment %" G_GINT64_FORMAT
|
|
||||||
" to %" G_GINT64_FORMAT, src->segment.start, src->segment.last_stop);
|
|
||||||
|
|
||||||
/* queue the segment for sending in the stream thread */
|
|
||||||
if (src->priv->close_segment)
|
|
||||||
gst_event_unref (src->priv->close_segment);
|
|
||||||
src->priv->close_segment =
|
|
||||||
gst_event_new_new_segment (TRUE,
|
|
||||||
src->segment.rate, src->segment.applied_rate, src->segment.format,
|
|
||||||
src->segment.start, src->segment.last_stop, src->segment.time);
|
|
||||||
gst_event_set_seqnum (src->priv->close_segment, seqnum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The subclass must have converted the segment to the processing format
|
/* The subclass must have converted the segment to the processing format
|
||||||
|
@ -1446,7 +1412,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
|
||||||
GstMessage *message;
|
GstMessage *message;
|
||||||
|
|
||||||
message = gst_message_new_segment_start (GST_OBJECT (src),
|
message = gst_message_new_segment_start (GST_OBJECT (src),
|
||||||
seeksegment.format, seeksegment.last_stop);
|
seeksegment.format, seeksegment.position);
|
||||||
gst_message_set_seqnum (message, seqnum);
|
gst_message_set_seqnum (message, seqnum);
|
||||||
|
|
||||||
gst_element_post_message (GST_ELEMENT (src), message);
|
gst_element_post_message (GST_ELEMENT (src), message);
|
||||||
|
@ -1457,28 +1423,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
|
||||||
if ((stop = seeksegment.stop) == -1)
|
if ((stop = seeksegment.stop) == -1)
|
||||||
stop = seeksegment.duration;
|
stop = seeksegment.duration;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
|
src->priv->segment_pending = TRUE;
|
||||||
" to %" G_GINT64_FORMAT, seeksegment.start, stop);
|
|
||||||
|
|
||||||
/* now replace the old segment so that we send it in the stream thread the
|
|
||||||
* next time it is scheduled. */
|
|
||||||
if (src->priv->start_segment)
|
|
||||||
gst_event_unref (src->priv->start_segment);
|
|
||||||
if (seeksegment.rate >= 0.0) {
|
|
||||||
/* forward, we send data from last_stop to stop */
|
|
||||||
src->priv->start_segment =
|
|
||||||
gst_event_new_new_segment (FALSE,
|
|
||||||
seeksegment.rate, seeksegment.applied_rate, seeksegment.format,
|
|
||||||
seeksegment.last_stop, stop, seeksegment.time);
|
|
||||||
} else {
|
|
||||||
/* reverse, we send data from last_stop to start */
|
|
||||||
src->priv->start_segment =
|
|
||||||
gst_event_new_new_segment (FALSE,
|
|
||||||
seeksegment.rate, seeksegment.applied_rate, seeksegment.format,
|
|
||||||
seeksegment.start, seeksegment.last_stop, seeksegment.time);
|
|
||||||
}
|
|
||||||
gst_event_set_seqnum (src->priv->start_segment, seqnum);
|
|
||||||
src->priv->newsegment_pending = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
src->priv->discont = TRUE;
|
src->priv->discont = TRUE;
|
||||||
|
@ -1584,8 +1529,8 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
/* sending random NEWSEGMENT downstream can break sync. */
|
/* sending random SEGMENT downstream can break sync. */
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_TAG:
|
case GST_EVENT_TAG:
|
||||||
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
||||||
|
@ -2081,8 +2026,8 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
|
||||||
/* keep track of current position and update duration.
|
/* keep track of current position and update duration.
|
||||||
* segment is in bytes, we checked that above. */
|
* segment is in bytes, we checked that above. */
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
gst_segment_set_duration (&src->segment, GST_FORMAT_BYTES, size);
|
src->segment.duration = size;
|
||||||
gst_segment_set_last_stop (&src->segment, GST_FORMAT_BYTES, offset);
|
src->segment.position = offset;
|
||||||
GST_OBJECT_UNLOCK (src);
|
GST_OBJECT_UNLOCK (src);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -2384,7 +2329,7 @@ gst_base_src_loop (GstPad * pad)
|
||||||
|
|
||||||
/* if we operate in bytes, we can calculate an offset */
|
/* if we operate in bytes, we can calculate an offset */
|
||||||
if (src->segment.format == GST_FORMAT_BYTES) {
|
if (src->segment.format == GST_FORMAT_BYTES) {
|
||||||
position = src->segment.last_stop;
|
position = src->segment.position;
|
||||||
/* for negative rates, start with subtracting the blocksize */
|
/* for negative rates, start with subtracting the blocksize */
|
||||||
if (src->segment.rate < 0.0) {
|
if (src->segment.rate < 0.0) {
|
||||||
/* we cannot go below segment.start */
|
/* we cannot go below segment.start */
|
||||||
|
@ -2414,15 +2359,10 @@ gst_base_src_loop (GstPad * pad)
|
||||||
goto null_buffer;
|
goto null_buffer;
|
||||||
|
|
||||||
/* push events to close/start our segment before we push the buffer. */
|
/* push events to close/start our segment before we push the buffer. */
|
||||||
if (G_UNLIKELY (src->priv->close_segment)) {
|
if (G_UNLIKELY (src->priv->segment_pending)) {
|
||||||
gst_pad_push_event (pad, src->priv->close_segment);
|
gst_pad_push_event (pad, gst_event_new_segment (&src->segment));
|
||||||
src->priv->close_segment = NULL;
|
src->priv->segment_pending = FALSE;
|
||||||
}
|
}
|
||||||
if (G_UNLIKELY (src->priv->start_segment)) {
|
|
||||||
gst_pad_push_event (pad, src->priv->start_segment);
|
|
||||||
src->priv->start_segment = NULL;
|
|
||||||
}
|
|
||||||
src->priv->newsegment_pending = FALSE;
|
|
||||||
|
|
||||||
if (g_atomic_int_get (&src->priv->have_events)) {
|
if (g_atomic_int_get (&src->priv->have_events)) {
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
|
@ -2463,7 +2403,7 @@ gst_base_src_loop (GstPad * pad)
|
||||||
if (GST_CLOCK_TIME_IS_VALID (start))
|
if (GST_CLOCK_TIME_IS_VALID (start))
|
||||||
position = start;
|
position = start;
|
||||||
else
|
else
|
||||||
position = src->segment.last_stop;
|
position = src->segment.position;
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (duration)) {
|
if (GST_CLOCK_TIME_IS_VALID (duration)) {
|
||||||
if (src->segment.rate >= 0.0)
|
if (src->segment.rate >= 0.0)
|
||||||
|
@ -2505,7 +2445,7 @@ gst_base_src_loop (GstPad * pad)
|
||||||
src->priv->discont = TRUE;
|
src->priv->discont = TRUE;
|
||||||
}
|
}
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
gst_segment_set_last_stop (&src->segment, src->segment.format, position);
|
src->segment.position = position;
|
||||||
GST_OBJECT_UNLOCK (src);
|
GST_OBJECT_UNLOCK (src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2551,18 +2491,18 @@ pause:
|
||||||
if (ret == GST_FLOW_UNEXPECTED) {
|
if (ret == GST_FLOW_UNEXPECTED) {
|
||||||
gboolean flag_segment;
|
gboolean flag_segment;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 last_stop;
|
gint64 position;
|
||||||
|
|
||||||
/* perform EOS logic */
|
/* perform EOS logic */
|
||||||
flag_segment = (src->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0;
|
flag_segment = (src->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0;
|
||||||
format = src->segment.format;
|
format = src->segment.format;
|
||||||
last_stop = src->segment.last_stop;
|
position = src->segment.position;
|
||||||
|
|
||||||
if (flag_segment) {
|
if (flag_segment) {
|
||||||
GstMessage *message;
|
GstMessage *message;
|
||||||
|
|
||||||
message = gst_message_new_segment_done (GST_OBJECT_CAST (src),
|
message = gst_message_new_segment_done (GST_OBJECT_CAST (src),
|
||||||
format, last_stop);
|
format, position);
|
||||||
gst_message_set_seqnum (message, src->priv->seqnum);
|
gst_message_set_seqnum (message, src->priv->seqnum);
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (src), message);
|
gst_element_post_message (GST_ELEMENT_CAST (src), message);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2714,7 +2654,7 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
GST_OBJECT_UNLOCK (basesrc);
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
|
|
||||||
basesrc->running = FALSE;
|
basesrc->running = FALSE;
|
||||||
basesrc->priv->newsegment_pending = FALSE;
|
basesrc->priv->segment_pending = FALSE;
|
||||||
|
|
||||||
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
||||||
if (bclass->start)
|
if (bclass->start)
|
||||||
|
@ -2742,7 +2682,7 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
/* only update the size when operating in bytes, subclass is supposed
|
/* only update the size when operating in bytes, subclass is supposed
|
||||||
* to set duration in the start method for other formats */
|
* to set duration in the start method for other formats */
|
||||||
GST_OBJECT_LOCK (basesrc);
|
GST_OBJECT_LOCK (basesrc);
|
||||||
gst_segment_set_duration (&basesrc->segment, GST_FORMAT_BYTES, size);
|
basesrc->segment.duration = size;
|
||||||
GST_OBJECT_UNLOCK (basesrc);
|
GST_OBJECT_UNLOCK (basesrc);
|
||||||
} else {
|
} else {
|
||||||
size = -1;
|
size = -1;
|
||||||
|
@ -3133,10 +3073,6 @@ gst_base_src_change_state (GstElement * element, GstStateChange transition)
|
||||||
g_atomic_int_set (&basesrc->priv->pending_eos, FALSE);
|
g_atomic_int_set (&basesrc->priv->pending_eos, FALSE);
|
||||||
event_p = &basesrc->pending_seek;
|
event_p = &basesrc->pending_seek;
|
||||||
gst_event_replace (event_p, NULL);
|
gst_event_replace (event_p, NULL);
|
||||||
event_p = &basesrc->priv->close_segment;
|
|
||||||
gst_event_replace (event_p, NULL);
|
|
||||||
event_p = &basesrc->priv->start_segment;
|
|
||||||
gst_event_replace (event_p, NULL);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
|
|
|
@ -250,7 +250,7 @@ struct _GstBaseTransformPrivate
|
||||||
guint64 processed;
|
guint64 processed;
|
||||||
guint64 dropped;
|
guint64 dropped;
|
||||||
|
|
||||||
GstClockTime last_stop_out;
|
GstClockTime position_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
@ -1163,13 +1163,13 @@ gst_base_transform_query (GstPad * pad, GstQuery ** query)
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
if ((pad == trans->sinkpad)
|
if ((pad == trans->sinkpad)
|
||||||
|| (trans->priv->last_stop_out == GST_CLOCK_TIME_NONE)) {
|
|| (trans->priv->position_out == GST_CLOCK_TIME_NONE)) {
|
||||||
pos =
|
pos =
|
||||||
gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
|
gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
|
||||||
trans->segment.last_stop);
|
trans->segment.position);
|
||||||
} else {
|
} else {
|
||||||
pos = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
|
pos = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
|
||||||
trans->priv->last_stop_out);
|
trans->priv->position_out);
|
||||||
}
|
}
|
||||||
gst_query_set_position (*query, format, pos);
|
gst_query_set_position (*query, format, pos);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1515,9 +1515,9 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
|
||||||
trans->priv->dropped = 0;
|
trans->priv->dropped = 0;
|
||||||
GST_OBJECT_UNLOCK (trans);
|
GST_OBJECT_UNLOCK (trans);
|
||||||
/* we need new segment info after the flush. */
|
/* we need new segment info after the flush. */
|
||||||
trans->have_newsegment = FALSE;
|
trans->have_segment = FALSE;
|
||||||
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
|
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
|
||||||
trans->priv->last_stop_out = GST_CLOCK_TIME_NONE;
|
trans->priv->position_out = GST_CLOCK_TIME_NONE;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
break;
|
break;
|
||||||
|
@ -1533,36 +1533,13 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
|
||||||
forward = FALSE;
|
forward = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
GstFormat format;
|
gst_event_parse_segment (event, &trans->segment);
|
||||||
gdouble rate, arate;
|
trans->have_segment = TRUE;
|
||||||
gint64 start, stop, time;
|
|
||||||
gboolean update;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate, &format,
|
GST_DEBUG_OBJECT (trans, "received SEGMENT %" GST_SEGMENT_FORMAT,
|
||||||
&start, &stop, &time);
|
&trans->segment);
|
||||||
|
|
||||||
trans->have_newsegment = TRUE;
|
|
||||||
|
|
||||||
gst_segment_set_newsegment (&trans->segment, update, rate, arate,
|
|
||||||
format, start, stop, time);
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_TIME) {
|
|
||||||
GST_DEBUG_OBJECT (trans, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
|
|
||||||
" -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
|
|
||||||
", accum %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (trans->segment.start),
|
|
||||||
GST_TIME_ARGS (trans->segment.stop),
|
|
||||||
GST_TIME_ARGS (trans->segment.time),
|
|
||||||
GST_TIME_ARGS (trans->segment.accum));
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (trans, "received NEW_SEGMENT %" G_GINT64_FORMAT
|
|
||||||
" -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
|
|
||||||
", accum %" G_GINT64_FORMAT,
|
|
||||||
trans->segment.start, trans->segment.stop,
|
|
||||||
trans->segment.time, trans->segment.accum);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -1896,7 +1873,7 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GstBaseTransform *trans;
|
GstBaseTransform *trans;
|
||||||
GstBaseTransformClass *klass;
|
GstBaseTransformClass *klass;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstClockTime last_stop = GST_CLOCK_TIME_NONE;
|
GstClockTime position = GST_CLOCK_TIME_NONE;
|
||||||
GstClockTime timestamp, duration;
|
GstClockTime timestamp, duration;
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
|
|
||||||
|
@ -1908,9 +1885,9 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
/* calculate end position of the incoming buffer */
|
/* calculate end position of the incoming buffer */
|
||||||
if (timestamp != GST_CLOCK_TIME_NONE) {
|
if (timestamp != GST_CLOCK_TIME_NONE) {
|
||||||
if (duration != GST_CLOCK_TIME_NONE)
|
if (duration != GST_CLOCK_TIME_NONE)
|
||||||
last_stop = timestamp + duration;
|
position = timestamp + duration;
|
||||||
else
|
else
|
||||||
last_stop = timestamp;
|
position = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
||||||
|
@ -1926,23 +1903,23 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
* GST_BASE_TRANSFORM_FLOW_DROPPED we will not push either. */
|
* GST_BASE_TRANSFORM_FLOW_DROPPED we will not push either. */
|
||||||
if (outbuf != NULL) {
|
if (outbuf != NULL) {
|
||||||
if ((ret == GST_FLOW_OK)) {
|
if ((ret == GST_FLOW_OK)) {
|
||||||
GstClockTime last_stop_out = GST_CLOCK_TIME_NONE;
|
GstClockTime position_out = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
/* Remember last stop position */
|
/* Remember last stop position */
|
||||||
if (last_stop != GST_CLOCK_TIME_NONE &&
|
if (position != GST_CLOCK_TIME_NONE &&
|
||||||
trans->segment.format == GST_FORMAT_TIME)
|
trans->segment.format == GST_FORMAT_TIME)
|
||||||
gst_segment_set_last_stop (&trans->segment, GST_FORMAT_TIME, last_stop);
|
trans->segment.position = position;
|
||||||
|
|
||||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) {
|
if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) {
|
||||||
last_stop_out = GST_BUFFER_TIMESTAMP (outbuf);
|
position_out = GST_BUFFER_TIMESTAMP (outbuf);
|
||||||
if (GST_BUFFER_DURATION_IS_VALID (outbuf))
|
if (GST_BUFFER_DURATION_IS_VALID (outbuf))
|
||||||
last_stop_out += GST_BUFFER_DURATION (outbuf);
|
position_out += GST_BUFFER_DURATION (outbuf);
|
||||||
} else if (last_stop != GST_CLOCK_TIME_NONE) {
|
} else if (position != GST_CLOCK_TIME_NONE) {
|
||||||
last_stop_out = last_stop;
|
position_out = position;
|
||||||
}
|
}
|
||||||
if (last_stop_out != GST_CLOCK_TIME_NONE
|
if (position_out != GST_CLOCK_TIME_NONE
|
||||||
&& trans->segment.format == GST_FORMAT_TIME)
|
&& trans->segment.format == GST_FORMAT_TIME)
|
||||||
trans->priv->last_stop_out = last_stop_out;
|
trans->priv->position_out = position_out;
|
||||||
|
|
||||||
/* apply DISCONT flag if the buffer is not yet marked as such */
|
/* apply DISCONT flag if the buffer is not yet marked as such */
|
||||||
if (trans->priv->discont) {
|
if (trans->priv->discont) {
|
||||||
|
@ -2030,9 +2007,9 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
|
||||||
trans->have_same_caps = trans->passthrough;
|
trans->have_same_caps = trans->passthrough;
|
||||||
GST_DEBUG_OBJECT (trans, "have_same_caps %d", trans->have_same_caps);
|
GST_DEBUG_OBJECT (trans, "have_same_caps %d", trans->have_same_caps);
|
||||||
trans->negotiated = FALSE;
|
trans->negotiated = FALSE;
|
||||||
trans->have_newsegment = FALSE;
|
trans->have_segment = FALSE;
|
||||||
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
|
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
|
||||||
trans->priv->last_stop_out = GST_CLOCK_TIME_NONE;
|
trans->priv->position_out = GST_CLOCK_TIME_NONE;
|
||||||
trans->priv->proportion = 1.0;
|
trans->priv->proportion = 1.0;
|
||||||
trans->priv->earliest_time = -1;
|
trans->priv->earliest_time = -1;
|
||||||
trans->priv->discont = FALSE;
|
trans->priv->discont = FALSE;
|
||||||
|
|
|
@ -128,7 +128,7 @@ struct _GstBaseTransform {
|
||||||
gboolean pending_configure;
|
gboolean pending_configure;
|
||||||
gboolean negotiated;
|
gboolean negotiated;
|
||||||
|
|
||||||
gboolean have_newsegment;
|
gboolean have_segment;
|
||||||
|
|
||||||
/* MT-protected (with STREAM_LOCK) */
|
/* MT-protected (with STREAM_LOCK) */
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
|
|
|
@ -1198,23 +1198,12 @@ gst_collect_pads_event (GstPad * pad, GstEvent * event)
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gint64 start, stop, time;
|
gst_event_parse_segment (event, &data->segment);
|
||||||
gdouble rate, arate;
|
|
||||||
GstFormat format;
|
|
||||||
gboolean update;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate, &format,
|
|
||||||
&start, &stop, &time);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (data->pad, "got newsegment, start %" GST_TIME_FORMAT
|
|
||||||
", stop %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
|
|
||||||
GST_TIME_ARGS (stop));
|
|
||||||
|
|
||||||
gst_segment_set_newsegment (&data->segment, update, rate, arate,
|
|
||||||
format, start, stop, time);
|
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (data->pad, "got newsegment %" GST_SEGMENT_FORMAT,
|
||||||
|
&data->segment);
|
||||||
data->abidata.ABI.new_segment = TRUE;
|
data->abidata.ABI.new_segment = TRUE;
|
||||||
|
|
||||||
/* we must not forward this event since multiple segments will be
|
/* we must not forward this event since multiple segments will be
|
||||||
|
@ -1317,7 +1306,7 @@ gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GstClockTime timestamp = GST_BUFFER_TIMESTAMP (data->buffer);
|
GstClockTime timestamp = GST_BUFFER_TIMESTAMP (data->buffer);
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (timestamp))
|
if (GST_CLOCK_TIME_IS_VALID (timestamp))
|
||||||
gst_segment_set_last_stop (&data->segment, GST_FORMAT_TIME, timestamp);
|
data->segment.position = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* While we have data queued on this pad try to collect stuff */
|
/* While we have data queued on this pad try to collect stuff */
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
struct _GstStreamConsistency
|
struct _GstStreamConsistency
|
||||||
{
|
{
|
||||||
gboolean flushing;
|
gboolean flushing;
|
||||||
gboolean newsegment;
|
gboolean segment;
|
||||||
gboolean eos;
|
gboolean eos;
|
||||||
gulong probeid;
|
gulong probeid;
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
|
@ -50,8 +50,8 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (GST_BUFFER (data))));
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (GST_BUFFER (data))));
|
||||||
/* If an EOS went through, a buffer would be invalid */
|
/* If an EOS went through, a buffer would be invalid */
|
||||||
fail_if (consist->eos, "Buffer received after EOS");
|
fail_if (consist->eos, "Buffer received after EOS");
|
||||||
/* Buffers need to be preceded by a newsegment event */
|
/* Buffers need to be preceded by a segment event */
|
||||||
fail_unless (consist->newsegment, "Buffer received without newsegment");
|
fail_unless (consist->segment, "Buffer received without segment");
|
||||||
} else if (GST_IS_EVENT (data)) {
|
} else if (GST_IS_EVENT (data)) {
|
||||||
GstEvent *event = (GstEvent *) data;
|
GstEvent *event = (GstEvent *) data;
|
||||||
|
|
||||||
|
@ -67,15 +67,15 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
|
||||||
fail_if (consist->eos, "Received a FLUSH_STOP after an EOS");
|
fail_if (consist->eos, "Received a FLUSH_STOP after an EOS");
|
||||||
consist->flushing = FALSE;
|
consist->flushing = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
consist->newsegment = TRUE;
|
consist->segment = TRUE;
|
||||||
consist->eos = FALSE;
|
consist->eos = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
/* FIXME : not 100% sure about whether two eos in a row is valid */
|
/* FIXME : not 100% sure about whether two eos in a row is valid */
|
||||||
fail_if (consist->eos, "Received EOS just after another EOS");
|
fail_if (consist->eos, "Received EOS just after another EOS");
|
||||||
consist->eos = TRUE;
|
consist->eos = TRUE;
|
||||||
consist->newsegment = FALSE;
|
consist->segment = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_TAG:
|
case GST_EVENT_TAG:
|
||||||
GST_DEBUG_OBJECT (pad, "tag %" GST_PTR_FORMAT,
|
GST_DEBUG_OBJECT (pad, "tag %" GST_PTR_FORMAT,
|
||||||
|
@ -84,7 +84,7 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
|
||||||
default:
|
default:
|
||||||
if (GST_EVENT_IS_SERIALIZED (event) && GST_EVENT_IS_DOWNSTREAM (event)) {
|
if (GST_EVENT_IS_SERIALIZED (event) && GST_EVENT_IS_DOWNSTREAM (event)) {
|
||||||
fail_if (consist->eos, "Event received after EOS");
|
fail_if (consist->eos, "Event received after EOS");
|
||||||
fail_unless (consist->newsegment, "Event received before newsegment");
|
fail_unless (consist->segment, "Event received before segment");
|
||||||
}
|
}
|
||||||
/* FIXME : Figure out what to do for other events */
|
/* FIXME : Figure out what to do for other events */
|
||||||
break;
|
break;
|
||||||
|
@ -137,7 +137,7 @@ gst_consistency_checker_reset (GstStreamConsistency * consist)
|
||||||
{
|
{
|
||||||
consist->eos = FALSE;
|
consist->eos = FALSE;
|
||||||
consist->flushing = FALSE;
|
consist->flushing = FALSE;
|
||||||
consist->newsegment = FALSE;
|
consist->segment = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -523,7 +523,7 @@ gst_dp_event_from_packet_0_2 (guint header_length, const guint8 * header,
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
event = gst_event_new_custom (type, NULL);
|
event = gst_event_new_custom (type, NULL);
|
||||||
GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
|
GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -539,28 +539,27 @@ gst_fd_sink_event (GstBaseSink * sink, GstEvent * event)
|
||||||
type = GST_EVENT_TYPE (event);
|
type = GST_EVENT_TYPE (event);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gint64 start, stop, pos;
|
GstSegment segment;
|
||||||
GstFormat format;
|
|
||||||
gst_event_parse_new_segment (event, NULL, NULL, NULL, &format, &start,
|
|
||||||
&stop, &pos);
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_BYTES) {
|
gst_event_parse_segment (event, &segment);
|
||||||
|
|
||||||
|
if (segment.format == GST_FORMAT_BYTES) {
|
||||||
/* only try to seek and fail when we are going to a different
|
/* only try to seek and fail when we are going to a different
|
||||||
* position */
|
* position */
|
||||||
if (fdsink->current_pos != start) {
|
if (fdsink->current_pos != segment.start) {
|
||||||
/* FIXME, the seek should be performed on the pos field, start/stop are
|
/* FIXME, the seek should be performed on the pos field, start/stop are
|
||||||
* just boundaries for valid bytes offsets. We should also fill the file
|
* just boundaries for valid bytes offsets. We should also fill the file
|
||||||
* with zeroes if the new position extends the current EOF (sparse streams
|
* with zeroes if the new position extends the current EOF (sparse streams
|
||||||
* and segment accumulation). */
|
* and segment accumulation). */
|
||||||
if (!gst_fd_sink_do_seek (fdsink, (guint64) start))
|
if (!gst_fd_sink_do_seek (fdsink, (guint64) segment.start))
|
||||||
goto seek_failed;
|
goto seek_failed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (fdsink,
|
GST_DEBUG_OBJECT (fdsink,
|
||||||
"Ignored NEWSEGMENT event of format %u (%s)", (guint) format,
|
"Ignored SEGMENT event of format %u (%s)", (guint) segment.format,
|
||||||
gst_format_get_name (format));
|
gst_format_get_name (segment.format));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -584,7 +584,7 @@ gst_fd_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
|
||||||
if (G_UNLIKELY (res < 0 || res != offset))
|
if (G_UNLIKELY (res < 0 || res != offset))
|
||||||
goto seek_failed;
|
goto seek_failed;
|
||||||
|
|
||||||
segment->last_stop = segment->start;
|
segment->position = segment->start;
|
||||||
segment->time = segment->start;
|
segment->time = segment->start;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -541,31 +541,29 @@ gst_file_sink_event (GstBaseSink * sink, GstEvent * event)
|
||||||
type = GST_EVENT_TYPE (event);
|
type = GST_EVENT_TYPE (event);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gint64 start, stop, pos;
|
GstSegment segment;
|
||||||
GstFormat format;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, NULL, NULL, NULL, &format, &start,
|
gst_event_parse_segment (event, &segment);
|
||||||
&stop, &pos);
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_BYTES) {
|
if (segment.format == GST_FORMAT_BYTES) {
|
||||||
/* only try to seek and fail when we are going to a different
|
/* only try to seek and fail when we are going to a different
|
||||||
* position */
|
* position */
|
||||||
if (filesink->current_pos != start) {
|
if (filesink->current_pos != segment.start) {
|
||||||
/* FIXME, the seek should be performed on the pos field, start/stop are
|
/* FIXME, the seek should be performed on the pos field, start/stop are
|
||||||
* just boundaries for valid bytes offsets. We should also fill the file
|
* just boundaries for valid bytes offsets. We should also fill the file
|
||||||
* with zeroes if the new position extends the current EOF (sparse streams
|
* with zeroes if the new position extends the current EOF (sparse streams
|
||||||
* and segment accumulation). */
|
* and segment accumulation). */
|
||||||
if (!gst_file_sink_do_seek (filesink, (guint64) start))
|
if (!gst_file_sink_do_seek (filesink, (guint64) segment.start))
|
||||||
goto seek_failed;
|
goto seek_failed;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (filesink, "Ignored NEWSEGMENT, no seek needed");
|
GST_DEBUG_OBJECT (filesink, "Ignored SEGMENT, no seek needed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (filesink,
|
GST_DEBUG_OBJECT (filesink,
|
||||||
"Ignored NEWSEGMENT event of format %u (%s)", (guint) format,
|
"Ignored SEGMENT event of format %u (%s)", (guint) segment.format,
|
||||||
gst_format_get_name (format));
|
gst_format_get_name (segment.format));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,13 +247,11 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
if (fpad->segment.format == GST_FORMAT_UNDEFINED) {
|
if (fpad->segment.format == GST_FORMAT_UNDEFINED) {
|
||||||
GST_WARNING_OBJECT (funnel, "Got buffer without segment,"
|
GST_WARNING_OBJECT (funnel, "Got buffer without segment,"
|
||||||
" setting segment [0,inf[");
|
" setting segment [0,inf[");
|
||||||
gst_segment_set_newsegment (&fpad->segment, FALSE, 1.0, 1.0,
|
gst_segment_init (&fpad->segment, GST_FORMAT_TIME);
|
||||||
GST_FORMAT_TIME, 0, -1, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)))
|
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)))
|
||||||
gst_segment_set_last_stop (&fpad->segment, fpad->segment.format,
|
fpad->segment.position = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
GST_BUFFER_TIMESTAMP (buffer));
|
|
||||||
|
|
||||||
newts = gst_segment_to_running_time (&fpad->segment,
|
newts = gst_segment_to_running_time (&fpad->segment,
|
||||||
fpad->segment.format, GST_BUFFER_TIMESTAMP (buffer));
|
fpad->segment.format, GST_BUFFER_TIMESTAMP (buffer));
|
||||||
|
@ -263,8 +261,10 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!funnel->has_segment) {
|
if (!funnel->has_segment) {
|
||||||
event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
|
GstSegment segment;
|
||||||
0, -1, 0);
|
|
||||||
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
funnel->has_segment = TRUE;
|
funnel->has_segment = TRUE;
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (funnel);
|
GST_OBJECT_UNLOCK (funnel);
|
||||||
|
@ -312,34 +312,23 @@ gst_funnel_sink_event (GstPad * pad, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gboolean update;
|
|
||||||
gdouble rate, arate;
|
|
||||||
GstFormat format;
|
|
||||||
gint64 start;
|
|
||||||
gint64 stop;
|
|
||||||
gint64 time;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate,
|
|
||||||
&format, &start, &stop, &time);
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (funnel);
|
GST_OBJECT_LOCK (funnel);
|
||||||
gst_segment_set_newsegment (&fpad->segment, update, rate, arate,
|
gst_event_parse_segment (event, &fpad->segment);
|
||||||
format, start, stop, time);
|
|
||||||
GST_OBJECT_UNLOCK (funnel);
|
GST_OBJECT_UNLOCK (funnel);
|
||||||
|
|
||||||
forward = FALSE;
|
forward = FALSE;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
{
|
{
|
||||||
GST_OBJECT_LOCK (funnel);
|
GST_OBJECT_LOCK (funnel);
|
||||||
gst_segment_init (&fpad->segment, GST_FORMAT_UNDEFINED);
|
gst_segment_init (&fpad->segment, GST_FORMAT_UNDEFINED);
|
||||||
funnel->has_segment = FALSE;
|
funnel->has_segment = FALSE;
|
||||||
GST_OBJECT_UNLOCK (funnel);
|
GST_OBJECT_UNLOCK (funnel);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ gst_identity_class_init (GstIdentityClass * klass)
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (gobject_class, PROP_SINGLE_SEGMENT,
|
g_object_class_install_property (gobject_class, PROP_SINGLE_SEGMENT,
|
||||||
g_param_spec_boolean ("single-segment", "Single Segment",
|
g_param_spec_boolean ("single-segment", "Single Segment",
|
||||||
"Timestamp buffers and eat newsegments so as to appear as one segment",
|
"Timestamp buffers and eat segments so as to appear as one segment",
|
||||||
DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
pspec_last_message = g_param_spec_string ("last-message", "last-message",
|
pspec_last_message = g_param_spec_string ("last-message", "last-message",
|
||||||
"last-message", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
"last-message", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
@ -348,17 +348,16 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
gst_identity_notify_last_message (identity);
|
gst_identity_notify_last_message (identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identity->single_segment
|
if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) {
|
||||||
&& (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
|
if (trans->have_segment == FALSE) {
|
||||||
if (trans->have_newsegment == FALSE) {
|
|
||||||
GstEvent *news;
|
GstEvent *news;
|
||||||
GstFormat format;
|
GstSegment segment;
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, NULL, NULL, NULL, &format, NULL, NULL,
|
gst_event_parse_segment (event, &segment);
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* This is the first newsegment, send out a (0, -1) newsegment */
|
/* This is the first segment, send out a (0, -1) segment */
|
||||||
news = gst_event_new_new_segment (TRUE, 1.0, 1.0, format, 0, -1, 0);
|
gst_segment_init (&segment, segment.format);
|
||||||
|
news = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
gst_pad_event_default (trans->sinkpad, news);
|
gst_pad_event_default (trans->sinkpad, news);
|
||||||
}
|
}
|
||||||
|
@ -366,15 +365,14 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
|
|
||||||
/* Reset previous timestamp, duration and offsets on NEWSEGMENT
|
/* Reset previous timestamp, duration and offsets on NEWSEGMENT
|
||||||
* to prevent false warnings when checking for perfect streams */
|
* to prevent false warnings when checking for perfect streams */
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
|
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||||
identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE;
|
identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE;
|
||||||
identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
|
identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
|
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
|
||||||
|
|
||||||
if (identity->single_segment
|
if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) {
|
||||||
&& (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
|
|
||||||
/* eat up segments */
|
/* eat up segments */
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,11 +292,11 @@ gst_selector_pad_get_running_time (GstSelectorPad * pad)
|
||||||
|
|
||||||
GST_OBJECT_LOCK (pad);
|
GST_OBJECT_LOCK (pad);
|
||||||
if (pad->active) {
|
if (pad->active) {
|
||||||
gint64 last_stop = pad->segment.last_stop;
|
gint64 position = pad->segment.position;
|
||||||
|
|
||||||
if (last_stop >= 0)
|
if (position >= 0)
|
||||||
ret = gst_segment_to_running_time (&pad->segment, GST_FORMAT_TIME,
|
ret = gst_segment_to_running_time (&pad->segment, GST_FORMAT_TIME,
|
||||||
last_stop);
|
position);
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (pad);
|
GST_OBJECT_UNLOCK (pad);
|
||||||
|
|
||||||
|
@ -393,26 +393,13 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
|
||||||
sel->pending_close = FALSE;
|
sel->pending_close = FALSE;
|
||||||
GST_INPUT_SELECTOR_UNLOCK (sel);
|
GST_INPUT_SELECTOR_UNLOCK (sel);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gboolean update;
|
|
||||||
GstFormat format;
|
|
||||||
gdouble rate, arate;
|
|
||||||
gint64 start, stop, time;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate, &format,
|
|
||||||
&start, &stop, &time);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad,
|
|
||||||
"configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
|
||||||
"format %d, "
|
|
||||||
"%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
|
|
||||||
G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
GST_INPUT_SELECTOR_LOCK (sel);
|
GST_INPUT_SELECTOR_LOCK (sel);
|
||||||
GST_OBJECT_LOCK (selpad);
|
GST_OBJECT_LOCK (selpad);
|
||||||
gst_segment_set_newsegment (&selpad->segment, update,
|
gst_event_parse_segment (event, &selpad->segment);
|
||||||
rate, arate, format, start, stop, time);
|
GST_DEBUG_OBJECT (pad, "configured SEGMENT %" GST_SEGMENT_FORMAT,
|
||||||
|
&selpad->segment);
|
||||||
GST_OBJECT_UNLOCK (selpad);
|
GST_OBJECT_UNLOCK (selpad);
|
||||||
|
|
||||||
/* If we aren't forwarding the event because the pad is not the
|
/* If we aren't forwarding the event because the pad is not the
|
||||||
|
@ -543,7 +530,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GstSelectorPad *selpad;
|
GstSelectorPad *selpad;
|
||||||
GstClockTime start_time;
|
GstClockTime start_time;
|
||||||
GstSegment *seg;
|
GstSegment *seg;
|
||||||
GstEvent *close_event = NULL, *start_event = NULL;
|
GstEvent *start_event = NULL;
|
||||||
#if 0
|
#if 0
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
#endif
|
#endif
|
||||||
|
@ -572,7 +559,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf)));
|
GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf)));
|
||||||
|
|
||||||
GST_OBJECT_LOCK (pad);
|
GST_OBJECT_LOCK (pad);
|
||||||
gst_segment_set_last_stop (seg, seg->format, start_time);
|
seg->position = start_time;
|
||||||
GST_OBJECT_UNLOCK (pad);
|
GST_OBJECT_UNLOCK (pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,22 +567,6 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
|
||||||
if (pad != active_sinkpad)
|
if (pad != active_sinkpad)
|
||||||
goto ignore;
|
goto ignore;
|
||||||
|
|
||||||
if (G_UNLIKELY (sel->pending_close)) {
|
|
||||||
GstSegment *cseg = &sel->segment;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (sel,
|
|
||||||
"pushing close NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
|
||||||
"format %d, "
|
|
||||||
"%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
|
|
||||||
G_GINT64_FORMAT, TRUE, cseg->rate, cseg->applied_rate, cseg->format,
|
|
||||||
cseg->start, cseg->stop, cseg->time);
|
|
||||||
|
|
||||||
/* create update segment */
|
|
||||||
close_event = gst_event_new_new_segment (TRUE, cseg->rate,
|
|
||||||
cseg->applied_rate, cseg->format, cseg->start, cseg->stop, cseg->time);
|
|
||||||
|
|
||||||
sel->pending_close = FALSE;
|
|
||||||
}
|
|
||||||
/* if we have a pending segment, push it out now */
|
/* if we have a pending segment, push it out now */
|
||||||
if (G_UNLIKELY (selpad->segment_pending)) {
|
if (G_UNLIKELY (selpad->segment_pending)) {
|
||||||
GST_DEBUG_OBJECT (pad,
|
GST_DEBUG_OBJECT (pad,
|
||||||
|
@ -605,8 +576,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
|
||||||
G_GINT64_FORMAT, FALSE, seg->rate, seg->applied_rate, seg->format,
|
G_GINT64_FORMAT, FALSE, seg->rate, seg->applied_rate, seg->format,
|
||||||
seg->start, seg->stop, seg->time);
|
seg->start, seg->stop, seg->time);
|
||||||
|
|
||||||
start_event = gst_event_new_new_segment (FALSE, seg->rate,
|
start_event = gst_event_new_segment (seg);
|
||||||
seg->applied_rate, seg->format, seg->start, seg->stop, seg->time);
|
|
||||||
|
|
||||||
selpad->segment_pending = FALSE;
|
selpad->segment_pending = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -618,9 +588,6 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
|
||||||
NOTIFY_MUTEX_UNLOCK ();
|
NOTIFY_MUTEX_UNLOCK ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close_event)
|
|
||||||
gst_pad_push_event (sel->srcpad, close_event);
|
|
||||||
|
|
||||||
if (start_event)
|
if (start_event)
|
||||||
gst_pad_push_event (sel->srcpad, start_event);
|
gst_pad_push_event (sel->srcpad, start_event);
|
||||||
|
|
||||||
|
@ -931,10 +898,10 @@ gst_input_selector_dispose (GObject * object)
|
||||||
static gint64
|
static gint64
|
||||||
gst_segment_get_timestamp (GstSegment * segment, gint64 running_time)
|
gst_segment_get_timestamp (GstSegment * segment, gint64 running_time)
|
||||||
{
|
{
|
||||||
if (running_time <= segment->accum)
|
if (running_time <= segment->base)
|
||||||
return segment->start;
|
return segment->start;
|
||||||
else
|
else
|
||||||
return (running_time - segment->accum) * ABS (segment->rate) +
|
return (running_time - segment->base) * ABS (segment->rate) +
|
||||||
segment->start;
|
segment->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +909,7 @@ static void
|
||||||
gst_segment_set_stop (GstSegment * segment, gint64 running_time)
|
gst_segment_set_stop (GstSegment * segment, gint64 running_time)
|
||||||
{
|
{
|
||||||
segment->stop = gst_segment_get_timestamp (segment, running_time);
|
segment->stop = gst_segment_get_timestamp (segment, running_time);
|
||||||
segment->last_stop = -1;
|
segment->position = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -955,7 +922,7 @@ gst_segment_set_start (GstSegment * segment, gint64 running_time)
|
||||||
/* this is the duration we skipped */
|
/* this is the duration we skipped */
|
||||||
duration = new_start - segment->start;
|
duration = new_start - segment->start;
|
||||||
/* add the duration to the accumulated segment time */
|
/* add the duration to the accumulated segment time */
|
||||||
segment->accum += duration;
|
segment->base += duration;
|
||||||
/* move position in the segment */
|
/* move position in the segment */
|
||||||
segment->time += duration;
|
segment->time += duration;
|
||||||
segment->start += duration;
|
segment->start += duration;
|
||||||
|
|
|
@ -832,7 +832,7 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
|
||||||
if (sq->sink_tainted) {
|
if (sq->sink_tainted) {
|
||||||
sink_time = sq->sinktime =
|
sink_time = sq->sinktime =
|
||||||
gst_segment_to_running_time (&sq->sink_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&sq->sink_segment, GST_FORMAT_TIME,
|
||||||
sq->sink_segment.last_stop);
|
sq->sink_segment.position);
|
||||||
|
|
||||||
if (G_UNLIKELY (sink_time != GST_CLOCK_TIME_NONE))
|
if (G_UNLIKELY (sink_time != GST_CLOCK_TIME_NONE))
|
||||||
/* if we have a time, we become untainted and use the time */
|
/* if we have a time, we become untainted and use the time */
|
||||||
|
@ -843,7 +843,7 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
|
||||||
if (sq->src_tainted) {
|
if (sq->src_tainted) {
|
||||||
src_time = sq->srctime =
|
src_time = sq->srctime =
|
||||||
gst_segment_to_running_time (&sq->src_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&sq->src_segment, GST_FORMAT_TIME,
|
||||||
sq->src_segment.last_stop);
|
sq->src_segment.position);
|
||||||
/* if we have a time, we become untainted and use the time */
|
/* if we have a time, we become untainted and use the time */
|
||||||
if (G_UNLIKELY (src_time != GST_CLOCK_TIME_NONE))
|
if (G_UNLIKELY (src_time != GST_CLOCK_TIME_NONE))
|
||||||
sq->src_tainted = FALSE;
|
sq->src_tainted = FALSE;
|
||||||
|
@ -867,44 +867,33 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* take a NEWSEGMENT event and apply the values to segment, updating the time
|
/* take a SEGMENT event and apply the values to segment, updating the time
|
||||||
* level of queue. */
|
* level of queue. */
|
||||||
static void
|
static void
|
||||||
apply_segment (GstMultiQueue * mq, GstSingleQueue * sq, GstEvent * event,
|
apply_segment (GstMultiQueue * mq, GstSingleQueue * sq, GstEvent * event,
|
||||||
GstSegment * segment)
|
GstSegment * segment)
|
||||||
{
|
{
|
||||||
gboolean update;
|
gst_event_parse_segment (event, segment);
|
||||||
GstFormat format;
|
|
||||||
gdouble rate, arate;
|
|
||||||
gint64 start, stop, time;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate,
|
|
||||||
&format, &start, &stop, &time);
|
|
||||||
|
|
||||||
/* now configure the values, we use these to track timestamps on the
|
/* now configure the values, we use these to track timestamps on the
|
||||||
* sinkpad. */
|
* sinkpad. */
|
||||||
if (format != GST_FORMAT_TIME) {
|
if (segment->format != GST_FORMAT_TIME) {
|
||||||
/* non-time format, pretent the current time segment is closed with a
|
/* non-time format, pretent the current time segment is closed with a
|
||||||
* 0 start and unknown stop time. */
|
* 0 start and unknown stop time. */
|
||||||
update = FALSE;
|
segment->format = GST_FORMAT_TIME;
|
||||||
format = GST_FORMAT_TIME;
|
segment->start = 0;
|
||||||
start = 0;
|
segment->stop = -1;
|
||||||
stop = -1;
|
segment->time = 0;
|
||||||
time = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
||||||
|
|
||||||
gst_segment_set_newsegment (segment, update,
|
|
||||||
rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
if (segment == &sq->sink_segment)
|
if (segment == &sq->sink_segment)
|
||||||
sq->sink_tainted = TRUE;
|
sq->sink_tainted = TRUE;
|
||||||
else
|
else
|
||||||
sq->src_tainted = TRUE;
|
sq->src_tainted = TRUE;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (mq,
|
GST_DEBUG_OBJECT (mq,
|
||||||
"queue %d, configured NEWSEGMENT %" GST_SEGMENT_FORMAT, sq->id, segment);
|
"queue %d, configured SEGMENT %" GST_SEGMENT_FORMAT, sq->id, segment);
|
||||||
|
|
||||||
/* segment can update the time level of the queue */
|
/* segment can update the time level of the queue */
|
||||||
update_time_level (mq, sq);
|
update_time_level (mq, sq);
|
||||||
|
@ -922,16 +911,16 @@ apply_buffer (GstMultiQueue * mq, GstSingleQueue * sq, GstClockTime timestamp,
|
||||||
/* if no timestamp is set, assume it's continuous with the previous
|
/* if no timestamp is set, assume it's continuous with the previous
|
||||||
* time */
|
* time */
|
||||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||||
timestamp = segment->last_stop;
|
timestamp = segment->position;
|
||||||
|
|
||||||
/* add duration */
|
/* add duration */
|
||||||
if (duration != GST_CLOCK_TIME_NONE)
|
if (duration != GST_CLOCK_TIME_NONE)
|
||||||
timestamp += duration;
|
timestamp += duration;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (mq, "queue %d, last_stop updated to %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (mq, "queue %d, position updated to %" GST_TIME_FORMAT,
|
||||||
sq->id, GST_TIME_ARGS (timestamp));
|
sq->id, GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
|
segment->position = timestamp;
|
||||||
|
|
||||||
if (segment == &sq->sink_segment)
|
if (segment == &sq->sink_segment)
|
||||||
sq->sink_tainted = TRUE;
|
sq->sink_tainted = TRUE;
|
||||||
|
@ -990,7 +979,7 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = GST_FLOW_UNEXPECTED;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
apply_segment (mq, sq, event, &sq->src_segment);
|
apply_segment (mq, sq, event, &sq->src_segment);
|
||||||
/* Applying the segment may have made the queue non-full again, unblock it if needed */
|
/* Applying the segment may have made the queue non-full again, unblock it if needed */
|
||||||
gst_data_queue_limits_changed (sq->queue);
|
gst_data_queue_limits_changed (sq->queue);
|
||||||
|
@ -1330,7 +1319,7 @@ gst_multi_queue_sink_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
gst_single_queue_flush (mq, sq, FALSE);
|
gst_single_queue_flush (mq, sq, FALSE);
|
||||||
goto done;
|
goto done;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
/* take ref because the queue will take ownership and we need the event
|
/* take ref because the queue will take ownership and we need the event
|
||||||
* afterwards to update the segment */
|
* afterwards to update the segment */
|
||||||
sref = gst_event_ref (event);
|
sref = gst_event_ref (event);
|
||||||
|
@ -1371,7 +1360,7 @@ gst_multi_queue_sink_event (GstPad * pad, GstEvent * event)
|
||||||
update_buffering (mq, sq);
|
update_buffering (mq, sq);
|
||||||
single_queue_overrun_cb (sq->queue, sq);
|
single_queue_overrun_cb (sq->queue, sq);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
apply_segment (mq, sq, sref, &sq->sink_segment);
|
apply_segment (mq, sq, sref, &sq->sink_segment);
|
||||||
gst_event_unref (sref);
|
gst_event_unref (sref);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -411,19 +411,22 @@ gst_output_selector_switch (GstOutputSelector * osel)
|
||||||
osel->pending_srcpad = NULL;
|
osel->pending_srcpad = NULL;
|
||||||
GST_OBJECT_UNLOCK (GST_OBJECT (osel));
|
GST_OBJECT_UNLOCK (GST_OBJECT (osel));
|
||||||
|
|
||||||
/* Send NEWSEGMENT event and latest buffer if switching succeeded */
|
/* Send SEGMENT event and latest buffer if switching succeeded */
|
||||||
if (res) {
|
if (res) {
|
||||||
/* Send NEWSEGMENT to the pad we are going to switch to */
|
/* Send SEGMENT to the pad we are going to switch to */
|
||||||
seg = &osel->segment;
|
seg = &osel->segment;
|
||||||
/* If resending then mark newsegment start and position accordingly */
|
/* If resending then mark segment start and position accordingly */
|
||||||
if (osel->resend_latest && osel->latest_buffer &&
|
if (osel->resend_latest && osel->latest_buffer &&
|
||||||
GST_BUFFER_TIMESTAMP_IS_VALID (osel->latest_buffer)) {
|
GST_BUFFER_TIMESTAMP_IS_VALID (osel->latest_buffer)) {
|
||||||
start = position = GST_BUFFER_TIMESTAMP (osel->latest_buffer);
|
start = position = GST_BUFFER_TIMESTAMP (osel->latest_buffer);
|
||||||
} else {
|
} else {
|
||||||
start = position = seg->last_stop;
|
start = position = seg->position;
|
||||||
}
|
}
|
||||||
ev = gst_event_new_new_segment (TRUE, seg->rate, seg->applied_rate,
|
|
||||||
seg->format, start, seg->stop, position);
|
seg->start = start;
|
||||||
|
seg->position = position;
|
||||||
|
ev = gst_event_new_segment (seg);
|
||||||
|
|
||||||
if (!gst_pad_push_event (osel->active_srcpad, ev)) {
|
if (!gst_pad_push_event (osel->active_srcpad, ev)) {
|
||||||
GST_WARNING_OBJECT (osel,
|
GST_WARNING_OBJECT (osel,
|
||||||
"newsegment handling failed in %" GST_PTR_FORMAT,
|
"newsegment handling failed in %" GST_PTR_FORMAT,
|
||||||
|
@ -447,7 +450,7 @@ gst_output_selector_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstFlowReturn res;
|
GstFlowReturn res;
|
||||||
GstOutputSelector *osel;
|
GstOutputSelector *osel;
|
||||||
GstClockTime last_stop, duration;
|
GstClockTime position, duration;
|
||||||
|
|
||||||
osel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
|
osel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
@ -479,15 +482,15 @@ gst_output_selector_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
/* Keep track of last stop and use it in NEWSEGMENT start after
|
/* Keep track of last stop and use it in NEWSEGMENT start after
|
||||||
switching to a new src pad */
|
switching to a new src pad */
|
||||||
last_stop = GST_BUFFER_TIMESTAMP (buf);
|
position = GST_BUFFER_TIMESTAMP (buf);
|
||||||
if (GST_CLOCK_TIME_IS_VALID (last_stop)) {
|
if (GST_CLOCK_TIME_IS_VALID (position)) {
|
||||||
duration = GST_BUFFER_DURATION (buf);
|
duration = GST_BUFFER_DURATION (buf);
|
||||||
if (GST_CLOCK_TIME_IS_VALID (duration)) {
|
if (GST_CLOCK_TIME_IS_VALID (duration)) {
|
||||||
last_stop += duration;
|
position += duration;
|
||||||
}
|
}
|
||||||
GST_LOG_OBJECT (osel, "setting last stop %" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (osel, "setting last stop %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (last_stop));
|
GST_TIME_ARGS (position));
|
||||||
gst_segment_set_last_stop (&osel->segment, osel->segment.format, last_stop);
|
osel->segment.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (osel, "pushing buffer to %" GST_PTR_FORMAT,
|
GST_LOG_OBJECT (osel, "pushing buffer to %" GST_PTR_FORMAT,
|
||||||
|
@ -541,23 +544,12 @@ gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gboolean update;
|
gst_event_parse_segment (event, &sel->segment);
|
||||||
GstFormat format;
|
|
||||||
gdouble rate, arate;
|
|
||||||
gint64 start, stop, time;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate, &format,
|
GST_DEBUG_OBJECT (sel, "configured SEGMENT update %" GST_SEGMENT_FORMAT,
|
||||||
&start, &stop, &time);
|
&sel->segment);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (sel,
|
|
||||||
"configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
|
||||||
"format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
|
|
||||||
G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
gst_segment_set_newsegment (&sel->segment, update,
|
|
||||||
rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
/* Send newsegment to all src pads */
|
/* Send newsegment to all src pads */
|
||||||
gst_pad_event_default (pad, event);
|
gst_pad_event_default (pad, event);
|
||||||
|
|
|
@ -542,7 +542,7 @@ update_time_level (GstQueue * queue)
|
||||||
if (queue->sink_tainted) {
|
if (queue->sink_tainted) {
|
||||||
queue->sinktime =
|
queue->sinktime =
|
||||||
gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
|
||||||
queue->sink_segment.last_stop);
|
queue->sink_segment.position);
|
||||||
queue->sink_tainted = FALSE;
|
queue->sink_tainted = FALSE;
|
||||||
}
|
}
|
||||||
sink_time = queue->sinktime;
|
sink_time = queue->sinktime;
|
||||||
|
@ -550,7 +550,7 @@ update_time_level (GstQueue * queue)
|
||||||
if (queue->src_tainted) {
|
if (queue->src_tainted) {
|
||||||
queue->srctime =
|
queue->srctime =
|
||||||
gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
|
||||||
queue->src_segment.last_stop);
|
queue->src_segment.position);
|
||||||
queue->src_tainted = FALSE;
|
queue->src_tainted = FALSE;
|
||||||
}
|
}
|
||||||
src_time = queue->srctime;
|
src_time = queue->srctime;
|
||||||
|
@ -564,41 +564,30 @@ update_time_level (GstQueue * queue)
|
||||||
queue->cur_level.time = 0;
|
queue->cur_level.time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* take a NEWSEGMENT event and apply the values to segment, updating the time
|
/* take a SEGMENT event and apply the values to segment, updating the time
|
||||||
* level of queue. */
|
* level of queue. */
|
||||||
static void
|
static void
|
||||||
apply_segment (GstQueue * queue, GstEvent * event, GstSegment * segment,
|
apply_segment (GstQueue * queue, GstEvent * event, GstSegment * segment,
|
||||||
gboolean sink)
|
gboolean sink)
|
||||||
{
|
{
|
||||||
gboolean update;
|
gst_event_parse_segment (event, segment);
|
||||||
GstFormat format;
|
|
||||||
gdouble rate, arate;
|
|
||||||
gint64 start, stop, time;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate,
|
|
||||||
&format, &start, &stop, &time);
|
|
||||||
|
|
||||||
/* now configure the values, we use these to track timestamps on the
|
/* now configure the values, we use these to track timestamps on the
|
||||||
* sinkpad. */
|
* sinkpad. */
|
||||||
if (format != GST_FORMAT_TIME) {
|
if (segment->format != GST_FORMAT_TIME) {
|
||||||
/* non-time format, pretent the current time segment is closed with a
|
/* non-time format, pretent the current time segment is closed with a
|
||||||
* 0 start and unknown stop time. */
|
* 0 start and unknown stop time. */
|
||||||
update = FALSE;
|
segment->format = GST_FORMAT_TIME;
|
||||||
format = GST_FORMAT_TIME;
|
segment->start = 0;
|
||||||
start = 0;
|
segment->stop = -1;
|
||||||
stop = -1;
|
segment->time = 0;
|
||||||
time = 0;
|
|
||||||
}
|
}
|
||||||
gst_segment_set_newsegment (segment, update,
|
|
||||||
rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
if (sink)
|
if (sink)
|
||||||
queue->sink_tainted = TRUE;
|
queue->sink_tainted = TRUE;
|
||||||
else
|
else
|
||||||
queue->src_tainted = TRUE;
|
queue->src_tainted = TRUE;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (queue,
|
GST_DEBUG_OBJECT (queue, "configured SEGMENT %" GST_SEGMENT_FORMAT, segment);
|
||||||
"configured NEWSEGMENT %" GST_SEGMENT_FORMAT, segment);
|
|
||||||
|
|
||||||
/* segment can update the time level of the queue */
|
/* segment can update the time level of the queue */
|
||||||
update_time_level (queue);
|
update_time_level (queue);
|
||||||
|
@ -617,16 +606,16 @@ apply_buffer (GstQueue * queue, GstBuffer * buffer, GstSegment * segment,
|
||||||
/* if no timestamp is set, assume it's continuous with the previous
|
/* if no timestamp is set, assume it's continuous with the previous
|
||||||
* time */
|
* time */
|
||||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||||
timestamp = segment->last_stop;
|
timestamp = segment->position;
|
||||||
|
|
||||||
/* add duration */
|
/* add duration */
|
||||||
if (with_duration && duration != GST_CLOCK_TIME_NONE)
|
if (with_duration && duration != GST_CLOCK_TIME_NONE)
|
||||||
timestamp += duration;
|
timestamp += duration;
|
||||||
|
|
||||||
GST_LOG_OBJECT (queue, "last_stop updated to %" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (queue, "position updated to %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (timestamp));
|
GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
|
segment->position = timestamp;
|
||||||
if (sink)
|
if (sink)
|
||||||
queue->sink_tainted = TRUE;
|
queue->sink_tainted = TRUE;
|
||||||
else
|
else
|
||||||
|
@ -691,7 +680,7 @@ gst_queue_locked_enqueue_event (GstQueue * queue, gpointer item)
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "got EOS from upstream");
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "got EOS from upstream");
|
||||||
queue->eos = TRUE;
|
queue->eos = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
apply_segment (queue, event, &queue->sink_segment, TRUE);
|
apply_segment (queue, event, &queue->sink_segment, TRUE);
|
||||||
/* if the queue is empty, apply sink segment on the source */
|
/* if the queue is empty, apply sink segment on the source */
|
||||||
if (queue->queue->length == 0) {
|
if (queue->queue->length == 0) {
|
||||||
|
@ -747,7 +736,7 @@ gst_queue_locked_dequeue (GstQueue * queue, gboolean * is_buffer)
|
||||||
/* queue is empty now that we dequeued the EOS */
|
/* queue is empty now that we dequeued the EOS */
|
||||||
GST_QUEUE_CLEAR_LEVEL (queue->cur_level);
|
GST_QUEUE_CLEAR_LEVEL (queue->cur_level);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
/* apply newsegment if it has not already been applied */
|
/* apply newsegment if it has not already been applied */
|
||||||
if (G_LIKELY (!queue->newseg_applied_to_src)) {
|
if (G_LIKELY (!queue->newseg_applied_to_src)) {
|
||||||
apply_segment (queue, event, &queue->src_segment, FALSE);
|
apply_segment (queue, event, &queue->src_segment, FALSE);
|
||||||
|
@ -1059,21 +1048,9 @@ out_unexpected:
|
||||||
static void
|
static void
|
||||||
gst_queue_push_newsegment (GstQueue * queue)
|
gst_queue_push_newsegment (GstQueue * queue)
|
||||||
{
|
{
|
||||||
GstSegment *s;
|
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
|
||||||
s = &queue->src_segment;
|
event = gst_event_new_segment (&queue->src_segment);
|
||||||
|
|
||||||
if (s->accum != 0) {
|
|
||||||
event = gst_event_new_new_segment (FALSE, 1.0, 1.0, s->format, 0,
|
|
||||||
s->accum, 0);
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
|
||||||
"pushing accum newsegment event");
|
|
||||||
gst_pad_push_event (queue->srcpad, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
event = gst_event_new_new_segment (FALSE, s->rate, s->applied_rate,
|
|
||||||
s->format, s->start, s->stop, s->time);
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "pushing real newsegment event");
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "pushing real newsegment event");
|
||||||
gst_pad_push_event (queue->srcpad, event);
|
gst_pad_push_event (queue->srcpad, event);
|
||||||
}
|
}
|
||||||
|
@ -1138,7 +1115,7 @@ next:
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
||||||
"got UNEXPECTED from downstream");
|
"got UNEXPECTED from downstream");
|
||||||
/* stop pushing buffers, we dequeue all items until we see an item that we
|
/* stop pushing buffers, we dequeue all items until we see an item that we
|
||||||
* can push again, which is EOS or NEWSEGMENT. If there is nothing in the
|
* can push again, which is EOS or SEGMENT. If there is nothing in the
|
||||||
* queue we can push, we set a flag to make the sinkpad refuse more
|
* queue we can push, we set a flag to make the sinkpad refuse more
|
||||||
* buffers with an UNEXPECTED return value. */
|
* buffers with an UNEXPECTED return value. */
|
||||||
while ((data = gst_queue_locked_dequeue (queue, &is_buffer))) {
|
while ((data = gst_queue_locked_dequeue (queue, &is_buffer))) {
|
||||||
|
@ -1150,7 +1127,7 @@ next:
|
||||||
GstEvent *event = GST_EVENT_CAST (data);
|
GstEvent *event = GST_EVENT_CAST (data);
|
||||||
GstEventType type = GST_EVENT_TYPE (event);
|
GstEventType type = GST_EVENT_TYPE (event);
|
||||||
|
|
||||||
if (type == GST_EVENT_EOS || type == GST_EVENT_NEWSEGMENT) {
|
if (type == GST_EVENT_EOS || type == GST_EVENT_SEGMENT) {
|
||||||
/* we found a pushable item in the queue, push it out */
|
/* we found a pushable item in the queue, push it out */
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
||||||
"pushing pushable event %s after UNEXPECTED",
|
"pushing pushable event %s after UNEXPECTED",
|
||||||
|
@ -1164,7 +1141,7 @@ next:
|
||||||
}
|
}
|
||||||
/* no more items in the queue. Set the unexpected flag so that upstream
|
/* no more items in the queue. Set the unexpected flag so that upstream
|
||||||
* make us refuse any more buffers on the sinkpad. Since we will still
|
* make us refuse any more buffers on the sinkpad. Since we will still
|
||||||
* accept EOS and NEWSEGMENT we return _FLOW_OK to the caller so that the
|
* accept EOS and SEGMENT we return _FLOW_OK to the caller so that the
|
||||||
* task function does not shut down. */
|
* task function does not shut down. */
|
||||||
queue->unexpected = TRUE;
|
queue->unexpected = TRUE;
|
||||||
result = GST_FLOW_OK;
|
result = GST_FLOW_OK;
|
||||||
|
@ -1175,7 +1152,7 @@ next:
|
||||||
|
|
||||||
GST_QUEUE_MUTEX_UNLOCK (queue);
|
GST_QUEUE_MUTEX_UNLOCK (queue);
|
||||||
|
|
||||||
if (queue->push_newsegment && type != GST_EVENT_NEWSEGMENT) {
|
if (queue->push_newsegment && type != GST_EVENT_SEGMENT) {
|
||||||
gst_queue_push_newsegment (queue);
|
gst_queue_push_newsegment (queue);
|
||||||
}
|
}
|
||||||
gst_pad_push_event (queue->srcpad, event);
|
gst_pad_push_event (queue->srcpad, event);
|
||||||
|
|
|
@ -658,14 +658,14 @@ update_time_level (GstQueue2 * queue)
|
||||||
if (queue->sink_tainted) {
|
if (queue->sink_tainted) {
|
||||||
queue->sinktime =
|
queue->sinktime =
|
||||||
gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
|
||||||
queue->sink_segment.last_stop);
|
queue->sink_segment.position);
|
||||||
queue->sink_tainted = FALSE;
|
queue->sink_tainted = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queue->src_tainted) {
|
if (queue->src_tainted) {
|
||||||
queue->srctime =
|
queue->srctime =
|
||||||
gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
|
||||||
queue->src_segment.last_stop);
|
queue->src_segment.position);
|
||||||
queue->src_tainted = FALSE;
|
queue->src_tainted = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,30 +680,18 @@ update_time_level (GstQueue2 * queue)
|
||||||
queue->cur_level.time = 0;
|
queue->cur_level.time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* take a NEWSEGMENT event and apply the values to segment, updating the time
|
/* take a SEGMENT event and apply the values to segment, updating the time
|
||||||
* level of queue. */
|
* level of queue. */
|
||||||
static void
|
static void
|
||||||
apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment,
|
apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment,
|
||||||
gboolean is_sink)
|
gboolean is_sink)
|
||||||
{
|
{
|
||||||
gboolean update;
|
gst_event_parse_segment (event, segment);
|
||||||
GstFormat format;
|
|
||||||
gdouble rate, arate;
|
|
||||||
gint64 start, stop, time;
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &arate,
|
if (segment->format == GST_FORMAT_BYTES) {
|
||||||
&format, &start, &stop, &time);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (queue,
|
|
||||||
"received NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
|
||||||
"format %d, "
|
|
||||||
"%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
|
|
||||||
G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_BYTES) {
|
|
||||||
if (QUEUE_IS_USING_TEMP_FILE (queue)) {
|
if (QUEUE_IS_USING_TEMP_FILE (queue)) {
|
||||||
/* start is where we'll be getting from and as such writing next */
|
/* start is where we'll be getting from and as such writing next */
|
||||||
queue->current = add_range (queue, start);
|
queue->current = add_range (queue, segment->start);
|
||||||
/* update the stats for this range */
|
/* update the stats for this range */
|
||||||
update_cur_level (queue, queue->current);
|
update_cur_level (queue, queue->current);
|
||||||
}
|
}
|
||||||
|
@ -711,20 +699,16 @@ apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment,
|
||||||
|
|
||||||
/* now configure the values, we use these to track timestamps on the
|
/* now configure the values, we use these to track timestamps on the
|
||||||
* sinkpad. */
|
* sinkpad. */
|
||||||
if (format != GST_FORMAT_TIME) {
|
if (segment->format != GST_FORMAT_TIME) {
|
||||||
/* non-time format, pretent the current time segment is closed with a
|
/* non-time format, pretent the current time segment is closed with a
|
||||||
* 0 start and unknown stop time. */
|
* 0 start and unknown stop time. */
|
||||||
update = FALSE;
|
segment->format = GST_FORMAT_TIME;
|
||||||
format = GST_FORMAT_TIME;
|
segment->start = 0;
|
||||||
start = 0;
|
segment->stop = -1;
|
||||||
stop = -1;
|
segment->time = 0;
|
||||||
time = 0;
|
|
||||||
}
|
}
|
||||||
gst_segment_set_newsegment (segment, update,
|
|
||||||
rate, arate, format, start, stop, time);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (queue,
|
GST_DEBUG_OBJECT (queue, "configured SEGMENT %" GST_SEGMENT_FORMAT, segment);
|
||||||
"configured NEWSEGMENT %" GST_SEGMENT_FORMAT, segment);
|
|
||||||
|
|
||||||
if (is_sink)
|
if (is_sink)
|
||||||
queue->sink_tainted = TRUE;
|
queue->sink_tainted = TRUE;
|
||||||
|
@ -748,16 +732,16 @@ apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment,
|
||||||
/* if no timestamp is set, assume it's continuous with the previous
|
/* if no timestamp is set, assume it's continuous with the previous
|
||||||
* time */
|
* time */
|
||||||
if (timestamp == GST_CLOCK_TIME_NONE)
|
if (timestamp == GST_CLOCK_TIME_NONE)
|
||||||
timestamp = segment->last_stop;
|
timestamp = segment->position;
|
||||||
|
|
||||||
/* add duration */
|
/* add duration */
|
||||||
if (duration != GST_CLOCK_TIME_NONE)
|
if (duration != GST_CLOCK_TIME_NONE)
|
||||||
timestamp += duration;
|
timestamp += duration;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (queue, "last_stop updated to %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (queue, "position updated to %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (timestamp));
|
GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
|
segment->position = timestamp;
|
||||||
|
|
||||||
if (is_sink)
|
if (is_sink)
|
||||||
queue->sink_tainted = TRUE;
|
queue->sink_tainted = TRUE;
|
||||||
|
@ -1825,7 +1809,7 @@ gst_queue2_locked_enqueue (GstQueue2 * queue, gpointer item, gboolean isbuffer)
|
||||||
GST_DEBUG_OBJECT (queue, "we have EOS");
|
GST_DEBUG_OBJECT (queue, "we have EOS");
|
||||||
queue->is_eos = TRUE;
|
queue->is_eos = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
apply_segment (queue, event, &queue->sink_segment, TRUE);
|
apply_segment (queue, event, &queue->sink_segment, TRUE);
|
||||||
/* This is our first new segment, we hold it
|
/* This is our first new segment, we hold it
|
||||||
* as we can't save it on the temp file */
|
* as we can't save it on the temp file */
|
||||||
|
@ -1934,7 +1918,7 @@ gst_queue2_locked_dequeue (GstQueue2 * queue, gboolean * is_buffer)
|
||||||
/* queue is empty now that we dequeued the EOS */
|
/* queue is empty now that we dequeued the EOS */
|
||||||
GST_QUEUE2_CLEAR_LEVEL (queue->cur_level);
|
GST_QUEUE2_CLEAR_LEVEL (queue->cur_level);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
apply_segment (queue, event, &queue->src_segment, FALSE);
|
apply_segment (queue, event, &queue->src_segment, FALSE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2228,7 +2212,7 @@ next:
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
||||||
"got UNEXPECTED from downstream");
|
"got UNEXPECTED from downstream");
|
||||||
/* stop pushing buffers, we dequeue all items until we see an item that we
|
/* stop pushing buffers, we dequeue all items until we see an item that we
|
||||||
* can push again, which is EOS or NEWSEGMENT. If there is nothing in the
|
* can push again, which is EOS or SEGMENT. If there is nothing in the
|
||||||
* queue we can push, we set a flag to make the sinkpad refuse more
|
* queue we can push, we set a flag to make the sinkpad refuse more
|
||||||
* buffers with an UNEXPECTED return value until we receive something
|
* buffers with an UNEXPECTED return value until we receive something
|
||||||
* pushable again or we get flushed. */
|
* pushable again or we get flushed. */
|
||||||
|
@ -2241,7 +2225,7 @@ next:
|
||||||
GstEvent *event = GST_EVENT_CAST (data);
|
GstEvent *event = GST_EVENT_CAST (data);
|
||||||
GstEventType type = GST_EVENT_TYPE (event);
|
GstEventType type = GST_EVENT_TYPE (event);
|
||||||
|
|
||||||
if (type == GST_EVENT_EOS || type == GST_EVENT_NEWSEGMENT) {
|
if (type == GST_EVENT_EOS || type == GST_EVENT_SEGMENT) {
|
||||||
/* we found a pushable item in the queue, push it out */
|
/* we found a pushable item in the queue, push it out */
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
||||||
"pushing pushable event %s after UNEXPECTED",
|
"pushing pushable event %s after UNEXPECTED",
|
||||||
|
@ -2255,7 +2239,7 @@ next:
|
||||||
}
|
}
|
||||||
/* no more items in the queue. Set the unexpected flag so that upstream
|
/* no more items in the queue. Set the unexpected flag so that upstream
|
||||||
* make us refuse any more buffers on the sinkpad. Since we will still
|
* make us refuse any more buffers on the sinkpad. Since we will still
|
||||||
* accept EOS and NEWSEGMENT we return _FLOW_OK to the caller so that the
|
* accept EOS and SEGMENT we return _FLOW_OK to the caller so that the
|
||||||
* task function does not shut down. */
|
* task function does not shut down. */
|
||||||
queue->unexpected = TRUE;
|
queue->unexpected = TRUE;
|
||||||
result = GST_FLOW_OK;
|
result = GST_FLOW_OK;
|
||||||
|
|
|
@ -99,15 +99,19 @@ GST_START_TEST (test_clipping)
|
||||||
|
|
||||||
/* send segment */
|
/* send segment */
|
||||||
{
|
{
|
||||||
GstEvent *segment;
|
GstEvent *event;
|
||||||
|
GstSegment segment;
|
||||||
gboolean eret;
|
gboolean eret;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
segment = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 1 * GST_SECOND, 5 * GST_SECOND,
|
segment.start = 1 * GST_SECOND;
|
||||||
1 * GST_SECOND);
|
segment.stop = 5 * GST_SECOND;
|
||||||
|
segment.time = 1 * GST_SECOND;
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, segment);
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == FALSE);
|
fail_if (eret == FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,15 +263,18 @@ GST_START_TEST (test_preroll_sync)
|
||||||
|
|
||||||
/* send segment */
|
/* send segment */
|
||||||
{
|
{
|
||||||
GstEvent *segment;
|
GstEvent *event;
|
||||||
|
GstSegment segment;
|
||||||
gboolean eret;
|
gboolean eret;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
segment = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 102 * GST_SECOND,
|
segment.start = 0 * GST_SECOND;
|
||||||
0 * GST_SECOND);
|
segment.stop = 102 * GST_SECOND;
|
||||||
|
segment.time = 0 * GST_SECOND;
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, segment);
|
event = gst_event_new_segment (&segment);
|
||||||
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == FALSE);
|
fail_if (eret == FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,15 +427,18 @@ GST_START_TEST (test_eos)
|
||||||
|
|
||||||
/* send segment, this should fail */
|
/* send segment, this should fail */
|
||||||
{
|
{
|
||||||
GstEvent *segment;
|
GstEvent *event;
|
||||||
|
GstSegment segment;
|
||||||
gboolean eret;
|
gboolean eret;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
segment = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND,
|
segment.start = 0 * GST_SECOND;
|
||||||
0 * GST_SECOND);
|
segment.stop = 2 * GST_SECOND;
|
||||||
|
segment.time = 0 * GST_SECOND;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, segment);
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == TRUE);
|
fail_if (eret == TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,15 +476,18 @@ GST_START_TEST (test_eos)
|
||||||
|
|
||||||
/* send segment, this should now work again */
|
/* send segment, this should now work again */
|
||||||
{
|
{
|
||||||
GstEvent *segment;
|
GstEvent *event;
|
||||||
|
GstSegment segment;
|
||||||
gboolean eret;
|
gboolean eret;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
segment = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND,
|
segment.start = 0 * GST_SECOND;
|
||||||
0 * GST_SECOND);
|
segment.stop = 2 * GST_SECOND;
|
||||||
|
segment.time = 0 * GST_SECOND;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, segment);
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_unless (eret == TRUE);
|
fail_unless (eret == TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,15 +541,18 @@ GST_START_TEST (test_eos2)
|
||||||
|
|
||||||
/* send segment, this should work */
|
/* send segment, this should work */
|
||||||
{
|
{
|
||||||
GstEvent *segment;
|
GstEvent *event;
|
||||||
|
GstSegment segment;
|
||||||
gboolean eret;
|
gboolean eret;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
segment = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND,
|
segment.start = 0 * GST_SECOND;
|
||||||
0 * GST_SECOND);
|
segment.stop = 2 * GST_SECOND;
|
||||||
|
segment.time = 0 * GST_SECOND;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, segment);
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == FALSE);
|
fail_if (eret == FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,10 +650,14 @@ GST_START_TEST (test_position)
|
||||||
|
|
||||||
/* send segment, this should work */
|
/* send segment, this should work */
|
||||||
{
|
{
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
event = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 1 * GST_SECOND, 3 * GST_SECOND,
|
segment.start = 1 * GST_SECOND;
|
||||||
1 * GST_SECOND);
|
segment.stop = 3 * GST_SECOND;
|
||||||
|
segment.time = 1 * GST_SECOND;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, event);
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == FALSE);
|
fail_if (eret == FALSE);
|
||||||
|
@ -707,10 +727,14 @@ GST_START_TEST (test_position)
|
||||||
|
|
||||||
/* send segment, this should work */
|
/* send segment, this should work */
|
||||||
{
|
{
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
event = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 4 * GST_SECOND,
|
segment.start = 2 * GST_SECOND;
|
||||||
1 * GST_SECOND);
|
segment.stop = 4 * GST_SECOND;
|
||||||
|
segment.time = 1 * GST_SECOND;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, event);
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == FALSE);
|
fail_if (eret == FALSE);
|
||||||
|
@ -791,10 +815,14 @@ GST_START_TEST (test_position)
|
||||||
|
|
||||||
/* send segment, this should work */
|
/* send segment, this should work */
|
||||||
{
|
{
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
event = gst_event_new_new_segment (FALSE,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1.0, 1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 4 * GST_SECOND,
|
segment.start = 2 * GST_SECOND;
|
||||||
1 * GST_SECOND);
|
segment.stop = 4 * GST_SECOND;
|
||||||
|
segment.time = 1 * GST_SECOND;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
|
||||||
eret = gst_pad_send_event (sinkpad, event);
|
eret = gst_pad_send_event (sinkpad, event);
|
||||||
fail_if (eret == FALSE);
|
fail_if (eret == FALSE);
|
||||||
|
|
|
@ -105,6 +105,7 @@ GST_START_TEST (test_seeking)
|
||||||
GstElement *filesink;
|
GstElement *filesink;
|
||||||
gchar *tmp_fn;
|
gchar *tmp_fn;
|
||||||
gint fd;
|
gint fd;
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
tmpdir = g_get_tmp_dir ();
|
tmpdir = g_get_tmp_dir ();
|
||||||
if (tmpdir == NULL)
|
if (tmpdir == NULL)
|
||||||
|
@ -144,9 +145,8 @@ GST_START_TEST (test_seeking)
|
||||||
gst_query_unref (seeking_query);
|
gst_query_unref (seeking_query);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fail_unless (gst_pad_push_event (mysrcpad,
|
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
||||||
gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0, -1,
|
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
|
||||||
0)));
|
|
||||||
|
|
||||||
CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 0);
|
CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 0);
|
||||||
|
|
||||||
|
@ -163,9 +163,8 @@ GST_START_TEST (test_seeking)
|
||||||
PUSH_BYTES (8800);
|
PUSH_BYTES (8800);
|
||||||
CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8900);
|
CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8900);
|
||||||
|
|
||||||
if (gst_pad_push_event (mysrcpad,
|
segment.start = 8800;
|
||||||
gst_event_new_new_segment (TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 8800, -1,
|
if (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment))) {
|
||||||
0))) {
|
|
||||||
GST_LOG ("seek ok");
|
GST_LOG ("seek ok");
|
||||||
/* make sure that that new position is reported immediately */
|
/* make sure that that new position is reported immediately */
|
||||||
CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8800);
|
CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8800);
|
||||||
|
|
|
@ -562,6 +562,7 @@ GST_START_TEST (test_sparse_stream)
|
||||||
GCond *cond;
|
GCond *cond;
|
||||||
gint i;
|
gint i;
|
||||||
const gint NBUFFERS = 100;
|
const gint NBUFFERS = 100;
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
mutex = g_mutex_new ();
|
mutex = g_mutex_new ();
|
||||||
cond = g_cond_new ();
|
cond = g_cond_new ();
|
||||||
|
@ -628,8 +629,8 @@ GST_START_TEST (test_sparse_stream)
|
||||||
gst_element_set_state (pipe, GST_STATE_PLAYING);
|
gst_element_set_state (pipe, GST_STATE_PLAYING);
|
||||||
|
|
||||||
/* Push 2 new segment events */
|
/* Push 2 new segment events */
|
||||||
event =
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1, 0);
|
event = gst_event_new_segment (&segment);
|
||||||
gst_pad_push_event (inputpads[0], gst_event_ref (event));
|
gst_pad_push_event (inputpads[0], gst_event_ref (event));
|
||||||
gst_pad_push_event (inputpads[1], event);
|
gst_pad_push_event (inputpads[1], event);
|
||||||
|
|
||||||
|
@ -663,8 +664,10 @@ GST_START_TEST (test_sparse_stream)
|
||||||
g_static_mutex_unlock (&_check_lock);
|
g_static_mutex_unlock (&_check_lock);
|
||||||
|
|
||||||
/* Push a new segment update on the 2nd pad */
|
/* Push a new segment update on the 2nd pad */
|
||||||
event =
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
gst_event_new_new_segment (TRUE, 1.0, 1.0, GST_FORMAT_TIME, ts, -1, ts);
|
segment.start = ts;
|
||||||
|
segment.time = ts;
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
gst_pad_push_event (inputpads[1], event);
|
gst_pad_push_event (inputpads[1], event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -541,6 +541,7 @@ GST_START_TEST (test_time_level_task_not_started)
|
||||||
{
|
{
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
GST_DEBUG ("starting");
|
GST_DEBUG ("starting");
|
||||||
|
|
||||||
|
@ -548,15 +549,19 @@ GST_START_TEST (test_time_level_task_not_started)
|
||||||
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
|
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
|
||||||
"could not set to playing");
|
"could not set to playing");
|
||||||
|
|
||||||
event = gst_event_new_new_segment (TRUE, 1.0, 1.0, GST_FORMAT_TIME,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
1 * GST_SECOND, 5 * GST_SECOND, 0);
|
segment.start = 1 * GST_SECOND;
|
||||||
|
segment.stop = 5 * GST_SECOND;
|
||||||
|
segment.time = 0;
|
||||||
|
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
gst_pad_push_event (mysrcpad, event);
|
gst_pad_push_event (mysrcpad, event);
|
||||||
|
|
||||||
g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
|
g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
|
||||||
fail_if (time != 0 * GST_SECOND);
|
fail_if (time != 0 * GST_SECOND);
|
||||||
|
|
||||||
event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
|
segment.base = 4 * GST_SECOND;
|
||||||
1 * GST_SECOND, 5 * GST_SECOND, 0);
|
event = gst_event_new_segment (&segment);
|
||||||
gst_pad_push_event (mysrcpad, event);
|
gst_pad_push_event (mysrcpad, event);
|
||||||
|
|
||||||
g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
|
g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
|
||||||
|
@ -569,6 +574,7 @@ GST_START_TEST (test_time_level_task_not_started)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
#if 0
|
||||||
static gboolean
|
static gboolean
|
||||||
event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
|
event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
|
||||||
GstFormat format, gint64 start, gint64 stop, gint64 position)
|
GstFormat format, gint64 start, gint64 stop, gint64 position)
|
||||||
|
@ -580,7 +586,7 @@ event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
|
||||||
gint64 ns_stop;
|
gint64 ns_stop;
|
||||||
gint64 ns_position;
|
gint64 ns_position;
|
||||||
|
|
||||||
if (GST_EVENT_TYPE (event) != GST_EVENT_NEWSEGMENT) {
|
if (GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,6 +698,7 @@ GST_START_TEST (test_newsegment)
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
#endif
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
queue_suite (void)
|
queue_suite (void)
|
||||||
|
@ -707,7 +714,9 @@ queue_suite (void)
|
||||||
tcase_add_test (tc_chain, test_leaky_downstream);
|
tcase_add_test (tc_chain, test_leaky_downstream);
|
||||||
tcase_add_test (tc_chain, test_time_level);
|
tcase_add_test (tc_chain, test_time_level);
|
||||||
tcase_add_test (tc_chain, test_time_level_task_not_started);
|
tcase_add_test (tc_chain, test_time_level_task_not_started);
|
||||||
|
#if 0
|
||||||
tcase_add_test (tc_chain, test_newsegment);
|
tcase_add_test (tc_chain, test_newsegment);
|
||||||
|
#endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1050,6 +1050,7 @@ GST_START_TEST (test_async_done)
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 position;
|
gint64 position;
|
||||||
gboolean qret;
|
gboolean qret;
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
sink = gst_element_factory_make ("fakesink", "sink");
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
|
g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
|
||||||
|
@ -1071,9 +1072,10 @@ GST_START_TEST (test_async_done)
|
||||||
|
|
||||||
/* make newsegment, this sets the position to 10sec when the buffer prerolls */
|
/* make newsegment, this sets the position to 10sec when the buffer prerolls */
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
event =
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1,
|
segment.time = 10 * GST_SECOND;
|
||||||
10 * GST_SECOND);
|
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
res = gst_pad_send_event (sinkpad, event);
|
res = gst_pad_send_event (sinkpad, event);
|
||||||
|
|
||||||
/* We have not yet received any buffers so we are still in the READY state,
|
/* We have not yet received any buffers so we are still in the READY state,
|
||||||
|
@ -1192,6 +1194,7 @@ GST_START_TEST (test_async_done_eos)
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 position;
|
gint64 position;
|
||||||
gboolean qret;
|
gboolean qret;
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
sink = gst_element_factory_make ("fakesink", "sink");
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
|
g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
|
||||||
|
@ -1209,9 +1212,9 @@ GST_START_TEST (test_async_done_eos)
|
||||||
|
|
||||||
/* make newsegment, this sets the position to 10sec when the buffer prerolls */
|
/* make newsegment, this sets the position to 10sec when the buffer prerolls */
|
||||||
GST_DEBUG ("sending segment");
|
GST_DEBUG ("sending segment");
|
||||||
event =
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1,
|
segment.time = 10 * GST_SECOND;
|
||||||
10 * GST_SECOND);
|
event = gst_event_new_segment (&segment);
|
||||||
res = gst_pad_send_event (sinkpad, event);
|
res = gst_pad_send_event (sinkpad, event);
|
||||||
|
|
||||||
/* We have not yet received any buffers so we are still in the READY state,
|
/* We have not yet received any buffers so we are still in the READY state,
|
||||||
|
|
|
@ -57,64 +57,31 @@ GST_START_TEST (create_events)
|
||||||
fail_unless (GST_EVENT_IS_SERIALIZED (event));
|
fail_unless (GST_EVENT_IS_SERIALIZED (event));
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
}
|
}
|
||||||
/* NEWSEGMENT */
|
/* SEGMENT */
|
||||||
{
|
{
|
||||||
gdouble rate, applied_rate;
|
GstSegment segment, parsed;
|
||||||
GstFormat format;
|
|
||||||
gint64 start, end, base;
|
|
||||||
gboolean update;
|
|
||||||
|
|
||||||
event =
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
gst_event_new_new_segment (FALSE, 0.5, 1.0, GST_FORMAT_TIME, 1,
|
segment.rate = 0.5;
|
||||||
G_MAXINT64, 0xdeadbeef);
|
segment.applied_rate = 1.0;
|
||||||
|
segment.start = 1;
|
||||||
|
segment.stop = G_MAXINT64;
|
||||||
|
segment.time = 0xdeadbeef;
|
||||||
|
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
fail_if (event == NULL);
|
fail_if (event == NULL);
|
||||||
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
|
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
|
||||||
fail_if (GST_EVENT_IS_UPSTREAM (event));
|
fail_if (GST_EVENT_IS_UPSTREAM (event));
|
||||||
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
|
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
|
||||||
fail_unless (GST_EVENT_IS_SERIALIZED (event));
|
fail_unless (GST_EVENT_IS_SERIALIZED (event));
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &applied_rate, &format,
|
gst_event_parse_segment (event, &parsed);
|
||||||
&start, &end, &base);
|
fail_unless (parsed.rate == 0.5);
|
||||||
fail_unless (update == FALSE);
|
fail_unless (parsed.applied_rate == 1.0);
|
||||||
fail_unless (rate == 0.5);
|
fail_unless (parsed.format == GST_FORMAT_TIME);
|
||||||
fail_unless (applied_rate == 1.0);
|
fail_unless (parsed.start == 1);
|
||||||
fail_unless (format == GST_FORMAT_TIME);
|
fail_unless (parsed.stop == G_MAXINT64);
|
||||||
fail_unless (start == 1);
|
fail_unless (parsed.time == 0xdeadbeef);
|
||||||
fail_unless (end == G_MAXINT64);
|
|
||||||
fail_unless (base == 0xdeadbeef);
|
|
||||||
|
|
||||||
/* Check that the new segment was created with applied_rate of 1.0 */
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &applied_rate,
|
|
||||||
&format, &start, &end, &base);
|
|
||||||
|
|
||||||
fail_unless (update == FALSE);
|
|
||||||
fail_unless (rate == 0.5);
|
|
||||||
fail_unless (applied_rate == 1.0);
|
|
||||||
fail_unless (format == GST_FORMAT_TIME);
|
|
||||||
fail_unless (start == 1);
|
|
||||||
fail_unless (end == G_MAXINT64);
|
|
||||||
|
|
||||||
gst_event_unref (event);
|
|
||||||
|
|
||||||
event =
|
|
||||||
gst_event_new_new_segment (TRUE, 0.75, 0.5, GST_FORMAT_BYTES, 0,
|
|
||||||
G_MAXINT64 - 1, 0xdeadbeef);
|
|
||||||
|
|
||||||
fail_if (event == NULL);
|
|
||||||
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
|
|
||||||
fail_if (GST_EVENT_IS_UPSTREAM (event));
|
|
||||||
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
|
|
||||||
fail_unless (GST_EVENT_IS_SERIALIZED (event));
|
|
||||||
|
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &applied_rate,
|
|
||||||
&format, &start, &end, &base);
|
|
||||||
|
|
||||||
fail_unless (update == TRUE);
|
|
||||||
fail_unless (rate == 0.75);
|
|
||||||
fail_unless (applied_rate == 0.5);
|
|
||||||
fail_unless (format == GST_FORMAT_BYTES);
|
|
||||||
fail_unless (start == 0);
|
|
||||||
fail_unless (end == (G_MAXINT64 - 1));
|
|
||||||
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,10 +127,13 @@ GST_START_TEST (info_segment_format_printf_extension)
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 2.0,
|
segment.rate = 1.0;
|
||||||
GST_FORMAT_TIME, 0, 5 * 60 * GST_SECOND, 0);
|
segment.applied_rate = 2.0;
|
||||||
|
segment.start = 0;
|
||||||
|
segment.stop = 5 * 60 * GST_SECOND;
|
||||||
|
segment.time = 0;
|
||||||
|
|
||||||
segment.last_stop = 2 * GST_SECOND;
|
segment.position = 2 * GST_SECOND;
|
||||||
segment.duration = 90 * 60 * GST_SECOND;
|
segment.duration = 90 * 60 * GST_SECOND;
|
||||||
|
|
||||||
GST_LOG ("TIME: %" GST_SEGMENT_FORMAT, &segment);
|
GST_LOG ("TIME: %" GST_SEGMENT_FORMAT, &segment);
|
||||||
|
@ -142,8 +145,11 @@ GST_START_TEST (info_segment_format_printf_extension)
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
||||||
|
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
segment.rate = 1.0;
|
||||||
GST_FORMAT_BYTES, 0, 9999999, 0);
|
segment.applied_rate = 1.0;
|
||||||
|
segment.start = 0;
|
||||||
|
segment.stop = 9999999;
|
||||||
|
segment.time = 0;
|
||||||
|
|
||||||
GST_LOG ("BYTE: %" GST_SEGMENT_FORMAT, &segment);
|
GST_LOG ("BYTE: %" GST_SEGMENT_FORMAT, &segment);
|
||||||
}
|
}
|
||||||
|
@ -154,8 +160,11 @@ GST_START_TEST (info_segment_format_printf_extension)
|
||||||
|
|
||||||
gst_segment_init (&segment, 98765432);
|
gst_segment_init (&segment, 98765432);
|
||||||
|
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
segment.rate = 1.0;
|
||||||
GST_FORMAT_BYTES, 0, 987654321, 0);
|
segment.applied_rate = 1.0;
|
||||||
|
segment.start = 0;
|
||||||
|
segment.stop = 987654321;
|
||||||
|
segment.time = 0;
|
||||||
|
|
||||||
GST_LOG ("UNKNOWN: %" GST_SEGMENT_FORMAT, &segment);
|
GST_LOG ("UNKNOWN: %" GST_SEGMENT_FORMAT, &segment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,13 @@ GST_START_TEST (segment_seek_nosize)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
gint64 cstart, cstop;
|
guint64 cstart, cstop;
|
||||||
gboolean update;
|
gboolean update;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
||||||
|
|
||||||
/* configure segment to start 100 */
|
/* configure segment to start 100 */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
|
@ -43,7 +43,7 @@ GST_START_TEST (segment_seek_nosize)
|
||||||
|
|
||||||
/* configure segment to stop relative, should not do anything since
|
/* configure segment to stop relative, should not do anything since
|
||||||
* size is unknown. */
|
* size is unknown. */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
|
GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
|
||||||
|
@ -121,7 +121,7 @@ GST_START_TEST (segment_seek_nosize)
|
||||||
fail_unless (cstop == -1);
|
fail_unless (cstop == -1);
|
||||||
|
|
||||||
/* add 100 to start, set stop to 300 */
|
/* add 100 to start, set stop to 300 */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
|
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
|
||||||
|
@ -133,7 +133,7 @@ GST_START_TEST (segment_seek_nosize)
|
||||||
/* add 100 to start (to 300), set stop to 200, this is not allowed.
|
/* add 100 to start (to 300), set stop to 200, this is not allowed.
|
||||||
* nothing should be updated in the segment. A g_warning is
|
* nothing should be updated in the segment. A g_warning is
|
||||||
* emited. */
|
* emited. */
|
||||||
ASSERT_CRITICAL (gst_segment_set_seek (&segment, 1.0,
|
ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update));
|
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update));
|
||||||
|
@ -145,7 +145,7 @@ GST_START_TEST (segment_seek_nosize)
|
||||||
update = TRUE;
|
update = TRUE;
|
||||||
/* seek relative to end, should not do anything since size is
|
/* seek relative to end, should not do anything since size is
|
||||||
* unknown. */
|
* unknown. */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
|
GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
|
||||||
|
@ -226,14 +226,14 @@ GST_START_TEST (segment_seek_size)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
gint64 cstart, cstop;
|
guint64 cstart, cstop;
|
||||||
gboolean update;
|
gboolean update;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
||||||
gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
|
segment.duration = 200;
|
||||||
|
|
||||||
/* configure segment to start 100 */
|
/* configure segment to start 100 */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
|
@ -243,7 +243,7 @@ GST_START_TEST (segment_seek_size)
|
||||||
|
|
||||||
/* configure segment to stop relative, does not update stop
|
/* configure segment to stop relative, does not update stop
|
||||||
* since we did not set it before. */
|
* since we did not set it before. */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
|
GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
|
||||||
|
@ -310,7 +310,7 @@ GST_START_TEST (segment_seek_size)
|
||||||
fail_unless (cstop == -1);
|
fail_unless (cstop == -1);
|
||||||
|
|
||||||
/* add 100 to start, set stop to 300, stop clips to 200 */
|
/* add 100 to start, set stop to 300, stop clips to 200 */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
|
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
|
||||||
|
@ -319,7 +319,7 @@ GST_START_TEST (segment_seek_size)
|
||||||
|
|
||||||
/* add 100 to start (to 300), set stop to 200, this clips start
|
/* add 100 to start (to 300), set stop to 200, this clips start
|
||||||
* to duration */
|
* to duration */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update);
|
GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update);
|
||||||
|
@ -328,7 +328,7 @@ GST_START_TEST (segment_seek_size)
|
||||||
fail_unless (update == FALSE);
|
fail_unless (update == FALSE);
|
||||||
|
|
||||||
/* seek relative to end */
|
/* seek relative to end */
|
||||||
gst_segment_set_seek (&segment, 1.0,
|
gst_segment_do_seek (&segment, 1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
|
GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
|
||||||
|
@ -410,38 +410,38 @@ GST_START_TEST (segment_seek_reverse)
|
||||||
gboolean update;
|
gboolean update;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
||||||
gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
|
segment.duration = 200;
|
||||||
|
|
||||||
/* configure segment to stop 100 */
|
/* configure segment to stop 100 */
|
||||||
gst_segment_set_seek (&segment, -1.0,
|
gst_segment_do_seek (&segment, -1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
|
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 100);
|
fail_unless (segment.stop == 100);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.last_stop == 100);
|
fail_unless (segment.position == 100);
|
||||||
fail_unless (update == TRUE);
|
fail_unless (update == TRUE);
|
||||||
|
|
||||||
/* update */
|
/* update */
|
||||||
gst_segment_set_seek (&segment, -1.0,
|
gst_segment_do_seek (&segment, -1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_CUR, -20, &update);
|
GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_CUR, -20, &update);
|
||||||
fail_unless (segment.start == 10);
|
fail_unless (segment.start == 10);
|
||||||
fail_unless (segment.stop == 80);
|
fail_unless (segment.stop == 80);
|
||||||
fail_unless (segment.time == 10);
|
fail_unless (segment.time == 10);
|
||||||
fail_unless (segment.last_stop == 80);
|
fail_unless (segment.position == 80);
|
||||||
fail_unless (update == TRUE);
|
fail_unless (update == TRUE);
|
||||||
|
|
||||||
gst_segment_set_seek (&segment, -1.0,
|
gst_segment_do_seek (&segment, -1.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
|
GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
|
||||||
fail_unless (segment.start == 20);
|
fail_unless (segment.start == 20);
|
||||||
fail_unless (segment.stop == 80);
|
fail_unless (segment.stop == 80);
|
||||||
fail_unless (segment.time == 20);
|
fail_unless (segment.time == 20);
|
||||||
fail_unless (segment.last_stop == 80);
|
fail_unless (segment.position == 80);
|
||||||
fail_unless (update == FALSE);
|
fail_unless (update == FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ GST_START_TEST (segment_seek_rate)
|
||||||
|
|
||||||
/* configure segment to rate 2.0, format does not matter when we don't specify
|
/* configure segment to rate 2.0, format does not matter when we don't specify
|
||||||
* a start or stop position. */
|
* a start or stop position. */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_UNDEFINED,
|
GST_FORMAT_UNDEFINED,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
|
@ -468,42 +468,42 @@ GST_START_TEST (segment_seek_rate)
|
||||||
fail_unless (update == FALSE);
|
fail_unless (update == FALSE);
|
||||||
|
|
||||||
/* 0 is the same in all formats and should not fail */
|
/* 0 is the same in all formats and should not fail */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
fail_unless (segment.format == GST_FORMAT_BYTES);
|
fail_unless (segment.format == GST_FORMAT_BYTES);
|
||||||
|
|
||||||
/* set to -1 means start from 0 */
|
/* set to -1 means start from 0 */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_SET, -1, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_SET, -1, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
fail_unless (segment.format == GST_FORMAT_BYTES);
|
fail_unless (segment.format == GST_FORMAT_BYTES);
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
|
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, 0, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_CUR, 0, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
|
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_END, 0, GST_SEEK_TYPE_NONE, -1, &update);
|
GST_SEEK_TYPE_END, 0, GST_SEEK_TYPE_NONE, -1, &update);
|
||||||
|
|
||||||
/* -1 for end is fine too in all formats */
|
/* -1 for end is fine too in all formats */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
|
||||||
|
|
||||||
/* 0 as relative end is fine too */
|
/* 0 as relative end is fine too */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
|
||||||
|
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
|
||||||
|
|
||||||
/* set a real stop position, this must happen in bytes */
|
/* set a real stop position, this must happen in bytes */
|
||||||
gst_segment_set_seek (&segment, 3.0,
|
gst_segment_do_seek (&segment, 3.0,
|
||||||
GST_FORMAT_BYTES,
|
GST_FORMAT_BYTES,
|
||||||
GST_SEEK_FLAG_NONE,
|
GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
|
||||||
|
@ -516,51 +516,51 @@ GST_START_TEST (segment_seek_rate)
|
||||||
fail_unless (update == FALSE);
|
fail_unless (update == FALSE);
|
||||||
|
|
||||||
/* 0 as relative end is fine too */
|
/* 0 as relative end is fine too */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
|
||||||
fail_unless (segment.stop == 100);
|
fail_unless (segment.stop == 100);
|
||||||
|
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
|
||||||
fail_unless (segment.stop == 100);
|
fail_unless (segment.stop == 100);
|
||||||
|
|
||||||
/* -1 for end is fine too in all formats */
|
/* -1 for end is fine too in all formats */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
|
|
||||||
/* set some duration, stop -1 END seeks will now work with the
|
/* set some duration, stop -1 END seeks will now work with the
|
||||||
* duration, if the formats match */
|
* duration, if the formats match */
|
||||||
gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
|
segment.duration = 200;
|
||||||
fail_unless (segment.duration == 200);
|
fail_unless (segment.duration == 200);
|
||||||
|
|
||||||
/* seek to end in any format with 0 should set the stop to the
|
/* seek to end in any format with 0 should set the stop to the
|
||||||
* duration */
|
* duration */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.duration == 200);
|
fail_unless (segment.duration == 200);
|
||||||
|
|
||||||
/* subtract 100 from the end */
|
/* subtract 100 from the end */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
|
||||||
fail_unless (segment.stop == 100);
|
fail_unless (segment.stop == 100);
|
||||||
fail_unless (segment.duration == 200);
|
fail_unless (segment.duration == 200);
|
||||||
|
|
||||||
/* add 100 to the duration, this should be clamped to the duration */
|
/* add 100 to the duration, this should be clamped to the duration */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
|
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.duration == 200);
|
fail_unless (segment.duration == 200);
|
||||||
|
|
||||||
/* add 300 to the start, this should be clamped to the duration */
|
/* add 300 to the start, this should be clamped to the duration */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, 300, GST_SEEK_TYPE_END, 0, &update);
|
GST_SEEK_TYPE_CUR, 300, GST_SEEK_TYPE_END, 0, &update);
|
||||||
fail_unless (segment.start == 200);
|
fail_unless (segment.start == 200);
|
||||||
|
@ -568,7 +568,7 @@ GST_START_TEST (segment_seek_rate)
|
||||||
fail_unless (segment.duration == 200);
|
fail_unless (segment.duration == 200);
|
||||||
|
|
||||||
/* subtract 300 from the start, this should be clamped to 0 */
|
/* subtract 300 from the start, this should be clamped to 0 */
|
||||||
gst_segment_set_seek (&segment, 2.0,
|
gst_segment_do_seek (&segment, 2.0,
|
||||||
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
|
||||||
GST_SEEK_TYPE_CUR, -300, GST_SEEK_TYPE_END, 0, &update);
|
GST_SEEK_TYPE_CUR, -300, GST_SEEK_TYPE_END, 0, &update);
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
|
@ -578,6 +578,7 @@ GST_START_TEST (segment_seek_rate)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* mess with the segment structure in the bytes format */
|
/* mess with the segment structure in the bytes format */
|
||||||
GST_START_TEST (segment_newsegment_open)
|
GST_START_TEST (segment_newsegment_open)
|
||||||
{
|
{
|
||||||
|
@ -595,8 +596,8 @@ GST_START_TEST (segment_newsegment_open)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* we set stop but in the wrong format, stop stays open. */
|
/* we set stop but in the wrong format, stop stays open. */
|
||||||
|
@ -606,8 +607,8 @@ GST_START_TEST (segment_newsegment_open)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
|
|
||||||
/* update, nothing changes */
|
/* update, nothing changes */
|
||||||
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 0, -1,
|
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 0, -1,
|
||||||
|
@ -616,8 +617,8 @@ GST_START_TEST (segment_newsegment_open)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
|
|
||||||
/* update */
|
/* update */
|
||||||
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
|
||||||
|
@ -626,31 +627,31 @@ GST_START_TEST (segment_newsegment_open)
|
||||||
fail_unless (segment.start == 100);
|
fail_unless (segment.start == 100);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
fail_unless (segment.time == 100);
|
fail_unless (segment.time == 100);
|
||||||
fail_unless (segment.accum == 100);
|
fail_unless (segment.base == 100);
|
||||||
fail_unless (segment.last_stop == 100);
|
fail_unless (segment.position == 100);
|
||||||
|
|
||||||
/* last_stop 0, accum does not change */
|
/* last_stop 0, base does not change */
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
|
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 100);
|
fail_unless (segment.base == 100);
|
||||||
|
|
||||||
gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 200);
|
gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 200);
|
||||||
|
|
||||||
fail_unless (segment.last_stop == 200);
|
fail_unless (segment.position == 200);
|
||||||
|
|
||||||
/* last_stop 200, accum changes */
|
/* last_stop 200, base changes */
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
|
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == -1);
|
fail_unless (segment.stop == -1);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 300);
|
fail_unless (segment.base == 300);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -672,13 +673,13 @@ GST_START_TEST (segment_newsegment_closed)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* assume we advanced to position 40 */
|
/* assume we advanced to position 40 */
|
||||||
gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 40);
|
gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 40);
|
||||||
fail_unless (segment.last_stop == 40);
|
fail_unless (segment.position == 40);
|
||||||
|
|
||||||
/* do an update to the start, last_stop is unchanged because it's bigger */
|
/* do an update to the start, last_stop is unchanged because it's bigger */
|
||||||
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 20,
|
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 20,
|
||||||
|
@ -687,8 +688,8 @@ GST_START_TEST (segment_newsegment_closed)
|
||||||
fail_unless (segment.start == 20);
|
fail_unless (segment.start == 20);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 20);
|
fail_unless (segment.time == 20);
|
||||||
fail_unless (segment.accum == 20);
|
fail_unless (segment.base == 20);
|
||||||
fail_unless (segment.last_stop == 40);
|
fail_unless (segment.position == 40);
|
||||||
|
|
||||||
/* do an update past our last_stop, it should be updated now */
|
/* do an update past our last_stop, it should be updated now */
|
||||||
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 50,
|
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 50,
|
||||||
|
@ -697,8 +698,8 @@ GST_START_TEST (segment_newsegment_closed)
|
||||||
fail_unless (segment.start == 50);
|
fail_unless (segment.start == 50);
|
||||||
fail_unless (segment.stop == 300);
|
fail_unless (segment.stop == 300);
|
||||||
fail_unless (segment.time == 50);
|
fail_unless (segment.time == 50);
|
||||||
fail_unless (segment.accum == 50);
|
fail_unless (segment.base == 50);
|
||||||
fail_unless (segment.last_stop == 50);
|
fail_unless (segment.position == 50);
|
||||||
|
|
||||||
/* and a new accumulated one */
|
/* and a new accumulated one */
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
||||||
|
@ -707,7 +708,7 @@ GST_START_TEST (segment_newsegment_closed)
|
||||||
fail_unless (segment.start == 100);
|
fail_unless (segment.start == 100);
|
||||||
fail_unless (segment.stop == 400);
|
fail_unless (segment.stop == 400);
|
||||||
fail_unless (segment.time == 300);
|
fail_unless (segment.time == 300);
|
||||||
fail_unless (segment.accum == 300);
|
fail_unless (segment.base == 300);
|
||||||
|
|
||||||
/* and a new updated one */
|
/* and a new updated one */
|
||||||
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
|
||||||
|
@ -716,7 +717,7 @@ GST_START_TEST (segment_newsegment_closed)
|
||||||
fail_unless (segment.start == 100);
|
fail_unless (segment.start == 100);
|
||||||
fail_unless (segment.stop == 500);
|
fail_unless (segment.stop == 500);
|
||||||
fail_unless (segment.time == 300);
|
fail_unless (segment.time == 300);
|
||||||
fail_unless (segment.accum == 300);
|
fail_unless (segment.base == 300);
|
||||||
|
|
||||||
/* and a new partially updated one */
|
/* and a new partially updated one */
|
||||||
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
|
||||||
|
@ -725,7 +726,7 @@ GST_START_TEST (segment_newsegment_closed)
|
||||||
fail_unless (segment.start == 200);
|
fail_unless (segment.start == 200);
|
||||||
fail_unless (segment.stop == 500);
|
fail_unless (segment.stop == 500);
|
||||||
fail_unless (segment.time == 400);
|
fail_unless (segment.time == 400);
|
||||||
fail_unless (segment.accum == 400);
|
fail_unless (segment.base == 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -734,7 +735,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_streamtime)
|
GST_START_TEST (segment_newsegment_streamtime)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -751,8 +752,8 @@ GST_START_TEST (segment_newsegment_streamtime)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -778,7 +779,7 @@ GST_START_TEST (segment_newsegment_streamtime)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
||||||
GST_FORMAT_TIME, 0, 200, 500);
|
GST_FORMAT_TIME, 0, 200, 500);
|
||||||
|
|
||||||
fail_unless (segment.accum == 200);
|
fail_unless (segment.base == 200);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -803,7 +804,7 @@ GST_START_TEST (segment_newsegment_streamtime)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
||||||
GST_FORMAT_TIME, 500, 700, 0);
|
GST_FORMAT_TIME, 500, 700, 0);
|
||||||
|
|
||||||
fail_unless (segment.accum == 400);
|
fail_unless (segment.base == 400);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -832,7 +833,7 @@ GST_START_TEST (segment_newsegment_streamtime)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
|
||||||
GST_FORMAT_TIME, 500, 700, 200);
|
GST_FORMAT_TIME, 500, 700, 200);
|
||||||
|
|
||||||
fail_unless (segment.accum == 600);
|
fail_unless (segment.base == 600);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -862,7 +863,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_streamtime_rate)
|
GST_START_TEST (segment_newsegment_streamtime_rate)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -879,8 +880,8 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -909,7 +910,7 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
|
||||||
GST_FORMAT_TIME, 100, 300, 0);
|
GST_FORMAT_TIME, 100, 300, 0);
|
||||||
|
|
||||||
fail_unless (segment.accum == 100);
|
fail_unless (segment.base == 100);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -940,7 +941,7 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
|
||||||
GST_FORMAT_TIME, 100, 300, 0);
|
GST_FORMAT_TIME, 100, 300, 0);
|
||||||
|
|
||||||
fail_unless (segment.accum == 200);
|
fail_unless (segment.base == 200);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -982,7 +983,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_streamtime_applied_rate)
|
GST_START_TEST (segment_newsegment_streamtime_applied_rate)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -1001,8 +1002,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 200);
|
fail_unless (segment.time == 200);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1041,8 +1042,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 200);
|
fail_unless (segment.base == 200);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1083,8 +1084,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 400);
|
fail_unless (segment.time == 400);
|
||||||
/* previous segment lasted 200, rate of 2.0 was already applied */
|
/* previous segment lasted 200, rate of 2.0 was already applied */
|
||||||
fail_unless (segment.accum == 400);
|
fail_unless (segment.base == 400);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1124,8 +1125,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 200);
|
fail_unless (segment.time == 200);
|
||||||
fail_unless (segment.accum == 600);
|
fail_unless (segment.base == 600);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1157,7 +1158,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
|
GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -1177,8 +1178,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1218,8 +1219,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 200);
|
fail_unless (segment.time == 200);
|
||||||
/* previous segment lasted 100 */
|
/* previous segment lasted 100 */
|
||||||
fail_unless (segment.accum == 100);
|
fail_unless (segment.base == 100);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1259,8 +1260,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 200);
|
fail_unless (segment.time == 200);
|
||||||
/* accumulated 100 of previous segment to make 200 */
|
/* accumulated 100 of previous segment to make 200 */
|
||||||
fail_unless (segment.accum == 200);
|
fail_unless (segment.base == 200);
|
||||||
fail_unless (segment.last_stop == 200);
|
fail_unless (segment.position == 200);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1299,8 +1300,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 400);
|
fail_unless (segment.base == 400);
|
||||||
fail_unless (segment.last_stop == 200);
|
fail_unless (segment.position == 200);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1331,7 +1332,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_runningtime)
|
GST_START_TEST (segment_newsegment_runningtime)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -1348,8 +1349,8 @@ GST_START_TEST (segment_newsegment_runningtime)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 0);
|
fail_unless (segment.position == 0);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1388,7 +1389,7 @@ GST_START_TEST (segment_newsegment_runningtime)
|
||||||
GST_FORMAT_TIME, 0, 200, 500);
|
GST_FORMAT_TIME, 0, 200, 500);
|
||||||
|
|
||||||
/* normal speed gives elapsed of 200 */
|
/* normal speed gives elapsed of 200 */
|
||||||
fail_unless (segment.accum == 200);
|
fail_unless (segment.base == 200);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -1419,7 +1420,7 @@ GST_START_TEST (segment_newsegment_runningtime)
|
||||||
|
|
||||||
/* previous segment played at double speed gives elapsed time of
|
/* previous segment played at double speed gives elapsed time of
|
||||||
* 100 added to previous accum of 200 gives 300. */
|
* 100 added to previous accum of 200 gives 300. */
|
||||||
fail_unless (segment.accum == 300);
|
fail_unless (segment.base == 300);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -1461,7 +1462,7 @@ GST_START_TEST (segment_newsegment_runningtime)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
|
gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
|
||||||
GST_FORMAT_TIME, 500, 700, 200);
|
GST_FORMAT_TIME, 500, 700, 200);
|
||||||
|
|
||||||
fail_unless (segment.accum == 500);
|
fail_unless (segment.base == 500);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -1503,7 +1504,7 @@ GST_START_TEST (segment_newsegment_runningtime)
|
||||||
gst_segment_set_newsegment (&segment, FALSE, -2.0, -2.0,
|
gst_segment_set_newsegment (&segment, FALSE, -2.0, -2.0,
|
||||||
GST_FORMAT_TIME, 500, 700, 200);
|
GST_FORMAT_TIME, 500, 700, 200);
|
||||||
|
|
||||||
fail_unless (segment.accum == 700);
|
fail_unless (segment.base == 700);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
||||||
|
@ -1542,7 +1543,7 @@ GST_START_TEST (segment_newsegment_runningtime)
|
||||||
GST_FORMAT_TIME, 500, 700, 200);
|
GST_FORMAT_TIME, 500, 700, 200);
|
||||||
|
|
||||||
/* previous segment lasted 100, and was at 700 so we should get 800 */
|
/* previous segment lasted 100, and was at 700 so we should get 800 */
|
||||||
fail_unless (segment.accum == 800);
|
fail_unless (segment.base == 800);
|
||||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
|
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
|
||||||
fail_unless (result == 700);
|
fail_unless (result == 700);
|
||||||
}
|
}
|
||||||
|
@ -1553,7 +1554,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_accum)
|
GST_START_TEST (segment_newsegment_accum)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -1570,8 +1571,8 @@ GST_START_TEST (segment_newsegment_accum)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 200);
|
fail_unless (segment.position == 200);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1599,8 +1600,8 @@ GST_START_TEST (segment_newsegment_accum)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 150);
|
fail_unless (segment.stop == 150);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 50);
|
fail_unless (segment.base == 50);
|
||||||
fail_unless (segment.last_stop == 150);
|
fail_unless (segment.position == 150);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
||||||
|
@ -1625,8 +1626,8 @@ GST_START_TEST (segment_newsegment_accum)
|
||||||
fail_unless (segment.start == 100);
|
fail_unless (segment.start == 100);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 100);
|
fail_unless (segment.time == 100);
|
||||||
fail_unless (segment.accum == 50);
|
fail_unless (segment.base == 50);
|
||||||
fail_unless (segment.last_stop == 150);
|
fail_unless (segment.position == 150);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
|
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
|
||||||
|
@ -1646,7 +1647,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (segment_newsegment_accum2)
|
GST_START_TEST (segment_newsegment_accum2)
|
||||||
{
|
{
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
gint64 result;
|
guint64 result;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -1663,8 +1664,8 @@ GST_START_TEST (segment_newsegment_accum2)
|
||||||
fail_unless (segment.start == 0);
|
fail_unless (segment.start == 0);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 200);
|
fail_unless (segment.position == 200);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1694,8 +1695,8 @@ GST_START_TEST (segment_newsegment_accum2)
|
||||||
fail_unless (segment.start == 150);
|
fail_unless (segment.start == 150);
|
||||||
fail_unless (segment.stop == 200);
|
fail_unless (segment.stop == 200);
|
||||||
fail_unless (segment.time == 0);
|
fail_unless (segment.time == 0);
|
||||||
fail_unless (segment.accum == 0);
|
fail_unless (segment.base == 0);
|
||||||
fail_unless (segment.last_stop == 200);
|
fail_unless (segment.position == 200);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* new segment, this accumulates 50. */
|
/* new segment, this accumulates 50. */
|
||||||
|
@ -1709,8 +1710,8 @@ GST_START_TEST (segment_newsegment_accum2)
|
||||||
fail_unless (segment.start == 150);
|
fail_unless (segment.start == 150);
|
||||||
fail_unless (segment.stop == 300);
|
fail_unless (segment.stop == 300);
|
||||||
fail_unless (segment.time == 150);
|
fail_unless (segment.time == 150);
|
||||||
fail_unless (segment.accum == 50);
|
fail_unless (segment.base == 50);
|
||||||
fail_unless (segment.last_stop == 150);
|
fail_unless (segment.position == 150);
|
||||||
fail_unless (segment.duration == -1);
|
fail_unless (segment.duration == -1);
|
||||||
|
|
||||||
/* invalid time gives invalid result */
|
/* invalid time gives invalid result */
|
||||||
|
@ -1729,6 +1730,7 @@ GST_START_TEST (segment_newsegment_accum2)
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_START_TEST (segment_copy)
|
GST_START_TEST (segment_copy)
|
||||||
{
|
{
|
||||||
|
@ -1740,8 +1742,11 @@ GST_START_TEST (segment_copy)
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
|
segment.rate = -1.0;
|
||||||
GST_FORMAT_TIME, 0, 200, 0);
|
segment.applied_rate = 1.0;
|
||||||
|
segment.start = 0;
|
||||||
|
segment.stop = 200;
|
||||||
|
segment.time = 0;
|
||||||
|
|
||||||
copy = gst_segment_copy (&segment);
|
copy = gst_segment_copy (&segment);
|
||||||
fail_unless (copy != NULL);
|
fail_unless (copy != NULL);
|
||||||
|
@ -1766,6 +1771,7 @@ gst_segment_suite (void)
|
||||||
tcase_add_test (tc_chain, segment_seek_size);
|
tcase_add_test (tc_chain, segment_seek_size);
|
||||||
tcase_add_test (tc_chain, segment_seek_reverse);
|
tcase_add_test (tc_chain, segment_seek_reverse);
|
||||||
tcase_add_test (tc_chain, segment_seek_rate);
|
tcase_add_test (tc_chain, segment_seek_rate);
|
||||||
|
#if 0
|
||||||
tcase_add_test (tc_chain, segment_newsegment_open);
|
tcase_add_test (tc_chain, segment_newsegment_open);
|
||||||
tcase_add_test (tc_chain, segment_newsegment_closed);
|
tcase_add_test (tc_chain, segment_newsegment_closed);
|
||||||
tcase_add_test (tc_chain, segment_newsegment_streamtime);
|
tcase_add_test (tc_chain, segment_newsegment_streamtime);
|
||||||
|
@ -1775,6 +1781,7 @@ gst_segment_suite (void)
|
||||||
tcase_add_test (tc_chain, segment_newsegment_runningtime);
|
tcase_add_test (tc_chain, segment_newsegment_runningtime);
|
||||||
tcase_add_test (tc_chain, segment_newsegment_accum);
|
tcase_add_test (tc_chain, segment_newsegment_accum);
|
||||||
tcase_add_test (tc_chain, segment_newsegment_accum2);
|
tcase_add_test (tc_chain, segment_newsegment_accum2);
|
||||||
|
#endif
|
||||||
tcase_add_test (tc_chain, segment_copy);
|
tcase_add_test (tc_chain, segment_copy);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
|
@ -484,15 +484,14 @@ GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
newsegment_event_catcher (GstObject * pad, GstEvent * event,
|
segment_event_catcher (GstObject * pad, GstEvent * event, gpointer * user_data)
|
||||||
gpointer * user_data)
|
|
||||||
{
|
{
|
||||||
GstEvent **last_event = (GstEvent **) user_data;
|
GstEvent **last_event = (GstEvent **) user_data;
|
||||||
fail_unless (event != NULL);
|
fail_unless (event != NULL);
|
||||||
fail_unless (GST_IS_EVENT (event));
|
fail_unless (GST_IS_EVENT (event));
|
||||||
fail_unless (user_data != NULL);
|
fail_unless (user_data != NULL);
|
||||||
|
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
|
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||||
if (*last_event)
|
if (*last_event)
|
||||||
gst_event_unref (*last_event);
|
gst_event_unref (*last_event);
|
||||||
*last_event = gst_event_copy (event);
|
*last_event = gst_event_copy (event);
|
||||||
|
@ -502,7 +501,7 @@ newsegment_event_catcher (GstObject * pad, GstEvent * event,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* basesrc_seek_events_rate_update:
|
/* basesrc_seek_events_rate_update:
|
||||||
* - make sure we get expected newsegment after sending a seek event
|
* - make sure we get expected segment after sending a seek event
|
||||||
*/
|
*/
|
||||||
GST_START_TEST (basesrc_seek_events_rate_update)
|
GST_START_TEST (basesrc_seek_events_rate_update)
|
||||||
{
|
{
|
||||||
|
@ -512,10 +511,10 @@ GST_START_TEST (basesrc_seek_events_rate_update)
|
||||||
GstBus *bus;
|
GstBus *bus;
|
||||||
GstPad *probe_pad;
|
GstPad *probe_pad;
|
||||||
guint probe;
|
guint probe;
|
||||||
GstEvent *newseg_event = NULL;
|
GstEvent *seg_event = NULL;
|
||||||
GstEvent *rate_seek;
|
GstEvent *rate_seek;
|
||||||
gboolean event_ret;
|
gboolean event_ret;
|
||||||
gdouble rate = 0.5;
|
GstSegment segment;
|
||||||
|
|
||||||
pipe = gst_pipeline_new ("pipeline");
|
pipe = gst_pipeline_new ("pipeline");
|
||||||
sink = gst_element_factory_make ("fakesink", "sink");
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
|
@ -537,7 +536,7 @@ GST_START_TEST (basesrc_seek_events_rate_update)
|
||||||
fail_unless (probe_pad != NULL);
|
fail_unless (probe_pad != NULL);
|
||||||
|
|
||||||
probe = gst_pad_add_event_probe (probe_pad,
|
probe = gst_pad_add_event_probe (probe_pad,
|
||||||
G_CALLBACK (newsegment_event_catcher), &newseg_event);
|
G_CALLBACK (segment_event_catcher), &seg_event);
|
||||||
|
|
||||||
/* prepare the seek */
|
/* prepare the seek */
|
||||||
rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
|
||||||
|
@ -579,16 +578,15 @@ GST_START_TEST (basesrc_seek_events_rate_update)
|
||||||
GST_INFO ("stopped");
|
GST_INFO ("stopped");
|
||||||
|
|
||||||
/* check that we have go the event */
|
/* check that we have go the event */
|
||||||
fail_unless (newseg_event != NULL);
|
fail_unless (seg_event != NULL);
|
||||||
|
|
||||||
gst_event_parse_new_segment (newseg_event, NULL, &rate, NULL, NULL, NULL,
|
gst_event_parse_segment (seg_event, &segment);
|
||||||
NULL, NULL);
|
fail_unless (segment.rate == 0.5);
|
||||||
fail_unless (rate == 0.5);
|
|
||||||
|
|
||||||
gst_pad_remove_event_probe (probe_pad, probe);
|
gst_pad_remove_event_probe (probe_pad, probe);
|
||||||
gst_object_unref (probe_pad);
|
gst_object_unref (probe_pad);
|
||||||
gst_message_unref (msg);
|
gst_message_unref (msg);
|
||||||
gst_event_unref (newseg_event);
|
gst_event_unref (seg_event);
|
||||||
gst_object_unref (bus);
|
gst_object_unref (bus);
|
||||||
gst_object_unref (pipe);
|
gst_object_unref (pipe);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue