1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "media/engine/multiplex_codec_factory.h"
12
13 #include <map>
14 #include <string>
15 #include <utility>
16
17 #include "absl/strings/match.h"
18 #include "api/video_codecs/sdp_video_format.h"
19 #include "media/base/codec.h"
20 #include "media/base/media_constants.h"
21 #include "modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h"
22 #include "modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h"
23 #include "rtc_base/logging.h"
24
25 namespace {
26
IsMultiplexCodec(const cricket::VideoCodec & codec)27 bool IsMultiplexCodec(const cricket::VideoCodec& codec) {
28 return absl::EqualsIgnoreCase(codec.name.c_str(),
29 cricket::kMultiplexCodecName);
30 }
31
32 } // anonymous namespace
33
34 namespace webrtc {
35
36 constexpr const char* kMultiplexAssociatedCodecName = cricket::kVp9CodecName;
37
MultiplexEncoderFactory(std::unique_ptr<VideoEncoderFactory> factory,bool supports_augmenting_data)38 MultiplexEncoderFactory::MultiplexEncoderFactory(
39 std::unique_ptr<VideoEncoderFactory> factory,
40 bool supports_augmenting_data)
41 : factory_(std::move(factory)),
42 supports_augmenting_data_(supports_augmenting_data) {}
43
GetSupportedFormats() const44 std::vector<SdpVideoFormat> MultiplexEncoderFactory::GetSupportedFormats()
45 const {
46 std::vector<SdpVideoFormat> formats = factory_->GetSupportedFormats();
47 for (const auto& format : formats) {
48 if (absl::EqualsIgnoreCase(format.name, kMultiplexAssociatedCodecName)) {
49 SdpVideoFormat multiplex_format = format;
50 multiplex_format.parameters[cricket::kCodecParamAssociatedCodecName] =
51 format.name;
52 multiplex_format.name = cricket::kMultiplexCodecName;
53 formats.push_back(multiplex_format);
54 break;
55 }
56 }
57 return formats;
58 }
59
CreateVideoEncoder(const SdpVideoFormat & format)60 std::unique_ptr<VideoEncoder> MultiplexEncoderFactory::CreateVideoEncoder(
61 const SdpVideoFormat& format) {
62 if (!IsMultiplexCodec(cricket::VideoCodec(format)))
63 return factory_->CreateVideoEncoder(format);
64 const auto& it =
65 format.parameters.find(cricket::kCodecParamAssociatedCodecName);
66 if (it == format.parameters.end()) {
67 RTC_LOG(LS_ERROR) << "No assicated codec for multiplex.";
68 return nullptr;
69 }
70 SdpVideoFormat associated_format = format;
71 associated_format.name = it->second;
72 return std::unique_ptr<VideoEncoder>(new MultiplexEncoderAdapter(
73 factory_.get(), associated_format, supports_augmenting_data_));
74 }
75
MultiplexDecoderFactory(std::unique_ptr<VideoDecoderFactory> factory,bool supports_augmenting_data)76 MultiplexDecoderFactory::MultiplexDecoderFactory(
77 std::unique_ptr<VideoDecoderFactory> factory,
78 bool supports_augmenting_data)
79 : factory_(std::move(factory)),
80 supports_augmenting_data_(supports_augmenting_data) {}
81
GetSupportedFormats() const82 std::vector<SdpVideoFormat> MultiplexDecoderFactory::GetSupportedFormats()
83 const {
84 std::vector<SdpVideoFormat> formats = factory_->GetSupportedFormats();
85 std::vector<SdpVideoFormat> augmented_formats = formats;
86 for (const auto& format : formats) {
87 if (absl::EqualsIgnoreCase(format.name, kMultiplexAssociatedCodecName)) {
88 SdpVideoFormat multiplex_format = format;
89 multiplex_format.parameters[cricket::kCodecParamAssociatedCodecName] =
90 format.name;
91 multiplex_format.name = cricket::kMultiplexCodecName;
92 augmented_formats.push_back(multiplex_format);
93 }
94 }
95 return augmented_formats;
96 }
97
CreateVideoDecoder(const SdpVideoFormat & format)98 std::unique_ptr<VideoDecoder> MultiplexDecoderFactory::CreateVideoDecoder(
99 const SdpVideoFormat& format) {
100 if (!IsMultiplexCodec(cricket::VideoCodec(format)))
101 return factory_->CreateVideoDecoder(format);
102 const auto& it =
103 format.parameters.find(cricket::kCodecParamAssociatedCodecName);
104 if (it == format.parameters.end()) {
105 RTC_LOG(LS_ERROR) << "No assicated codec for multiplex.";
106 return nullptr;
107 }
108 SdpVideoFormat associated_format = format;
109 associated_format.name = it->second;
110 return std::unique_ptr<VideoDecoder>(new MultiplexDecoderAdapter(
111 factory_.get(), associated_format, supports_augmenting_data_));
112 }
113
114 } // namespace webrtc
115