/* --------------------------------------------------------------------------- ** This software is in the public domain, furnished "as is", without technical ** support, and with no warranty, express or implied, as to its usefulness for ** any purpose. ** ** BaseServerMediaSubsession.h ** ** -------------------------------------------------------------------------*/ #pragma once #include #include #include #include #include #include // live555 #include // libv4l2cpp #include "V4l2Device.h" // v4l2rtspserver #include "V4L2DeviceSource.h" #include "logger.h" #ifdef HAVE_ALSA #include "ALSACapture.h" #endif // --------------------------------- // BaseServerMediaSubsession // --------------------------------- class BaseServerMediaSubsession { public: BaseServerMediaSubsession(StreamReplicator* replicator): m_replicator(replicator) { V4L2DeviceSource* deviceSource = dynamic_cast(replicator->inputSource()); if (deviceSource) { DeviceInterface* device = deviceSource->getDevice(); if (device->getVideoFormat() >= 0) { m_format = BaseServerMediaSubsession::getVideoRtpFormat(device->getVideoFormat()); } else { m_format = BaseServerMediaSubsession::getAudioRtpFormat(device->getAudioFormat(), device->getSampleRate(), device->getChannels()); } LOG(NOTICE) << "RTP format:" << m_format; } } // ----------------------------------------- // convert V4L2 pix format to RTP mime // ----------------------------------------- static std::string getVideoRtpFormat(int format) { std::string rtpFormat; switch(format) { case V4L2_PIX_FMT_HEVC : rtpFormat = "video/H265"; break; case V4L2_PIX_FMT_H264 : rtpFormat = "video/H264"; break; case V4L2_PIX_FMT_MJPEG : rtpFormat = "video/JPEG"; break; case V4L2_PIX_FMT_JPEG : rtpFormat = "video/JPEG"; break; case V4L2_PIX_FMT_VP8 : rtpFormat = "video/VP8" ; break; case V4L2_PIX_FMT_VP9 : rtpFormat = "video/VP9" ; break; case V4L2_PIX_FMT_YUV444: rtpFormat = "video/RAW" ; break; case V4L2_PIX_FMT_UYVY : rtpFormat = "video/RAW" ; break; case V4L2_PIX_FMT_NV12 : rtpFormat = "video/RAW" ; break; case V4L2_PIX_FMT_BGR24 : rtpFormat = "video/RAW" ; break; case V4L2_PIX_FMT_BGR32 : rtpFormat = "video/RAW" ; break; case V4L2_PIX_FMT_RGB24 : rtpFormat = "video/RAW" ; break; case V4L2_PIX_FMT_RGB32 : rtpFormat = "video/RAW" ; break; } return rtpFormat; } static std::string getAudioRtpFormat(int format, int sampleRate, int channels) { std::ostringstream os; #ifdef HAVE_ALSA os << "audio/"; switch (format) { case SND_PCM_FORMAT_A_LAW: os << "PCMA"; break; case SND_PCM_FORMAT_MU_LAW: os << "PCMU"; break; case SND_PCM_FORMAT_S8: os << "L8"; break; case SND_PCM_FORMAT_S24_BE: case SND_PCM_FORMAT_S24_LE: os << "L24"; break; case SND_PCM_FORMAT_S32_BE: case SND_PCM_FORMAT_S32_LE: os << "L32"; break; case SND_PCM_FORMAT_MPEG: os << "MPEG"; break; default: os << "L16"; break; } os << "/" << sampleRate << "/" << channels; #endif return os.str(); } public: static FramedSource* createSource(UsageEnvironment& env, FramedSource * videoES, const std::string& format); static RTPSink* createSink(UsageEnvironment& env, Groupsock * rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, const std::string& format, V4L2DeviceSource* source); char const* getAuxLine(V4L2DeviceSource* source, RTPSink* rtpSink); protected: StreamReplicator* m_replicator; std::string m_format; };