diff options
author | Jordan Bayles <jophba@chromium.org> | 2021-03-30 10:01:12 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-01 03:02:12 +0000 |
commit | 0d56b58a5c140924c107bde67a890a0a79c5fbeb (patch) | |
tree | 8003631d1ec1a35ff44c51aae0d3420e9e953c23 | |
parent | 21f04aefd1b06a959576202fc3a7616bc4de0b1d (diff) | |
download | openscreen-0d56b58a5c140924c107bde67a890a0a79c5fbeb.tar.gz |
[Cast] Make additional Constraint fields optional
This patch makes the maxDelay and maxPixelsPerSecond fields optional.
Bug: 1154956
Change-Id: I0afc8b31a657a5a6224a74a7c168273fb86ac59b
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/2794863
Commit-Queue: Jordan Bayles <jophba@chromium.org>
Reviewed-by: Brandon Tolsch <btolsch@chromium.org>
-rw-r--r-- | cast/protocol/castv2/streaming_examples/answer.json | 3 | ||||
-rw-r--r-- | cast/protocol/castv2/streaming_schema.json | 6 | ||||
-rw-r--r-- | cast/streaming/answer_messages.cc | 51 | ||||
-rw-r--r-- | cast/streaming/answer_messages.h | 12 | ||||
-rw-r--r-- | cast/streaming/capture_recommendations.cc | 16 | ||||
-rw-r--r-- | cast/streaming/capture_recommendations.h | 2 | ||||
-rw-r--r-- | cast/streaming/capture_recommendations_unittest.cc | 4 |
7 files changed, 61 insertions, 33 deletions
diff --git a/cast/protocol/castv2/streaming_examples/answer.json b/cast/protocol/castv2/streaming_examples/answer.json index 97a3e59a..73c45ea2 100644 --- a/cast/protocol/castv2/streaming_examples/answer.json +++ b/cast/protocol/castv2/streaming_examples/answer.json @@ -12,8 +12,7 @@ "maxSampleRate": 96000, "maxChannels": 5, "minBitRate": 32000, - "maxBitRate": 320000, - "maxDelay": 4000 + "maxBitRate": 320000 }, "video": { "maxPixelsPerSecond": 62208000, diff --git a/cast/protocol/castv2/streaming_schema.json b/cast/protocol/castv2/streaming_schema.json index 2c2fc59a..392d135c 100644 --- a/cast/protocol/castv2/streaming_schema.json +++ b/cast/protocol/castv2/streaming_schema.json @@ -110,7 +110,7 @@ "maxBitRate": {"type": "integer", "minimum": 32000, "maximum": 320000}, "maxDelay": {"$ref": "#/definitions/delay"} }, - "required": ["maxSampleRate", "maxChannels", "maxBitRate", "maxDelay"] + "required": ["maxSampleRate", "maxChannels", "maxBitRate"] }, "video_constraints": { "properties": { @@ -122,10 +122,8 @@ "maxDelay": {"$ref": "#/definitions/delay"} }, "required": [ - "maxPixelsPerSecond", "maxDimensions", - "maxBitRate", - "maxDelay" + "maxBitRate" ] }, "constraints": { diff --git a/cast/streaming/answer_messages.cc b/cast/streaming/answer_messages.cc index ed308260..906e8901 100644 --- a/cast/streaming/answer_messages.cc +++ b/cast/streaming/answer_messages.cc @@ -210,10 +210,15 @@ bool AudioConstraints::ParseAndValidate(const Json::Value& root, if (!json::ParseAndValidateInt(root[kMaxSampleRate], &(out->max_sample_rate)) || !json::ParseAndValidateInt(root[kMaxChannels], &(out->max_channels)) || - !json::ParseAndValidateInt(root[kMaxBitRate], &(out->max_bit_rate)) || - !json::ParseAndValidateMilliseconds(root[kMaxDelay], &(out->max_delay))) { + !json::ParseAndValidateInt(root[kMaxBitRate], &(out->max_bit_rate))) { return false; } + + std::chrono::milliseconds max_delay; + if (json::ParseAndValidateMilliseconds(root[kMaxDelay], &max_delay)) { + out->max_delay = max_delay; + } + if (!json::ParseAndValidateInt(root[kMinBitRate], &(out->min_bit_rate))) { out->min_bit_rate = kDefaultAudioMinBitRate; } @@ -227,7 +232,9 @@ Json::Value AudioConstraints::ToJson() const { root[kMaxChannels] = max_channels; root[kMinBitRate] = min_bit_rate; root[kMaxBitRate] = max_bit_rate; - root[kMaxDelay] = Json::Value::Int64(max_delay.count()); + if (max_delay.has_value()) { + root[kMaxDelay] = Json::Value::Int64(max_delay->count()); + } return root; } @@ -262,16 +269,25 @@ Json::Value Dimensions::ToJson() const { // static bool VideoConstraints::ParseAndValidate(const Json::Value& root, VideoConstraints* out) { - if (!json::ParseAndValidateDouble(root[kMaxPixelsPerSecond], - &(out->max_pixels_per_second)) || - !Dimensions::ParseAndValidate(root[kMaxDimensions], + if (!Dimensions::ParseAndValidate(root[kMaxDimensions], &(out->max_dimensions)) || !json::ParseAndValidateInt(root[kMaxBitRate], &(out->max_bit_rate)) || - !json::ParseAndValidateMilliseconds(root[kMaxDelay], &(out->max_delay)) || !ParseOptional<Dimensions>(root[kMinDimensions], &(out->min_dimensions))) { return false; } + + std::chrono::milliseconds max_delay; + if (json::ParseAndValidateMilliseconds(root[kMaxDelay], &max_delay)) { + out->max_delay = max_delay; + } + + double max_pixels_per_second; + if (json::ParseAndValidateDouble(root[kMaxPixelsPerSecond], + &max_pixels_per_second)) { + out->max_pixels_per_second = max_pixels_per_second; + } + if (!json::ParseAndValidateInt(root[kMinBitRate], &(out->min_bit_rate))) { out->min_bit_rate = kDefaultVideoMinBitRate; } @@ -280,7 +296,8 @@ bool VideoConstraints::ParseAndValidate(const Json::Value& root, bool VideoConstraints::IsValid() const { return max_pixels_per_second > 0 && min_bit_rate > 0 && - max_bit_rate > min_bit_rate && max_delay.count() > 0 && + max_bit_rate > min_bit_rate && + (!max_delay.has_value() || max_delay->count() > 0) && max_dimensions.IsValid() && (!min_dimensions.has_value() || min_dimensions->IsValid()) && max_dimensions.frame_rate.numerator > 0; @@ -289,14 +306,20 @@ bool VideoConstraints::IsValid() const { Json::Value VideoConstraints::ToJson() const { OSP_DCHECK(IsValid()); Json::Value root; - root[kMaxPixelsPerSecond] = max_pixels_per_second; - if (min_dimensions.has_value()) { - root[kMinDimensions] = min_dimensions->ToJson(); - } root[kMaxDimensions] = max_dimensions.ToJson(); root[kMinBitRate] = min_bit_rate; root[kMaxBitRate] = max_bit_rate; - root[kMaxDelay] = Json::Value::Int64(max_delay.count()); + if (max_pixels_per_second.has_value()) { + root[kMaxPixelsPerSecond] = max_pixels_per_second.value(); + } + + if (min_dimensions.has_value()) { + root[kMinDimensions] = min_dimensions->ToJson(); + } + + if (max_delay.has_value()) { + root[kMaxDelay] = Json::Value::Int64(max_delay->count()); + } return root; } @@ -346,9 +369,11 @@ bool DisplayDescription::IsValid() const { if (aspect_ratio.has_value() && !aspect_ratio->IsValid()) { return false; } + if (dimensions.has_value() && !dimensions->IsValid()) { return false; } + // Sender behavior is undefined if the aspect ratio is fixed but no // dimensions or aspect ratio are provided. if (aspect_ratio_constraint.has_value() && diff --git a/cast/streaming/answer_messages.h b/cast/streaming/answer_messages.h index 4298913b..1f62706a 100644 --- a/cast/streaming/answer_messages.h +++ b/cast/streaming/answer_messages.h @@ -41,10 +41,9 @@ struct AudioConstraints { int max_sample_rate = 0; int max_channels = 0; - // Technically optional, sender will assume 32kbps if omitted. - int min_bit_rate = 0; + int min_bit_rate = 0; // optional int max_bit_rate = 0; - std::chrono::milliseconds max_delay = {}; + absl::optional<std::chrono::milliseconds> max_delay = {}; }; struct Dimensions { @@ -62,13 +61,12 @@ struct VideoConstraints { Json::Value ToJson() const; bool IsValid() const; - double max_pixels_per_second = {}; + absl::optional<double> max_pixels_per_second = {}; absl::optional<Dimensions> min_dimensions = {}; Dimensions max_dimensions = {}; - // Technically optional, sender will assume 300kbps if omitted. - int min_bit_rate = 0; + int min_bit_rate = 0; // optional int max_bit_rate = 0; - std::chrono::milliseconds max_delay = {}; + absl::optional<std::chrono::milliseconds> max_delay = {}; }; struct Constraints { diff --git a/cast/streaming/capture_recommendations.cc b/cast/streaming/capture_recommendations.cc index 94ac47de..b30b5dc1 100644 --- a/cast/streaming/capture_recommendations.cc +++ b/cast/streaming/capture_recommendations.cc @@ -83,7 +83,9 @@ void ApplyConstraints(const Constraints& constraints, Recommendations* recommendations) { // Audio has no fields in the display description, so we can safely // ignore the current recommendations when setting values here. - recommendations->audio.max_delay = constraints.audio.max_delay; + if (constraints.audio.max_delay.has_value()) { + recommendations->audio.max_delay = constraints.audio.max_delay.value(); + } recommendations->audio.max_channels = constraints.audio.max_channels; recommendations->audio.max_sample_rate = constraints.audio.max_sample_rate; @@ -93,9 +95,15 @@ void ApplyConstraints(const Constraints& constraints, // With video, we take the intersection of values of the constraints and // the display description. - recommendations->video.max_delay = constraints.video.max_delay; - recommendations->video.max_pixels_per_second = - constraints.video.max_pixels_per_second; + if (constraints.video.max_delay.has_value()) { + recommendations->video.max_delay = constraints.video.max_delay.value(); + } + + if (constraints.video.max_pixels_per_second.has_value()) { + recommendations->video.max_pixels_per_second = + constraints.video.max_pixels_per_second.value(); + } + recommendations->video.bit_rate_limits = BitRateLimits{std::max(constraints.video.min_bit_rate, recommendations->video.bit_rate_limits.minimum), diff --git a/cast/streaming/capture_recommendations.h b/cast/streaming/capture_recommendations.h index 94855c7c..ccb2475b 100644 --- a/cast/streaming/capture_recommendations.h +++ b/cast/streaming/capture_recommendations.h @@ -29,7 +29,7 @@ namespace capture_recommendations { // Default maximum delay for both audio and video. Used if the sender fails // to provide any constraints. -constexpr std::chrono::milliseconds kDefaultMaxDelayMs(4000); +constexpr std::chrono::milliseconds kDefaultMaxDelayMs(400); // Bit rate limits, used for both audio and video streams. struct BitRateLimits { diff --git a/cast/streaming/capture_recommendations_unittest.cc b/cast/streaming/capture_recommendations_unittest.cc index 8e9765af..4f76b9d9 100644 --- a/cast/streaming/capture_recommendations_unittest.cc +++ b/cast/streaming/capture_recommendations_unittest.cc @@ -16,9 +16,9 @@ namespace capture_recommendations { namespace { constexpr Recommendations kDefaultRecommendations{ - Audio{BitRateLimits{32000, 256000}, milliseconds(4000), 2, 48000, 16000}, + Audio{BitRateLimits{32000, 256000}, milliseconds(400), 2, 48000, 16000}, Video{BitRateLimits{300000, 1920 * 1080 * 30}, Resolution{320, 240, 30}, - Resolution{1920, 1080, 30}, false, milliseconds(4000), + Resolution{1920, 1080, 30}, false, milliseconds(400), 1920 * 1080 * 30 / 8}}; constexpr DisplayDescription kEmptyDescription{}; |