00001 #include <sys/socket.h>
00002 #include <netinet/in.h>
00003 #include <arpa/inet.h>
00004
00005 #include "streamer.h"
00006 #include "helpers.h"
00007
00008 #include <iostream>
00009
00010 using namespace std;
00011
00012 #undef RTSP_DEBUG
00013
00014
00015 #ifdef RTSP_DEBUG
00016 #define D(a) a
00017 #else
00018 #define D(a)
00019 #endif
00020
00021 Streamer *Streamer::_streamer = NULL;
00022
00023 Streamer::Streamer(const map<string, string> &_args) {
00024 if(_streamer != NULL)
00025 throw("can't make an another instance of streamer");
00026 else
00027 _streamer = this;
00028 session = new Session();
00029 args = _args;
00030 session->process_audio = false;
00031 if(opt_present("a")) {
00032 session->process_audio = true;
00033 int channels = 0;
00034 int sample_rate = 0;
00035 string _sample_rate, _channels;
00036 String::split(args["a"], '/', _sample_rate, _channels);
00037 if(_sample_rate != "")
00038 sample_rate = atol(_sample_rate.c_str());
00039 if(_channels != "")
00040 channels = atol(_channels.c_str());
00041 audio = new Audio(true, sample_rate, channels);
00042 } else {
00043 audio = new Audio(false);
00044
00045 }
00046
00047 video = new Video();
00048 float fps = 0;
00049 if(opt_present("f")) {
00050 fps = atof(args["f"].c_str());
00051 if(fps < 0.1)
00052 fps = 0;
00053 }
00054 D(cout << "use fps: " << fps << endl;)
00055 video->fps(fps);
00056 rtsp_server=NULL;
00057 }
00058
00059 Streamer::~Streamer(void) {
00060 delete video;
00061 delete audio;
00062 }
00063
00064 int Streamer::f_handler(void *ptr, RTSP_Server *rtsp_server, RTSP_Server::event event) {
00065 Streamer *__this = (Streamer *)ptr;
00066 return __this->handler(rtsp_server, event);
00067 }
00068
00069 int Streamer::handler(RTSP_Server *rtsp_server, RTSP_Server::event event) {
00070 static bool _play = false;
00071 if(session->rtp_out.multicast)
00072
00073 return 0;
00074 D( cerr << "event: running= " << running << " ";)
00075 switch(event) {
00076 case RTSP_Server::DESCRIBE:
00077
00078 session->video.width = video->width();
00079 session->video.height = video->height();
00080 session->video.type = video->ptype();
00081 session->video.fps = video->fps();
00082 break;
00083 case RTSP_Server::PLAY:
00085 if(running) {
00086 D(cerr << ".......................... already play....." << endl;)
00087 break;
00088 }
00089 D( cerr << "==PLAY==";)
00090
00091
00092
00093
00094
00095
00096
00097
00098 video->Start(session->rtp_out.ip, session->rtp_out.port_video);
00099 audio->Start(session->rtp_out.ip, session->rtp_out.port_audio);
00100
00101 _play = true;
00102 running=true;
00103 break;
00104 case RTSP_Server::PAUSE:
00105 D( cerr << "PAUSE";)
00106 video->Stop();
00107 audio->Stop();
00108 _play = false;
00109 running=false;
00110 break;
00111 case RTSP_Server::TEARDOWN:
00112 D( cerr << "TEARDOWN";)
00113 if (!running) {
00114 D( cerr << " was not running";)
00115 break;
00116 }
00117 video->Stop();
00118 audio->Stop();
00119 _play = false;
00120 running=false;
00121 break;
00122 case RTSP_Server::IS_DAEMON_ENABLED:
00123 D( cerr << "IS_DAEMON_ENABLED video->isDaemonEnabled(-1)=" << video->isDaemonEnabled(-1) << endl;)
00124 return video->isDaemonEnabled(-1);
00125 break;
00126 default:
00127 D( cerr << "unknown == " << event;)
00128 break;
00129 }
00130 D( cerr << endl;)
00131 return 0;
00132 }
00133
00134 void Streamer::Main(void) {
00135 string def_mcast = "232.1.1.1";
00136 int def_port = 20020;
00137 string def_ttl = "2";
00138
00139 in_addr_t a_min = inet_addr("224.0.0.0");
00140 in_addr_t a_max = inet_addr("239.255.255.255");
00141 if(a_min > a_max) {
00142 in_addr_t a = a_min;
00143 a_min = a_max;
00144 a_max = a;
00145 }
00146 int port_min = 256;
00147 while (true) {
00149 if (! video->waitDaemonEnabled(-1)) continue;
00150
00151
00152 session->rtp_out.ip = def_mcast;
00153
00154 session->rtp_out.port_video = def_port;
00155 session->rtp_out.port_audio = def_port + 2;
00156 session->rtp_out.ttl = def_ttl;
00157 if(opt_present("m")) {
00158 session->rtp_out.multicast = true;
00159 string m_addr, m_port;
00160 String::split(args["m"], ':', m_addr, m_port);
00161 if(m_addr != "") {
00162
00163 string mcast = m_addr;
00164 in_addr_t a = inet_addr(mcast.c_str());
00165 if(a >= a_min && a <= a_max)
00166 session->rtp_out.ip = mcast;
00167 }
00168 if(m_port != "") {
00169 int p = atoi(m_port.c_str());
00170 if(p >= port_min) {
00171 session->rtp_out.port_video = p;
00172 session->rtp_out.port_audio = p + 2;
00173
00174 }
00175 }
00176 } else
00177 session->rtp_out.multicast = false;
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 if(opt_present("t")) {
00193 int t = atoi(args["t"].c_str());
00194 if(t < 1)
00195 session->rtp_out.ttl = "1";
00196 else
00197 session->rtp_out.ttl = args["t"];
00198 }
00199
00200 session->video.width = video->width();
00201 session->video.height = video->height();
00202 session->video.type = video->ptype();
00203 session->video.fps = video->fps();
00204 D(cout << "audio: " << audio->present() << endl;)
00205 if(audio->present()) {
00206 session->audio.sample_rate = audio->sample_rate();
00207 session->audio.channels = audio->channels();
00208 session->audio.type = audio->ptype();
00209 } else
00210 session->audio.type = -1;
00211 if(session->rtp_out.multicast) {
00212 video->Start(session->rtp_out.ip, session->rtp_out.port_video);
00213 audio->Start(session->rtp_out.ip, session->rtp_out.port_audio);
00214
00215
00216
00217 }
00218
00219 D(cout << "start server" << endl;)
00220 rtsp_server = new RTSP_Server(Streamer::f_handler, (void *)this, session);
00221 rtsp_server->main();
00222 }
00223 }