00001 #include <arpa/inet.h>
00002 #include <iostream>
00003 #include "rtp_stream.h"
00004 #include "helper.h"
00005
00006 using namespace std;
00007
00008 #define CNAME "elphel353"
00009
00010 #undef RTP_DEBUG
00011
00012
00013 #ifdef RTP_DEBUG
00014 #define D(a) a
00015 #else
00016 #define D(a)
00017 #endif
00018
00019
00020 int RTP_Stream::_fd = -1;
00021
00022 RTP_Stream::RTP_Stream(void) {
00023 _play = false;
00024 pthread_mutex_init(&pthm_flow, NULL);
00025 stream_name = "unknown";
00026 }
00027
00028 void RTP_Stream::init_pthread(void *__this) {
00029 pth_id = pthread_create(&pth, NULL, RTP_Stream::pthread_f, (void *)__this);
00030 }
00031
00032 void *RTP_Stream::pthread_f(void *_this) {
00033 RTP_Stream *__this = (RTP_Stream *)_this;
00034 return __this->thread();
00035 }
00036
00037 void RTP_Stream::Start(string ip, int port) {
00038 D(cerr << " new " << stream_name << " UDP socket at port: " << port << endl;)
00039 rtp_socket = new Socket(ip, port, Socket::TYPE_UDP);
00040 rtcp_socket = new Socket(ip, port + 1, Socket::TYPE_UDP);
00041 rtp_packets = 0;
00042 rtp_octets = 0;
00043 rtcp_tv.tv_sec = 0;
00044 rtcp_tv.tv_usec = 0;
00045 rtcp_delay = 1000000;
00046 _play = true;
00047 }
00048
00049 void RTP_Stream::Stop(void) {
00050 D(cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ <<endl;)
00051 pthread_mutex_lock(&pthm_flow);
00052 _play = false;
00053
00054 delete rtp_socket;
00055 pthread_mutex_unlock(&pthm_flow);
00056 }
00057
00067 void *RTP_Stream::thread(void) {
00068 D( cerr << "RTP_Stream::thread(void)" <<endl;)
00069 for(;;) {
00070 if(_play) {
00071 pthread_mutex_lock(&pthm_flow);
00072 long f = 0;
00073 if(_play) {
00074 f = process();
00075 }
00076 if(f>0)
00077 rtcp();
00078 pthread_mutex_unlock(&pthm_flow);
00079 if (f<0) {
00080 D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__<< "process exception detected: " << f << endl;)
00082 Stop();
00083 }
00084 } else
00085 sched_yield();
00086 }
00087 return NULL;
00088 }
00089
00090 void RTP_Stream::rtcp(void) {
00091
00092 if(f_tv.tv_sec == 0 && f_tv.tv_usec == 0)
00093 return;
00094 long td = time_delta_us(f_tv, rtcp_tv);
00095 if(td < 0) {
00096 rtcp_tv = f_tv;
00097 return;
00098 }
00099 if(td < rtcp_delay)
00100 return;
00101 rtcp_tv = f_tv;
00102 rtcp_send_sdes();
00103 rtcp_send_sr();
00104 }
00105
00106 void RTP_Stream::rtcp_send_sr(void) {
00107 char packet[8 + 20];
00108 int packet_len = sizeof(packet);
00109 unsigned short us;
00110 unsigned long ul;
00111
00112
00113 packet[0] = 0x81;
00114 packet[1] = 200;
00115 us = htons(((packet_len) / 4) - 1);
00116 memcpy((void *)&packet[2], (void *)&us, 2);
00117 memcpy((void *)&packet[4], (void *)&SSRC, 4);
00118
00119 char buf[64];
00120 sprintf(buf, "%d:%06d", (int) f_tv.tv_sec, (int) f_tv.tv_usec);
00121 ul = htonl(f_tv.tv_sec);
00122 memcpy((void *)&packet[8], (void *)&ul, 4);
00123 ul = htonl(f_tv.tv_usec);
00124 memcpy((void *)&packet[12], (void *)&ul, 4);
00125 ul = htonl(timestamp);
00126 memcpy((void *)&packet[16], (void *)&ul, 4);
00127 ul = htonl(rtp_packets);
00128 memcpy((void *)&packet[20], (void *)&ul, 4);
00129 ul = htonl(rtp_octets);
00130 memcpy((void *)&packet[24], (void *)&ul, 4);
00131 rtcp_socket->send(packet, packet_len);
00132
00133
00134
00135
00136 }
00137
00138 void RTP_Stream::rtcp_send_sdes(void) {
00139 char packet[8 + 4 + 128];
00140 int packet_len = 0;
00141
00142 unsigned short us;
00143 const char *cname = CNAME;
00144 int cname_len = strlen(cname);
00145
00146 packet[0] = 0x81;
00147 packet[1] = 202;
00148 memcpy((void *)&packet[4], (void *)&SSRC, 4);
00149 packet_len += 8;
00150
00151 packet[8] = 0x01;
00152 packet[9] = cname_len;
00153 memcpy((void *)&packet[10], (void *)cname, cname_len);
00154 packet_len += 2 + cname_len;
00155 us = htons((packet_len / 4) - 1);
00156 memcpy((void *)&packet[2], (void *)&us, 2);
00157
00158 rtcp_socket->send(packet, packet_len);
00159 }