Skip to content

Commit 5e4d3a5

Browse files
H264inclient (#398)
* opt h264 in client * decide video codec support at conf alloc, vp8 default if list is empty
1 parent f1fa78c commit 5e4d3a5

File tree

18 files changed

+346
-329
lines changed

18 files changed

+346
-329
lines changed

api/AllocateConference.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "bridge/CodecCapabilities.h"
34
#include "utils/Optional.h"
45
#include <cstdint>
56

@@ -10,6 +11,7 @@ struct AllocateConference
1011
{
1112
utils::Optional<uint32_t> lastN;
1213
bool useGlobalPort = true;
14+
bridge::VideoCodecSpec videoCodecs = bridge::VideoCodecSpec::makeVp8();
1315
};
1416

1517
} // namespace api

api/Parser.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,25 @@ AllocateConference parseAllocateConference(const nlohmann::json& data)
284284
}
285285
}
286286
setIfExistsOrDefault(allocateConference.useGlobalPort, data, "global-port", true);
287+
auto it = data.find("video-codecs");
288+
if (it != data.end())
289+
{
290+
for (auto codec : data["video-codecs"])
291+
{
292+
if (codec == "vp8")
293+
{
294+
allocateConference.videoCodecs.vp8 = true;
295+
}
296+
else if (codec == "h264")
297+
{
298+
allocateConference.videoCodecs.h264 = true;
299+
}
300+
}
301+
}
302+
else
303+
{
304+
allocateConference.videoCodecs.vp8 = true;
305+
}
287306

288307
return allocateConference;
289308
}

bridge/CodecCapabilities.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include <string>
3+
4+
namespace bridge
5+
{
6+
7+
struct VideoCodecSpec
8+
{
9+
bool vp8 : 1;
10+
bool h264 : 1;
11+
12+
VideoCodecSpec() : vp8(0), h264(0) {}
13+
14+
static VideoCodecSpec makeVp8()
15+
{
16+
VideoCodecSpec v;
17+
v.vp8 = 1;
18+
return v;
19+
}
20+
21+
std::string toString() const
22+
{
23+
std::string s;
24+
if (vp8)
25+
{
26+
s += "vp8 ";
27+
}
28+
if (h264)
29+
{
30+
s += "h264 ";
31+
}
32+
33+
return s;
34+
}
35+
};
36+
} // namespace bridge

bridge/Mixer.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ Mixer::Mixer(std::string id,
156156
const std::vector<uint32_t>& audioSsrcs,
157157
const std::vector<api::SimulcastGroup>& videoSsrcs,
158158
const std::vector<api::SsrcPair>& videoPinSsrcs,
159-
bool useGlobalPort)
159+
bool useGlobalPort,
160+
VideoCodecSpec videoCodecs)
160161
: _config(config),
161162
_id(std::move(id)),
162163
_loggableId("Mixer", logInstanceId),
@@ -169,7 +170,8 @@ Mixer::Mixer(std::string id,
169170
_engineMixer(std::move(engineMixer)),
170171
_idGenerator(idGenerator),
171172
_ssrcGenerator(ssrcGenerator),
172-
_useGlobalPort(useGlobalPort)
173+
_useGlobalPort(useGlobalPort),
174+
_videoCodecs(videoCodecs)
173175
{
174176
}
175177

@@ -2432,4 +2434,8 @@ void Mixer::engineBarbellRemoved(const EngineBarbell& engineBarbell)
24322434
}
24332435
}
24342436

2437+
bool Mixer::isH264Enabled() const
2438+
{
2439+
return _videoCodecs.h264;
2440+
}
24352441
} // namespace bridge

bridge/Mixer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "bridge/Barbell.h"
4+
#include "bridge/CodecCapabilities.h"
45
#include "bridge/RecordingStream.h"
56
#include "bridge/Stats.h"
67
#include "bridge/engine/ActiveTalker.h"
@@ -94,7 +95,8 @@ class Mixer
9495
const std::vector<uint32_t>& audioSsrcs,
9596
const std::vector<api::SimulcastGroup>& videoSsrcs,
9697
const std::vector<api::SsrcPair>& videoPinSsrcs,
97-
bool useGlobalPort);
98+
bool useGlobalPort,
99+
VideoCodecSpec videoCodecs);
98100

99101
virtual ~Mixer() = default;
100102

@@ -298,6 +300,8 @@ class Mixer
298300
const config::Config& getConfig() const { return _config; }
299301
bridge::Stats::MixerBarbellStats gatherBarbellStats(const uint64_t engineIterationStartTimestamp);
300302

303+
bool isH264Enabled() const;
304+
301305
private:
302306
struct BundleTransport
303307
{
@@ -332,6 +336,7 @@ class Mixer
332336

333337
std::unordered_map<std::string, BundleTransport> _bundleTransports;
334338
bool _useGlobalPort;
339+
const VideoCodecSpec _videoCodecs;
335340
transport::Endpoints _rtpPorts;
336341
std::unordered_map<size_t, std::unordered_map<uint32_t, std::unique_ptr<PacketCache>>> _videoPacketCaches;
337342
std::unordered_map<size_t, std::unordered_map<uint32_t, std::unique_ptr<PacketCache>>> _recordingRtpPacketCaches;

bridge/MixerManager.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,12 @@ MixerManager::~MixerManager()
116116
logger::debug("Deleted", "MixerManager");
117117
}
118118

119-
Mixer* MixerManager::create(bool useGlobalPort)
119+
Mixer* MixerManager::create(bool useGlobalPort, VideoCodecSpec videoCodecs)
120120
{
121-
return create(_config.defaultLastN, useGlobalPort);
121+
return create(_config.defaultLastN, useGlobalPort, videoCodecs);
122122
}
123123

124-
Mixer* MixerManager::create(uint32_t lastN, bool useGlobalPort)
124+
Mixer* MixerManager::create(uint32_t lastN, bool useGlobalPort, VideoCodecSpec videoCodecs)
125125
{
126126
lastN = std::min(lastN, maxLastN);
127127
logger::info("Create mixer, last-n %u", "MixerManager", lastN);
@@ -190,7 +190,8 @@ Mixer* MixerManager::create(uint32_t lastN, bool useGlobalPort)
190190
audioSsrcs,
191191
videoSsrcs,
192192
videoPinSsrcs,
193-
useGlobalPort));
193+
useGlobalPort,
194+
videoCodecs));
194195
if (!mixerEmplaceResult.second)
195196
{
196197
logger::error("Failed to create mixer", "MixerManager");

bridge/MixerManager.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "bridge/CodecCapabilities.h"
34
#include "bridge/MixerManagerAsync.h"
45
#include "bridge/Stats.h"
56
#include "bridge/engine/EngineMixer.h"
@@ -60,8 +61,8 @@ class MixerManager final : public MixerManagerAsync
6061

6162
~MixerManager();
6263

63-
bridge::Mixer* create(bool useGlobalPort);
64-
bridge::Mixer* create(uint32_t lastN, bool useGlobalPort);
64+
bridge::Mixer* create(bool useGlobalPort, VideoCodecSpec videoCodecs = VideoCodecSpec());
65+
bridge::Mixer* create(uint32_t lastN, bool useGlobalPort, VideoCodecSpec videoCodecs = VideoCodecSpec());
6566
void remove(const std::string& id);
6667
std::vector<std::string> getMixerIds();
6768
std::unique_lock<std::mutex> getMixer(const std::string& id, Mixer*& outMixer);

bridge/endpointActions/AllocateConference.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,23 @@ httpd::Response allocateConference(ActionContext* context, RequestLogger& reques
2121
const auto allocateConference = api::Parser::parseAllocateConference(requestBodyJson);
2222

2323
auto mixer = allocateConference.lastN.isSet()
24-
? context->mixerManager.create(allocateConference.lastN.get(), allocateConference.useGlobalPort)
25-
: context->mixerManager.create(allocateConference.useGlobalPort);
24+
? context->mixerManager.create(allocateConference.lastN.get(),
25+
allocateConference.useGlobalPort,
26+
allocateConference.videoCodecs)
27+
: context->mixerManager.create(allocateConference.useGlobalPort, allocateConference.videoCodecs);
2628

2729
if (!mixer)
2830
{
2931
throw httpd::RequestErrorException(httpd::StatusCode::INTERNAL_SERVER_ERROR, "Conference creation has failed");
3032
}
3133

32-
logger::info("Allocate conference %s, mixer %s, last-n %d, global-port %c",
34+
logger::info("Allocate conference %s, mixer %s, last-n %d, global-port %c, codec %s",
3335
"ApiRequestHandler",
3436
mixer->getId().c_str(),
3537
mixer->getLoggableId().c_str(),
3638
allocateConference.lastN.isSet() ? allocateConference.lastN.get() : -1,
37-
allocateConference.useGlobalPort ? 't' : 'f');
39+
allocateConference.useGlobalPort ? 't' : 'f',
40+
allocateConference.videoCodecs.toString().c_str());
3841

3942
nlohmann::json responseJson;
4043
responseJson["id"] = mixer->getId();

bridge/endpointActions/ConferenceActions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,13 @@ httpd::Response generateAllocateEndpointResponse(ActionContext* context,
242242
responseVideo.transport.set(responseTransport);
243243
}
244244

245-
if (context->config.codec.videoCodec.get() == "H264")
245+
if (context->config.codec.videoCodec.get() == "H264" || mixer.isH264Enabled())
246246
{
247247
addH264VideoProperties(responseVideo,
248248
context->config.codec.h264ProfileLevelId.get(),
249249
context->config.codec.h264PacketizationMode.get());
250250
}
251-
else
251+
else if (context->config.codec.videoCodec.get() == "VP8")
252252
{
253253
addVp8VideoProperties(responseVideo);
254254
}

config/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ class Config : public ConfigReader
139139

140140
CFG_GROUP()
141141
CFG_PROP(std::string, videoCodec, "VP8");
142+
// webRTC profiles: 42001f, 42e01f, 4d001f, 64001f, f4001f
142143
CFG_PROP(std::string, h264ProfileLevelId, "42001f");
143144
CFG_PROP(uint32_t, h264PacketizationMode, 1);
144145

0 commit comments

Comments
 (0)