| 691 | | int inclport = (psz_destination != NULL); |
|---|
| 692 | | |
|---|
| 693 | | /* FIXME: breaks IP version check on unknown destination */ |
|---|
| 694 | | if( psz_destination == NULL ) |
|---|
| 695 | | psz_destination = "0.0.0.0"; |
|---|
| 696 | | |
|---|
| 697 | | i_size = sizeof( "v=0\r\n" ) + |
|---|
| 698 | | sizeof( "o=- * * IN IP4 127.0.0.1\r\n" ) + 10 + 10 + |
|---|
| 699 | | sizeof( "s=*\r\n" ) + strlen( p_sys->psz_session_name ) + |
|---|
| 700 | | sizeof( "i=*\r\n" ) + strlen( p_sys->psz_session_description ) + |
|---|
| 701 | | sizeof( "u=*\r\n" ) + strlen( p_sys->psz_session_url ) + |
|---|
| 702 | | sizeof( "e=*\r\n" ) + strlen( p_sys->psz_session_email ) + |
|---|
| 703 | | sizeof( "t=0 0\r\n" ) + |
|---|
| 704 | | sizeof( "b=RR:0\r\n" ) + |
|---|
| 705 | | sizeof( "a=tool:"PACKAGE_STRING"\r\n" ) + |
|---|
| 706 | | sizeof( "a=recvonly\r\n" ) + |
|---|
| 707 | | sizeof( "a=type:broadcast\r\n" ) + |
|---|
| 708 | | sizeof( "c=IN IP4 */*\r\n" ) + 20 + 10 + |
|---|
| 709 | | strlen( psz_destination ) ; |
|---|
| 710 | | for( i = 0; i < p_sys->i_es; i++ ) |
|---|
| 711 | | { |
|---|
| 712 | | sout_stream_id_t *id = p_sys->es[i]; |
|---|
| 713 | | |
|---|
| 714 | | i_size += strlen( "m=**d*o * RTP/AVP *\r\n" ) + 10 + 10; |
|---|
| 715 | | if ( id->i_bitrate ) |
|---|
| 716 | | { |
|---|
| 717 | | i_size += strlen( "b=AS: *\r\n") + 10; |
|---|
| 718 | | } |
|---|
| 719 | | if( id->psz_rtpmap ) |
|---|
| 720 | | { |
|---|
| 721 | | i_size += strlen( "a=rtpmap:* *\r\n" ) + strlen( id->psz_rtpmap )+10; |
|---|
| 722 | | } |
|---|
| 723 | | if( id->psz_fmtp ) |
|---|
| 724 | | { |
|---|
| 725 | | i_size += strlen( "a=fmtp:* *\r\n" ) + strlen( id->psz_fmtp ) + 10; |
|---|
| 726 | | } |
|---|
| 727 | | if( rtsp_url != NULL ) |
|---|
| 728 | | { |
|---|
| 729 | | i_size += strlen( "a=control:*/trackID=*\r\n" ) + strlen( rtsp_url ) + 10; |
|---|
| 730 | | } |
|---|
| 731 | | } |
|---|
| 732 | | |
|---|
| 733 | | ipv = ( strchr( psz_destination, ':' ) != NULL ) ? '6' : '4'; |
|---|
| 734 | | |
|---|
| 735 | | p = psz_sdp = malloc( i_size ); |
|---|
| 736 | | p += sprintf( p, "v=0\r\n" ); |
|---|
| 737 | | p += sprintf( p, "o=- "I64Fu" %d IN IP%c %s\r\n", |
|---|
| 738 | | p_sys->i_sdp_id, p_sys->i_sdp_version, |
|---|
| 739 | | ipv, ipv == '6' ? "::1" : "127.0.0.1" ); |
|---|
| 740 | | if( *p_sys->psz_session_name ) |
|---|
| 741 | | p += sprintf( p, "s=%s\r\n", p_sys->psz_session_name ); |
|---|
| 742 | | if( *p_sys->psz_session_description ) |
|---|
| 743 | | p += sprintf( p, "i=%s\r\n", p_sys->psz_session_description ); |
|---|
| 744 | | if( *p_sys->psz_session_url ) |
|---|
| 745 | | p += sprintf( p, "u=%s\r\n", p_sys->psz_session_url ); |
|---|
| 746 | | if( *p_sys->psz_session_email ) |
|---|
| 747 | | p += sprintf( p, "e=%s\r\n", p_sys->psz_session_email ); |
|---|
| 748 | | |
|---|
| 749 | | p += sprintf( p, "t=0 0\r\n" ); /* permanent stream */ |
|---|
| 750 | | /* when scheduled from vlm, we should set this info correctly */ |
|---|
| 751 | | p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" ); |
|---|
| 752 | | p += sprintf( p, "a=recvonly\r\n" ); |
|---|
| 753 | | p += sprintf( p, "a=type:broadcast\r\n" ); |
|---|
| 754 | | |
|---|
| 755 | | p += sprintf( p, "c=IN IP%c %s", ipv, psz_destination ); |
|---|
| 756 | | |
|---|
| 757 | | if( ( ipv == 4 ) |
|---|
| 758 | | && net_AddressIsMulticast( (vlc_object_t *)p_stream, psz_destination ) ) |
|---|
| 759 | | { |
|---|
| 760 | | /* Add the deprecated TTL field if it is an IPv4 multicast address */ |
|---|
| 761 | | p += sprintf( p, "/%d", p_sys->i_ttl ?: 1 ); |
|---|
| 762 | | } |
|---|
| 763 | | p += sprintf( p, "\r\n" ); |
|---|
| 764 | | p += sprintf( p, "b=RR:0\r\n" ); |
|---|
| 765 | | |
|---|
| | 691 | int inclport; |
|---|
| | 692 | |
|---|
| | 693 | if( p_sys->psz_destination != NULL ) |
|---|
| | 694 | { |
|---|
| | 695 | inclport = 1; |
|---|
| | 696 | |
|---|
| | 697 | /* Oh boy, this is really ugly! (+ race condition on lock_es) */ |
|---|
| | 698 | dstlen = sizeof( dst ); |
|---|
| | 699 | getsockname( p_sys->es[0]->sinkv[0].rtp_fd, (struct sockaddr *)&dst, |
|---|
| | 700 | &dstlen ); |
|---|
| | 701 | } |
|---|
| | 702 | else |
|---|
| | 703 | { |
|---|
| | 704 | inclport = 0; |
|---|
| | 705 | |
|---|
| | 706 | /* Dummy destination address for RTSP */ |
|---|
| | 707 | memset (&dst, 0, sizeof( struct sockaddr_in ) ); |
|---|
| | 708 | dst.ss_family = AF_INET; |
|---|
| | 709 | #ifdef HAVE_SA_LEN |
|---|
| | 710 | dst.ss_len = |
|---|
| | 711 | #endif |
|---|
| | 712 | dstlen = sizeof( struct sockaddr_in ); |
|---|
| | 713 | } |
|---|
| | 714 | |
|---|
| | 715 | psz_sdp = sdp_Start( p_sys->psz_session_name, |
|---|
| | 716 | p_sys->psz_session_description, |
|---|
| | 717 | p_sys->psz_session_url, p_sys->psz_session_email, |
|---|
| | 718 | NULL, NULL, 0, (struct sockaddr *)&dst, dstlen ); |
|---|
| | 719 | if( psz_sdp == NULL ) |
|---|
| | 720 | return NULL; |
|---|
| | 721 | |
|---|
| | 722 | /* TODO: a=source-filter */ |
|---|
| | 723 | |
|---|
| | 724 | /* FIXME: locking?! */ |
|---|