Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Side by Side Diff: webrtc/modules/video_coding/video_codec_initializer.cc

Issue 2489843002: Revert of Extract bitrate allocation of spatial/temporal layers out of codec impl. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 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 "webrtc/modules/video_coding/include/video_codec_initializer.h"
12
13 #include "webrtc/base/basictypes.h"
14 #include "webrtc/common_video/include/video_bitrate_allocator.h"
15 #include "webrtc/common_types.h"
16 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
17 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
18 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h"
19 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h"
20 #include "webrtc/system_wrappers/include/clock.h"
21
22 namespace webrtc {
23
24 struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory {
25 ScreenshareTemporalLayersFactory() {}
26 virtual ~ScreenshareTemporalLayersFactory() {}
27
28 virtual webrtc::TemporalLayers* Create(int simulcast_id,
29 int num_temporal_layers,
30 uint8_t initial_tl0_pic_idx) const {
31 webrtc::TemporalLayers* tl = new webrtc::ScreenshareLayers(
32 num_temporal_layers, rand(), webrtc::Clock::GetRealTimeClock());
33 if (listener_)
34 listener_->OnTemporalLayersCreated(simulcast_id, tl);
35 return tl;
36 }
37 };
38
39 bool VideoCodecInitializer::SetupCodec(
40 const VideoEncoderConfig& config,
41 const VideoSendStream::Config::EncoderSettings settings,
42 const std::vector<VideoStream>& streams,
43 VideoCodec* codec,
44 std::unique_ptr<VideoBitrateAllocator>* bitrate_allocator) {
45 *codec = VideoEncoderConfigToVideoCodec(
46 config, streams, settings.payload_name, settings.payload_type);
47
48 std::unique_ptr<TemporalLayersFactory> tl_factory;
49 switch (codec->codecType) {
50 case kVideoCodecVP8: {
51 if (!codec->VP8()->tl_factory) {
52 if (codec->mode == kScreensharing &&
53 codec->numberOfSimulcastStreams == 1 &&
54 codec->VP8()->numberOfTemporalLayers == 2) {
55 // Conference mode temporal layering for screen content.
56 tl_factory.reset(new ScreenshareTemporalLayersFactory());
57 } else {
58 // Standard video temporal layers.
59 tl_factory.reset(new TemporalLayersFactory());
60 }
61 codec->VP8()->tl_factory = tl_factory.get();
62 }
63 break;
64 }
65 default: {
66 // TODO(sprang): Warn, once we have specific allocators for all supported
67 // codec types.
68 break;
69 }
70 }
71 *bitrate_allocator = CreateBitrateAllocator(*codec, std::move(tl_factory));
72
73 return true;
74 }
75
76 std::unique_ptr<VideoBitrateAllocator>
77 VideoCodecInitializer::CreateBitrateAllocator(
78 const VideoCodec& codec,
79 std::unique_ptr<TemporalLayersFactory> tl_factory) {
80 std::unique_ptr<VideoBitrateAllocator> rate_allocator;
81
82 switch (codec.codecType) {
83 case kVideoCodecVP8: {
84 // Set up default VP8 temporal layer factory, if not provided.
85 rate_allocator.reset(
86 new SimulcastRateAllocator(codec, std::move(tl_factory)));
87 } break;
88 default:
89 rate_allocator.reset(new DefaultVideoBitrateAllocator(codec));
90 }
91
92 return rate_allocator;
93 }
94
95 // TODO(sprang): Split this up and separate the codec specific parts.
96 VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
97 const VideoEncoderConfig& config,
98 const std::vector<VideoStream>& streams,
99 const std::string& payload_name,
100 int payload_type) {
101 static const int kEncoderMinBitrateKbps = 30;
102 RTC_DCHECK(!streams.empty());
103 RTC_DCHECK_GE(config.min_transmit_bitrate_bps, 0);
104
105 VideoCodec video_codec;
106 memset(&video_codec, 0, sizeof(video_codec));
107 video_codec.codecType = PayloadNameToCodecType(payload_name)
108 .value_or(VideoCodecType::kVideoCodecGeneric);
109
110 switch (config.content_type) {
111 case VideoEncoderConfig::ContentType::kRealtimeVideo:
112 video_codec.mode = kRealtimeVideo;
113 break;
114 case VideoEncoderConfig::ContentType::kScreen:
115 video_codec.mode = kScreensharing;
116 if (streams.size() == 1 &&
117 streams[0].temporal_layer_thresholds_bps.size() == 1) {
118 video_codec.targetBitrate =
119 streams[0].temporal_layer_thresholds_bps[0] / 1000;
120 }
121 break;
122 }
123
124 if (config.encoder_specific_settings)
125 config.encoder_specific_settings->FillEncoderSpecificSettings(&video_codec);
126
127 switch (video_codec.codecType) {
128 case kVideoCodecVP8: {
129 if (!config.encoder_specific_settings)
130 video_codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
131 video_codec.codecSpecific.VP8.numberOfTemporalLayers =
132 static_cast<unsigned char>(
133 streams.back().temporal_layer_thresholds_bps.size() + 1);
134 break;
135 }
136 case kVideoCodecVP9: {
137 if (!config.encoder_specific_settings)
138 video_codec.codecSpecific.VP9 = VideoEncoder::GetDefaultVp9Settings();
139 if (video_codec.mode == kScreensharing &&
140 config.encoder_specific_settings) {
141 video_codec.codecSpecific.VP9.flexibleMode = true;
142 // For now VP9 screensharing use 1 temporal and 2 spatial layers.
143 RTC_DCHECK_EQ(1, video_codec.codecSpecific.VP9.numberOfTemporalLayers);
144 RTC_DCHECK_EQ(2, video_codec.codecSpecific.VP9.numberOfSpatialLayers);
145 }
146 video_codec.codecSpecific.VP9.numberOfTemporalLayers =
147 static_cast<unsigned char>(
148 streams.back().temporal_layer_thresholds_bps.size() + 1);
149 break;
150 }
151 case kVideoCodecH264: {
152 if (!config.encoder_specific_settings)
153 video_codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
154 break;
155 }
156 default:
157 // TODO(pbos): Support encoder_settings codec-agnostically.
158 RTC_DCHECK(!config.encoder_specific_settings)
159 << "Encoder-specific settings for codec type not wired up.";
160 break;
161 }
162
163 strncpy(video_codec.plName, payload_name.c_str(), kPayloadNameSize - 1);
164 video_codec.plName[kPayloadNameSize - 1] = '\0';
165 video_codec.plType = payload_type;
166 video_codec.numberOfSimulcastStreams =
167 static_cast<unsigned char>(streams.size());
168 video_codec.minBitrate = streams[0].min_bitrate_bps / 1000;
169 if (video_codec.minBitrate < kEncoderMinBitrateKbps)
170 video_codec.minBitrate = kEncoderMinBitrateKbps;
171 RTC_DCHECK_LE(streams.size(), static_cast<size_t>(kMaxSimulcastStreams));
172 if (video_codec.codecType == kVideoCodecVP9) {
173 // If the vector is empty, bitrates will be configured automatically.
174 RTC_DCHECK(config.spatial_layers.empty() ||
175 config.spatial_layers.size() ==
176 video_codec.codecSpecific.VP9.numberOfSpatialLayers);
177 RTC_DCHECK_LE(video_codec.codecSpecific.VP9.numberOfSpatialLayers,
178 kMaxSimulcastStreams);
179 for (size_t i = 0; i < config.spatial_layers.size(); ++i)
180 video_codec.spatialLayers[i] = config.spatial_layers[i];
181 }
182 for (size_t i = 0; i < streams.size(); ++i) {
183 SimulcastStream* sim_stream = &video_codec.simulcastStream[i];
184 RTC_DCHECK_GT(streams[i].width, 0u);
185 RTC_DCHECK_GT(streams[i].height, 0u);
186 RTC_DCHECK_GT(streams[i].max_framerate, 0);
187 // Different framerates not supported per stream at the moment.
188 RTC_DCHECK_EQ(streams[i].max_framerate, streams[0].max_framerate);
189 RTC_DCHECK_GE(streams[i].min_bitrate_bps, 0);
190 RTC_DCHECK_GE(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
191 RTC_DCHECK_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
192 RTC_DCHECK_GE(streams[i].max_qp, 0);
193
194 sim_stream->width = static_cast<uint16_t>(streams[i].width);
195 sim_stream->height = static_cast<uint16_t>(streams[i].height);
196 sim_stream->minBitrate = streams[i].min_bitrate_bps / 1000;
197 sim_stream->targetBitrate = streams[i].target_bitrate_bps / 1000;
198 sim_stream->maxBitrate = streams[i].max_bitrate_bps / 1000;
199 sim_stream->qpMax = streams[i].max_qp;
200 sim_stream->numberOfTemporalLayers = static_cast<unsigned char>(
201 streams[i].temporal_layer_thresholds_bps.size() + 1);
202
203 video_codec.width =
204 std::max(video_codec.width, static_cast<uint16_t>(streams[i].width));
205 video_codec.height =
206 std::max(video_codec.height, static_cast<uint16_t>(streams[i].height));
207 video_codec.minBitrate =
208 std::min(static_cast<uint16_t>(video_codec.minBitrate),
209 static_cast<uint16_t>(streams[i].min_bitrate_bps / 1000));
210 video_codec.maxBitrate += streams[i].max_bitrate_bps / 1000;
211 video_codec.qpMax = std::max(video_codec.qpMax,
212 static_cast<unsigned int>(streams[i].max_qp));
213 }
214
215 if (video_codec.maxBitrate == 0) {
216 // Unset max bitrate -> cap to one bit per pixel.
217 video_codec.maxBitrate =
218 (video_codec.width * video_codec.height * video_codec.maxFramerate) /
219 1000;
220 }
221 if (video_codec.maxBitrate < kEncoderMinBitrateKbps)
222 video_codec.maxBitrate = kEncoderMinBitrateKbps;
223
224 RTC_DCHECK_GT(streams[0].max_framerate, 0);
225 video_codec.maxFramerate = streams[0].max_framerate;
226 return video_codec;
227 }
228
229 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/utility/video_coding_utility.gyp ('k') | webrtc/modules/video_coding/video_coding.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698