X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=subprojects%2Fgst-rtsp-server%2Fgst%2Frtsp-server%2Frtsp-client.c;h=382ef2f590d32bfb72a8ea34a2d1cfc47cac4a9f;hb=9fecc618c16a4ed99834d0202046b3e741613878;hp=5a2085b08502428e522bdbb963a421abca58b288;hpb=b30a16ff00cf24e7fc2fcfa65cd2a8e99a72410d;p=platform%2Fupstream%2Fgstreamer.git diff --git a/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-client.c b/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-client.c index 5a2085b..382ef2f 100644 --- a/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-client.c +++ b/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-client.c @@ -217,7 +217,6 @@ static GstRTSPStatusCode default_pre_signal_handler (GstRTSPClient * client, GstRTSPContext * ctx); static gboolean pre_signal_accumulator (GSignalInvocationHint * ihint, GValue * return_accu, const GValue * handler_return, gpointer data); -gboolean gst_rtsp_media_has_completed_sender (GstRTSPMedia * media); G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT); @@ -948,6 +947,23 @@ send_generic_response (GstRTSPClient * client, GstRTSPStatusCode code, } static void +send_generic_error_response (GstRTSPClient * client, GstRTSPStatusCode code, + GstRTSPContext * ctx) +{ + GstRTSPClientClass *klass = GST_RTSP_CLIENT_GET_CLASS (client); + GstRTSPStatusCode adjusted_code = code; + + if (klass->adjust_error_code != NULL) { + adjusted_code = klass->adjust_error_code (client, ctx, code); + if (adjusted_code != code) { + GST_DEBUG ("adjusted response error code from %d to %d", code, + adjusted_code); + } + } + send_generic_response (client, adjusted_code, ctx); +} + +static void send_option_not_supported_response (GstRTSPClient * client, GstRTSPContext * ctx, const gchar * unsupported_options) { @@ -991,6 +1007,7 @@ find_media (GstRTSPClient * client, GstRTSPContext * ctx, gchar * path, GstRTSPClientPrivate *priv = client->priv; GstRTSPMediaFactory *factory; GstRTSPMedia *media; + GstRTSPUrl *url; gint path_len; /* find the longest matching factory for the uri first */ @@ -1011,13 +1028,20 @@ find_media (GstRTSPClient * client, GstRTSPContext * ctx, gchar * path, else path_len = strlen (path); + url = gst_rtsp_url_copy (ctx->uri); + /* normalize rtsp://: to rtsp://:/ */ + if (url->abspath[0] == 0) { + g_free (url->abspath); + url->abspath = g_strdup ("/"); + } + if (!paths_are_equal (priv->path, path, path_len)) { /* remove any previously cached values before we try to construct a new * media for uri */ clean_cached_media (client, TRUE); /* prepare the media and add it to the pipeline */ - if (!(media = gst_rtsp_media_factory_construct (factory, ctx->uri))) + if (!(media = gst_rtsp_media_factory_construct (factory, url))) goto no_media; ctx->media = media; @@ -1046,6 +1070,7 @@ find_media (GstRTSPClient * client, GstRTSPContext * ctx, gchar * path, GST_INFO ("reusing cached media %p for path %s", media, priv->path); } + gst_rtsp_url_free (url); g_object_unref (factory); ctx->factory = NULL; @@ -1058,7 +1083,7 @@ find_media (GstRTSPClient * client, GstRTSPContext * ctx, gchar * path, no_factory: { GST_ERROR ("client %p: no factory for path %s", client, path); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); return NULL; } no_factory_access: @@ -1081,7 +1106,8 @@ not_authorized: no_media: { GST_ERROR ("client %p: can't create media", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + gst_rtsp_url_free (url); g_object_unref (factory); ctx->factory = NULL; return NULL; @@ -1089,7 +1115,8 @@ no_media: no_thread: { GST_ERROR ("client %p: can't create thread", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + gst_rtsp_url_free (url); g_object_unref (media); ctx->media = NULL; g_object_unref (factory); @@ -1099,7 +1126,8 @@ no_thread: no_prepare: { GST_ERROR ("client %p: can't prepare media", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + gst_rtsp_url_free (url); g_object_unref (media); ctx->media = NULL; g_object_unref (factory); @@ -1461,7 +1489,7 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx) path = klass->make_path_from_uri (client, ctx->uri); /* get a handle to the configuration of the media in the session */ - sessmedia = gst_rtsp_session_get_media (session, path, &matched); + sessmedia = gst_rtsp_session_dup_media (session, path, &matched); if (!sessmedia) goto not_found; @@ -1496,6 +1524,7 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx) /* unmanage the media in the session, returns false if all media session * are torn down. */ keep_session = gst_rtsp_session_release_media (session, sessmedia); + g_object_unref (sessmedia); /* construct the response now */ code = GST_RTSP_STS_OK; @@ -1524,37 +1553,39 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx) no_session: { GST_ERROR ("client %p: no session", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); return FALSE; } no_uri: { GST_ERROR ("client %p: no uri supplied", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } not_found: { GST_ERROR ("client %p: no media for uri", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); g_free (path); return FALSE; } no_aggregate: { GST_ERROR ("client %p: no aggregate path %s", client, path); - send_generic_response (client, + send_generic_error_response (client, GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx); g_free (path); + g_object_unref (sessmedia); return FALSE; } sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } } @@ -1626,13 +1657,13 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); return FALSE; } bad_request: { GST_ERROR ("client %p: bad request", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } } @@ -1678,13 +1709,13 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); return FALSE; } bad_request: { GST_ERROR ("client %p: bad request", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } } @@ -1713,7 +1744,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx) path = klass->make_path_from_uri (client, ctx->uri); /* get a handle to the configuration of the media in the session */ - sessmedia = gst_rtsp_session_get_media (session, path, &matched); + sessmedia = gst_rtsp_session_dup_media (session, path, &matched); if (!sessmedia) goto not_found; @@ -1760,6 +1791,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx) /* the state is now READY */ gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_READY); + g_object_unref (sessmedia); g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST], 0, ctx); @@ -1772,27 +1804,28 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx) no_session: { GST_ERROR ("client %p: no session", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); return FALSE; } no_uri: { GST_ERROR ("client %p: no uri supplied", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } not_found: { GST_ERROR ("client %p: no media for uri", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); g_free (path); return FALSE; } no_aggregate: { GST_ERROR ("client %p: no aggregate path %s", client, path); - send_generic_response (client, + send_generic_error_response (client, GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx); + g_object_unref (sessmedia); g_free (path); return FALSE; } @@ -1800,25 +1833,28 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); gst_rtsp_media_unlock (media); + g_object_unref (sessmedia); g_object_unref (media); return FALSE; } invalid_state: { GST_ERROR ("client %p: not PLAYING or RECORDING", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, - ctx); + send_generic_error_response (client, + GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, ctx); gst_rtsp_media_unlock (media); + g_object_unref (sessmedia); g_object_unref (media); return FALSE; } not_supported: { GST_ERROR ("client %p: pausing not supported", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); gst_rtsp_media_unlock (media); + g_object_unref (sessmedia); g_object_unref (media); return FALSE; } @@ -2082,7 +2118,7 @@ default_handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) path = klass->make_path_from_uri (client, uri); /* get a handle to the configuration of the media in the session */ - sessmedia = gst_rtsp_session_get_media (session, path, &matched); + sessmedia = gst_rtsp_session_dup_media (session, path, &matched); if (!sessmedia) goto not_found; @@ -2152,10 +2188,14 @@ default_handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) /* 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 */ +#ifdef TIZEN_PROFILE_TV + /* Temporal workaround fix for TV */ + rate = applied_rate = 1.0; +#else if (!gst_rtsp_media_get_rates (media, &rate, &applied_rate)) goto get_rates_error; g_assert (rate != 0 && applied_rate != 0); - +#endif 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)); @@ -2177,6 +2217,7 @@ default_handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) gst_rtsp_session_media_set_state (sessmedia, GST_STATE_PLAYING); gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_PLAYING); + g_object_unref (sessmedia); g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST], 0, ctx); @@ -2189,26 +2230,27 @@ default_handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) no_session: { GST_ERROR ("client %p: no session", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); return FALSE; } no_uri: { GST_ERROR ("client %p: no uri supplied", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } not_found: { GST_ERROR ("client %p: media not found", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); return FALSE; } no_aggregate: { GST_ERROR ("client %p: no aggregate path %s", client, path); - send_generic_response (client, + send_generic_error_response (client, GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx); + g_object_unref (sessmedia); g_free (path); return FALSE; } @@ -2216,75 +2258,86 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } invalid_state: { GST_ERROR ("client %p: not PLAYING or READY", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, - ctx); + send_generic_error_response (client, + GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } pipeline_error: { GST_ERROR ("client %p: failed to configure the pipeline", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, - ctx); + send_generic_error_response (client, + GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } unsuspend_failed: { GST_ERROR ("client %p: unsuspend failed", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } invalid_mode: { GST_ERROR ("client %p: seek failed", client); - send_generic_response (client, code, ctx); + send_generic_error_response (client, code, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } unsupported_mode: { GST_ERROR ("client %p: media does not support PLAY", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); + send_generic_error_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); 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); + send_generic_error_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, + ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } adjust_play_response_failed: { GST_ERROR ("client %p: failed to adjust play response", client); - send_generic_response (client, code, ctx); + send_generic_error_response (client, code, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } rtp_info_error: { GST_ERROR ("client %p: failed to add RTP-Info", client); - send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx); + send_generic_error_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, + ctx); gst_rtsp_media_unlock (media); g_object_unref (media); + g_object_unref (sessmedia); return FALSE; } } @@ -2379,7 +2432,7 @@ done: parse_failed: { GST_ERROR_OBJECT (client, "failed to parse blocksize"); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } } @@ -3072,19 +3125,20 @@ handle_setup_request (GstRTSPClient * client, GstRTSPContext * ctx) no_uri: { GST_ERROR ("client %p: no uri", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } no_transport: { GST_ERROR ("client %p: no transport", client); - send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx); + send_generic_error_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, + ctx); goto cleanup_path; } no_pool: { GST_ERROR ("client %p: no session pool configured", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); goto cleanup_path; } media_not_found_no_reply: @@ -3096,13 +3150,13 @@ media_not_found_no_reply: media_not_found: { GST_ERROR ("client %p: media '%s' not found", client, path); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); goto cleanup_session; } control_not_found: { GST_ERROR ("client %p: no control in path '%s'", client, path); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); goto cleanup_session; @@ -3111,7 +3165,7 @@ stream_not_found: { GST_ERROR ("client %p: stream '%s' not found", client, GST_STR_NULL (control)); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); goto cleanup_session; @@ -3120,7 +3174,7 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); goto cleanup_path; @@ -3128,7 +3182,7 @@ sig_failed: service_unavailable: { GST_ERROR ("client %p: can't create session", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); gst_rtsp_media_unlock (media); g_object_unref (media); goto cleanup_session; @@ -3136,7 +3190,7 @@ service_unavailable: sessmedia_unavailable: { GST_ERROR ("client %p: can't create session media", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); goto cleanup_transport; } configure_media_failed_no_reply: @@ -3150,13 +3204,15 @@ configure_media_failed_no_reply: unsupported_transports: { GST_ERROR ("client %p: unsupported transports", client); - send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx); + send_generic_error_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, + ctx); goto cleanup_transport; } unsupported_client_transport: { GST_ERROR ("client %p: unsupported client transport", client); - send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx); + send_generic_error_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, + ctx); goto cleanup_transport; } unsupported_mode: @@ -3167,20 +3223,22 @@ unsupported_mode: GST_RTSP_TRANSPORT_MODE_PLAY), ! !(gst_rtsp_media_get_transport_mode (media) & GST_RTSP_TRANSPORT_MODE_RECORD), ct->mode_play, ct->mode_record); - send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx); + send_generic_error_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, + ctx); goto cleanup_transport; } unsupported_range_unit: { GST_ERROR ("Client %p: does not support any range format we support", client); - send_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, ctx); goto cleanup_transport; } keymgmt_error: { GST_ERROR ("client %p: keymgmt error", client); - send_generic_response (client, GST_RTSP_STS_KEY_MANAGEMENT_FAILURE, ctx); + send_generic_error_response (client, GST_RTSP_STS_KEY_MANAGEMENT_FAILURE, + ctx); goto cleanup_transport; } { @@ -3349,25 +3407,25 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); return FALSE; } no_uri: { GST_ERROR ("client %p: no uri", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } no_mount_points: { GST_ERROR ("client %p: no mount points configured", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); return FALSE; } no_path: { GST_ERROR ("client %p: can't find path for url", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); return FALSE; } no_media: @@ -3380,7 +3438,7 @@ no_media: unsupported_mode: { GST_ERROR ("client %p: media does not support DESCRIBE", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); + send_generic_error_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); g_free (path); gst_rtsp_media_unlock (media); g_object_unref (media); @@ -3389,7 +3447,7 @@ unsupported_mode: no_sdp: { GST_ERROR ("client %p: can't create SDP", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); g_free (path); gst_rtsp_media_unlock (media); g_object_unref (media); @@ -3542,38 +3600,38 @@ handle_announce_request (GstRTSPClient * client, GstRTSPContext * ctx) no_uri: { GST_ERROR ("client %p: no uri", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } no_mount_points: { GST_ERROR ("client %p: no mount points configured", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); return FALSE; } no_path: { GST_ERROR ("client %p: can't find path for url", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); gst_sdp_message_free (sdp); return FALSE; } wrong_content_type: { GST_ERROR ("client %p: unknown content type", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } no_message: { GST_ERROR ("client %p: can't find SDP message", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } sdp_parse_failed: { GST_ERROR ("client %p: failed to parse SDP message", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); gst_sdp_message_free (sdp); return FALSE; } @@ -3589,7 +3647,7 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); gst_sdp_message_free (sdp); gst_rtsp_media_unlock (media); g_object_unref (media); @@ -3598,7 +3656,7 @@ sig_failed: unsupported_mode: { GST_ERROR ("client %p: media does not support ANNOUNCE", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); + send_generic_error_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); g_free (path); gst_rtsp_media_unlock (media); g_object_unref (media); @@ -3608,7 +3666,8 @@ unsupported_mode: unhandled_sdp: { GST_ERROR ("client %p: can't handle SDP", client); - send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_MEDIA_TYPE, ctx); + send_generic_error_response (client, GST_RTSP_STS_UNSUPPORTED_MEDIA_TYPE, + ctx); g_free (path); gst_rtsp_media_unlock (media); g_object_unref (media); @@ -3699,25 +3758,25 @@ handle_record_request (GstRTSPClient * client, GstRTSPContext * ctx) no_session: { GST_ERROR ("client %p: no session", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); return FALSE; } no_uri: { GST_ERROR ("client %p: no uri supplied", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); return FALSE; } not_found: { GST_ERROR ("client %p: media not found", client); - send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_FOUND, ctx); return FALSE; } no_aggregate: { GST_ERROR ("client %p: no aggregate path %s", client, path); - send_generic_response (client, + send_generic_error_response (client, GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx); g_free (path); return FALSE; @@ -3726,33 +3785,33 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); return FALSE; } unsupported_mode: { GST_ERROR ("client %p: media does not support RECORD", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); + send_generic_error_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); return FALSE; } invalid_state: { GST_ERROR ("client %p: not PLAYING or READY", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, - ctx); + send_generic_error_response (client, + GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, ctx); return FALSE; } pipeline_error: { GST_ERROR ("client %p: failed to configure the pipeline", client); - send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, - ctx); + send_generic_error_response (client, + GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, ctx); return FALSE; } unsuspend_failed: { GST_ERROR ("client %p: unsuspend failed", client); - send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); + send_generic_error_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); return FALSE; } } @@ -3803,7 +3862,7 @@ sig_failed: { GST_ERROR ("client %p: pre signal returned error: %s", client, gst_rtsp_status_as_text (sig_result)); - send_generic_response (client, sig_result, ctx); + send_generic_error_response (client, sig_result, ctx); gst_rtsp_message_free (ctx->response); return FALSE; } @@ -4119,32 +4178,32 @@ done: not_supported: { GST_ERROR ("client %p: version %d not supported", client, version); - send_generic_response (client, GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED, - ctx); + send_generic_error_response (client, + GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED, ctx); goto done; } invalid_command_for_version: { GST_ERROR ("client %p: invalid command for version", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); goto done; } bad_request: { GST_ERROR ("client %p: bad request", client); - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); goto done; } no_pool: { GST_ERROR ("client %p: no pool configured", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); goto done; } session_not_found: { GST_ERROR ("client %p: session not found", client); - send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); + send_generic_error_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx); goto done; } not_authorized: @@ -4164,7 +4223,7 @@ unsupported_requirement: not_implemented: { GST_ERROR ("client %p: method %d not implemented", client, method); - send_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, ctx); + send_generic_error_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, ctx); goto done; } } @@ -5033,11 +5092,12 @@ error_full (GstRTSPWatch * watch, GstRTSPResult result, goto done; if (result == GST_RTSP_ENOMEM) { - send_generic_response (client, GST_RTSP_STS_REQUEST_ENTITY_TOO_LARGE, ctx); + send_generic_error_response (client, GST_RTSP_STS_REQUEST_ENTITY_TOO_LARGE, + ctx); goto done; } if (result == GST_RTSP_EPARSE) { - send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); + send_generic_error_response (client, GST_RTSP_STS_BAD_REQUEST, ctx); goto done; } @@ -5306,12 +5366,15 @@ gst_rtsp_client_attach (GstRTSPClient * client, GMainContext * context) gst_rtsp_watch_set_send_backlog (priv->watch, 0, WATCH_BACKLOG_SIZE); + /* take the lock before attaching the client watch, so that the client thread + * can not access the control channel timer until it's properly in place */ + g_mutex_lock (&priv->lock); + GST_INFO ("client %p: attaching to context %p", client, context); res = gst_rtsp_watch_attach (priv->watch, context); /* Setting up a timeout for the RTSP control channel until a session * is up where it is handling timeouts. */ - g_mutex_lock (&priv->lock); /* remove old timeout if any */ rtsp_ctrl_timeout_remove_unlocked (client->priv);