1/* ---------------------------------------------------------------------------
2** This software is in the public domain, furnished "as is", without technical
3** support, and with no warranty, express or implied, as to its usefulness for
4** any purpose.
5**
6** ServerMediaSubsession.cpp
7**
8** -------------------------------------------------------------------------*/
9
10#include <sstream>
11#include <linux/videodev2.h>
12
13// project
14#include "ServerMediaSubsession.h"
15#include "MJPEGVideoSource.h"
16#include "DeviceSource.h"
17
18// ---------------------------------
19// BaseServerMediaSubsession
20// ---------------------------------
21FramedSource* BaseServerMediaSubsession::createSource(UsageEnvironment& env, FramedSource* videoES, const std::string& format)
22{
23 FramedSource* source = NULL;
24 if (format == "video/MP2T")
25 {
26 source = MPEG2TransportStreamFramer::createNew(env, videoES);
27 }
28 else if (format == "video/H264")
29 {
30 source = H264VideoStreamDiscreteFramer::createNew(env, videoES);
31 }
32#if LIVEMEDIA_LIBRARY_VERSION_INT > 1414454400
33 else if (format == "video/H265")
34 {
35 source = H265VideoStreamDiscreteFramer::createNew(env, videoES);
36 }
37#endif
38 else if (format == "video/JPEG")
39 {
40 source = MJPEGVideoSource::createNew(env, videoES);
41 }
42 else
43 {
44 source = videoES;
45 }
46 return source;
47}
48
49RTPSink* BaseServerMediaSubsession::createSink(UsageEnvironment& env, Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, const std::string& format, V4L2DeviceSource* source)
50{
51 RTPSink* videoSink = NULL;
52 if (format == "video/MP2T")
53 {
54 videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, 90000, "video", "MP2T", 1, True, False);
55 }
56 else if (format == "video/H264")
57 {
58 videoSink = H264VideoRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic);
59 }
60 else if (format == "video/VP8")
61 {
62 videoSink = VP8VideoRTPSink::createNew (env, rtpGroupsock,rtpPayloadTypeIfDynamic);
63 }
64#if LIVEMEDIA_LIBRARY_VERSION_INT > 1414454400
65 else if (format == "video/VP9")
66 {
67 videoSink = VP9VideoRTPSink::createNew (env, rtpGroupsock,rtpPayloadTypeIfDynamic);
68 }
69 else if (format == "video/H265")
70 {
71 videoSink = H265VideoRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic);
72 }
73#endif
74 else if (format == "video/JPEG")
75 {
76 videoSink = JPEGVideoRTPSink::createNew (env, rtpGroupsock);
77 }
78#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1536192000
79 else if (format =="video/RAW")
80 {
81 std::string sampling;
82 switch (source->getCaptureFormat()) {
83 case V4L2_PIX_FMT_YUV444: sampling = "YCbCr-4:4:4"; break;
84 case V4L2_PIX_FMT_YUYV: sampling = "YCbCr-4:2:2"; break;
85 case V4L2_PIX_FMT_UYVY: sampling = "YCbCr-4:2:2"; break;
86 }
87 videoSink = RawVideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic, source->getHeight(), source->getWidth(), 8, sampling.c_str());
88 }
89#endif
90 else if (format.find("audio/L16") == 0)
91 {
92 std::istringstream is(format);
93 std::string dummy;
94 getline(is, dummy, '/');
95 getline(is, dummy, '/');
96 std::string sampleRate("44100");
97 getline(is, sampleRate, '/');
98 std::string channels("2");
99 getline(is, channels);
100 videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, atoi(sampleRate.c_str()), "audio", "L16", atoi(channels.c_str()), True, False);
101 }
102 return videoSink;
103}
104
105char const* BaseServerMediaSubsession::getAuxLine(V4L2DeviceSource* source, RTPSink* rtpSink)
106{
107 const char* auxLine = NULL;
108 if (rtpSink) {
109 std::ostringstream os;
110 if (rtpSink->auxSDPLine()) {
111 os << rtpSink->auxSDPLine();
112 }
113 else if (source) {
114 unsigned char rtpPayloadType = rtpSink->rtpPayloadType();
115 os << "a=fmtp:" << int(rtpPayloadType) << " " << source->getAuxLine() << "\r\n";
116 int width = source->getWidth();
117 int height = source->getHeight();
118 if ( (width > 0) && (height>0) ) {
119 os << "a=x-dimensions:" << width << "," << height << "\r\n";
120 }
121 }
122 auxLine = strdup(os.str().c_str());
123 }
124 return auxLine;
125}
126
127