X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Frtsp.c;h=566966678926c723180945b9e1ba088eeccb4d03;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=6a54f40c4c71175fe7faf0fe191f475d6f8d98ed;hpb=55b8d4f97994dc4fc894db43729257c80c37074c;p=vlc diff --git a/modules/misc/rtsp.c b/modules/misc/rtsp.c index 6a54f40c4c..5669666789 100644 --- a/modules/misc/rtsp.c +++ b/modules/misc/rtsp.c @@ -25,10 +25,6 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#define _GNU_SOURCE -#include - -#include #include #include @@ -42,6 +38,8 @@ #include #include +#include + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -77,7 +75,8 @@ vlc_module_begin(); set_callbacks( Open, Close ); add_shortcut( "rtsp" ); add_string ( "rtsp-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE ); - add_string( "rtsp-raw-mux", "ts", NULL, RAWMUX_TEXT, RAWMUX_TEXT, VLC_TRUE ); + add_string( "rtsp-raw-mux", "ts", NULL, RAWMUX_TEXT, + RAWMUX_TEXT, VLC_TRUE ); add_integer( "rtsp-throttle-users", 0, NULL, THROTLE_TEXT, THROTLE_LONGTEXT, VLC_TRUE ); add_integer( "rtsp-session-timeout", 5, NULL, SESSION_TIMEOUT_TEXT, @@ -223,9 +222,9 @@ static rtsp_client_t *RtspClientGet( vod_media_t *, const char * ); static void RtspClientDel( vod_media_t *, rtsp_client_t * ); static int RtspCallback( httpd_callback_sys_t *, httpd_client_t *, - httpd_message_t *, httpd_message_t * ); + httpd_message_t *, const httpd_message_t * ); static int RtspCallbackES( httpd_callback_sys_t *, httpd_client_t *, - httpd_message_t *, httpd_message_t * ); + httpd_message_t *, const httpd_message_t * ); static char *SDPGenerate( const vod_media_t *, httpd_client_t *cl ); @@ -324,7 +323,7 @@ static void Close( vlc_object_t * p_this ) vod_sys_t *p_sys = p_vod->p_sys; /* Stop command thread */ - p_vod->b_die = VLC_TRUE; + vlc_object_kill( p_vod ); CommandPush( p_vod, RTSP_CMD_TYPE_NONE, NULL, NULL, 0.0, NULL ); vlc_thread_join( p_vod ); @@ -370,7 +369,9 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name, TAB_INIT( p_media->i_rtsp, p_media->rtsp ); p_media->b_raw = VLC_FALSE; - asprintf( &p_media->psz_rtsp_path, "%s%s", p_sys->psz_path, psz_name ); + if( asprintf( &p_media->psz_rtsp_path, "%s%s", + p_sys->psz_path, psz_name ) <0 ) + return NULL; p_media->p_rtsp_url = httpd_UrlNewUnique( p_sys->p_rtsp_host, p_media->psz_rtsp_path, NULL, NULL, NULL ); @@ -385,12 +386,14 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name, msg_Dbg( p_vod, "created RTSP url: %s", p_media->psz_rtsp_path ); - asprintf( &p_media->psz_rtsp_control_v4, + if( asprintf( &p_media->psz_rtsp_control_v4, "a=control:rtsp://%%s:%d%s/trackID=%%d\r\n", - p_sys->i_port, p_media->psz_rtsp_path ); - asprintf( &p_media->psz_rtsp_control_v6, + p_sys->i_port, p_media->psz_rtsp_path ) < 0 ) + return NULL; + if( asprintf( &p_media->psz_rtsp_control_v6, "a=control:rtsp://[%%s]:%d%s/trackID=%%d\r\n", - p_sys->i_port, p_media->psz_rtsp_path ); + p_sys->i_port, p_media->psz_rtsp_path ) < 0 ) + return NULL; httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_SETUP, RtspCallback, (void*)p_media ); @@ -424,7 +427,7 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name, p_media->i_sdp_id = mdate(); p_media->i_sdp_version = 1; - p_media->i_length = p_item->i_duration; + p_media->i_length = input_item_GetDuration( p_item ); vlc_mutex_lock( &p_item->lock ); msg_Dbg( p_vod, "media has %i declared ES", p_item->i_es ); @@ -463,7 +466,8 @@ static void MediaDel( vod_t *p_vod, vod_media_t *p_media ) vlc_mutex_destroy( &p_media->lock ); if( p_media->psz_session_name ) free( p_media->psz_session_name ); - if( p_media->psz_session_description ) free( p_media->psz_session_description ); + if( p_media->psz_session_description ) + free( p_media->psz_session_description ); if( p_media->psz_session_url ) free( p_media->psz_session_url ); if( p_media->psz_session_email ) free( p_media->psz_session_email ); if( p_media->psz_mux ) free( p_media->psz_mux ); @@ -482,8 +486,9 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) p_media->psz_mux = NULL; /* TODO: update SDP, etc... */ - asprintf( &psz_urlc, "%s/trackID=%d", - p_media->psz_rtsp_path, p_media->i_es ); + if( asprintf( &psz_urlc, "%s/trackID=%d", + p_media->psz_rtsp_path, p_media->i_es ) < 0 ) + return VLC_ENOMEM; msg_Dbg( p_vod, " - ES %4.4s (%s)", (char *)&p_fmt->i_codec, psz_urlc ); switch( p_fmt->i_codec ) @@ -493,7 +498,8 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) { p_es->i_payload_type = 11; } - else if( p_fmt->audio.i_channels == 2 && p_fmt->audio.i_rate == 44100 ) + else if( p_fmt->audio.i_channels == 2 && + p_fmt->audio.i_rate == 44100 ) { p_es->i_payload_type = 10; } @@ -572,7 +578,11 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) } /* */ if( p_64_sps && p_64_pps ) - asprintf( &p_es->psz_fmtp, "packetization-mode=1;profile-level-id=%s;sprop-parameter-sets=%s,%s;", hexa, p_64_sps, p_64_pps ); + if( asprintf( &p_es->psz_fmtp, + "packetization-mode=1;profile-level-id=%s;" + "sprop-parameter-sets=%s,%s;", hexa, p_64_sps, + p_64_pps ) < 0 ) + return VLC_ENOMEM; if( p_64_sps ) free( p_64_sps ); if( p_64_pps ) @@ -898,7 +908,7 @@ static void RtspClientDel( vod_media_t *p_media, rtsp_client_t *p_rtsp ) } static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, - httpd_message_t *answer, httpd_message_t *query ) + httpd_message_t *answer, const httpd_message_t *query ) { vod_media_t *p_media = (vod_media_t*)p_args; vod_t *p_vod = p_media->p_vod; @@ -926,6 +936,11 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, { psz_playnow = httpd_MsgGet( query, "x-playNow" ); psz_transport = httpd_MsgGet( query, "Transport" ); + if( psz_transport == NULL ) + { + answer->i_status = 400; + break; + } msg_Dbg( p_vod, "HTTPD_MSG_SETUP: transport=%s", psz_transport ); if( strstr( psz_transport, "unicast" ) && @@ -948,7 +963,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( httpd_ClientIP( cl, ip ) == NULL ) { answer->i_status = 500; - answer->psz_status = strdup( "Internal server error" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -965,19 +979,18 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, ( p_vod->p_sys->i_connections >= p_vod->p_sys->i_throttle_users ) ) { answer->i_status = 503; - answer->psz_status = strdup( "Too many connections" ); answer->i_body = 0; answer->p_body = NULL; break; } - asprintf( &psz_new, "%d", rand() ); + if( asprintf( &psz_new, "%d", rand() ) < 0 ) + return VLC_ENOMEM; psz_session = psz_new; p_rtsp = RtspClientNew( p_media, psz_new ); if( !p_rtsp ) { answer->i_status = 454; - answer->psz_status = strdup( "Unknown session id" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -989,7 +1002,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( !p_rtsp ) { answer->i_status = 454; - answer->psz_status = strdup( "Unknown session id" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -997,7 +1009,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, } answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; @@ -1005,23 +1016,25 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, { if( strstr( psz_transport, "MP2T/H2221/UDP" ) ) { - httpd_MsgAdd( answer, "Transport", "MP2T/H2221/UDP;client_port=%d-%d", + httpd_MsgAdd( answer, "Transport", + "MP2T/H2221/UDP;client_port=%d-%d", i_port, i_port + 1 ); } else if( strstr( psz_transport, "RAW/RAW/UDP" ) ) { - httpd_MsgAdd( answer, "Transport", "RAW/RAW/UDP;client_port=%d-%d", + httpd_MsgAdd( answer, "Transport", + "RAW/RAW/UDP;client_port=%d-%d", i_port, i_port + 1 ); } } else - httpd_MsgAdd( answer, "Transport", "RTP/AVP/UDP;client_port=%d-%d", + httpd_MsgAdd( answer, "Transport", + "RTP/AVP/UDP;client_port=%d-%d", i_port, i_port + 1 ); } else /* TODO strstr( psz_transport, "interleaved" ) ) */ { answer->i_status = 461; - answer->psz_status = strdup( "Unsupported Transport" ); answer->i_body = 0; answer->p_body = NULL; } @@ -1040,7 +1053,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( !psz_playnow ) { answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; } @@ -1053,7 +1065,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( !p_rtsp ) { answer->i_status = 500; - answer->psz_status = strdup( "Internal server error" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -1063,7 +1074,8 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, { const char *psz_position = httpd_MsgGet( query, "Range" ); const char *psz_scale = httpd_MsgGet( query, "Scale" ); - if( psz_position ) psz_position = strstr( psz_position, "npt=" ); + if( psz_position ) + psz_position = strstr( psz_position, "npt=" ); if( psz_position && !psz_scale ) { double f_pos; @@ -1076,7 +1088,8 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( end > psz_position ) { f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100; - CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, psz_session, f_pos, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, + psz_session, f_pos, NULL ); } break; } @@ -1092,18 +1105,22 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( psz_scale[0] == '-' ) /* rewind */ { msg_Dbg( p_vod, "rewind request: %s", psz_scale ); - CommandPush( p_vod, RTSP_CMD_TYPE_REWIND, p_media, psz_session, f_scale, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_REWIND, p_media, + psz_session, f_scale, NULL ); } else if(psz_scale[0] != '1' ) /* fast-forward */ { - msg_Dbg( p_vod, "fastforward request: %s", psz_scale ); - CommandPush( p_vod, RTSP_CMD_TYPE_FORWARD, p_media, psz_session, f_scale, NULL ); + msg_Dbg( p_vod, "fastforward request: %s", + psz_scale ); + CommandPush( p_vod, RTSP_CMD_TYPE_FORWARD, p_media, + psz_session, f_scale, NULL ); } if( p_rtsp->b_paused == VLC_TRUE ) { p_rtsp->b_paused = VLC_FALSE; - CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, psz_session, 0, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, + psz_session, 0, NULL ); } } break; @@ -1112,7 +1129,8 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( p_rtsp->b_playing && p_rtsp->b_paused ) { - CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, psz_session, 0, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, + psz_session, 0, NULL ); p_rtsp->b_paused = VLC_FALSE; break; } @@ -1135,22 +1153,29 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, { if( p_media->b_raw ) { - asprintf( &psz_output, "std{access=udp,dst=%s:%i,mux=%s}", - ip, i_port, p_media->psz_mux ); + if( asprintf( &psz_output, + "std{access=udp,dst=%s:%i,mux=%s}", + ip, i_port, p_media->psz_mux ) < 0 ) + return VLC_ENOMEM; } else { - asprintf( &psz_output, "rtp{dst=%s,port=%i,mux=%s}", - ip, i_port_video, p_media->psz_mux ); + if( asprintf( &psz_output, + "rtp{dst=%s,port=%i,mux=%s}", + ip, i_port_video, p_media->psz_mux ) < 0 ) + return VLC_ENOMEM; } } else { - asprintf( &psz_output, "rtp{dst=%s,port-video=%i," - "port-audio=%i}", ip, i_port_video, i_port_audio ); + if( asprintf( &psz_output, + "rtp{dst=%s,port-video=%i,port-audio=%i}", + ip, i_port_video, i_port_audio ) < 0 ) + return VLC_ENOMEM; } - CommandPush( p_vod, RTSP_CMD_TYPE_PLAY, p_media, psz_session, 0, psz_output ); + CommandPush( p_vod, RTSP_CMD_TYPE_PLAY, p_media, psz_session, + 0, psz_output ); free( psz_output ); break; } @@ -1163,8 +1188,8 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( psz_sdp != NULL ) { answer->i_status = 200; - answer->psz_status = strdup( "OK" ); - httpd_MsgAdd( answer, "Content-type", "%s", "application/sdp" ); + httpd_MsgAdd( answer, "Content-type", "%s", + "application/sdp" ); answer->p_body = (uint8_t *)psz_sdp; answer->i_body = strlen( psz_sdp ); @@ -1172,7 +1197,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, else { answer->i_status = 500; - answer->psz_status = strdup( "Internal server error" ); answer->p_body = NULL; answer->i_body = 0; } @@ -1186,11 +1210,11 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, p_rtsp = RtspClientGet( p_media, psz_session ); if( !p_rtsp ) break; - CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, psz_session, 0, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, psz_session, + 0, NULL ); p_rtsp->b_paused = VLC_TRUE; answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -1198,7 +1222,6 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, case HTTPD_MSG_TEARDOWN: /* for now only multicast so easy again */ answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; @@ -1208,13 +1231,13 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, p_rtsp = RtspClientGet( p_media, psz_session ); if( !p_rtsp ) break; - CommandPush( p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session, 0, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session, + 0, NULL ); RtspClientDel( p_media, p_rtsp ); break; case HTTPD_MSG_GETPARAMETER: answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -1237,13 +1260,14 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, p_media->p_vod->p_sys->i_session_timeout ); else httpd_MsgAdd( answer, "Session", "%s", psz_session ); - } + } return VLC_SUCCESS; } static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, - httpd_message_t *answer, httpd_message_t *query ) + httpd_message_t *answer, + const httpd_message_t *query ) { media_es_t *p_es = (media_es_t*)p_args; vod_media_t *p_media = p_es->p_media; @@ -1282,12 +1306,11 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, rtsp_client_es_t *p_rtsp_es = NULL; char ip[NI_MAXNUMERICHOST]; int i_port = atoi( strstr( psz_transport, "client_port=" ) + - strlen("client_port=") ); + strlen("client_port=") ); if( httpd_ClientIP( cl, ip ) == NULL ) { answer->i_status = 500; - answer->psz_status = strdup( "Internal server error" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -1304,12 +1327,12 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ( p_vod->p_sys->i_connections >= p_vod->p_sys->i_throttle_users ) ) { answer->i_status = 503; - answer->psz_status = strdup( "Too many connections" ); answer->i_body = 0; answer->p_body = NULL; break; } - asprintf( &psz_new, "%d", rand() ); + if( asprintf( &psz_new, "%d", rand() ) < 0 ) + return VLC_ENOMEM; psz_session = psz_new; p_rtsp = RtspClientNew( p_media, psz_new ); @@ -1320,7 +1343,6 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( !p_rtsp ) { answer->i_status = 454; - answer->psz_status = strdup( "Unknown session id" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -1331,7 +1353,6 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( !p_rtsp_es ) { answer->i_status = 500; - answer->psz_status = strdup( "Internal server error" ); answer->i_body = 0; answer->p_body = NULL; break; @@ -1342,7 +1363,6 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, TAB_APPEND( p_rtsp->i_es, p_rtsp->es, p_rtsp_es ); answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; @@ -1350,25 +1370,27 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, { if( strstr( psz_transport, "MP2T/H2221/UDP" ) ) { - httpd_MsgAdd( answer, "Transport", "MP2T/H2221/UDP;client_port=%d-%d", - p_rtsp_es->i_port, p_rtsp_es->i_port + 1 ); + httpd_MsgAdd( answer, "Transport", + "MP2T/H2221/UDP;client_port=%d-%d", + p_rtsp_es->i_port, p_rtsp_es->i_port + 1 ); } else if( strstr( psz_transport, "RAW/RAW/UDP" ) ) { - httpd_MsgAdd( answer, "Transport", "RAW/RAW/UDP;client_port=%d-%d", - p_rtsp_es->i_port, p_rtsp_es->i_port + 1 ); + httpd_MsgAdd( answer, "Transport", + "RAW/RAW/UDP;client_port=%d-%d", + p_rtsp_es->i_port, p_rtsp_es->i_port + 1 ); } } else { - httpd_MsgAdd( answer, "Transport", "RTP/AVP/UDP;client_port=%d-%d", + httpd_MsgAdd( answer, "Transport", + "RTP/AVP/UDP;client_port=%d-%d", p_rtsp_es->i_port, p_rtsp_es->i_port + 1 ); } } else /* TODO strstr( psz_transport, "interleaved" ) ) */ { answer->i_status = 461; - answer->psz_status = strdup( "Unsupported Transport" ); answer->i_body = 0; answer->p_body = NULL; } @@ -1400,14 +1422,14 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( end > psz_position ) { f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100; - CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, psz_session, f_pos, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, + psz_session, f_pos, NULL ); } } if( !psz_playnow ) { answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; } @@ -1415,7 +1437,6 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, case HTTPD_MSG_TEARDOWN: answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; @@ -1437,7 +1458,8 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( !p_rtsp->i_es ) { - CommandPush( p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session, 0, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session, + 0, NULL ); RtspClientDel( p_media, p_rtsp ); } break; @@ -1451,11 +1473,11 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, p_rtsp = RtspClientGet( p_media, psz_session ); if( !p_rtsp ) break; - CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, psz_session, 0, NULL ); + CommandPush( p_vod, RTSP_CMD_TYPE_PAUSE, p_media, psz_session, + 0, NULL ); p_rtsp->b_paused = VLC_TRUE; answer->i_status = 200; - answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; break;