From 5e91d61fa015d15dbe464a4959f4efb25f0d99c9 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Wed, 31 Jul 2024 16:16:18 +0200 Subject: [PATCH] vcap/rtsp: decompress - do not enforce H.264 decompress will work for JPEG as well if leaving the actual color_spec --- src/rtsp/BasicRTSPOnlyServer.cpp | 54 +++++++++--------------- src/rtsp/BasicRTSPOnlyServer.hh | 19 ++------- src/rtsp/BasicRTSPOnlySubsession.cpp | 63 +++++++++++++--------------- src/rtsp/BasicRTSPOnlySubsession.hh | 14 ++----- src/rtsp/c_basicRTSPOnlyServer.cpp | 14 ++----- src/rtsp/c_basicRTSPOnlyServer.h | 26 +++++++----- src/video_capture/rtsp.c | 1 - src/video_rxtx/h264_rtp.cpp | 19 ++++++--- 8 files changed, 87 insertions(+), 123 deletions(-) diff --git a/src/rtsp/BasicRTSPOnlyServer.cpp b/src/rtsp/BasicRTSPOnlyServer.cpp index bd8698a9f..b444a603e 100644 --- a/src/rtsp/BasicRTSPOnlyServer.cpp +++ b/src/rtsp/BasicRTSPOnlyServer.cpp @@ -51,30 +51,23 @@ BasicRTSPOnlyServer *BasicRTSPOnlyServer::srvInstance = NULL; -BasicRTSPOnlyServer::BasicRTSPOnlyServer(int port, struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio){ - if(mod == NULL){ +BasicRTSPOnlyServer::BasicRTSPOnlyServer(struct rtsp_server_parameters params) { + if (params.parent == NULL) { exit(1); } - this->fPort = port; - this->mod = mod; - this->avType = avType; - this->audio_codec = audio_codec; - this->audio_sample_rate = audio_sample_rate; - this->audio_channels = audio_channels; - this->audio_bps = audio_bps; - this->rtp_port = rtp_port; - this->rtp_port_audio = rtp_port_audio; + this->params = params; this->rtspServer = NULL; this->env = NULL; this->srvInstance = this; } BasicRTSPOnlyServer* -BasicRTSPOnlyServer::initInstance(int port, struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio){ +BasicRTSPOnlyServer::initInstance(struct rtsp_server_parameters params) +{ if (srvInstance != NULL){ return srvInstance; } - return new BasicRTSPOnlyServer(port, mod, avType, audio_codec, audio_sample_rate, audio_channels, audio_bps, rtp_port, rtp_port_audio); + return new BasicRTSPOnlyServer(params); } BasicRTSPOnlyServer* @@ -89,8 +82,8 @@ int BasicRTSPOnlyServer::init_server() { assert(env == nullptr && rtspServer == nullptr); - assert(mod != nullptr); - assert(avType > none && avType <= rtsp_av_type_last); + assert(params.parent != nullptr); + assert(params.avType > none && params.avType <= rtsp_av_type_last); //setting livenessTimeoutTask unsigned reclamationTestSeconds = 60; @@ -107,11 +100,12 @@ BasicRTSPOnlyServer::init_server() // access to the server. #endif - if (fPort == 0){ - fPort = 8554; + if (params.rtsp_port == 0) { + params.rtsp_port = 8554; } - rtspServer = RTSPServer::createNew(*env, fPort, authDB, reclamationTestSeconds); + rtspServer = RTSPServer::createNew(*env, params.rtsp_port, authDB, + reclamationTestSeconds); if (rtspServer == NULL) { *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n"; exit(1); @@ -122,22 +116,14 @@ BasicRTSPOnlyServer::init_server() "UltraGrid RTSP server enabling standard transport", "UltraGrid RTSP server"); - if(avType == av){ - sms->addSubsession(BasicRTSPOnlySubsession - ::createNew(*env, True, mod, audio, audio_codec, audio_sample_rate, audio_channels, audio_bps, rtp_port, rtp_port_audio)); - sms->addSubsession(BasicRTSPOnlySubsession - ::createNew(*env, True, mod, video, audio_codec, audio_sample_rate, audio_channels, audio_bps, rtp_port, rtp_port_audio)); - }else if(avType == audio){ - sms->addSubsession(BasicRTSPOnlySubsession - ::createNew(*env, True, mod, audio, audio_codec, audio_sample_rate, audio_channels, audio_bps, rtp_port, rtp_port_audio)); - - }else if(avType == video){ - sms->addSubsession(BasicRTSPOnlySubsession - ::createNew(*env, True, mod, video, audio_codec, audio_sample_rate, audio_channels, audio_bps, rtp_port, rtp_port_audio)); - }else{ - *env << "\n[RTSP Server] Error when trying to play stream type: \"" << avType << "\"\n"; - exit(1); - } + if ((params.avType & audio) != 0) { + sms->addSubsession(BasicRTSPOnlySubsession ::createNew( + *env, True, audio, params)); + } + if ((params.avType & video) != 0) { + sms->addSubsession(BasicRTSPOnlySubsession ::createNew( + *env, True, video, params)); + } rtspServer->addServerMediaSession(sms); diff --git a/src/rtsp/BasicRTSPOnlyServer.hh b/src/rtsp/BasicRTSPOnlyServer.hh index a437eaacc..a1bef9deb 100644 --- a/src/rtsp/BasicRTSPOnlyServer.hh +++ b/src/rtsp/BasicRTSPOnlyServer.hh @@ -47,18 +47,15 @@ #include #include -#include "rtsp/rtsp_utils.h" -#include "audio/types.h" -#include "module.h" - +#include "c_basicRTSPOnlyServer.h" // for rtsp_server_parameters class BasicRTSPOnlyServer { private: - BasicRTSPOnlyServer(int port, struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio); + BasicRTSPOnlyServer(struct rtsp_server_parameters params); public: - static BasicRTSPOnlyServer* initInstance(int port, struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio); + static BasicRTSPOnlyServer* initInstance(struct rtsp_server_parameters params); static BasicRTSPOnlyServer* getInstance(); int init_server(); @@ -70,15 +67,7 @@ public: private: static BasicRTSPOnlyServer* srvInstance; - int fPort; - struct module *mod; - rtps_types_t avType; - audio_codec_t audio_codec; - int audio_sample_rate; - int audio_channels; - int audio_bps; - int rtp_port; //server rtp port - int rtp_port_audio; //server rtp port + struct rtsp_server_parameters params; RTSPServer* rtspServer; UsageEnvironment* env; }; diff --git a/src/rtsp/BasicRTSPOnlySubsession.cpp b/src/rtsp/BasicRTSPOnlySubsession.cpp index 16dbe38f9..dfa71e9a2 100644 --- a/src/rtsp/BasicRTSPOnlySubsession.cpp +++ b/src/rtsp/BasicRTSPOnlySubsession.cpp @@ -59,30 +59,22 @@ BasicRTSPOnlySubsession* BasicRTSPOnlySubsession::createNew(UsageEnvironment& env, - Boolean reuseFirstSource, struct module *mod, rtps_types_t avType, - audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, - int audio_bps, int rtp_port, int rtp_port_audio) { - return new BasicRTSPOnlySubsession(env, reuseFirstSource, mod, avType, - audio_codec, audio_sample_rate, audio_channels, audio_bps, rtp_port, rtp_port_audio); + Boolean reuseFirstSource, rtps_types_t avType, + struct rtsp_server_parameters params) { + return new BasicRTSPOnlySubsession(env, reuseFirstSource, avType, params); } BasicRTSPOnlySubsession::BasicRTSPOnlySubsession(UsageEnvironment& env, - Boolean reuseFirstSource, struct module *mod, rtps_types_t avType, - audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, - int audio_bps, int rtp_port, int rtp_port_audio) : + Boolean reuseFirstSource, rtps_types_t avType, + struct rtsp_server_parameters params) : ServerMediaSubsession(env), fSDPLines(NULL), fReuseFirstSource( - reuseFirstSource), fLastStreamToken(NULL) { + reuseFirstSource), fLastStreamToken(NULL), + rtsp_params(params) +{ Vdestination = NULL; Adestination = NULL; gethostname(fCNAME, sizeof fCNAME); - this->fmod = mod; this->avType = avType; - this->audio_codec = audio_codec; - this->audio_sample_rate = audio_sample_rate; - this->audio_channels = audio_channels; - this->audio_bps = audio_bps; - this->rtp_port = rtp_port; - this->rtp_port_audio = rtp_port_audio; fCNAME[sizeof fCNAME - 1] = '\0'; } @@ -125,11 +117,11 @@ void BasicRTSPOnlySubsession::setSDPLines(int addressFamily) { char* sdpLines = new char[sdpFmtSize]; snprintf(sdpLines, sdpFmtSize, sdpFmt, mediaType, // m= - rtp_port,//fPortNumForSDP, // m= + rtsp_params.rtp_port,//fPortNumForSDP, // m= rtpPayloadType, // m= ip_ver_list_addr, // c= address estBitrate, // b=AS: - rtp_port + 1, + rtsp_params.rtp_port + 1, rtpmapLine, // a=rtpmap:... (if present) trackId()); // a=control: @@ -144,7 +136,8 @@ void BasicRTSPOnlySubsession::setSDPLines(int addressFamily) { char rtpmapLine[STR_LEN]; //char const* auxSDPLine = ""; const uint8_t rtpPayloadType = get_audio_rtp_pt_rtpmap( - audio_codec, audio_sample_rate, audio_channels, rtpmapLine); + rtsp_params.audio_codec, rtsp_params.audio_sample_rate, + rtsp_params.audio_channels, rtpmapLine); char const* const sdpFmt = "m=%s %u RTP/AVP %u\r\n" "c=IN IP%s\r\n" @@ -160,11 +153,11 @@ void BasicRTSPOnlySubsession::setSDPLines(int addressFamily) { snprintf(sdpLines, sdpFmtSize, sdpFmt, mediaType, // m= - rtp_port_audio,//fPortNumForSDP, // m= + rtsp_params.rtp_port_audio,//fPortNumForSDP, // m= rtpPayloadType, // m= ip_ver_list_addr, // c= address estBitrate, // b=AS: - rtp_port_audio + 1, + rtsp_params.rtp_port_audio + 1, rtpmapLine, // a=rtpmap:... (if present) trackId()); // a=control: @@ -182,9 +175,9 @@ void BasicRTSPOnlySubsession::getStreamParameters(unsigned /* clientSessionId */ Boolean& /* isMulticast */, Port& serverRTPPort, Port& serverRTCPPort, void*& /* streamToken */) { if (avType == video || avType == av) { - Port rtp(rtp_port); + Port rtp(rtsp_params.rtp_port); serverRTPPort = rtp; - Port rtcp(rtp_port + 1); + Port rtcp(rtsp_params.rtp_port + 1); serverRTCPPort = rtcp; delete Vdestination; @@ -192,9 +185,9 @@ void BasicRTSPOnlySubsession::getStreamParameters(unsigned /* clientSessionId */ clientRTCPPort); } if (avType == audio || avType == av) { - Port rtp(rtp_port_audio); + Port rtp(rtsp_params.rtp_port_audio); serverRTPPort = rtp; - Port rtcp(rtp_port_audio + 1); + Port rtcp(rtsp_params.rtp_port_audio + 1); serverRTCPPort = rtcp; delete Adestination; @@ -225,7 +218,7 @@ void BasicRTSPOnlySubsession::startStream(unsigned /* clientSessionId */, sizeof(struct msg_sender)); msgV1->tx_port = ntohs(Vdestination->rtpPort.num()); msgV1->type = SENDER_MSG_CHANGE_PORT; - resp = send_message(fmod, pathV, (struct message *) msgV1); + resp = send_message(rtsp_params.parent, pathV, (struct message *) msgV1); free_response(resp); //CHANGE DST ADDRESS @@ -241,7 +234,7 @@ void BasicRTSPOnlySubsession::startStream(unsigned /* clientSessionId */, sizeof(msgV2->receiver) - 1); msgV2->type = SENDER_MSG_CHANGE_RECEIVER; - resp = send_message(fmod, pathV, (struct message *) msgV2); + resp = send_message(rtsp_params.parent, pathV, (struct message *) msgV2); free_response(resp); } } @@ -260,7 +253,7 @@ void BasicRTSPOnlySubsession::startStream(unsigned /* clientSessionId */, sizeof(struct msg_sender)); msgA1->tx_port = ntohs(Adestination->rtpPort.num()); msgA1->type = SENDER_MSG_CHANGE_PORT; - resp = send_message(fmod, pathA, (struct message *) msgA1); + resp = send_message(rtsp_params.parent, pathA, (struct message *) msgA1); free_response(resp); resp = NULL; @@ -277,7 +270,7 @@ void BasicRTSPOnlySubsession::startStream(unsigned /* clientSessionId */, sizeof(msgA2->receiver) - 1); msgA2->type = SENDER_MSG_CHANGE_RECEIVER; - resp = send_message(fmod, pathA, (struct message *) msgA2); + resp = send_message(rtsp_params.parent, pathA, (struct message *) msgA2); free_response(resp); resp = NULL; } @@ -299,10 +292,10 @@ void BasicRTSPOnlySubsession::deleteStream(unsigned /* clientSessionId */, //CHANGE DST PORT struct msg_sender *msgV1 = (struct msg_sender *) new_message( sizeof(struct msg_sender)); - msgV1->tx_port = rtp_port; + msgV1->tx_port = rtsp_params.rtp_port; msgV1->type = SENDER_MSG_CHANGE_PORT; struct response *resp; - resp = send_message(fmod, pathV, (struct message *) msgV1); + resp = send_message(rtsp_params.parent, pathV, (struct message *) msgV1); free_response(resp); //CHANGE DST ADDRESS @@ -310,7 +303,7 @@ void BasicRTSPOnlySubsession::deleteStream(unsigned /* clientSessionId */, sizeof(struct msg_sender)); strncpy(msgV2->receiver, "127.0.0.1", sizeof(msgV2->receiver) - 1); msgV2->type = SENDER_MSG_CHANGE_RECEIVER; - resp = send_message(fmod, pathV, (struct message *) msgV2); + resp = send_message(rtsp_params.parent, pathV, (struct message *) msgV2); free_response(resp); } } @@ -330,10 +323,10 @@ void BasicRTSPOnlySubsession::deleteStream(unsigned /* clientSessionId */, sizeof(struct msg_sender)); //TODO: GET AUDIO PORT SET (NOT A COMMON CASE WHEN RTSP IS ENABLED: DEFAULT -> vport + 2) - msgA1->tx_port = rtp_port_audio; + msgA1->tx_port = rtsp_params.rtp_port_audio; msgA1->type = SENDER_MSG_CHANGE_PORT; struct response *resp; - resp = send_message(fmod, pathA, (struct message *) msgA1); + resp = send_message(rtsp_params.parent, pathA, (struct message *) msgA1); free_response(resp); //CHANGE DST ADDRESS @@ -341,7 +334,7 @@ void BasicRTSPOnlySubsession::deleteStream(unsigned /* clientSessionId */, sizeof(struct msg_sender)); strncpy(msgA2->receiver, "127.0.0.1", sizeof(msgA2->receiver) - 1); msgA2->type = SENDER_MSG_CHANGE_RECEIVER; - resp = send_message(fmod, pathA, (struct message *) msgA2); + resp = send_message(rtsp_params.parent, pathA, (struct message *) msgA2); free_response(resp); } } diff --git a/src/rtsp/BasicRTSPOnlySubsession.hh b/src/rtsp/BasicRTSPOnlySubsession.hh index a48cc1951..af42d6883 100644 --- a/src/rtsp/BasicRTSPOnlySubsession.hh +++ b/src/rtsp/BasicRTSPOnlySubsession.hh @@ -50,6 +50,7 @@ #include +#include "c_basicRTSPOnlyServer.h" // for rtsp_server_parameters #include "rtsp/rtsp_utils.h" #include "audio/types.h" #include "module.h" @@ -94,13 +95,12 @@ public: static BasicRTSPOnlySubsession* createNew(UsageEnvironment& env, Boolean reuseFirstSource, - struct module *mod, - rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio); + rtps_types_t avType, struct rtsp_server_parameters); protected: BasicRTSPOnlySubsession(UsageEnvironment& env, Boolean reuseFirstSource, - struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio); + rtps_types_t avType, struct rtsp_server_parameters); ~BasicRTSPOnlySubsession() override; @@ -152,14 +152,8 @@ private: MAYBE_UNUSED_ATTRIBUTE Boolean fReuseFirstSource; MAYBE_UNUSED_ATTRIBUTE void* fLastStreamToken; char fCNAME[100]; - struct module *fmod; rtps_types_t avType; - audio_codec_t audio_codec; - int audio_sample_rate; - int audio_channels; - int audio_bps; - int rtp_port; //server rtp port - int rtp_port_audio; //server rtp port + struct rtsp_server_parameters rtsp_params; }; diff --git a/src/rtsp/c_basicRTSPOnlyServer.cpp b/src/rtsp/c_basicRTSPOnlyServer.cpp index e16fe669c..d524ec267 100644 --- a/src/rtsp/c_basicRTSPOnlyServer.cpp +++ b/src/rtsp/c_basicRTSPOnlyServer.cpp @@ -46,7 +46,7 @@ int c_start_server(rtsp_serv_t* server){ int ret; - BasicRTSPOnlyServer *srv = BasicRTSPOnlyServer::initInstance(server->port, server->mod, server->avType, server->audio_codec, server->audio_sample_rate, server->audio_channels, server->audio_bps, server->rtp_port, server->rtp_port_audio); + BasicRTSPOnlyServer *srv = BasicRTSPOnlyServer::initInstance(server->params); srv->init_server(); ret = pthread_create(&server->server_th, NULL, BasicRTSPOnlyServer::start_server, &server->watch); if (ret == 0){ @@ -57,19 +57,11 @@ int c_start_server(rtsp_serv_t* server){ return ret; } -rtsp_serv_t *init_rtsp_server(unsigned int port, struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio){ +rtsp_serv_t* init_rtsp_server(struct rtsp_server_parameters params) { rtsp_serv_t *server = (rtsp_serv_t*) malloc(sizeof(rtsp_serv_t)); - server->port = port; - server->mod = mod; + server->params = params; server->watch = 0; server->run = FALSE; - server->avType = avType; - server->audio_codec = audio_codec; - server->audio_sample_rate = audio_sample_rate; - server->audio_channels = audio_channels; - server->audio_bps = audio_bps; - server->rtp_port = rtp_port; - server->rtp_port_audio = rtp_port_audio; return server; } diff --git a/src/rtsp/c_basicRTSPOnlyServer.h b/src/rtsp/c_basicRTSPOnlyServer.h index 8a9794e9a..39060b2bc 100644 --- a/src/rtsp/c_basicRTSPOnlyServer.h +++ b/src/rtsp/c_basicRTSPOnlyServer.h @@ -43,7 +43,6 @@ */ #ifndef C_BASIC_RTSP_ONLY_SERVER_H #define C_BASIC_RTSP_ONLY_SERVER_H -#endif #ifdef HAVE_CONFIG_H #include "config.h" @@ -65,26 +64,31 @@ #define EXTERNC #endif +struct rtsp_server_parameters { + unsigned int rtsp_port; + struct module *parent; + rtps_types_t avType; + audio_codec_t audio_codec; + int audio_sample_rate; + int audio_channels; + int audio_bps; + int rtp_port; //server rtp port + int rtp_port_audio; +}; + EXTERNC typedef struct rtsp_serv { - unsigned int port; - struct module *mod; + struct rtsp_server_parameters params; pthread_t server_th; uint8_t watch; uint8_t run; - rtps_types_t avType; - audio_codec_t audio_codec; - int audio_sample_rate; - int audio_channels; - int audio_bps; - int rtp_port; //server rtp port - int rtp_port_audio; } rtsp_serv_t; EXTERNC int c_start_server(rtsp_serv_t* server); EXTERNC void c_stop_server(rtsp_serv_t* server); -EXTERNC rtsp_serv_t* init_rtsp_server(unsigned int port, struct module *mod, rtps_types_t avType, audio_codec_t audio_codec, int audio_sample_rate, int audio_channels, int audio_bps, int rtp_port, int rtp_port_audio); +EXTERNC rtsp_serv_t* init_rtsp_server(struct rtsp_server_parameters params); #undef EXTERNC +#endif // defined C_BASIC_RTSP_ONLY_SERVER_H diff --git a/src/video_capture/rtsp.c b/src/video_capture/rtsp.c index b882a424b..350bf49ce 100644 --- a/src/video_capture/rtsp.c +++ b/src/video_capture/rtsp.c @@ -485,7 +485,6 @@ vidcap_rtsp_grab(void *state, struct audio_frame **audio) { if (s->vrtsp_state.decompress) { struct video_desc curr_desc = video_desc_from_frame(frame); - curr_desc.color_spec = H264; if (!video_desc_eq(s->vrtsp_state.decompress_desc, curr_desc)) { decompress_done(s->vrtsp_state.sd); if (init_decompressor(&s->vrtsp_state, curr_desc) == 0) { diff --git a/src/video_rxtx/h264_rtp.cpp b/src/video_rxtx/h264_rtp.cpp index 97090ffae..c90d5e58c 100644 --- a/src/video_rxtx/h264_rtp.cpp +++ b/src/video_rxtx/h264_rtp.cpp @@ -72,12 +72,19 @@ h264_rtp_video_rxtx::h264_rtp_video_rxtx(std::map const &p int rtsp_port) : rtp_video_rxtx(params) { - m_rtsp_server = init_rtsp_server(rtsp_port, - static_cast(params.at("parent").ptr), - static_cast(params.at("avType").l), - static_cast(params.at("audio_codec").l), - params.at("audio_sample_rate").i, params.at("audio_channels").i, - params.at("audio_bps").i, params.at("rx_port").i, params.at("a_rx_port").i); + struct rtsp_server_parameters rtsp_params = { + (unsigned) rtsp_port, + static_cast(params.at("parent").ptr), + static_cast(params.at("avType").l), + static_cast(params.at("audio_codec").l), + params.at("audio_sample_rate").i, + params.at("audio_channels").i, + params.at("audio_bps").i, + params.at("rx_port").i, + params.at("a_rx_port").i + }; + + m_rtsp_server = init_rtsp_server(rtsp_params); c_start_server(m_rtsp_server); }