apps/astreamer/rtp_stream.cpp

Go to the documentation of this file.
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 int RTP_Stream::_fd = -1;
00011 
00012 RTP_Stream::RTP_Stream(void) {
00013         _play = false;
00014         pthread_mutex_init(&pthm_flow, NULL);
00015         stream_name = "unknown";
00016 }
00017 
00018 void RTP_Stream::init_pthread(void *__this) {
00019         pth_id = pthread_create(&pth, NULL, RTP_Stream::pthread_f, (void *)__this);
00020 }
00021 
00022 void *RTP_Stream::pthread_f(void *_this) {
00023         RTP_Stream *__this = (RTP_Stream *)_this;
00024         return __this->thread();
00025 }
00026 
00027 void RTP_Stream::Start(string ip, int port) {
00028 cerr << " new " << stream_name << " UDP socket at port: " << port << endl;
00029         rtp_socket = new Socket(ip, port, Socket::TYPE_UDP);
00030         rtcp_socket = new Socket(ip, port + 1, Socket::TYPE_UDP);
00031         rtp_packets = 0;
00032         rtp_octets = 0;
00033         rtcp_tv.tv_sec = 0;
00034         rtcp_tv.tv_usec = 0;
00035         rtcp_delay = 1000000;
00036         _play = true;
00037 }
00038 
00039 void RTP_Stream::Stop(void) {
00040         pthread_mutex_lock(&pthm_flow);
00041         _play = false;
00042 //      delete rtcp_socket;
00043         delete rtp_socket;
00044         pthread_mutex_unlock(&pthm_flow);
00045 }
00046 
00047 void *RTP_Stream::thread(void) {
00048         for(;;) {
00049                 if(_play) {
00050                         pthread_mutex_lock(&pthm_flow);
00051                         bool f = false;
00052                         if(_play)
00053                                 f = process();
00054                         if(f)
00055                                 rtcp();
00056                         pthread_mutex_unlock(&pthm_flow);
00057                 } else
00058                         sched_yield();
00059         }
00060         return NULL;
00061 }
00062 
00063 void RTP_Stream::rtcp(void) {
00064         // check time for next one RTCP...
00065         if(f_tv.tv_sec == 0 && f_tv.tv_usec == 0)
00066                 return;
00067         long td = time_delta_us(f_tv, rtcp_tv);
00068 //cerr << "stream: " << stream_name << "; time delta == " << td << "; rtcp_delay == " << rtcp_delay << endl;
00069         if(td < 0) {
00070                 rtcp_tv = f_tv;
00071                 return;
00072         }
00073         if(td < rtcp_delay)
00074                 return;
00075         rtcp_tv = f_tv;
00076         rtcp_send_sdes();
00077         rtcp_send_sr();
00078 }
00079 
00080 void RTP_Stream::rtcp_send_sr(void) {
00081         char packet[8 + 20]; // by RTP RFC 3550, for SR RTCP packet needed 8 + 20 bytes
00082         int packet_len = sizeof(packet);
00083         unsigned short us;
00084         unsigned long ul;
00085 
00086         // RTCP header
00087         packet[0] = 0x81;
00088         packet[1] = 200;
00089         us = htons(((packet_len) / 4) - 1);
00090         memcpy((void *)&packet[2], (void *)&us, 2);
00091         memcpy((void *)&packet[4], (void *)&SSRC, 4);
00092         // SR
00093 char buf[64];
00094 sprintf(buf, "%d:%06d", f_tv.tv_sec, f_tv.tv_usec);
00095         ul = htonl(f_tv.tv_sec);
00096         memcpy((void *)&packet[8], (void *)&ul, 4);
00097         ul = htonl(f_tv.tv_usec);
00098         memcpy((void *)&packet[12], (void *)&ul, 4);
00099         ul = htonl(timestamp);
00100         memcpy((void *)&packet[16], (void *)&ul, 4);
00101         ul = htonl(rtp_packets);
00102         memcpy((void *)&packet[20], (void *)&ul, 4);
00103         ul = htonl(rtp_octets);
00104         memcpy((void *)&packet[24], (void *)&ul, 4);
00105         rtcp_socket->send(packet, packet_len);
00106 //cerr << "stream: " << stream_name << "; send SR; timestamp == " << timestamp << "; sync CLOCK == " << buf << endl;
00107         // fresh statistically information
00108 //      rtp_packets = 0;
00109 //      rtp_octets = 0;
00110 }
00111 
00112 void RTP_Stream::rtcp_send_sdes(void) {
00113         char packet[8 + 4 + 128]; // by RTP RFC 3550, for SDES RTCP packet needed 8 + 4 + ... bytes, so get additional 128 bytes for 126 CNAME field
00114         int packet_len = 0;
00115 
00116         unsigned short us;
00117         const char *cname = CNAME;
00118         int cname_len = strlen(cname);
00119         // RTCP header
00120         packet[0] = 0x81;
00121         packet[1] = 202;
00122         memcpy((void *)&packet[4], (void *)&SSRC, 4);
00123         packet_len += 8;
00124         // SDES fields
00125         packet[8] = 0x01;
00126         packet[9] = cname_len;
00127         memcpy((void *)&packet[10], (void *)cname, cname_len);
00128         packet_len += 2 + cname_len;
00129         us = htons((packet_len / 4) - 1);
00130         memcpy((void *)&packet[2], (void *)&us, 2);
00131 
00132         rtcp_socket->send(packet, packet_len);
00133 }

Generated on Thu Aug 7 16:18:58 2008 for elphel by  doxygen 1.5.1