#include "rtsp-server.h"
+#define ERRORIGNORE "errorignore ignore-error=false ignore-notlinked=true " \
+ "ignore-notnegotiated=false convert-to=ok"
#define VIDEO_PIPELINE "videotestsrc ! " \
+ ERRORIGNORE " ! " \
"video/x-raw,width=352,height=288 ! " \
"rtpgstpay name=pay0 pt=96"
#define AUDIO_PIPELINE "audiotestsrc ! " \
+ ERRORIGNORE " ! " \
"audio/x-raw,rate=8000 ! " \
"rtpgstpay name=pay1 pt=97"
}
static void
-start_tcp_server (void)
+start_tcp_server (gboolean set_shared_factory)
{
GstRTSPMountPoints *mounts;
gchar *service;
gst_rtsp_media_factory_set_launch (factory,
"( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
+ gst_rtsp_media_factory_set_shared (factory, set_shared_factory);
g_object_unref (mounts);
/* set port to any */
return NULL;
}
type = gst_rtsp_message_get_type (response);
- fail_unless (type == GST_RTSP_MESSAGE_RESPONSE || type == GST_RTSP_MESSAGE_DATA);
+ fail_unless (type == GST_RTSP_MESSAGE_RESPONSE
+ || type == GST_RTSP_MESSAGE_DATA);
return response;
}
NULL, NULL, NULL, NULL, NULL);
}
+/* send an rtsp request with a method,session and range in,
+ * and receive response. range_in is the Range in req header */
+static GstRTSPStatusCode
+do_simple_request_rangein (GstRTSPConnection * conn, GstRTSPMethod method,
+ const gchar * session, const gchar * rangein)
+{
+ return do_request (conn, method, NULL, session, NULL, rangein, NULL,
+ NULL, NULL, NULL, NULL, NULL);
+}
+
/* send a DESCRIBE request and receive response. returns a received
* GstSDPMessage that must be freed by the caller */
static GstSDPMessage *
{
GstRTSPMessage *message;
fail_unless (gst_rtsp_message_new (&message) == GST_RTSP_OK);
- fail_unless (gst_rtsp_connection_receive (conn, message, NULL) == GST_RTSP_OK);
+ fail_unless (gst_rtsp_connection_receive (conn, message,
+ NULL) == GST_RTSP_OK);
fail_unless (gst_rtsp_message_get_type (message) == GST_RTSP_MESSAGE_DATA);
gst_rtsp_message_free (message);
}
GstRTSPTransport *video_transport = NULL;
GstRTSPTransport *audio_transport = NULL;
- start_tcp_server ();
+ start_tcp_server (FALSE);
conn = connect_to_server (test_port, TEST_MOUNT_POINT);
/* send PLAY request and check that we get 200 OK */
fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
- session)== GST_RTSP_STS_OK);
+ session) == GST_RTSP_STS_OK);
/* send TEARDOWN request and check that we get 200 OK */
fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
GST_START_TEST (test_play_smpte_range_tcp)
{
- start_tcp_server ();
+ start_tcp_server (FALSE);
do_test_play_tcp_full ("npt=5-");
do_test_play_tcp_full ("smpte=0:00:00-");
GST_END_TEST;
static gpointer
-thread_func (gpointer data)
+thread_func_udp (gpointer data)
{
do_test_play_full (NULL, GST_RTSP_LOWER_TRANS_UDP, (GMutex *) data);
return NULL;
}
-/* Test adding and removing clients to a 'Shared' media. */
-GST_START_TEST (test_shared)
+static gpointer
+thread_func_tcp (gpointer data)
+{
+ do_test_play_tcp_full (NULL);
+ return NULL;
+}
+
+static void
+test_shared (gpointer (thread_func) (gpointer data))
{
GMutex lock1, lock2, lock3, lock4;
GThread *thread1, *thread2, *thread3, *thread4;
g_mutex_init (&lock3);
g_mutex_init (&lock4);
- start_server (TRUE);
+ if (thread_func == thread_func_tcp)
+ start_tcp_server (TRUE);
+ else
+ start_server (TRUE);
/* Start the first receiver thread. */
g_mutex_lock (&lock1);
iterate ();
}
+/* Test adding and removing clients to a 'Shared' media.
+ * CASE: unicast UDP */
+GST_START_TEST (test_shared_udp)
+{
+ test_shared (thread_func_udp);
+}
+
+GST_END_TEST;
+
+/* Test adding and removing clients to a 'Shared' media.
+ * CASE: unicast TCP */
+GST_START_TEST (test_shared_tcp)
+{
+ test_shared (thread_func_tcp);
+}
+
GST_END_TEST;
GST_START_TEST (test_announce_without_sdp)
bin = gst_rtsp_media_get_element (media);
*p_sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
GST_INFO ("media constructed!: %" GST_PTR_FORMAT, *p_sink);
+ gst_object_unref (bin);
}
#define RECORD_N_BUFS 10
{
GstRTSPMessage *message;
fail_unless (gst_rtsp_message_new (&message) == GST_RTSP_OK);
- fail_unless (gst_rtsp_connection_receive (conn2, message, NULL) == GST_RTSP_OK);
+ fail_unless (gst_rtsp_connection_receive (conn2, message,
+ NULL) == GST_RTSP_OK);
fail_unless (gst_rtsp_message_get_type (message) == GST_RTSP_MESSAGE_DATA);
gst_rtsp_message_free (message);
}
GST_START_TEST (test_multiple_transports)
{
start_server (TRUE);
- do_test_multiple_transports (GST_RTSP_LOWER_TRANS_UDP, GST_RTSP_LOWER_TRANS_TCP);
+ do_test_multiple_transports (GST_RTSP_LOWER_TRANS_UDP,
+ GST_RTSP_LOWER_TRANS_TCP);
stop_server ();
}
GST_END_TEST;
+GST_START_TEST (test_suspend_mode_reset_only_audio)
+{
+ GstRTSPMountPoints *mounts;
+ gchar *service;
+ GstRTSPMediaFactory *factory;
+ GstRTSPConnection *conn;
+ GstSDPMessage *sdp_message = NULL;
+ const GstSDPMedia *sdp_media;
+ const gchar *audio_control;
+ GstRTSPRange client_port;
+ gchar *session = NULL;
+ GstRTSPTransport *audio_transport = NULL;
+ GSocket *rtp_socket, *rtcp_socket;
+
+ mounts = gst_rtsp_server_get_mount_points (server);
+
+ factory = gst_rtsp_media_factory_new ();
+ gst_rtsp_media_factory_set_suspend_mode (factory,
+ GST_RTSP_SUSPEND_MODE_RESET);
+ gst_rtsp_media_factory_set_launch (factory,
+ "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
+ gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
+ g_object_unref (mounts);
+
+ /* set port to any */
+ gst_rtsp_server_set_service (server, "0");
+
+ /* attach to default main context */
+ source_id = gst_rtsp_server_attach (server, NULL);
+ fail_if (source_id == 0);
+
+ /* get port */
+ service = gst_rtsp_server_get_service (server);
+ test_port = atoi (service);
+ fail_unless (test_port != 0);
+ g_free (service);
+
+ conn = connect_to_server (test_port, TEST_MOUNT_POINT);
+
+ sdp_message = do_describe (conn, TEST_MOUNT_POINT);
+
+ /* get control strings from DESCRIBE response */
+ fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
+ sdp_media = gst_sdp_message_get_media (sdp_message, 1);
+ audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
+
+ get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
+
+ /* do SETUP for audio */
+ fail_unless (do_setup (conn, audio_control, &client_port, &session,
+ &audio_transport) == GST_RTSP_STS_OK);
+
+ /* send PLAY request and check that we get 200 OK */
+ fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
+ session) == GST_RTSP_STS_OK);
+
+ /* send TEARDOWN request and check that we get 200 OK */
+ fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
+ session) == GST_RTSP_STS_OK);
+
+ /* clean up and iterate so the clean-up can finish */
+ g_free (session);
+ gst_rtsp_transport_free (audio_transport);
+ gst_sdp_message_free (sdp_message);
+ gst_rtsp_connection_free (conn);
+
+ stop_server ();
+ iterate ();
+}
+
+GST_END_TEST;
+
+
+static GstRTSPStatusCode
+adjust_play_mode (GstRTSPClient * client, GstRTSPContext * ctx,
+ GstRTSPTimeRange ** range, GstSeekFlags * flags, gdouble * rate,
+ GstClockTime * trickmode_interval, gboolean * enable_rate_control)
+{
+ GstRTSPState rtspstate;
+
+ rtspstate = gst_rtsp_session_media_get_rtsp_state (ctx->sessmedia);
+ if (rtspstate == GST_RTSP_STATE_PLAYING) {
+ if (!gst_rtsp_session_media_set_state (ctx->sessmedia, GST_STATE_PAUSED))
+ return GST_RTSP_STS_INTERNAL_SERVER_ERROR;
+
+ if (!gst_rtsp_media_unsuspend (ctx->media))
+ return GST_RTSP_STS_INTERNAL_SERVER_ERROR;
+ }
+
+ return GST_RTSP_STS_OK;
+}
+
+GST_START_TEST (test_double_play)
+{
+ GstRTSPMountPoints *mounts;
+ gchar *service;
+ GstRTSPMediaFactory *factory;
+ GstRTSPConnection *conn;
+ GstSDPMessage *sdp_message = NULL;
+ const GstSDPMedia *sdp_media;
+ const gchar *video_control;
+ const gchar *audio_control;
+ GstRTSPRange client_port;
+ gchar *session = NULL;
+ GstRTSPTransport *audio_transport = NULL;
+ GstRTSPTransport *video_transport = NULL;
+ GSocket *rtp_socket, *rtcp_socket;
+ GstRTSPClient *client;
+ GstRTSPClientClass *klass;
+
+ client = gst_rtsp_client_new ();
+ klass = GST_RTSP_CLIENT_GET_CLASS (client);
+ klass->adjust_play_mode = adjust_play_mode;
+
+ mounts = gst_rtsp_server_get_mount_points (server);
+
+ factory = gst_rtsp_media_factory_new ();
+ gst_rtsp_media_factory_set_launch (factory,
+ "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
+ gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
+ g_object_unref (mounts);
+
+
+ /* set port to any */
+ gst_rtsp_server_set_service (server, "0");
+
+ /* attach to default main context */
+ source_id = gst_rtsp_server_attach (server, NULL);
+ fail_if (source_id == 0);
+
+ /* get port */
+ service = gst_rtsp_server_get_service (server);
+ test_port = atoi (service);
+ fail_unless (test_port != 0);
+ g_free (service);
+
+ conn = connect_to_server (test_port, TEST_MOUNT_POINT);
+
+ sdp_message = do_describe (conn, TEST_MOUNT_POINT);
+
+ /* get control strings from DESCRIBE response */
+ fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
+ sdp_media = gst_sdp_message_get_media (sdp_message, 0);
+ video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
+ sdp_media = gst_sdp_message_get_media (sdp_message, 1);
+ audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
+
+ get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
+
+ /* do SETUP for video */
+ fail_unless (do_setup (conn, video_control, &client_port, &session,
+ &video_transport) == GST_RTSP_STS_OK);
+
+ /* do SETUP for audio */
+ fail_unless (do_setup (conn, audio_control, &client_port, &session,
+ &audio_transport) == GST_RTSP_STS_OK);
+
+ /* send PLAY request and check that we get 200 OK */
+ fail_unless (do_simple_request_rangein (conn, GST_RTSP_PLAY,
+ session, "npt=0-") == GST_RTSP_STS_OK);
+
+ /* let it play for a while, so it needs to seek
+ * for next play (npt=0-) */
+ g_usleep (30000);
+
+ /* send PLAY request and check that we get 200 OK */
+ fail_unless (do_simple_request_rangein (conn, GST_RTSP_PLAY,
+ session, "npt=0-") == GST_RTSP_STS_OK);
+
+ /* send TEARDOWN request and check that we get 200 OK */
+ fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
+ session) == GST_RTSP_STS_OK);
+
+ /* clean up and iterate so the clean-up can finish */
+ g_free (session);
+ gst_rtsp_transport_free (video_transport);
+ gst_rtsp_transport_free (audio_transport);
+ gst_sdp_message_free (sdp_message);
+ gst_rtsp_connection_free (conn);
+
+ stop_server ();
+ iterate ();
+}
+
+GST_END_TEST;
+
+
static Suite *
rtspserver_suite (void)
{
tcase_add_test (tc, test_play_specific_server_port);
tcase_add_test (tc, test_play_smpte_range);
tcase_add_test (tc, test_play_smpte_range_tcp);
- tcase_add_test (tc, test_shared);
+ tcase_add_test (tc, test_shared_udp);
+ tcase_add_test (tc, test_shared_tcp);
tcase_add_test (tc, test_announce_without_sdp);
tcase_add_test (tc, test_record_tcp);
tcase_add_test (tc, test_multiple_transports);
+ tcase_add_test (tc, test_suspend_mode_reset_only_audio);
+ tcase_add_test (tc, test_double_play);
return s;
}