event/message: Add new instant-rate-sync-time event and instant-rate-request message

This commit is contained in:
Sebastian Dröge 2018-05-14 23:14:24 +03:00 committed by Jan Schmidt
parent be3c4d00cf
commit 74412496cf
6 changed files with 180 additions and 9 deletions

View file

@ -133,6 +133,7 @@ static GstEventQuarks event_quarks[] = {
{GST_EVENT_CUSTOM_BOTH_OOB, "custom-both-oob", 0},
{GST_EVENT_STREAM_GROUP_DONE, "stream-group-done", 0},
{GST_EVENT_INSTANT_RATE_CHANGE, "instant-rate-change", 0},
{GST_EVENT_INSTANT_RATE_SYNC_TIME, "instant-rate-sync-time", 0},
{0, NULL, 0}
};
@ -2239,3 +2240,83 @@ gst_event_parse_instant_rate_change (GstEvent * event,
rate_multiplier, GST_QUARK (FLAGS), GST_TYPE_SEGMENT_FLAGS, new_flags,
NULL);
}
/**
* gst_event_new_instant_rate_sync_time:
* @rate_multiplier: the new playback rate multiplier to be applied
* @running_time: Running time when the rate change should be applied
* @upstream_running_time: The upstream-centric running-time when the
* rate change should be applied.
*
* Create a new instant-rate-sync-time event. This event is sent by the
* pipeline to notify elements handling the instant-rate-change event about
* the running-time when the new rate should be applied. The running time
* may be in the past when elements handle this event, which can lead to
* switching artifacts. The magnitude of those depends on the exact timing
* of event delivery to each element and the magnitude of the change in
* playback rate being applied.
*
* The @running_time and @upstream_running_time are the same if this
* is the first instant-rate adjustment, but will differ for later ones
* to compensate for the accumulated offset due to playing at a rate
* different to the one indicated in the playback segments.
*
* Returns: (transfer full): the new instant-rate-sync-time event.
*
* Since: 1.18
*/
GstEvent *
gst_event_new_instant_rate_sync_time (gdouble rate_multiplier,
GstClockTime running_time, GstClockTime upstream_running_time)
{
GstEvent *event;
g_return_val_if_fail (rate_multiplier != 0.0, NULL);
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (running_time), NULL);
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (upstream_running_time), NULL);
GST_CAT_TRACE (GST_CAT_EVENT,
"creating instant-rate-sync-time event %lf %" GST_TIME_FORMAT
" %" GST_TIME_FORMAT, rate_multiplier,
GST_TIME_ARGS (running_time), GST_TIME_ARGS (upstream_running_time));
event = gst_event_new_custom (GST_EVENT_INSTANT_RATE_SYNC_TIME,
gst_structure_new_id (GST_QUARK (EVENT_INSTANT_RATE_SYNC_TIME),
GST_QUARK (RATE), G_TYPE_DOUBLE, rate_multiplier,
GST_QUARK (RUNNING_TIME), GST_TYPE_CLOCK_TIME, running_time,
GST_QUARK (UPSTREAM_RUNNING_TIME), GST_TYPE_CLOCK_TIME,
upstream_running_time, NULL));
return event;
}
/**
* gst_event_parse_instant_rate_sync_time:
* @event: a #GstEvent of type #GST_EVENT_INSTANT_RATE_CHANGE
* @rate_multiplier: (out) (allow-none): location where to store the rate of
* the instant-rate-sync-time event, or %NULL
* @running_time: (out) (allow-none): location in which to store the running time
* of the instant-rate-sync-time event, or %NULL
* @upstream_running_time: (out) (allow-none): location in which to store the
* upstream running time of the instant-rate-sync-time event, or %NULL
*
* Extract the rate multiplier and running times from an instant-rate-sync-time event.
*
* Since: 1.18
*/
void
gst_event_parse_instant_rate_sync_time (GstEvent * event,
gdouble * rate_multiplier, GstClockTime * running_time,
GstClockTime * upstream_running_time)
{
GstStructure *structure;
g_return_if_fail (GST_IS_EVENT (event));
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_INSTANT_RATE_SYNC_TIME);
structure = GST_EVENT_STRUCTURE (event);
gst_structure_id_get (structure, GST_QUARK (RATE), G_TYPE_DOUBLE,
rate_multiplier, GST_QUARK (RUNNING_TIME), GST_TYPE_CLOCK_TIME,
running_time, GST_QUARK (UPSTREAM_RUNNING_TIME), GST_TYPE_CLOCK_TIME,
upstream_running_time, NULL);
}

View file

@ -123,6 +123,9 @@ typedef enum {
* entry's UID.
* @GST_EVENT_INSTANT_RATE_CHANGE: Notify downstream that a playback rate override
* should be applied as soon as possible. (Since: 1.18)
* @GST_EVENT_INSTANT_RATE_SYNC_TIME: Sent by the pipeline to notify elements that handle the
* instant-rate-change event about the running-time when
* the rate multiplier should be applied (or was applied). (Since: 1.18)
* @GST_EVENT_CUSTOM_UPSTREAM: Upstream custom event
* @GST_EVENT_CUSTOM_DOWNSTREAM: Downstream custom event that travels in the
* data flow.
@ -169,14 +172,15 @@ typedef enum {
GST_EVENT_INSTANT_RATE_CHANGE = GST_EVENT_MAKE_TYPE (180, FLAG(DOWNSTREAM) | FLAG(STICKY)),
/* upstream events */
GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (190, FLAG(UPSTREAM)),
GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (200, FLAG(UPSTREAM)),
GST_EVENT_NAVIGATION = GST_EVENT_MAKE_TYPE (210, FLAG(UPSTREAM)),
GST_EVENT_LATENCY = GST_EVENT_MAKE_TYPE (220, FLAG(UPSTREAM)),
GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (230, FLAG(UPSTREAM)),
GST_EVENT_RECONFIGURE = GST_EVENT_MAKE_TYPE (240, FLAG(UPSTREAM)),
GST_EVENT_TOC_SELECT = GST_EVENT_MAKE_TYPE (250, FLAG(UPSTREAM)),
GST_EVENT_SELECT_STREAMS = GST_EVENT_MAKE_TYPE (260, FLAG(UPSTREAM)),
GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (190, FLAG(UPSTREAM)),
GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (200, FLAG(UPSTREAM)),
GST_EVENT_NAVIGATION = GST_EVENT_MAKE_TYPE (210, FLAG(UPSTREAM)),
GST_EVENT_LATENCY = GST_EVENT_MAKE_TYPE (220, FLAG(UPSTREAM)),
GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (230, FLAG(UPSTREAM)),
GST_EVENT_RECONFIGURE = GST_EVENT_MAKE_TYPE (240, FLAG(UPSTREAM)),
GST_EVENT_TOC_SELECT = GST_EVENT_MAKE_TYPE (250, FLAG(UPSTREAM)),
GST_EVENT_SELECT_STREAMS = GST_EVENT_MAKE_TYPE (260, FLAG(UPSTREAM)),
GST_EVENT_INSTANT_RATE_SYNC_TIME = GST_EVENT_MAKE_TYPE (261, FLAG(UPSTREAM)),
/* custom events start here */
GST_EVENT_CUSTOM_UPSTREAM = GST_EVENT_MAKE_TYPE (270, FLAG(UPSTREAM)),
@ -745,6 +749,19 @@ GST_API
void gst_event_parse_instant_rate_change (GstEvent *event,
gdouble *rate_multiplier, GstSegmentFlags *new_flags);
/* instant-rate-change-sync-time event */
GST_API
GstEvent * gst_event_new_instant_rate_sync_time (gdouble rate,
GstClockTime running_time,
GstClockTime upstream_running_time) G_GNUC_MALLOC;
GST_API
void gst_event_parse_instant_rate_sync_time (GstEvent *event,
gdouble *rate,
GstClockTime *running_time,
GstClockTime *upstream_running_time);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstEvent, gst_event_unref)
G_END_DECLS

View file

@ -112,6 +112,7 @@ static GstMessageQuarks message_quarks[] = {
{GST_MESSAGE_STREAM_COLLECTION, "stream-collection", 0},
{GST_MESSAGE_STREAMS_SELECTED, "streams-selected", 0},
{GST_MESSAGE_REDIRECT, "redirect", 0},
{GST_MESSAGE_INSTANT_RATE_REQUEST, "instant-rate-request", 0},
{0, NULL, 0}
};
@ -3266,3 +3267,59 @@ gst_message_get_num_redirect_entries (GstMessage * message)
return size;
}
/**
* gst_message_new_instant_rate_request:
* @src: The #GstObject that posted the message
* @rate_multiplier: the rate multiplier factor that should be applied
*
* Creates a new instant-rate-request message. Elements handling the
* instant-rate-change event must post this message. The message is
* handled at the pipeline, and allows the pipeline to select the
* running time when the rate change should happen and to send an
* @GST_EVENT_INSTANT_RATE_SYNC_TIME event to notify the elements
* in the pipeline.
*
* Returns: a newly allocated #GstMessage
*
* Since: 1.18
*/
GstMessage *
gst_message_new_instant_rate_request (GstObject * src, gdouble rate_multiplier)
{
GstStructure *structure;
GstMessage *message;
g_return_val_if_fail (rate_multiplier != 0.0, NULL);
structure = gst_structure_new_id (GST_QUARK (MESSAGE_INSTANT_RATE_REQUEST),
GST_QUARK (RATE), G_TYPE_DOUBLE, rate_multiplier, NULL);
message =
gst_message_new_custom (GST_MESSAGE_INSTANT_RATE_REQUEST, src, structure);
return message;
}
/**
* gst_message_parse_instant_rate_request:
* @message: a #GstMessage of type %GST_MESSAGE_INSTANT_RATE_REQUEST
* @rate_multiplier: (out) (allow-none): return location for the rate, or %NULL
*
* Parses the rate_multiplier from the instant-rate-request message.
*
* Since: 1.18
*/
void
gst_message_parse_instant_rate_request (GstMessage * message,
gdouble * rate_multiplier)
{
GstStructure *structure;
g_return_if_fail (GST_IS_MESSAGE (message));
g_return_if_fail (GST_MESSAGE_TYPE (message) ==
GST_MESSAGE_INSTANT_RATE_REQUEST);
structure = GST_MESSAGE_STRUCTURE (message);
gst_structure_id_get (structure, GST_QUARK (RATE), G_TYPE_DOUBLE,
rate_multiplier, NULL);
}

View file

@ -121,6 +121,9 @@ typedef struct _GstMessage GstMessage;
* response is received with a non-HTTP URL inside. (Since: 1.10)
* @GST_MESSAGE_DEVICE_CHANGED: Message indicating a #GstDevice was changed
* a #GstDeviceProvider (Since: 1.16)
* @GST_MESSAGE_INSTANT_RATE_REQUEST: Message sent by elements to request the
* running time from the pipeline when an instant rate change should
* be applied (which may be in the past when the answer arrives). (Since: 1.18)
* @GST_MESSAGE_ANY: mask for all of the above messages.
*
* The different message types that are available.
@ -174,6 +177,7 @@ typedef enum
GST_MESSAGE_STREAMS_SELECTED = GST_MESSAGE_EXTENDED + 5,
GST_MESSAGE_REDIRECT = GST_MESSAGE_EXTENDED + 6,
GST_MESSAGE_DEVICE_CHANGED = GST_MESSAGE_EXTENDED + 7,
GST_MESSAGE_INSTANT_RATE_REQUEST = GST_MESSAGE_EXTENDED + 8,
GST_MESSAGE_ANY = (gint) (0xffffffff)
} GstMessageType;
@ -869,6 +873,13 @@ void gst_message_parse_redirect_entry (GstMessage * message, gsiz
GST_API
gsize gst_message_get_num_redirect_entries (GstMessage * message);
/* INSTANT_RATE_REQUEST */
GST_API
GstMessage * gst_message_new_instant_rate_request (GstObject * src, gdouble rate_multiplier) G_GNUC_MALLOC;
GST_API
void gst_message_parse_instant_rate_request (GstMessage * message, gdouble * rate_multiplier);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstMessage, gst_message_unref)
G_END_DECLS

View file

@ -78,6 +78,8 @@ static const gchar *_quark_strings[] = {
"GstEventStreamGroupDone", "GstQueryBitrate", "nominal-bitrate",
"GstMessageDeviceChanged", "device-changed", "trickmode-interval",
"GstEventInstantRateChange",
"GstEventInstantRateSyncTime", "GstMessageInstantRateRequest",
"upstream-running-time"
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -223,7 +223,10 @@ typedef enum _GstQuarkId
GST_QUARK_DEVICE_CHANGED = 192,
GST_QUARK_TRICKMODE_INTERVAL = 193,
GST_QUARK_EVENT_INSTANT_RATE_CHANGE = 194,
GST_QUARK_MAX = 195
GST_QUARK_EVENT_INSTANT_RATE_SYNC_TIME = 195,
GST_QUARK_MESSAGE_INSTANT_RATE_REQUEST = 196,
GST_QUARK_UPSTREAM_RUNNING_TIME = 197,
GST_QUARK_MAX = 198
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];