00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "Devices/RTSPGrabber.H"
00040
00041 #include "Component/OptionManager.H"
00042 #include "Component/ModelOptionDef.H"
00043 #include "Devices/DeviceOpts.H"
00044 #include "Image/Image.H"
00045 #include "Image/Pixels.H"
00046 #include "Image/MathOps.H"
00047 #include "Raster/GenericFrame.H"
00048 #include "Util/Assert.H"
00049 #include "Util/SimTime.H"
00050 #include "Util/sformat.H"
00051 #include "Video/VideoFrame.H"
00052 #include "Video/FfmpegFrame.H"
00053
00054
00055 #ifdef INVT_HAVE_LIVEMEDIA
00056 #include <groupsock/GroupsockHelper.hh>
00057 #endif
00058
00059 #include <unistd.h>
00060
00061 #ifdef INVT_HAVE_LIVEMEDIA
00062 void sessionAfterPlaying(void* ) {
00063 LINFO("Sesstion after playing\n");
00064 }
00065
00066 static void getFrame(void *clientData, unsigned frameSize,
00067 unsigned, struct timeval pTime, unsigned)
00068 {
00069 RTSPGrabber* rtspGrabber = (RTSPGrabber*)clientData;
00070
00071 if (frameSize > rtspGrabber->getFrameBufferSize())
00072 LINFO("Frame buffer size to small, please increase (framesize %i)",
00073 frameSize);
00074
00075 rtspGrabber->itsFrameSize = frameSize;
00076 rtspGrabber->blockingFlag = ~0;
00077 }
00078
00079 static void onSourceClosure(void* clientData)
00080 {
00081 RTSPGrabber* rtspGrabber = (RTSPGrabber*)clientData;
00082 LINFO("On source closure\n");
00083 rtspGrabber->blockingFlag = ~0;
00084 }
00085 #endif
00086
00087
00088
00089
00090 void* RTSPGrabber_run(void *r0)
00091 {
00092 RTSPGrabber *r = (RTSPGrabber *)r0;
00093 r->run(); return NULL;
00094 }
00095
00096
00097 RTSPGrabber::RTSPGrabber(OptionManager& mgr,
00098 const std::string& descrName,
00099 const std::string& tagName,
00100 const ParamFlag flags,
00101 unsigned int bufferSize) :
00102 FrameIstream(mgr, descrName, tagName),
00103 itsDims(&OPT_FrameGrabberDims, this, Dims(320, 240), USE_MY_VAL),
00104 itsGrabMode(&OPT_FrameGrabberMode, this, VIDFMT_RGB24, USE_MY_VAL),
00105 itsByteSwap(&OPT_FrameGrabberByteSwap, this, false, USE_MY_VAL),
00106 itsWhiteBalTarR(&OPT_FrameGrabberWhiteBalTargetR, this, false, USE_MY_VAL),
00107 itsWhiteBalTarG(&OPT_FrameGrabberWhiteBalTargetG, this, false, USE_MY_VAL),
00108 itsWhiteBalTarB(&OPT_FrameGrabberWhiteBalTargetB, this, false, USE_MY_VAL),
00109 itsWhiteBalRefR(&OPT_FrameGrabberWhiteBalReferenceR, this, false, USE_MY_VAL),
00110 itsWhiteBalRefG(&OPT_FrameGrabberWhiteBalReferenceG, this, false, USE_MY_VAL),
00111 itsWhiteBalRefB(&OPT_FrameGrabberWhiteBalReferenceB, this, false, USE_MY_VAL),
00112 itsFPS(&OPT_FrameGrabberFPS, this, 15.0, USE_MY_VAL),
00113 itsFrameBufferSize(bufferSize),
00114 itsFrameBuffer(new unsigned char[bufferSize]),
00115 itsThreadRunning(false)
00116 {
00117 pthread_mutex_init(&itsLock, NULL);
00118
00119 #ifdef INVT_HAVE_AVCODEC
00120
00121
00122
00123 av_register_all();
00124
00125
00126 avcodec_init();
00127
00128
00129 avcodec_register_all();
00130
00131 itsCodecContext = avcodec_alloc_context();
00132
00133 AVCodec* codec = avcodec_find_decoder(CODEC_ID_MPEG4 );
00134
00135 if (codec == 0) LFATAL("no codec found for codec_id=%d", CODEC_ID_MPEG4);
00136
00137 if (!codec || avcodec_open(itsCodecContext, codec) < 0) LFATAL("avcodec_open() failed");
00138
00139 #if defined(INVT_FFMPEG_HAS_DEFAULTS_FUNCTIONS)
00140 avcodec_get_frame_defaults(&itsPicture);
00141 #else
00142 {
00143 AVFrame* tmp = avcodec_alloc_frame();
00144 memcpy(&itsPicture, tmp, sizeof(AVFrame));
00145 av_free(tmp);
00146 }
00147 #endif
00148
00149 Image<PixRGB<byte> > frame(itsDims.getVal(), NO_INIT);
00150 itsCurrentFrame = VideoFrame(frame);
00151 #endif
00152 }
00153
00154
00155 void RTSPGrabber::start1()
00156 {
00157 #ifndef INVT_HAVE_LIVEMEDIA
00158 LFATAL("you must have liveMedia support in order to use RTSPGrabber");
00159 #else
00160 LINFO("URL %s", itsURL.c_str());
00161 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00162 itsEnv = BasicUsageEnvironment::createNew(*scheduler);
00163 itsClient = RTSPClient::createNew(*itsEnv,
00164 0,
00165 "test",
00166 0);
00167
00168 if (itsClient == NULL)
00169 LFATAL("Failed to create client\n");
00170
00171 itsRTSPClient = (RTSPClient*)itsClient;
00172 char* optionsResponse = itsRTSPClient->sendOptionsCmd(itsURL.c_str(), NULL, NULL);
00173 LINFO("%s", optionsResponse);
00174
00175 char* sdpDescription = itsRTSPClient->describeURL(itsURL.c_str());
00176 if (sdpDescription == NULL) {
00177 Medium::close(itsClient);
00178 LFATAL("Failed to get a SDP description from URL %s", itsEnv->getResultMsg());
00179 }
00180 LINFO("SDP desc: %s", sdpDescription);
00181
00182 itsSession = MediaSession::createNew(*itsEnv, sdpDescription);
00183 delete[] sdpDescription;
00184
00185 if (itsSession == NULL)
00186 {
00187 Medium::close(itsClient);
00188 LFATAL("Failed to create a MediaSession object from the SDP description: %s ", itsEnv->getResultMsg());
00189 } else if (!itsSession->hasSubsessions()) {
00190 Medium::close(itsClient);
00191 LFATAL("This session has no media subsessions (i.e., \"m=\" lines)");
00192 }
00193
00194
00195 MediaSubsessionIterator iter(*itsSession);
00196 MediaSubsession *subsession;
00197 while ((subsession = iter.next()) != NULL) {
00198
00199
00200
00201 if (strcmp(subsession->mediumName(), "video") != 0) {
00202 LINFO("Ignoring %s/%s", subsession->mediumName(), subsession->codecName());
00203 continue;
00204 }
00205
00206
00207 if (!subsession->initiate(-1)) {
00208 LINFO("Unable to create receiver for %s/%s %s",
00209 subsession->mediumName(),
00210 subsession->codecName(),
00211 itsEnv->getResultMsg());
00212 } else {
00213 LINFO("Created receiver for %s/%s port %i",
00214 subsession->mediumName(),
00215 subsession->codecName(),
00216 subsession->clientPortNum());
00217
00218 if (subsession->readSource() != NULL)
00219 itsFramedSource = subsession->readSource();
00220
00221 if (subsession->rtpSource() != NULL) {
00222
00223
00224
00225 unsigned const thresh = 1000000;
00226 subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
00227
00228 unsigned int socketInputBufferSize = 20000;
00229 if (socketInputBufferSize > 0) {
00230
00231 int socketNum
00232 = subsession->rtpSource()->RTPgs()->socketNum();
00233 unsigned curBufferSize
00234 = getReceiveBufferSize(*itsEnv, socketNum);
00235 unsigned newBufferSize
00236 = setReceiveBufferTo(*itsEnv, socketNum, socketInputBufferSize);
00237 LINFO("Changed socket receive buffer size for the %s/%s cur=%i bytes new=%i bytes",
00238 subsession->mediumName(),
00239 subsession->codecName(),
00240 curBufferSize, newBufferSize);
00241 }
00242 }
00243
00244 Boolean streamUsingTCP = False;
00245 if (!itsRTSPClient->setupMediaSubsession(*subsession, false, streamUsingTCP)) {
00246 LINFO("Failed to setup %s/%s %s",
00247 subsession->mediumName(), subsession->codecName(),
00248 itsEnv->getResultMsg());
00249 } else {
00250 LINFO("Setup %s/%s port %i",
00251 subsession->mediumName(), subsession->codecName(),
00252 subsession->clientPortNum());
00253 }
00254 }
00255 }
00256
00257 if(!itsRTSPClient->playMediaSession(*itsSession))
00258 LINFO("Can not play %s", itsEnv->getResultMsg());
00259
00260
00261
00262
00263 pthread_create(&itsRunThread, NULL, &RTSPGrabber_run, (void *)this);
00264
00265 #endif
00266 }
00267
00268
00269 void RTSPGrabber::run()
00270 {
00271 #ifndef INVT_HAVE_LIVEMEDIA
00272 LFATAL("you must have liveMedia support in order to use RTSPGrabber");
00273 #else
00274
00275 itsThreadRunning = true;
00276
00277 while(itsThreadRunning)
00278 {
00279
00280
00281 blockingFlag = 0;
00282 itsFrameSize = 0;
00283 itsFramedSource->getNextFrame(itsFrameBuffer, itsFrameBufferSize,
00284 getFrame, this,
00285 onSourceClosure,this);
00286
00287
00288 TaskScheduler& scheduler = itsFramedSource->envir().taskScheduler();
00289 scheduler.doEventLoop(&blockingFlag);
00290
00291
00292 if (itsFrameSize > 0)
00293 {
00294 pthread_mutex_lock(&itsLock);
00295
00296
00297 int len = avcodec_decode_video(itsCodecContext,
00298 &itsPicture, &itsGotPicture,
00299 itsFrameBuffer, itsFrameSize);
00300 (void)len;
00301
00302 itsCurrentFrame = convertAVFrameToVideoFrame(&itsPicture,
00303 itsCodecContext->pix_fmt,
00304 itsDims.getVal());
00305 itsGotPicture = 0;
00306
00307 pthread_mutex_unlock(&itsLock);
00308 }
00309 usleep(10000);
00310 }
00311
00312
00313 pthread_exit(0);
00314 #endif
00315 }
00316
00317
00318
00319
00320 void RTSPGrabber::setConfigInfo(const std::string& url)
00321 {
00322
00323
00324
00325
00326
00327 itsURL = std::string("rtsp:") + url;
00328
00329 }
00330
00331
00332 void RTSPGrabber::shutdown()
00333 {
00334 itsThreadRunning = false;
00335
00336 if (0 != pthread_join(itsRunThread, NULL)) LERROR("Pthread__join() failed");
00337 LINFO("Disconnecting from stream");
00338
00339 #ifdef INVT_HAVE_LIVEMEDIA
00340
00341 MediaSubsessionIterator iter(*itsSession);
00342 MediaSubsession* subsession;
00343 while ((subsession = iter.next()) != NULL) {
00344 Medium::close(subsession->sink);
00345 subsession->sink = NULL;
00346 }
00347
00348 itsRTSPClient->teardownMediaSession(*itsSession);
00349 Medium::close(itsSession);
00350 Medium::close(itsClient);
00351 #endif
00352 }
00353
00354
00355 void RTSPGrabber::stop2()
00356 {
00357 #ifndef INVT_HAVE_LIVEMEDIA
00358 LFATAL("you must have liveMedia support in order to use RTSPGrabber");
00359 #else
00360 shutdown();
00361 #endif
00362
00363 }
00364
00365
00366 RTSPGrabber::~RTSPGrabber()
00367 {
00368 delete itsFrameBuffer;
00369
00370 #ifdef HAVE_FFMPEG_AVCODEC_H
00371 avcodec_close(itsCodecContext);
00372 av_free(itsCodecContext);
00373 av_free(&itsPicture);
00374 #endif
00375 }
00376
00377
00378 GenericFrameSpec RTSPGrabber::peekFrameSpec()
00379 {
00380 GenericFrameSpec result;
00381
00382 result.nativeType = GenericFrame::VIDEO;
00383 result.videoFormat = itsGrabMode.getVal();
00384 result.videoByteSwap = itsByteSwap.getVal();
00385 result.dims = itsDims.getVal();
00386 result.floatFlags = 0;
00387
00388 return result;
00389 }
00390
00391
00392 SimTime RTSPGrabber::getNaturalFrameTime() const
00393 {
00394 return SimTime::HERTZ(itsFPS.getVal());
00395 }
00396
00397
00398
00399
00400 GenericFrame RTSPGrabber::readFrame()
00401 {
00402 return GenericFrame(this->grabRaw());
00403 }
00404
00405
00406 VideoFrame RTSPGrabber::grabRaw()
00407 {
00408 #ifndef INVT_HAVE_LIVEMEDIA
00409 LFATAL("you must have liveMedia support in order to use RTSPGrabber");
00410 return VideoFrame();
00411 #else
00412 pthread_mutex_lock(&itsLock);
00413 VideoFrame videoFrame = itsCurrentFrame;
00414 pthread_mutex_unlock(&itsLock);
00415 usleep(10000);
00416 return videoFrame;
00417 #endif
00418 }
00419
00420
00421 void RTSPGrabber::paramChanged(ModelParamBase* const param,
00422 const bool valueChanged,
00423 ParamClient::ChangeStatus* status)
00424 {
00425 #ifndef INVT_HAVE_LIVEMEDIA
00426 LFATAL("you must have liveMedia support in order to use RTSPGrabber");
00427 #else
00428 FrameIstream::paramChanged(param, valueChanged, status);
00429 #endif
00430 }
00431
00432
00433 void RTSPGrabber::createDecoder()
00434 {
00435
00436 }
00437
00438
00439
00440
00441
00442
00443