Changeset 35754abaa2da8d632456163379721ab6446a0d0c
- Timestamp:
- 24/08/07 17:47:34 (1 year ago)
- git-parent:
- Files:
-
- modules/stream_out/rtp.c (modified) (15 diffs)
- modules/stream_out/rtp.h (modified) (1 diff)
- modules/stream_out/rtsp.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
modules/stream_out/rtp.c
r685ca38 r35754ab 167 167 static int HttpSetup( sout_stream_t *p_stream, vlc_url_t * ); 168 168 169 struct sout_stream_sys_t 170 { 171 /* sdp */ 172 int64_t i_sdp_id; 173 int i_sdp_version; 174 char *psz_sdp; 175 vlc_mutex_t lock_sdp; 176 177 char *psz_session_name; 178 char *psz_session_description; 179 char *psz_session_url; 180 char *psz_session_email; 181 182 /* */ 183 vlc_bool_t b_export_sdp_file; 184 char *psz_sdp_file; 185 /* sap */ 186 vlc_bool_t b_export_sap; 187 session_descriptor_t *p_session; 188 189 httpd_host_t *p_httpd_host; 190 httpd_file_t *p_httpd_file; 191 192 rtsp_stream_t *rtsp; 193 194 /* */ 195 char *psz_destination; 196 int i_port; 197 int i_port_audio; 198 int i_port_video; 199 int i_ttl; 200 vlc_bool_t b_latm; 201 202 /* when need to use a private one or when using muxer */ 203 int i_payload_type; 204 205 /* in case we do TS/PS over rtp */ 206 sout_mux_t *p_mux; 207 sout_access_out_t *p_access; 208 int i_mtu; 209 sout_access_out_t *p_grab; 210 uint16_t i_sequence; 211 uint32_t i_timestamp_start; 212 uint8_t ssrc[4]; 213 block_t *packet; 214 215 /* */ 216 vlc_mutex_t lock_es; 217 int i_es; 218 sout_stream_id_t **es; 219 }; 220 221 typedef int (*pf_rtp_packetizer_t)( sout_stream_t *, sout_stream_id_t *, 222 block_t * ); 223 169 224 struct sout_stream_id_t 170 225 { … … 301 356 p_sys->i_es = 0; 302 357 p_sys->es = NULL; 303 p_sys->i_rtsp = 0; 304 p_sys->rtsp = NULL; 358 p_sys->rtsp = NULL; 305 359 p_sys->psz_sdp = NULL; 306 360 … … 315 369 p_sys->p_httpd_host = NULL; 316 370 p_sys->p_httpd_file = NULL; 317 p_sys->p_rtsp_host = NULL;318 p_sys->p_rtsp_url = NULL;319 p_sys->psz_rtsp_control = NULL;320 p_sys->psz_rtsp_path = NULL;321 371 322 372 vlc_mutex_init( p_stream, &p_sys->lock_sdp ); … … 548 598 } 549 599 550 RtspUnsetup( p_stream ); 600 if( p_sys->rtsp != NULL ) 601 RtspUnsetup( p_sys->rtsp ); 551 602 552 603 vlc_mutex_destroy( &p_sys->lock_sdp ); … … 598 649 { 599 650 msg_Err( p_stream, "you can use sdp=http:// only once" ); 600 return;651 goto out; 601 652 } 602 653 603 654 if( HttpSetup( p_stream, &url ) ) 604 655 { 605 msg_Err( p_stream, "cannot export sdp as http" );656 msg_Err( p_stream, "cannot export SDP as HTTP" ); 606 657 } 607 658 } 608 659 else if( url.psz_protocol && !strcasecmp( url.psz_protocol, "rtsp" ) ) 609 660 { 610 if( p_sys-> p_rtsp_url)661 if( p_sys->rtsp != NULL ) 611 662 { 612 663 msg_Err( p_stream, "you can use sdp=rtsp:// only once" ); 613 return;664 goto out; 614 665 } 615 666 616 667 /* FIXME test if destination is multicast or no destination at all FIXME */ 617 if( RtspSetup( p_stream, &url ) ) 618 { 619 msg_Err( p_stream, "cannot export sdp as rtsp" ); 668 p_sys->rtsp = RtspSetup( p_stream, &url ); 669 if( p_sys->rtsp == NULL ) 670 { 671 msg_Err( p_stream, "cannot export SDP as RTSP" ); 620 672 } 621 673 } … … 631 683 { 632 684 msg_Err( p_stream, "you can use sdp=file:// only once" ); 633 return;685 goto out; 634 686 } 635 687 p_sys->b_export_sdp_file = VLC_TRUE; … … 644 696 url.psz_protocol ); 645 697 } 698 699 out: 646 700 vlc_UrlClean( &url ); 647 701 } … … 663 717 a= x-plgroup: (missing) 664 718 RTP packets need to get the correct src IP address */ 665 /*static*/ char *SDPGenerate( const sout_stream_t *p_stream, 666 const char *psz_destination, vlc_bool_t b_rtsp ) 667 { 668 sout_stream_sys_t *p_sys = p_stream->p_sys; 669 int i_size; 719 /*static*/ 720 char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url ) 721 { 722 const sout_stream_sys_t *p_sys = p_stream->p_sys; 723 size_t i_size; 724 const char *psz_destination = p_sys->psz_destination; 670 725 char *psz_sdp, *p, ipv; 671 726 int i; … … 703 758 i_size += strlen( "a=fmtp:* *\r\n" ) + strlen( id->psz_fmtp ) + 10; 704 759 } 705 if( b_rtsp)706 { 707 i_size += strlen( "a=control:*/trackID=*\r\n" ) + strlen( p_sys->psz_rtsp_control ) + 10;760 if( rtsp_url != NULL ) 761 { 762 i_size += strlen( "a=control:*/trackID=*\r\n" ) + strlen( rtsp_url ) + 10; 708 763 } 709 764 } … … 775 830 id->psz_fmtp ); 776 831 } 777 if( b_rtsp)832 if( rtsp_url != NULL ) 778 833 { 779 834 p += sprintf( p, "a=control:/trackID=%d\r\n", i ); … … 783 838 { 784 839 p += sprintf( p, "m=video %d RTP/AVP %d\r\n", 785 p_sys->i_port, p_sys->i_payload_type );840 p_sys->i_port, p_sys->i_payload_type ); 786 841 } 787 842 … … 1137 1192 msg_Dbg( p_stream, "maximum RTP packet size: %d bytes", id->i_mtu ); 1138 1193 1139 if( p_sys->p_rtsp_url ) 1140 id->rtsp_id = RtspAddId( p_stream, id, id->i_port, id->i_port + 1 ); 1194 if( p_sys->rtsp != NULL ) 1195 id->rtsp_id = RtspAddId( p_sys->rtsp, id, p_sys->i_es, 1196 p_sys->psz_destination, 1197 p_sys->i_ttl, id->i_port, id->i_port + 1 ); 1141 1198 1142 1199 /* Update p_sys context */ … … 1145 1202 vlc_mutex_unlock( &p_sys->lock_es ); 1146 1203 1147 psz_sdp = SDPGenerate( p_stream, p_sys->psz_destination, VLC_FALSE);1204 psz_sdp = SDPGenerate( p_stream, NULL ); 1148 1205 1149 1206 vlc_mutex_lock( &p_sys->lock_sdp ); … … 1197 1254 } 1198 1255 if( id->rtsp_id ) 1199 RtspDelId( p_s tream, id->rtsp_id );1256 RtspDelId( p_sys->rtsp, id->rtsp_id ); 1200 1257 1201 1258 vlc_mutex_destroy( &id->lock_sink ); … … 1478 1535 void rtp_del_sink( sout_stream_id_t *id, sout_access_out_t *access ) 1479 1536 { 1537 /* NOTE: must be safe to use if access is not a sink to id */ 1480 1538 vlc_mutex_lock( &id->lock_sink ); 1481 1539 TAB_REMOVE( id->i_sink, id->sink, access ); modules/stream_out/rtp.h
r685ca38 r35754ab 23 23 *****************************************************************************/ 24 24 25 /*ypedef struct rtsp_stream_t rtsp_stream_t;*/ 25 typedef struct rtsp_stream_t rtsp_stream_t; 26 26 typedef struct rtsp_stream_id_t rtsp_stream_id_t; 27 typedef struct rtsp_client_t rtsp_client_t;28 27 29 intRtspSetup( sout_stream_t *p_stream, const vlc_url_t *url );30 void RtspUnsetup( sout_stream_t *p_stream);28 rtsp_stream_t *RtspSetup( sout_stream_t *p_stream, const vlc_url_t *url ); 29 void RtspUnsetup( rtsp_stream_t *rtsp ); 31 30 32 rtsp_stream_id_t *RtspAddId( sout_stream_t *p_stream, sout_stream_id_t *sid, 31 rtsp_stream_id_t *RtspAddId( rtsp_stream_t *rtsp, sout_stream_id_t *sid, 32 unsigned i, 33 const char *dst, int ttl, 33 34 unsigned loport, unsigned hiport ); 34 void RtspDelId( sout_stream_t *p_stream, rtsp_stream_id_t * );35 void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t * ); 35 36 36 char *SDPGenerate( const sout_stream_t *p_stream, 37 const char *psz_destination, vlc_bool_t b_rtsp ); 37 char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url ); 38 38 39 39 int rtp_add_sink( sout_stream_id_t *id, sout_access_out_t *access ); 40 40 void rtp_del_sink( sout_stream_id_t *id, sout_access_out_t *access ); 41 41 42 typedef int (*pf_rtp_packetizer_t)( sout_stream_t *, sout_stream_id_t *,43 block_t * );44 45 struct sout_stream_sys_t46 {47 /* sdp */48 int64_t i_sdp_id;49 int i_sdp_version;50 char *psz_sdp;51 vlc_mutex_t lock_sdp;52 53 char *psz_session_name;54 char *psz_session_description;55 char *psz_session_url;56 char *psz_session_email;57 58 /* */59 vlc_bool_t b_export_sdp_file;60 char *psz_sdp_file;61 /* sap */62 vlc_bool_t b_export_sap;63 session_descriptor_t *p_session;64 65 httpd_host_t *p_httpd_host;66 httpd_file_t *p_httpd_file;67 68 httpd_host_t *p_rtsp_host;69 httpd_url_t *p_rtsp_url;70 char *psz_rtsp_control;71 char *psz_rtsp_path;72 73 /* */74 char *psz_destination;75 int i_port;76 int i_port_audio;77 int i_port_video;78 int i_ttl;79 vlc_bool_t b_latm;80 81 /* when need to use a private one or when using muxer */82 int i_payload_type;83 84 /* in case we do TS/PS over rtp */85 sout_mux_t *p_mux;86 sout_access_out_t *p_access;87 int i_mtu;88 sout_access_out_t *p_grab;89 uint16_t i_sequence;90 uint32_t i_timestamp_start;91 uint8_t ssrc[4];92 block_t *packet;93 94 /* */95 vlc_mutex_t lock_es;96 int i_es;97 sout_stream_id_t **es;98 99 /* */100 int i_rtsp;101 rtsp_client_t **rtsp;102 };modules/stream_out/rtsp.c
r685ca38 r35754ab 31 31 #include <vlc_url.h> 32 32 #include <vlc_network.h> 33 #include <assert.h> 33 34 34 35 #include "rtp.h" 35 36 36 /* For unicast/interleaved streaming */ 37 struct rtsp_client_t 38 { 39 char *psz_session; 40 int64_t i_last; /* for timeout */ 41 42 /* is it in "play" state */ 43 vlc_bool_t b_playing; 44 45 /* output (id-access) */ 46 int i_id; 47 sout_stream_id_t **id; 48 int i_access; 49 sout_access_out_t **access; 37 typedef struct rtsp_session_t rtsp_session_t; 38 39 struct rtsp_stream_t 40 { 41 vlc_mutex_t lock; 42 sout_stream_t *owner; 43 httpd_host_t *host; 44 httpd_url_t *url; 45 char *psz_control; 46 char *psz_path; 47 48 int sessionc; 49 rtsp_session_t **sessionv; 50 50 }; 51 51 52 52 53 static int RtspCallback( httpd_callback_sys_t *p_args, … … 56 57 httpd_client_t *cl, 57 58 httpd_message_t *answer, httpd_message_t *query ); 58 static void RtspClientDel( sout_stream_t *p_stream, rtsp_client_t *rtsp ); 59 60 int RtspSetup( sout_stream_t *p_stream, const vlc_url_t *url ) 61 { 62 sout_stream_sys_t *p_sys = p_stream->p_sys; 63 64 msg_Dbg( p_stream, "rtsp setup: %s : %d / %s\n", url->psz_host, url->i_port, url->psz_path ); 65 66 p_sys->p_rtsp_host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host, url->i_port > 0 ? url->i_port : 554 ); 67 if( p_sys->p_rtsp_host == NULL ) 68 { 69 return VLC_EGENERIC; 70 } 71 72 p_sys->psz_rtsp_path = strdup( url->psz_path ? url->psz_path : "/" ); 73 p_sys->psz_rtsp_control = malloc (strlen( url->psz_host ) + 20 + strlen( p_sys->psz_rtsp_path ) + 1 ); 74 sprintf( p_sys->psz_rtsp_control, "rtsp://%s:%d%s", 75 url->psz_host, url->i_port > 0 ? url->i_port : 554, p_sys->psz_rtsp_path ); 76 77 p_sys->p_rtsp_url = httpd_UrlNewUnique( p_sys->p_rtsp_host, p_sys->psz_rtsp_path, NULL, NULL, NULL ); 78 if( p_sys->p_rtsp_url == NULL ) 79 { 80 return VLC_EGENERIC; 81 } 82 httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_DESCRIBE, RtspCallback, (void*)p_stream ); 83 httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_SETUP, RtspCallback, (void*)p_stream ); 84 httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_PLAY, RtspCallback, (void*)p_stream ); 85 httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_PAUSE, RtspCallback, (void*)p_stream ); 86 httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_TEARDOWN, RtspCallback, (void*)p_stream ); 87 88 return VLC_SUCCESS; 89 } 90 91 92 void RtspUnsetup( sout_stream_t *p_stream ) 93 { 94 sout_stream_sys_t *p_sys = p_stream->p_sys; 95 while( p_sys->i_rtsp > 0 ) 96 RtspClientDel( p_stream, p_sys->rtsp[0] ); 97 98 if( p_sys->p_rtsp_url ) 99 httpd_UrlDelete( p_sys->p_rtsp_url ); 100 101 if( p_sys->p_rtsp_host ) 102 httpd_HostDelete( p_sys->p_rtsp_host ); 59 static void RtspClientDel( rtsp_stream_t *rtsp, rtsp_session_t *session ); 60 61 rtsp_stream_t *RtspSetup( sout_stream_t *p_stream, const vlc_url_t *url ) 62 { 63 rtsp_stream_t *rtsp = malloc( sizeof( *rtsp ) ); 64 65 if( rtsp == NULL ) 66 return NULL; 67 68 rtsp->owner = p_stream; 69 rtsp->sessionc = 0; 70 rtsp->sessionv = NULL; 71 vlc_mutex_init( p_stream, &rtsp->lock ); 72 73 msg_Dbg( p_stream, "rtsp setup: %s : %d / %s\n", 74 url->psz_host, url->i_port, url->psz_path ); 75 76 rtsp->psz_path = strdup( url->psz_path ? url->psz_path : "/" ); 77 if( rtsp->psz_path == NULL ) 78 goto error; 79 80 if( asprintf( &rtsp->psz_control, "rtsp://%s:%d%s", 81 url->psz_host, url->i_port > 0 ? url->i_port : 554, 82 rtsp->psz_path ) == -1 ) 83 { 84 rtsp->psz_control = NULL; 85 goto error; 86 } 87 88 rtsp->host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host, 89 url->i_port > 0 ? url->i_port : 554 ); 90 if( rtsp->host == NULL ) 91 goto error; 92 93 rtsp->url = httpd_UrlNewUnique( rtsp->host, rtsp->psz_path, NULL, NULL, 94 NULL ); 95 if( rtsp->url == NULL ) 96 goto error; 97 98 httpd_UrlCatch( rtsp->url, HTTPD_MSG_DESCRIBE, RtspCallback, (void*)rtsp ); 99 httpd_UrlCatch( rtsp->url, HTTPD_MSG_SETUP, RtspCallback, (void*)rtsp ); 100 httpd_UrlCatch( rtsp->url, HTTPD_MSG_PLAY, RtspCallback, (void*)rtsp ); 101 httpd_UrlCatch( rtsp->url, HTTPD_MSG_PAUSE, RtspCallback, (void*)rtsp ); 102 httpd_UrlCatch( rtsp->url, HTTPD_MSG_TEARDOWN, RtspCallback, (void*)rtsp ); 103 return rtsp; 104 105 error: 106 RtspUnsetup( rtsp ); 107 return NULL; 108 } 109 110 111 void RtspUnsetup( rtsp_stream_t *rtsp ) 112 { 113 while( rtsp->sessionc > 0 ) 114 RtspClientDel( rtsp, rtsp->sessionv[0] ); 115 116 if( rtsp->url ) 117 httpd_UrlDelete( rtsp->url ); 118 119 if( rtsp->host ) 120 httpd_HostDelete( rtsp->host ); 121 122 vlc_mutex_destroy( &rtsp->lock ); 103 123 } 104 124 … … 106 126 struct rtsp_stream_id_t 107 127 { 108 sout_stream_t *sout_stream;128 rtsp_stream_t *stream; 109 129 sout_stream_id_t *sout_id; 110 130 httpd_url_t *url; 131 const char *dst; 132 int ttl; 111 133 unsigned loport, hiport; 112 134 }; 113 135 114 rtsp_stream_id_t *RtspAddId( sout_stream_t *p_stream, sout_stream_id_t *sid, 136 137 /* For unicast streaming */ 138 struct rtsp_session_t 139 { 140 rtsp_stream_t *stream; 141 142 /* is it in "play" state */ 143 vlc_bool_t b_playing; 144 145 /* output (id-access) */ 146 int i_id; 147 sout_stream_id_t **id; 148 int i_access; 149 sout_access_out_t **access; 150 151 char name[0]; 152 }; 153 154 155 rtsp_stream_id_t *RtspAddId( rtsp_stream_t *rtsp, sout_stream_id_t *sid, 156 unsigned num, 157 /* Multicast stuff - TODO: cleanup */ 158 const char *dst, int ttl, 115 159 unsigned loport, unsigned hiport ) 116 160 { 117 sout_stream_sys_t *p_sys = p_stream->p_sys; 118 char psz_urlc[strlen( p_sys->psz_rtsp_control ) + 1 + 10]; 161 char urlbuf[strlen( rtsp->psz_control ) + 1 + 10]; 119 162 rtsp_stream_id_t *id = malloc( sizeof( *id ) ); 120 163 httpd_url_t *url; … … 123 166 return NULL; 124 167 125 id->s out_stream = p_stream;168 id->stream = rtsp; 126 169 id->sout_id = sid; 127 id->loport = loport; 128 id->hiport = loport; 129 130 sprintf( psz_urlc, "%s/trackID=%d", p_sys->psz_rtsp_path, p_sys->i_es ); 131 msg_Dbg( p_stream, "RTSP: adding %s\n", psz_urlc ); 132 url = id->url = 133 httpd_UrlNewUnique( p_sys->p_rtsp_host, psz_urlc, NULL, NULL, NULL ); 170 /* TODO: can we assume that this need not be strdup'd? */ 171 id->dst = dst; 172 if( id->dst != NULL ) 173 { 174 id->ttl = ttl; 175 id->loport = loport; 176 id->hiport = hiport; 177 } 178 179 sprintf( urlbuf, "%s/trackID=%d", rtsp->psz_path, num ); 180 msg_Dbg( rtsp->owner, "RTSP: adding %s\n", urlbuf ); 181 url = id->url = httpd_UrlNewUnique( rtsp->host, urlbuf, NULL, NULL, NULL ); 134 182 135 183 if( url == NULL ) … … 149 197 150 198 151 void RtspDelId( sout_stream_t *p_stream, rtsp_stream_id_t *id ) 152 { 153 httpd_UrlDelete( id->url ); 154 free( id ); 155 } 156 157 158 static rtsp_client_t *RtspClientNew( sout_stream_t *p_stream, const char *psz_session ) 159 { 160 rtsp_client_t *rtsp = malloc( sizeof( rtsp_client_t )); 161 162 rtsp->psz_session = strdup( psz_session ); 163 rtsp->i_last = 0; 164 rtsp->b_playing = VLC_FALSE; 165 rtsp->i_id = 0; 166 rtsp->id = NULL; 167 rtsp->i_access = 0; 168 rtsp->access = NULL; 169 170 TAB_APPEND( p_stream->p_sys->i_rtsp, p_stream->p_sys->rtsp, rtsp ); 171 172 return rtsp; 173 } 174 175 176 static rtsp_client_t *RtspClientGet( sout_stream_t *p_stream, const char *psz_session ) 199 void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t *id ) 200 { 201 vlc_mutex_lock( &rtsp->lock ); 202 for( int i = 0; i < rtsp->sessionc; i++ ) 203 { 204 rtsp_session_t *ses = rtsp->sessionv[i]; 205 206 for( int j = 0; j < ses->i_id; j++ ) 207 { 208 if( ses->id[j] == id->sout_id ) 209 { 210 REMOVE_ELEM( ses->id, ses->i_id, j ); 211 212 assert( ses->access[j] != NULL ); 213 sout_AccessOutDelete( ses->access[j] ); 214 REMOVE_ELEM( ses->access, ses->i_access, j ); 215 /* FIXME: are we supposed to notify the client? */ 216 } 217 } 218 } 219 220 vlc_mutex_unlock( &rtsp->lock ); 221 httpd_UrlDelete( id->url ); 222 free( id ); 223 } 224 225 226 /** rtsp must be locked */ 227 static 228 rtsp_session_t *RtspClientNew( rtsp_stream_t *rtsp, const char *name ) 229 { 230 rtsp_session_t *s = malloc( sizeof( *s ) + strlen( name ) + 1 ); 231 232 s->stream = rtsp; 233 s->b_playing = VLC_FALSE; 234 s->i_id = s->i_access = 0; 235 s->id = NULL; 236 s->access = NULL; 237 strcpy( s->name, name ); 238 239 TAB_APPEND( rtsp->sessionc, rtsp->sessionv, s ); 240 241 return s; 242 } 243 244 245 /** rtsp must be locked */ 246 static 247 rtsp_session_t *RtspClientGet( rtsp_stream_t *rtsp, const char *name ) 177 248 { 178 249 int i; 179 250 180 if( !psz_session ) return NULL;181 182 for( i = 0; i < p_stream->p_sys->i_rtsp; i++ ) 183 {184 if( !strcmp( p_stream->p_sys->rtsp[i]->psz_session, psz_session ))185 {186 return p_stream->p_sys->rtsp[i];187 }251 if( name == NULL ) 252 return NULL; 253 254 /* FIXME: use a hash/dictionary */ 255 for( i = 0; i < rtsp->sessionc; i++ ) 256 { 257 if( !strcmp( rtsp->sessionv[i]->name, name ) ) 258 return rtsp->sessionv[i]; 188 259 } 189 260 return NULL; … … 191 262 192 263 193 static void RtspClientDel( sout_stream_t *p_stream, rtsp_client_t *rtsp ) 264 /** rtsp must be locked */ 265 static 266 void RtspClientDel( rtsp_stream_t *rtsp, rtsp_session_t *session ) 194 267 { 195 268 int i; 196 TAB_REMOVE( p_stream->p_sys->i_rtsp, p_stream->p_sys->rtsp, rtsp);197 198 for( i = 0; i < rtsp->i_access; i++ )199 { 200 sout_AccessOutDelete( rtsp->access[i] );201 }202 if( rtsp->id ) free( rtsp->id );203 if( rtsp->access ) free( rtsp->access ); 204 205 free( rtsp->psz_session);206 free( rtsp);269 TAB_REMOVE( rtsp->sessionc, rtsp->sessionv, session ); 270 271 for( i = 0; i < session->i_access; i++ ) 272 { 273 rtp_del_sink( session->id[i], session->access[i] ); 274 sout_AccessOutDelete( session->access[i] ); 275 } 276 277 free( session->id ); 278 free( session->access ); 279 free( session ); 207 280 } 208 281 … … 213 286 httpd_message_t *answer, httpd_message_t *query ) 214 287 { 215 sout_stream_t *p_stream = (sout_stream_t*)p_args; 216 sout_stream_sys_t *p_sys = p_stream->p_sys; 217 char *psz_destination = p_sys->psz_destination; 218 const char *psz_session = NULL; 219 const char *psz_cseq = NULL; 288 rtsp_stream_t *rtsp = (rtsp_stream_t *)p_args; 289 const char *psz_session = NULL, *psz_cseq; 220 290 221 291 if( answer == NULL || query == NULL ) … … 242 312 case HTTPD_MSG_DESCRIBE: 243 313 { 244 char *psz_sdp = SDPGenerate( p_stream, psz_destination, VLC_TRUE);314 char *psz_sdp = SDPGenerate( rtsp->owner, rtsp->psz_control ); 245 315 246 316 answer->i_status = 200; 247 317 httpd_MsgAdd( answer, "Content-Type", "%s", "application/sdp" ); 248 httpd_MsgAdd( answer, "Content-Base", "%s", p_sys->psz_rtsp_control );318 httpd_MsgAdd( answer, "Content-Base", "%s", rtsp->psz_control ); 249 319 answer->p_body = (uint8_t *)psz_sdp; 250 320 answer->i_body = strlen( psz_sdp ); … … 258 328 case HTTPD_MSG_PLAY: 259 329 { 260 rtsp_ client_t *rtsp;330 rtsp_session_t *ses; 261 331 answer->i_status = 200; 262 332 263 333 psz_session = httpd_MsgGet( query, "Session" ); 264 rtsp = RtspClientGet( p_stream, psz_session ); 265 if( rtsp && !rtsp->b_playing ) 334 335 vlc_mutex_lock( &rtsp->lock ); 336 ses = RtspClientGet( rtsp, psz_session ); 337 if( ( ses != NULL ) && !ses->b_playing ) 266 338 { 267 int i_id;268 339 /* FIXME */ 269 rtsp->b_playing = VLC_TRUE; 270 271 vlc_mutex_lock( &p_sys->lock_es ); 272 for( i_id = 0; i_id < rtsp->i_id; i_id++ ) 273 { 274 sout_stream_id_t *id = rtsp->id[i_id]; 275 int i; 276 277 for( i = 0; i < p_sys->i_es; i++ ) 278 { 279 if( id == p_sys->es[i] ) 280 break; 281 } 282 if( i >= p_sys->i_es ) continue; 283 284 rtp_add_sink( id, rtsp->access[i_id] ); 285 } 286 vlc_mutex_unlock( &p_sys->lock_es ); 340 ses->b_playing = VLC_TRUE; 341 342 for( int i_id = 0; i_id < ses->i_id; i_id++ ) 343 rtp_add_sink( ses->id[i_id], ses->access[i_id] ); 287 344 } 345 vlc_mutex_unlock( &rtsp->lock ); 288 346 break; 289 347 } … … 296 354 case HTTPD_MSG_TEARDOWN: 297 355 { 298 rtsp_ client_t *rtsp;356 rtsp_session_t *ses; 299 357 300 358 /* for now only multicast so easy again */ … … 302 360 303 361 psz_session = httpd_MsgGet( query, "Session" ); 304 rtsp = RtspClientGet( p_stream, psz_session ); 305 if( rtsp ) 306 { 307 int i_id; 308 309 vlc_mutex_lock( &p_sys->lock_es ); 310 for( i_id = 0; i_id < rtsp->i_id; i_id++ ) 311 { 312 sout_stream_id_t *id = rtsp->id[i_id]; 313 int i; 314 315 for( i = 0; i < p_sys->i_es; i++ ) 316 { 317 if( id == p_sys->es[i] ) 318 break; 319 } 320 if( i >= p_sys->i_es ) continue; 321 322 rtp_del_sink( id, rtsp->access[i_id] ); 323 } 324 vlc_mutex_unlock( &p_sys->lock_es ); 325 326 RtspClientDel( p_stream, rtsp ); 327 } 362 363 vlc_mutex_lock( &rtsp->lock ); 364 ses = RtspClientGet( rtsp, psz_session ); 365 if( ses != NULL ) 366 RtspClientDel( rtsp, ses ); 367 vlc_mutex_unlock( &rtsp->lock ); 328 368 break; 329 369 } … … 377 417 httpd_message_t *answer, httpd_message_t *query ) 378 418 { 379 rtsp_stream_id_t *id = (rtsp_stream_id_t *)p_args;380 sout_stream_t *p_stream = id->s out_stream;419 rtsp_stream_id_t *id = (rtsp_stream_id_t *)p_args; 420 sout_stream_t *p_stream = id->stream->owner; 381 421 sout_stream_id_t *sid = id->sout_id; 382 sout_stream_sys_t *p_sys = p_stream->p_sys;383 422 char psz_session_init[21]; 384 423 const char *psz_session; … … 484 523 if( b_multicast ) 485 524 { 486 if( p_sys->psz_destination == NULL ) 525 const char *dst = id->dst; 526 if( dst == NULL ) 487 527 continue; 488 528 … … 492 532 "RTP/AVP/UDP;destination=%s;port=%u-%u;" 493 533 "ttl=%d;mode=play", 494 p_sys->psz_destination, id->loport, 495 id->hiport, 496 ( p_sys->i_ttl > 0 ) ? p_sys->i_ttl : 1 ); 534 dst, id->loport, id->hiport, 535 ( id->ttl > 0 ) ? id->ttl : 1 ); 497 536 } 498 537 else 499 538 { 500 char ip[NI_MAXNUMERICHOST], psz_access[22],501 url[NI_MAXNUMERICHOST + 8];539 char ip[NI_MAXNUMERICHOST], url[NI_MAXNUMERICHOST + 8]; 540 static const char access[] = "udp{raw,rtcp}"; 502 541 sout_access_out_t *p_access; 503 rtsp_client_t *rtsp = NULL; 504 505 if( ( hiport - loport ) != ( id->hiport - id->loport ) ) 506 continue; 507 508 if( psz_session == NULL ) 509 { 510 psz_session = psz_session_init; 511 rtsp = RtspClientNew( p_stream, psz_session ); 512 } 513 else 514 { 515 /* FIXME: we probably need to remove an access out, 516 * if there is already one for the same ID */ 517 rtsp = RtspClientGet( p_stream, psz_session ); 518 if( rtsp == NULL ) 519 { 520 answer->i_status = 454; 521 continue; 522 } 523 } 542 rtsp_session_t *ses = NULL; 524 543 525 544 if( httpd_ClientIP( cl, ip ) == NULL ) … … 528 547 continue; 529 548 } 530 531 if( p_sys->i_ttl > 0 )532 snprintf( psz_access, sizeof( psz_access ),533 "udp{raw,rtcp,ttl=%d}", p_sys->i_ttl );534 else535 strcpy( psz_access, "udp{raw,rtcp}" );536 549 537 550 snprintf( url, sizeof( url ), … … 539 552 ip, loport ); 540 553 541 p_access = sout_AccessOutNew( p_stream->p_sout, 542 psz_access,url );554 p_access = sout_AccessOutNew( p_stream->p_sout, access, 555 url ); 543 556 if( p_access == NULL ) 544 557 { 545 558 msg_Err( p_stream, 546 559 "cannot create access output for %s://%s", 547 psz_access, url );560 access, url ); 548 561 answer->i_status = 500; 549 break; 550 } 551 552 TAB_APPEND( rtsp->i_id, rtsp->id, sid ); 553 TAB_APPEND( rtsp->i_access, rtsp->access, p_access ); 562 continue; 563 } 564 565 vlc_mutex_lock( &id->stream->lock ); 566 if( psz_session == NULL ) 567 { 568 psz_session = psz_session_init; 569 ses = RtspClientNew( id->stream, psz_session ); 570 } 571 else 572 { 573 /* FIXME: we probably need to remove an access out, 574 * if there is already one for the same ID */ 575 ses = RtspClientGet( id->stream, psz_session ); 576 if( ses == NULL ) 577 { 578 answer->i_status = 454; 579 vlc_mutex_unlock( &id->stream->lock ); 580 continue; 581 } 582 } 583 584 assert( ses->i_id == ses->i_access ); 585 TAB_APPEND( ses->i_id, ses->id, sid ); 586 TAB_APPEND( ses->i_access, ses->access, p_access ); 587 assert( ses->i_id == ses->i_access ); 588 vlc_mutex_unlock( &id->stream->lock ); 554 589 555 590 char *src = var_GetNonEmptyString (p_access, "src-addr"); … … 569 604 "client_port=%u-%u;server_port=%u-%u;" 570 605 "mode=play", 571 src, loport, hiport, sport, sport + 1 );606 src, loport, loport + 1, sport, sport + 1 ); 572 607 } 573 608 else … … 577 612 "client_port=%u-%u;server_port=%u-%u;" 578 613 "mode=play", 579 loport, hiport, sport, sport + 1 );614 loport, loport + 1, sport, sport + 1 ); 580 615 } 581 616
