4 #include "liveMedia.hh" 17 #define RTSP_CLIENT_VERBOSITY_LEVEL 0 // by default, print verbose output from each "RTSPClient" 18 #define REQUEST_STREAMING_OVER_TCP 0 32 key = t_profile.
type * pow(10, 12) + t_profile.
fmt * pow(10, 10) + t_profile.
fps * pow(10, 8) + t_profile.
index + t_profile.
width * pow(10, 4) + t_profile.
height;
38 return stream_type * 10 + sensors_index;
43 TaskScheduler *scheduler = BasicTaskScheduler::createNew();
46 RTSPClient::responseBufferSize = 100000;
50 RsRTSPClient::RsRTSPClient(TaskScheduler *t_scheduler, UsageEnvironment *t_env,
char const *t_rtspURL,
int t_verbosityLevel,
char const *t_applicationName, portNumBits t_tunnelOverHTTPPortNum,
int idx)
51 : RTSPClient(*t_env, t_rtspURL, t_verbosityLevel, t_applicationName, t_tunnelOverHTTPPortNum, -1)
104 if (subsession ==
nullptr)
110 if (!subsession->initiate())
112 this->envir() <<
"Failed to initiate the subsession \n";
137 if (subsession->sink ==
NULL)
139 this->envir() <<
"Failed to create a data sink for the subsession: " << this->envir().getResultMsg() <<
"\n";
144 subsession->miscPtr =
this;
145 ((
RsSink *)(subsession->sink))->setCallback(t_callbackObj);
148 if (subsession->rtcpInstance() !=
NULL)
158 unsigned res = this->sendPlayCommand(*this->
m_scs.
m_session, this->continueAfterPLAY);
179 unsigned res = this->sendPauseCommand(*this->
m_scs.
m_session, this->continueAfterPAUSE);
200 unsigned res = this->sendTeardownCommand(*this->
m_scs.
m_session, this->continueAfterTEARDOWN);
221 this->envir() <<
"Closing the stream.\n";
222 UsageEnvironment *env =
m_env;
236 RTSPClient::sendSetParameterCommand(*this->
m_scs.
m_session, this->continueAfterSETCOMMAND, option.c_str(), value.c_str());
273 res = RTSPClient::sendGetParameterCommand(*this->
m_scs.
m_session, this->continueAfterGETCOMMAND, option.c_str());
309 thread_scheduler.detach();
345 while (std::getline(extrinsics_stream, s,
'&'))
349 int params_count = sscanf(s.c_str(),
350 "<to_sensor_%d>rotation:%f,%f,%f,%f,%f,%f,%f,%f,%ftranslation:%f,%f,%f",
368 extrinsics = {{NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN}, {NAN, NAN, NAN}};
382 if (
nullptr != resultString)
384 resultStr = resultString;
385 delete[] resultString;
387 UsageEnvironment &env = rtspClient->envir();
391 if (!resultStr.empty())
399 env <<
"Failed to get a SDP description: " << resultStr.c_str() <<
"\n";
409 env <<
"Failed to create a RsMediaSession object from the SDP description: " << env.getResultMsg() <<
"\n";
412 else if (!scs.
m_session->hasSubsessions())
414 env <<
"This session has no media subsessions (i.e., no \"m=\" lines)\n";
420 while (subsession !=
NULL)
423 const char *strWidthVal = subsession->attrVal_str(
"width");
424 const char *strHeightVal = subsession->attrVal_str(
"height");
425 const char *strFormatVal = subsession->attrVal_str(
"format");
426 const char *strUidVal = subsession->attrVal_str(
"uid");
427 const char *strFpsVal = subsession->attrVal_str(
"fps");
428 const char *strIndexVal = subsession->attrVal_str(
"stream_index");
429 const char *strStreamTypeVal = subsession->attrVal_str(
"stream_type");
430 const char *strBppVal = subsession->attrVal_str(
"bpp");
432 const char *strSerialNumVal = subsession->attrVal_str(
"cam_serial_num");
433 const char *strCamNameVal = subsession->attrVal_str(
"cam_name");
434 const char *strUsbTypeVal = subsession->attrVal_str(
"usb_type");
442 int stream_type = strStreamTypeVal !=
"" ?
std::stoi(strStreamTypeVal) : 0;
459 videoStream.
intrinsics.
fx = subsession->attrVal_int(
"fx");
460 videoStream.
intrinsics.
fy = subsession->attrVal_int(
"fy");
464 for (
size_t i = 0;
i < 5;
i++)
475 deviceData.
name = strCamNameVal;
477 std::replace(deviceData.
name.begin(), deviceData.
name.end(),
'^',
' ');
478 deviceData.
usbType = strUsbTypeVal;
482 rsRtspClient->
m_subsessionMap.insert(std::pair<long long int, RsMediaSubsession *>(uniqueKey, subsession));
484 subsession = iter.
next();
490 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
493 rsRtspClient->
m_cv.notify_one();
499 if (
nullptr != resultString)
501 resultStr = resultString;
502 delete[] resultString;
504 UsageEnvironment &env = rtspClient->envir();
508 env <<
"continueAfterSETUP " << resultCode <<
" " << resultStr.c_str() <<
"\n";
510 if (!resultStr.empty())
515 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
518 rsRtspClient->
m_cv.notify_one();
524 if (
nullptr != resultString)
526 resultStr = resultString;
527 delete[] resultString;
529 UsageEnvironment &env = rtspClient->envir();
531 env <<
"continueAfterPLAY " << resultCode <<
" " << resultStr.c_str() <<
"\n";
533 if (!resultStr.empty())
538 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
541 rsRtspClient->
m_cv.notify_one();
547 if (
nullptr != resultString)
549 resultStr = resultString;
550 delete[] resultString;
552 UsageEnvironment &env = rtspClient->envir();
554 env <<
"continueAfterTEARDOWN " << resultCode <<
" " << resultStr.c_str() <<
"\n";
556 if (!resultStr.empty())
561 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
564 rsRtspClient->
m_cv.notify_one();
570 if (
nullptr != resultString)
572 resultStr = resultString;
573 delete[] resultString;
575 UsageEnvironment &env = rtspClient->envir();
577 env <<
"continueAfterPAUSE " << resultCode <<
" " << resultStr.c_str() <<
"\n";
579 if (!resultStr.empty())
584 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
587 rsRtspClient->
m_cv.notify_one();
593 if (
nullptr != resultString)
595 resultStr = resultString;
596 delete[] resultString;
598 UsageEnvironment &env = rtspClient->envir();
600 env <<
"continueAfterOPTIONS " << resultCode <<
" " << resultStr.c_str() <<
"\n";
602 if (!resultStr.empty())
607 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
608 std::size_t foundBegin = resultStr.find_first_of(
"[");
611 while (foundBegin != std::string::npos)
614 std::size_t foundEnd = resultStr.find_first_of(
"]", foundBegin + 1);
615 std::string controlsPerSensor = resultStr.substr(foundBegin + 1, foundEnd - foundBegin);
617 while ((pos = controlsPerSensor.find(
';')) != std::string::npos)
619 std::string controlStr = controlsPerSensor.substr(0, pos);
621 controlData.
sensorId = counter == 0 ? 1 : 0;
623 int params_count = sscanf(controlStr.c_str(),
"%d{%f,%f,%f,%f}", &option_code, &controlData.
range.
min, &controlData.
range.
max, &controlData.
range.
def, &controlData.
range.
step);
628 controlsPerSensor.erase(0, pos + 1);
631 foundBegin = resultStr.find_first_of(
"[", foundBegin + 1);
635 rsRtspClient->
m_cv.notify_one();
641 if (
nullptr != resultString)
643 resultStr = resultString;
644 delete[] resultString;
646 UsageEnvironment &env = rtspClient->envir();
648 env <<
"continueAfterSETCOMMAND " << resultCode <<
"\n";
650 if (!resultStr.empty())
657 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
660 rsRtspClient->
m_cv.notify_one();
666 if (
nullptr != resultString)
668 resultStr = resultString;
669 delete[] resultString;
671 UsageEnvironment &env = rtspClient->envir();
673 DBG <<
"continueAfterGETCOMMAND: resultCode " << resultCode <<
", resultString '" << resultStr.c_str();
675 if (!resultStr.empty())
687 std::lock_guard<std::mutex> lck(rsRtspClient->
m_commandMtx);
690 rsRtspClient->
m_cv.notify_one();
696 MediaSubsession *subsession = (MediaSubsession *)clientData;
697 RTSPClient *rtspClient = (RTSPClient *)(subsession->miscPtr);
698 rtspClient->envir() <<
"subsessionAfterPlaying\n";
705 if (fCurrentAuthenticator < authenticator)
706 fCurrentAuthenticator = *authenticator;
707 char *paramString =
new char[strlen(parameterName) + strlen(parameterValue) + 10];
708 sprintf(paramString,
"%s: %s\r\n", parameterName, parameterValue);
709 unsigned result = sendRequest(
new RequestRecord(++fCSeq,
"SET_PARAMETER", responseHandler,
NULL,
NULL, False, 0.0
f, -1.0
f, 1.0
f, paramString));
710 delete[] paramString;
716 if (fCurrentAuthenticator < authenticator)
717 fCurrentAuthenticator = *authenticator;
723 unsigned parameterNameLen = parameterName ==
NULL ? 0 : strlen(parameterName);
724 char *paramString =
new char[parameterNameLen + 3];
725 if (parameterName ==
NULL)
727 paramString[0] =
'\0';
731 sprintf(paramString,
"%s\r\n", parameterName);
733 unsigned result = sendRequest(
new RequestRecord(++fCSeq,
"GET_PARAMETER", responseHandler,
NULL,
NULL, False, 0.0
f, -1.0
f, 1.0
f, paramString));
734 delete[] paramString;
738 Boolean
RsRTSPClient::setRequestFields(RequestRecord *request,
char *&cmdURL, Boolean &cmdURLWasAllocated,
char const *&protocolStr,
char *&extraHeaders, Boolean &extraHeadersWereAllocated)
741 if (request ==
nullptr)
745 if ((strcmp(request->commandName(),
"SET_PARAMETER") == 0 || strcmp(request->commandName(),
"GET_PARAMETER") == 0) && (request->session() ==
NULL))
747 cmdURL =
new char[4];
749 cmdURLWasAllocated = True;
750 sprintf(cmdURL,
"%s",
"*");
754 return RTSPClient::setRequestFields(request, cmdURL, cmdURLWasAllocated, protocolStr, extraHeaders, extraHeadersWereAllocated);
static int getPhysicalSensorUniqueKey(rs2_stream stream_type, int sensors_index)
std::vector< rs2_video_stream > m_supportedProfiles
float stof(const std::string &value)
RsRtspReturnCode exit_code
std::istringstream istringstream
::realsense_legacy_msgs::extrinsics_< std::allocator< void > > extrinsics
virtual std::vector< IpDeviceControlData > getControls()
rs2_option
Defines general configuration controls. These can generally be mapped to camera UVC controls...
std::mutex m_taskSchedulerMutex
TaskScheduler * m_scheduler
rs2_distortion
Distortion model: defines how pixel coordinates should be mapped to sensor coordinates.
static long long int getStreamProfileUniqueKey(rs2_video_stream t_profile)
unsigned sendSetParameterCommand(responseHandler *responseHandler, char const *parameterName, char const *parameterValue, Authenticator *authenticator=NULL)
#define RTSP_CLIENT_COMMANDS_TIMEOUT_SEC
All the parameters required to define a video stream.
#define REQUEST_STREAMING_OVER_TCP
std::string format_error_msg(std::string function, RsRtspReturnValue retVal)
std::condition_variable m_cv
static void subsessionByeHandler(void *clientData, char const *reason)
char & getEventLoopWatchVariable()
GLsizei const GLchar *const * string
static void continueAfterSETUP(RTSPClient *rtspClient, int resultCode, char *resultString)
RsRtspReturnValue m_lastReturnValue
RsRTSPClient(TaskScheduler *t_scheduler, UsageEnvironment *t_env, char const *t_rtspURL, int t_verbosityLevel, char const *t_applicationName, portNumBits t_tunnelOverHTTPPortNum, int idx)
void setDeviceData(DeviceData t_data)
GLenum GLuint GLenum GLsizei const GLchar * buf
void setGetParamResponse(float t_res)
virtual int setOption(const std::string &t_sensorName, rs2_option t_option, float t_value)
Boolean setRequestFields(RequestRecord *request, char *&cmdURL, Boolean &cmdURLWasAllocated, char const *&protocolStr, char *&extraHeaders, Boolean &extraHeadersWereAllocated)
static void continueAfterTEARDOWN(RTSPClient *rtspClient, int resultCode, char *resultString)
RsMediaSession * m_session
#define SDP_EXTRINSICS_ARGS
unsigned sendGetParameterCommand(responseHandler *responseHandler, char const *parameterName, Authenticator *authenticator=NULL)
char m_eventLoopWatchVariable
virtual int getOption(const std::string &t_sensorName, rs2_option t_option, float &t_value)
std::map< std::pair< int, int >, rs2_extrinsics > minimal_extrinsics_map
GLint GLsizei GLsizei height
GLint GLint GLsizei GLint GLenum format
static void continueAfterOPTIONS(RTSPClient *rtspClient, int resultCode, char *resultString)
rs2_format
A stream's format identifies how binary data is encoded within a frame.
static void continueAfterGETCOMMAND(RTSPClient *rtspClient, int resultCode, char *resultString)
std::vector< IpDeviceControlData > controls
rs2_stream
Streams are different types of data provided by RealSense devices.
virtual int addStream(rs2_video_stream t_stream, rtp_callback *t_frameCallBack)
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
static void continueAfterDESCRIBE(RTSPClient *rtspClient, int resultCode, char *resultString)
static void continueAfterPLAY(RTSPClient *rtspClient, int resultCode, char *resultString)
std::mutex & getTaskSchedulerMutex()
static IRsRtsp * createNew(char const *t_rtspURL, char const *t_applicationName, portNumBits t_tunnelOverHTTPPortNum, int idx)
static void continueAfterSETCOMMAND(RTSPClient *rtspClient, int resultCode, char *resultString)
static bool & getIsEnabled()
static void continueAfterPAUSE(RTSPClient *rtspClient, int resultCode, char *resultString)
int stoi(const std::string &value)
rs2_intrinsics intrinsics
virtual std::vector< rs2_video_stream > getStreams()
#define RTSP_CLIENT_VERBOSITY_LEVEL
static void subsessionAfterPlaying(void *clientData)
static RSUsageEnvironment * createNew(TaskScheduler &taskScheduler)
void schedulerThread(RsRTSPClient *t_rtspClientInstance)
std::map< long long int, RsMediaSubsession * > m_subsessionMap
void updateExtrinsicsMap(rs2_video_stream videoStream, std::string extrinsics_str)
void initFunc(MemoryPool *t_pool)
std::string to_string(T value)