mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-29 20:35:40 +00:00
rtsp-client: add support for Scale and Speed header
Add support for the RTSP Scale and Speed headers by setting the rate in the seek to (scale*speed). We then check the resulting segment for rate and applied rate, and use them as values for the Speed and Scale headers respectively. https://bugzilla.gnome.org/show_bug.cgi?id=754575
This commit is contained in:
parent
65d9aa327c
commit
bc74589601
4 changed files with 386 additions and 33 deletions
|
@ -1730,9 +1730,97 @@ make_base_url (GstRTSPClient * client, GstRTSPUrl * url, const gchar * path)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Check if the given header of type double is present and, if so,
|
||||
* put it's value in the supplied variable.
|
||||
*/
|
||||
static GstRTSPStatusCode
|
||||
parse_header_value_double (GstRTSPClient * client, GstRTSPContext * ctx,
|
||||
GstRTSPHeaderField header, gboolean * present, gdouble * value)
|
||||
{
|
||||
GstRTSPResult res;
|
||||
gchar *str;
|
||||
gchar *end;
|
||||
|
||||
res = gst_rtsp_message_get_header (ctx->request, header, &str, 0);
|
||||
if (res == GST_RTSP_OK) {
|
||||
*value = g_ascii_strtod (str, &end);
|
||||
if (end == str)
|
||||
goto parse_header_failed;
|
||||
|
||||
GST_DEBUG ("client %p: got '%s', value %f", client,
|
||||
gst_rtsp_header_as_text (header), *value);
|
||||
*present = TRUE;
|
||||
} else {
|
||||
*present = FALSE;
|
||||
}
|
||||
|
||||
return GST_RTSP_STS_OK;
|
||||
|
||||
parse_header_failed:
|
||||
{
|
||||
GST_ERROR ("client %p: failed parsing '%s' header", client,
|
||||
gst_rtsp_header_as_text (header));
|
||||
return GST_RTSP_STS_BAD_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse scale and speed headers, if present, and set the rate to
|
||||
* (rate * scale * speed) */
|
||||
static GstRTSPStatusCode
|
||||
parse_scale_and_speed (GstRTSPClient * client, GstRTSPContext * ctx,
|
||||
gboolean * scale_present, gboolean * speed_present, gdouble * rate)
|
||||
{
|
||||
gdouble scale = 1.0;
|
||||
gdouble speed = 1.0;
|
||||
GstRTSPStatusCode status;
|
||||
|
||||
GST_DEBUG ("got rate %f", *rate);
|
||||
|
||||
status = parse_header_value_double (client, ctx, GST_RTSP_HDR_SCALE,
|
||||
scale_present, &scale);
|
||||
if (status != GST_RTSP_STS_OK)
|
||||
return status;
|
||||
|
||||
if (scale_present) {
|
||||
GST_DEBUG ("got Scale %f", scale);
|
||||
if (scale == 0)
|
||||
goto bad_scale_value;
|
||||
*rate *= scale;
|
||||
}
|
||||
|
||||
GST_DEBUG ("rate after parsing Scale %f", *rate);
|
||||
|
||||
status = parse_header_value_double (client, ctx, GST_RTSP_HDR_SPEED,
|
||||
speed_present, &speed);
|
||||
if (status != GST_RTSP_STS_OK)
|
||||
return status;
|
||||
|
||||
if (speed_present) {
|
||||
GST_DEBUG ("got Speed %f", speed);
|
||||
if (speed <= 0)
|
||||
goto bad_speed_value;
|
||||
*rate *= speed;
|
||||
}
|
||||
|
||||
GST_DEBUG ("rate after parsing Speed %f", *rate);
|
||||
|
||||
return status;
|
||||
|
||||
bad_scale_value:
|
||||
{
|
||||
GST_ERROR ("client %p: bad 'Scale' header value (%f)", client, scale);
|
||||
return GST_RTSP_STS_BAD_REQUEST;
|
||||
}
|
||||
bad_speed_value:
|
||||
{
|
||||
GST_ERROR ("client %p: bad 'Speed' header value (%f)", client, speed);
|
||||
return GST_RTSP_STS_BAD_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
static GstRTSPStatusCode
|
||||
setup_play_mode (GstRTSPClient * client, GstRTSPContext * ctx,
|
||||
GstRTSPRangeUnit * unit)
|
||||
GstRTSPRangeUnit * unit, gboolean * scale_present, gboolean * speed_present)
|
||||
{
|
||||
gchar *str;
|
||||
GstRTSPResult res;
|
||||
|
@ -1740,7 +1828,7 @@ setup_play_mode (GstRTSPClient * client, GstRTSPContext * ctx,
|
|||
gdouble rate = 1.0;
|
||||
GstSeekFlags flags = GST_SEEK_FLAG_NONE;
|
||||
GstRTSPClientClass *klass = GST_RTSP_CLIENT_GET_CLASS (client);
|
||||
GstRTSPStatusCode status;
|
||||
GstRTSPStatusCode rtsp_status_code;
|
||||
|
||||
/* parse the range header if we have one */
|
||||
res = gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_RANGE, &str, 0);
|
||||
|
@ -1771,10 +1859,21 @@ setup_play_mode (GstRTSPClient * client, GstRTSPContext * ctx,
|
|||
}
|
||||
}
|
||||
|
||||
/* check for scale and/or speed headers
|
||||
* we will set the seek rate to (speed * scale) and let the media decide
|
||||
* the resulting scale and speed. in the response we will use rate and applied
|
||||
* rate from the resulting segment as values for the speed and scale headers
|
||||
* respectively */
|
||||
rtsp_status_code = parse_scale_and_speed (client, ctx, scale_present,
|
||||
speed_present, &rate);
|
||||
if (rtsp_status_code != GST_RTSP_STS_OK)
|
||||
goto scale_speed_failed;
|
||||
|
||||
/* give the application a chance to tweak range, flags, or rate */
|
||||
if (klass->adjust_play_mode != NULL) {
|
||||
status = klass->adjust_play_mode (client, ctx, &range, &flags, &rate);
|
||||
if (status != GST_RTSP_STS_OK)
|
||||
rtsp_status_code =
|
||||
klass->adjust_play_mode (client, ctx, &range, &flags, &rate);
|
||||
if (rtsp_status_code != GST_RTSP_STS_OK)
|
||||
goto adjust_play_mode_failed;
|
||||
}
|
||||
|
||||
|
@ -1793,12 +1892,20 @@ parse_range_failed:
|
|||
GST_ERROR ("client %p: failed parsing range header", client);
|
||||
return GST_RTSP_STS_BAD_REQUEST;
|
||||
}
|
||||
adjust_play_mode_failed:
|
||||
scale_speed_failed:
|
||||
{
|
||||
GST_ERROR ("client %p: sub class returned bad code (%d)", client, status);
|
||||
if (range != NULL)
|
||||
gst_rtsp_range_free (range);
|
||||
return status;
|
||||
GST_ERROR ("client %p: failed parsing Scale or Speed headers", client);
|
||||
return rtsp_status_code;
|
||||
}
|
||||
adjust_play_mode_failed:
|
||||
{
|
||||
GST_ERROR ("client %p: sub class returned bad code (%d)", client,
|
||||
rtsp_status_code);
|
||||
if (range != NULL)
|
||||
gst_rtsp_range_free (range);
|
||||
return rtsp_status_code;
|
||||
}
|
||||
seek_failed:
|
||||
{
|
||||
|
@ -1824,6 +1931,10 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
gchar *seek_style = NULL;
|
||||
GstRTSPStatusCode sig_result;
|
||||
GPtrArray *transports;
|
||||
gboolean scale_present;
|
||||
gboolean speed_present;
|
||||
gdouble rate;
|
||||
gdouble applied_rate;
|
||||
|
||||
if (!(session = ctx->session))
|
||||
goto no_session;
|
||||
|
@ -1874,7 +1985,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
if (!gst_rtsp_media_unsuspend (media))
|
||||
goto unsuspend_failed;
|
||||
|
||||
code = setup_play_mode (client, ctx, &unit);
|
||||
code = setup_play_mode (client, ctx, &unit, &scale_present, &speed_present);
|
||||
if (code != GST_RTSP_STS_OK)
|
||||
goto invalid_mode;
|
||||
|
||||
|
@ -1899,6 +2010,23 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
if (str)
|
||||
gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RANGE, str);
|
||||
|
||||
if (!gst_rtsp_media_is_receive_only (media)) {
|
||||
/* the scale and speed headers must always be added if they were present in
|
||||
* the request. however, even if they were not, we still add them if
|
||||
* applied_rate or rate deviate from the "normal", i.e. 1.0 */
|
||||
if (!gst_rtsp_media_get_rates (media, &rate, &applied_rate))
|
||||
goto get_rates_error;
|
||||
g_assert (rate != 0 && applied_rate != 0);
|
||||
|
||||
if (scale_present || applied_rate != 1.0)
|
||||
gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_SCALE,
|
||||
g_strdup_printf ("%1.3f", applied_rate));
|
||||
|
||||
if (speed_present || rate != 1.0)
|
||||
gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_SPEED,
|
||||
g_strdup_printf ("%1.3f", rate));
|
||||
}
|
||||
|
||||
send_message (client, ctx, ctx->response, FALSE);
|
||||
|
||||
/* start playing after sending the response */
|
||||
|
@ -1976,6 +2104,12 @@ unsupported_mode:
|
|||
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
|
||||
return FALSE;
|
||||
}
|
||||
get_rates_error:
|
||||
{
|
||||
GST_ERROR ("client %p: failed obtaining rate and applied_rate", client);
|
||||
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -732,25 +732,6 @@ default_create_rtpbin (GstRTSPMedia * media)
|
|||
return rtpbin;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_receive_only (GstRTSPMedia * media)
|
||||
{
|
||||
GstRTSPMediaPrivate *priv = media->priv;
|
||||
gboolean recive_only = TRUE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->streams->len; i++) {
|
||||
GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
|
||||
if (gst_rtsp_stream_is_sender (stream) ||
|
||||
!gst_rtsp_stream_is_receiver (stream)) {
|
||||
recive_only = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return recive_only;
|
||||
}
|
||||
|
||||
/* must be called with state lock */
|
||||
static void
|
||||
check_seekable (GstRTSPMedia * media)
|
||||
|
@ -759,7 +740,7 @@ check_seekable (GstRTSPMedia * media)
|
|||
GstRTSPMediaPrivate *priv = media->priv;
|
||||
|
||||
/* Update the seekable state of the pipeline in case it changed */
|
||||
if (is_receive_only (media)) {
|
||||
if (gst_rtsp_media_is_receive_only (media)) {
|
||||
/* TODO: Seeking for "receive-only"? */
|
||||
priv->seekable = -1;
|
||||
} else {
|
||||
|
@ -2984,8 +2965,9 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message)
|
|||
GST_DEBUG ("%p: went from %s to %s (pending %s)", media,
|
||||
gst_element_state_get_name (old), gst_element_state_get_name (new),
|
||||
gst_element_state_get_name (pending));
|
||||
if (priv->no_more_pads_pending == 0 && is_receive_only (media) &&
|
||||
old == GST_STATE_READY && new == GST_STATE_PAUSED) {
|
||||
if (priv->no_more_pads_pending == 0
|
||||
&& gst_rtsp_media_is_receive_only (media) && old == GST_STATE_READY
|
||||
&& new == GST_STATE_PAUSED) {
|
||||
GST_INFO ("%p: went to PAUSED, prepared now", media);
|
||||
collect_media_stats (media);
|
||||
|
||||
|
@ -3459,7 +3441,7 @@ start_prepare (GstRTSPMedia * media)
|
|||
g_object_set_data (G_OBJECT (elem), "gst-rtsp-dynpay-handlers", handlers);
|
||||
}
|
||||
|
||||
if (priv->nb_dynamic_elements == 0 && is_receive_only (media)) {
|
||||
if (priv->nb_dynamic_elements == 0 && gst_rtsp_media_is_receive_only (media)) {
|
||||
/* If we are receive_only (RECORD), do not try to preroll, to avoid
|
||||
* a second ASYNC state change failing */
|
||||
priv->is_live = TRUE;
|
||||
|
@ -4286,7 +4268,7 @@ default_unsuspend (GstRTSPMedia * media)
|
|||
|
||||
switch (priv->suspend_mode) {
|
||||
case GST_RTSP_SUSPEND_MODE_NONE:
|
||||
if (is_receive_only (media))
|
||||
if (gst_rtsp_media_is_receive_only (media))
|
||||
break;
|
||||
if (media_streams_blocking (media)) {
|
||||
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
|
||||
|
@ -4713,3 +4695,28 @@ gst_rtsp_media_complete_pipeline (GstRTSPMedia * media, GPtrArray * transports)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_media_is_receive_only:
|
||||
*
|
||||
* Returns: %TRUE if @media is receive-only, %FALSE otherwise.
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_media_is_receive_only (GstRTSPMedia * media)
|
||||
{
|
||||
GstRTSPMediaPrivate *priv = media->priv;
|
||||
gboolean receive_only = TRUE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->streams->len; i++) {
|
||||
GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
|
||||
if (gst_rtsp_stream_is_sender (stream) ||
|
||||
!gst_rtsp_stream_is_receiver (stream)) {
|
||||
receive_only = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return receive_only;
|
||||
}
|
||||
|
|
|
@ -417,6 +417,9 @@ void gst_rtsp_media_set_pipeline_state (GstRTSPMedia * media,
|
|||
GST_RTSP_SERVER_API
|
||||
gboolean gst_rtsp_media_complete_pipeline (GstRTSPMedia * media, GPtrArray * transports);
|
||||
|
||||
GST_RTSP_SERVER_API
|
||||
gboolean gst_rtsp_media_is_receive_only (GstRTSPMedia * media);
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstRTSPMedia, gst_object_unref)
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,10 @@ static gchar *session_id;
|
|||
static gint cseq;
|
||||
static guint expected_session_timeout = 60;
|
||||
static const gchar *expected_unsupported_header;
|
||||
static const gchar *expected_scale_header;
|
||||
static const gchar *expected_speed_header;
|
||||
static gdouble fake_rate_value = 0;
|
||||
static gdouble fake_applied_rate_value = 0;
|
||||
|
||||
static gboolean
|
||||
test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
|
||||
|
@ -1707,7 +1711,211 @@ GST_START_TEST (test_client_multicast_invalid_ttl)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
static gboolean
|
||||
test_response_scale_speed (GstRTSPClient * client, GstRTSPMessage * response,
|
||||
gboolean close, gpointer user_data)
|
||||
{
|
||||
GstRTSPStatusCode code;
|
||||
const gchar *reason;
|
||||
GstRTSPVersion version;
|
||||
gchar *header_value;
|
||||
|
||||
fail_unless (gst_rtsp_message_get_type (response) ==
|
||||
GST_RTSP_MESSAGE_RESPONSE);
|
||||
|
||||
fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
|
||||
&version)
|
||||
== GST_RTSP_OK);
|
||||
fail_unless (code == GST_RTSP_STS_OK);
|
||||
fail_unless (g_str_equal (reason, "OK"));
|
||||
fail_unless (version == GST_RTSP_VERSION_1_0);
|
||||
|
||||
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_RANGE,
|
||||
&header_value, 0) == GST_RTSP_OK);
|
||||
|
||||
if (expected_scale_header != NULL) {
|
||||
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SCALE,
|
||||
&header_value, 0) == GST_RTSP_OK);
|
||||
ck_assert_str_eq (header_value, expected_scale_header);
|
||||
} else {
|
||||
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SCALE,
|
||||
&header_value, 0) == GST_RTSP_ENOTIMPL);
|
||||
}
|
||||
|
||||
if (expected_speed_header != NULL) {
|
||||
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SPEED,
|
||||
&header_value, 0) == GST_RTSP_OK);
|
||||
ck_assert_str_eq (header_value, expected_speed_header);
|
||||
} else {
|
||||
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SPEED,
|
||||
&header_value, 0) == GST_RTSP_ENOTIMPL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Probe that tweaks segment events according to the values of the
|
||||
* fake_rate_value and fake_applied_rate_value variables. Used to simulate
|
||||
* seek results with different combinations of rate and applied rate.
|
||||
*/
|
||||
static GstPadProbeReturn
|
||||
rate_tweaking_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||
{
|
||||
GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
|
||||
GstSegment segment;
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||
GST_DEBUG ("got segment event %" GST_PTR_FORMAT, event);
|
||||
gst_event_copy_segment (event, &segment);
|
||||
if (fake_applied_rate_value)
|
||||
segment.applied_rate = fake_applied_rate_value;
|
||||
if (fake_rate_value)
|
||||
segment.rate = fake_rate_value;
|
||||
gst_event_unref (event);
|
||||
info->data = gst_event_new_segment (&segment);
|
||||
GST_DEBUG ("forwarding segment event %" GST_PTR_FORMAT,
|
||||
GST_EVENT (info->data));
|
||||
}
|
||||
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
attach_rate_tweaking_probe (void)
|
||||
{
|
||||
GstRTSPContext *ctx;
|
||||
GstRTSPMedia *media;
|
||||
GstRTSPStream *stream;
|
||||
GstPad *srcpad;
|
||||
|
||||
fail_unless ((ctx = gst_rtsp_context_get_current ()) != NULL);
|
||||
|
||||
media = ctx->media;
|
||||
fail_unless (media != NULL);
|
||||
stream = gst_rtsp_media_get_stream (media, 0);
|
||||
fail_unless (stream != NULL);
|
||||
|
||||
srcpad = gst_rtsp_stream_get_srcpad (stream);
|
||||
fail_unless (srcpad != NULL);
|
||||
|
||||
GST_DEBUG ("adding rate_tweaking_probe");
|
||||
|
||||
gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
||||
rate_tweaking_probe, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_test_scale_and_speed (const gchar * scale, const gchar * speed)
|
||||
{
|
||||
GstRTSPClient *client;
|
||||
GstRTSPMessage request = { 0, };
|
||||
gchar *str;
|
||||
GstRTSPContext ctx = { NULL };
|
||||
|
||||
client = setup_multicast_client (1);
|
||||
|
||||
ctx.client = client;
|
||||
ctx.auth = gst_rtsp_auth_new ();
|
||||
ctx.token =
|
||||
gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
|
||||
G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
|
||||
"user", NULL);
|
||||
gst_rtsp_context_push_current (&ctx);
|
||||
|
||||
expected_session_timeout = 20;
|
||||
g_signal_connect (G_OBJECT (client), "new-session",
|
||||
G_CALLBACK (new_session_cb), NULL);
|
||||
|
||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
||||
str = g_strdup_printf ("%d", cseq);
|
||||
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
|
||||
"RTP/AVP;multicast");
|
||||
expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
|
||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
||||
gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
|
||||
fail_unless (gst_rtsp_client_handle_message (client,
|
||||
&request) == GST_RTSP_OK);
|
||||
gst_rtsp_message_unset (&request);
|
||||
expected_transport = NULL;
|
||||
expected_session_timeout = 60;
|
||||
|
||||
if (fake_applied_rate_value || fake_rate_value)
|
||||
attach_rate_tweaking_probe ();
|
||||
|
||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
|
||||
"rtsp://localhost/test") == GST_RTSP_OK);
|
||||
str = g_strdup_printf ("%d", cseq);
|
||||
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
|
||||
|
||||
if (scale != NULL)
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SCALE, scale);
|
||||
if (speed != NULL)
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SPEED, speed);
|
||||
|
||||
gst_rtsp_client_set_send_func (client, test_response_scale_speed, NULL, NULL);
|
||||
fail_unless (gst_rtsp_client_handle_message (client,
|
||||
&request) == GST_RTSP_OK);
|
||||
gst_rtsp_message_unset (&request);
|
||||
|
||||
send_teardown (client);
|
||||
teardown_client (client);
|
||||
g_object_unref (ctx.auth);
|
||||
gst_rtsp_token_unref (ctx.token);
|
||||
gst_rtsp_context_pop_current (&ctx);
|
||||
|
||||
}
|
||||
|
||||
GST_START_TEST (test_scale_and_speed)
|
||||
{
|
||||
/* no scale/speed requested, no scale/speed should be received */
|
||||
expected_scale_header = NULL;
|
||||
expected_speed_header = NULL;
|
||||
do_test_scale_and_speed (NULL, NULL);
|
||||
|
||||
/* scale requested, scale should be received */
|
||||
fake_applied_rate_value = 2;
|
||||
fake_rate_value = 1;
|
||||
expected_scale_header = "2.000";
|
||||
expected_speed_header = NULL;
|
||||
do_test_scale_and_speed ("2.000", NULL);
|
||||
|
||||
/* speed requested, speed should be received */
|
||||
fake_applied_rate_value = 0;
|
||||
fake_rate_value = 0;
|
||||
expected_scale_header = NULL;
|
||||
expected_speed_header = "2.000";
|
||||
do_test_scale_and_speed (NULL, "2.000");
|
||||
|
||||
/* both requested, both should be received */
|
||||
fake_applied_rate_value = 2;
|
||||
fake_rate_value = 2;
|
||||
expected_scale_header = "2.000";
|
||||
expected_speed_header = "2.000";
|
||||
do_test_scale_and_speed ("2", "2");
|
||||
|
||||
/* scale requested but media doesn't handle scaling so both should be
|
||||
* received, with scale set to 1.000 and speed set to (requested scale
|
||||
* requested speed) */
|
||||
fake_applied_rate_value = 0;
|
||||
fake_rate_value = 5;
|
||||
expected_scale_header = "1.000";
|
||||
expected_speed_header = "5.000";
|
||||
do_test_scale_and_speed ("5", NULL);
|
||||
|
||||
/* both requested but media only handles scaling so both should be received,
|
||||
* with scale set to (requested scale * requested speed) and speed set to 1.00
|
||||
*/
|
||||
fake_rate_value = 1.000;
|
||||
fake_applied_rate_value = 4.000;
|
||||
expected_scale_header = "4.000";
|
||||
expected_speed_header = "1.000";
|
||||
do_test_scale_and_speed ("2", "2");
|
||||
}
|
||||
|
||||
GST_END_TEST static Suite *
|
||||
rtspclient_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("rtspclient");
|
||||
|
@ -1759,6 +1967,7 @@ rtspclient_suite (void)
|
|||
tcase_add_test (tc, test_client_multicast_max_ttl_first_client);
|
||||
tcase_add_test (tc, test_client_multicast_max_ttl_second_client);
|
||||
tcase_add_test (tc, test_client_multicast_invalid_ttl);
|
||||
tcase_add_test (tc, test_scale_and_speed);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue