Changeset 9160f1e048691054363ed6a28ff5ad08f63dff03
- Timestamp:
- 08/31/07 22:11:51
(1 year ago)
- Author:
- Rémi Denis-Courmont <rem@videolan.org>
- git-committer:
- Rémi Denis-Courmont <rem@videolan.org> 1188591111 +0000
- git-parent:
[01f85e92a05a776d374efde1dccf02987a4cf7cf]
- git-author:
- Rémi Denis-Courmont <rem@videolan.org> 1188591111 +0000
- Message:
Cleanup RTCP SR support a little bit
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r0b1c15a |
r9160f1e |
|
| 172 | 172 | static const char *MakeRandMulticast (int family, char *buf, size_t buflen); |
|---|
| 173 | 173 | |
|---|
| | 174 | typedef struct rtcp_sender_t |
|---|
| | 175 | { |
|---|
| | 176 | size_t length; /* RTCP packet length */ |
|---|
| | 177 | uint8_t payload[28 + 8 + (2 * 257)]; |
|---|
| | 178 | int handle; /* RTCP socket handler */ |
|---|
| | 179 | |
|---|
| | 180 | uint32_t packets; /* RTP packets sent */ |
|---|
| | 181 | uint32_t bytes; /* RTP bytes sent */ |
|---|
| | 182 | unsigned counter; /* RTP packets sent since last RTCP packet */ |
|---|
| | 183 | } rtcp_sender_t; |
|---|
| | 184 | |
|---|
| 174 | 185 | typedef struct sout_access_thread_t |
|---|
| 175 | 186 | { |
|---|
| … | … | |
| 187 | 198 | block_fifo_t *p_empty_blocks; |
|---|
| 188 | 199 | |
|---|
| 189 | | uint32_t sent_pkts; |
|---|
| 190 | | uint32_t sent_bytes; |
|---|
| 191 | | size_t rtcp_size; |
|---|
| 192 | | int rtcp_handle; |
|---|
| 193 | | uint8_t rtcp_data[28 + 8 + (2 * 257)]; |
|---|
| 194 | | |
|---|
| | 200 | rtcp_sender_t rtcp; |
|---|
| 195 | 201 | } sout_access_thread_t; |
|---|
| 196 | 202 | |
|---|
| … | … | |
| 213 | 219 | #define RTP_HEADER_LENGTH 12 |
|---|
| 214 | 220 | |
|---|
| 215 | | static int OpenRTCP (sout_access_out_t *obj, int proto, uint16_t dport); |
|---|
| 216 | | static void SendRTCP (sout_access_thread_t *obj, uint32_t timestamp); |
|---|
| 217 | | static void CloseRTCP (sout_access_thread_t *obj); |
|---|
| | 221 | static int OpenRTCP (vlc_object_t *obj, rtcp_sender_t *rtcp, int rtp_fd, |
|---|
| | 222 | int proto, uint16_t dport); |
|---|
| | 223 | static void SendRTCP (rtcp_sender_t *obj, const block_t *rtp); |
|---|
| | 224 | static void CloseRTCP (rtcp_sender_t *obj); |
|---|
| 218 | 225 | |
|---|
| 219 | 226 | /***************************************************************************** |
|---|
| … | … | |
| 383 | 390 | p_sys->i_ssrc = rand()&0xffffffff; |
|---|
| 384 | 391 | |
|---|
| 385 | | if (i_rtcp_port && OpenRTCP (p_access, proto, i_rtcp_port)) |
|---|
| | 392 | if (i_rtcp_port && OpenRTCP (VLC_OBJECT (p_access), &p_sys->p_thread->rtcp, |
|---|
| | 393 | i_handle, proto, i_rtcp_port)) |
|---|
| 386 | 394 | { |
|---|
| 387 | 395 | msg_Err (p_access, "cannot initialize RTCP sender"); |
|---|
| … | … | |
| 442 | 450 | |
|---|
| 443 | 451 | net_Close( p_sys->p_thread->i_handle ); |
|---|
| 444 | | CloseRTCP (p_sys->p_thread); |
|---|
| | 452 | CloseRTCP (&p_sys->p_thread->rtcp); |
|---|
| 445 | 453 | |
|---|
| 446 | 454 | vlc_object_detach( p_sys->p_thread ); |
|---|
| … | … | |
| 630 | 638 | # define strerror( x ) winsock_strerror( strerror_buf ) |
|---|
| 631 | 639 | #endif |
|---|
| 632 | | size_t rtcp_counter = 0; |
|---|
| 633 | 640 | |
|---|
| 634 | 641 | while( !p_thread->b_die ) |
|---|
| … | … | |
| 685 | 692 | msg_Warn( p_thread, "send error: %s", strerror(errno) ); |
|---|
| 686 | 693 | } |
|---|
| 687 | | else |
|---|
| 688 | | { |
|---|
| 689 | | p_thread->sent_pkts++; |
|---|
| 690 | | p_thread->sent_bytes += val; |
|---|
| 691 | | rtcp_counter += val; |
|---|
| 692 | | } |
|---|
| 693 | 694 | |
|---|
| 694 | 695 | if( i_dropped_packets ) |
|---|
| … | … | |
| 707 | 708 | #endif |
|---|
| 708 | 709 | |
|---|
| 709 | | if ((p_thread->rtcp_handle != -1) && (p_pk->i_buffer >= 8)) |
|---|
| 710 | | { // 1.25% rate limit: |
|---|
| 711 | | if ((rtcp_counter / 80) >= p_thread->rtcp_size) |
|---|
| 712 | | { |
|---|
| 713 | | SendRTCP (p_thread, GetDWBE (p_pk->p_buffer + 4)); |
|---|
| 714 | | rtcp_counter = 0; |
|---|
| 715 | | } |
|---|
| 716 | | } |
|---|
| | 710 | SendRTCP (&p_thread->rtcp, p_pk); |
|---|
| 717 | 711 | |
|---|
| 718 | 712 | block_FifoPut( p_thread->p_empty_blocks, p_pk ); |
|---|
| … | … | |
| 770 | 764 | * - we do not implement any profile-specific extensions for the time being. |
|---|
| 771 | 765 | */ |
|---|
| 772 | | static int OpenRTCP (sout_access_out_t *obj, int proto, uint16_t dport) |
|---|
| 773 | | { |
|---|
| 774 | | sout_access_out_sys_t *p_sys = obj->p_sys; |
|---|
| | 766 | static int OpenRTCP (vlc_object_t *obj, rtcp_sender_t *rtcp, int rtp_fd, |
|---|
| | 767 | int proto, uint16_t dport) |
|---|
| | 768 | { |
|---|
| 775 | 769 | uint8_t *ptr; |
|---|
| 776 | 770 | int fd; |
|---|
| … | … | |
| 779 | 773 | int sport; |
|---|
| 780 | 774 | |
|---|
| 781 | | fd = obj->p_sys->p_thread->i_handle; |
|---|
| 782 | | if (net_GetSockAddress (fd, src, &sport) |
|---|
| 783 | | || net_GetPeerAddress (fd, dst, NULL)) |
|---|
| | 775 | rtcp->bytes = rtcp->packets = rtcp->counter = 0; |
|---|
| | 776 | |
|---|
| | 777 | if (net_GetSockAddress (rtp_fd, src, &sport) |
|---|
| | 778 | || net_GetPeerAddress (rtp_fd, dst, NULL)) |
|---|
| 784 | 779 | return VLC_EGENERIC; |
|---|
| 785 | 780 | |
|---|
| … | … | |
| 789 | 784 | return VLC_EGENERIC; |
|---|
| 790 | 785 | |
|---|
| 791 | | obj->p_sys->p_thread->rtcp_handle = fd; |
|---|
| | 786 | rtcp->handle = fd; |
|---|
| 792 | 787 | |
|---|
| 793 | 788 | ptr = (uint8_t *)strchr (src, '%'); |
|---|
| … | … | |
| 795 | 790 | *ptr = '\0'; /* remove scope ID frop IPv6 addresses */ |
|---|
| 796 | 791 | |
|---|
| 797 | | ptr = obj->p_sys->p_thread->rtcp_data; |
|---|
| | 792 | ptr = rtcp->payload; |
|---|
| 798 | 793 | |
|---|
| 799 | 794 | /* Sender report */ |
|---|
| … | … | |
| 801 | 796 | ptr[1] = 200; /* payload type: Sender Report */ |
|---|
| 802 | 797 | SetWBE (ptr + 2, 6); /* length = 6 (7 double words) */ |
|---|
| 803 | | SetDWBE (ptr + 4, p_sys->i_ssrc); |
|---|
| | 798 | memset (ptr + 4, 0, 4); /* SSRC unknown yet */ |
|---|
| 804 | 799 | SetQWBE (ptr + 8, NTPtime64 ()); |
|---|
| | 800 | memset (ptr + 16, 0, 12); /* timestamp and counters */ |
|---|
| 805 | 801 | ptr += 28; |
|---|
| 806 | | /* timestamp and counter are handled later */ |
|---|
| 807 | 802 | |
|---|
| 808 | 803 | /* Source description */ |
|---|
| … | … | |
| 811 | 806 | ptr[1] = 202; /* payload type: Source Description */ |
|---|
| 812 | 807 | uint8_t *lenptr = ptr + 2; |
|---|
| 813 | | SetDWBE (ptr + 4, p_sys->i_ssrc); |
|---|
| | 808 | memset (ptr + 4, 0, 4); /* SSRC unknown yet */ |
|---|
| 814 | 809 | ptr += 8; |
|---|
| 815 | 810 | |
|---|
| … | … | |
| 830 | 825 | SetWBE (lenptr, ptr - sdes); |
|---|
| 831 | 826 | |
|---|
| 832 | | obj->p_sys->p_thread->rtcp_size = ptr - obj->p_sys->p_thread->rtcp_data; |
|---|
| | 827 | rtcp->length = ptr - rtcp->payload; |
|---|
| 833 | 828 | return VLC_SUCCESS; |
|---|
| 834 | 829 | } |
|---|
| 835 | 830 | |
|---|
| 836 | | static void CloseRTCP (sout_access_thread_t *obj) |
|---|
| 837 | | { |
|---|
| 838 | | if (obj->rtcp_handle == -1) |
|---|
| | 831 | static void CloseRTCP (rtcp_sender_t *rtcp) |
|---|
| | 832 | { |
|---|
| | 833 | if (rtcp->handle == -1) |
|---|
| 839 | 834 | return; |
|---|
| 840 | 835 | |
|---|
| 841 | | uint8_t *ptr = obj->rtcp_data; |
|---|
| | 836 | uint8_t *ptr = rtcp->payload; |
|---|
| 842 | 837 | /* Bye */ |
|---|
| 843 | 838 | ptr[0] = (2 << 6) | 1; /* V = 2, P = 0, SC = 1 */ |
|---|
| … | … | |
| 848 | 843 | /* We are THE sender, so we are more important than anybody else, so |
|---|
| 849 | 844 | * we can afford not to check bandwidth constraints here. */ |
|---|
| 850 | | send (obj->rtcp_handle, obj->rtcp_data, 8, 0); |
|---|
| 851 | | net_Close (obj->rtcp_handle); |
|---|
| 852 | | } |
|---|
| 853 | | |
|---|
| 854 | | static void SendRTCP (sout_access_thread_t *obj, uint32_t timestamp) |
|---|
| 855 | | { |
|---|
| 856 | | uint8_t *ptr = obj->rtcp_data; |
|---|
| | 845 | send (rtcp->handle, rtcp->payload, 8, 0); |
|---|
| | 846 | net_Close (rtcp->handle); |
|---|
| | 847 | } |
|---|
| | 848 | |
|---|
| | 849 | static void SendRTCP (rtcp_sender_t *rtcp, const block_t *rtp) |
|---|
| | 850 | { |
|---|
| | 851 | uint8_t *ptr = rtcp->payload; |
|---|
| | 852 | |
|---|
| | 853 | if ((rtcp->handle == -1) /* RTCP sender off */ |
|---|
| | 854 | || (rtp->i_buffer < 12)) /* too short RTP packet */ |
|---|
| | 855 | return; |
|---|
| | 856 | |
|---|
| | 857 | /* Updates statistics */ |
|---|
| | 858 | rtcp->packets++; |
|---|
| | 859 | rtcp->bytes += rtp->i_buffer; |
|---|
| | 860 | rtcp->counter += rtp->i_buffer; |
|---|
| | 861 | |
|---|
| | 862 | /* 1.25% rate limit */ |
|---|
| | 863 | if ((rtcp->counter / 80) < rtcp->length) |
|---|
| | 864 | return; |
|---|
| 857 | 865 | |
|---|
| 858 | 866 | uint32_t last = GetDWBE (ptr + 8); // last RTCP SR send time |
|---|
| … | … | |
| 861 | 869 | return; // no more than one SR every 5 seconds |
|---|
| 862 | 870 | |
|---|
| | 871 | memcpy (ptr + 4, rtp->p_buffer + 8, 4); /* SR SSRC */ |
|---|
| 863 | 872 | SetQWBE (ptr + 8, now64); |
|---|
| 864 | | SetDWBE (ptr + 16, timestamp); |
|---|
| 865 | | SetDWBE (ptr + 20, obj->sent_pkts); |
|---|
| 866 | | SetDWBE (ptr + 24, obj->sent_bytes); |
|---|
| 867 | | |
|---|
| 868 | | send (obj->rtcp_handle, ptr, obj->rtcp_size, 0); |
|---|
| 869 | | } |
|---|
| | 873 | memcpy (ptr + 16, rtp->p_buffer + 4, 4); /* RTP timestamp */ |
|---|
| | 874 | SetDWBE (ptr + 20, rtcp->packets); |
|---|
| | 875 | SetDWBE (ptr + 24, rtcp->bytes); |
|---|
| | 876 | memcpy (ptr + 28 + 4, rtp->p_buffer + 8, 4); /* SDES SSRC */ |
|---|
| | 877 | |
|---|
| | 878 | if (send (rtcp->handle, ptr, rtcp->length, 0) == (ssize_t)rtcp->length) |
|---|
| | 879 | rtcp->counter = 0; |
|---|
| | 880 | } |
|---|