1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// Media
19// Implementation
20
21#include "Media.hh"
22#include "HashTable.hh"
23
24////////// Medium //////////
25
26Medium::Medium(UsageEnvironment& env)
27 : fEnviron(env), fNextTask(NULL) {
28 // First generate a name for the new medium:
29 MediaLookupTable::ourMedia(env)->generateNewName(fMediumName, mediumNameMaxLen);
30 env.setResultMsg(fMediumName);
31
32 // Then add it to our table:
33 MediaLookupTable::ourMedia(env)->addNew(this, fMediumName);
34}
35
36Medium::~Medium() {
37 // Remove any tasks that might be pending for us:
38 fEnviron.taskScheduler().unscheduleDelayedTask(fNextTask);
39}
40
41Boolean Medium::lookupByName(UsageEnvironment& env, char const* mediumName,
42 Medium*& resultMedium) {
43 resultMedium = MediaLookupTable::ourMedia(env)->lookup(mediumName);
44 if (resultMedium == NULL) {
45 env.setResultMsg("Medium ", mediumName, " does not exist");
46 return False;
47 }
48
49 return True;
50}
51
52void Medium::close(UsageEnvironment& env, char const* name) {
53 MediaLookupTable::ourMedia(env)->remove(name);
54}
55
56void Medium::close(Medium* medium) {
57 if (medium == NULL) return;
58
59 close(medium->envir(), medium->name());
60}
61
62Boolean Medium::isSource() const {
63 return False; // default implementation
64}
65
66Boolean Medium::isSink() const {
67 return False; // default implementation
68}
69
70Boolean Medium::isRTCPInstance() const {
71 return False; // default implementation
72}
73
74Boolean Medium::isRTSPClient() const {
75 return False; // default implementation
76}
77
78Boolean Medium::isRTSPServer() const {
79 return False; // default implementation
80}
81
82Boolean Medium::isMediaSession() const {
83 return False; // default implementation
84}
85
86Boolean Medium::isServerMediaSession() const {
87 return False; // default implementation
88}
89
90
91////////// _Tables implementation //////////
92
93_Tables* _Tables::getOurTables(UsageEnvironment& env, Boolean createIfNotPresent) {
94 if (env.liveMediaPriv == NULL && createIfNotPresent) {
95 env.liveMediaPriv = new _Tables(env);
96 }
97 return (_Tables*)(env.liveMediaPriv);
98}
99
100void _Tables::reclaimIfPossible() {
101 if (mediaTable == NULL && socketTable == NULL) {
102 fEnv.liveMediaPriv = NULL;
103 delete this;
104 }
105}
106
107_Tables::_Tables(UsageEnvironment& env)
108 : mediaTable(NULL), socketTable(NULL), fEnv(env) {
109}
110
111_Tables::~_Tables() {
112}
113
114
115////////// MediaLookupTable implementation //////////
116
117MediaLookupTable* MediaLookupTable::ourMedia(UsageEnvironment& env) {
118 _Tables* ourTables = _Tables::getOurTables(env);
119 if (ourTables->mediaTable == NULL) {
120 // Create a new table to record the media that are to be created in
121 // this environment:
122 ourTables->mediaTable = new MediaLookupTable(env);
123 }
124 return ourTables->mediaTable;
125}
126
127Medium* MediaLookupTable::lookup(char const* name) const {
128 return (Medium*)(fTable->Lookup(name));
129}
130
131void MediaLookupTable::addNew(Medium* medium, char* mediumName) {
132 fTable->Add(mediumName, (void*)medium);
133}
134
135void MediaLookupTable::remove(char const* name) {
136 Medium* medium = lookup(name);
137 if (medium != NULL) {
138 fTable->Remove(name);
139 if (fTable->IsEmpty()) {
140 // We can also delete ourselves (to reclaim space):
141 _Tables* ourTables = _Tables::getOurTables(fEnv);
142 delete this;
143 ourTables->mediaTable = NULL;
144 ourTables->reclaimIfPossible();
145 }
146
147 delete medium;
148 }
149}
150
151void MediaLookupTable::generateNewName(char* mediumName,
152 unsigned /*maxLen*/) {
153 // We should really use snprintf() here, but not all systems have it
154 sprintf(mediumName, "liveMedia%d", fNameGenerator++);
155}
156
157MediaLookupTable::MediaLookupTable(UsageEnvironment& env)
158 : fEnv(env), fTable(HashTable::create(STRING_HASH_KEYS)), fNameGenerator(0) {
159}
160
161MediaLookupTable::~MediaLookupTable() {
162 delete fTable;
163}
164