aboutsummaryrefslogtreecommitdiff
path: root/cast/streaming/answer_messages.h
blob: 1f62706a1a84e1cb847c2f4f06c171e34d20f843 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CAST_STREAMING_ANSWER_MESSAGES_H_
#define CAST_STREAMING_ANSWER_MESSAGES_H_

#include <array>
#include <chrono>
#include <cstdint>
#include <initializer_list>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/types/optional.h"
#include "cast/streaming/ssrc.h"
#include "json/value.h"
#include "platform/base/error.h"
#include "util/simple_fraction.h"

namespace openscreen {
namespace cast {

// For each of the below classes, though a number of methods are shared, the use
// of a shared base class has intentionally been avoided. This is to improve
// readability of the structs provided in this file by cutting down on the
// amount of obscuring boilerplate code. For each of the following struct
// definitions, the following method definitions are shared:
// (1) ParseAndValidate. Shall return a boolean indicating whether the out
//     parameter is in a valid state after checking bounds and restrictions.
// (2) ToJson. Should return a proper JSON object. Assumes that IsValid()
//     has been called already, OSP_DCHECKs if not IsValid().
// (3) IsValid. Used by both ParseAndValidate and ToJson to ensure that the
//     object is in a good state.
struct AudioConstraints {
  static bool ParseAndValidate(const Json::Value& value, AudioConstraints* out);
  Json::Value ToJson() const;
  bool IsValid() const;

  int max_sample_rate = 0;
  int max_channels = 0;
  int min_bit_rate = 0;  // optional
  int max_bit_rate = 0;
  absl::optional<std::chrono::milliseconds> max_delay = {};
};

struct Dimensions {
  static bool ParseAndValidate(const Json::Value& value, Dimensions* out);
  Json::Value ToJson() const;
  bool IsValid() const;

  int width = 0;
  int height = 0;
  SimpleFraction frame_rate;
};

struct VideoConstraints {
  static bool ParseAndValidate(const Json::Value& value, VideoConstraints* out);
  Json::Value ToJson() const;
  bool IsValid() const;

  absl::optional<double> max_pixels_per_second = {};
  absl::optional<Dimensions> min_dimensions = {};
  Dimensions max_dimensions = {};
  int min_bit_rate = 0;  // optional
  int max_bit_rate = 0;
  absl::optional<std::chrono::milliseconds> max_delay = {};
};

struct Constraints {
  static bool ParseAndValidate(const Json::Value& value, Constraints* out);
  Json::Value ToJson() const;
  bool IsValid() const;

  AudioConstraints audio;
  VideoConstraints video;
};

// Decides whether the Sender scales and letterboxes content to 16:9, or if
// it may send video frames of any arbitrary size and the Receiver must
// handle the presentation details.
enum class AspectRatioConstraint : uint8_t { kVariable = 0, kFixed };

struct AspectRatio {
  static bool ParseAndValidate(const Json::Value& value, AspectRatio* out);
  bool IsValid() const;

  bool operator==(const AspectRatio& other) const {
    return width == other.width && height == other.height;
  }

  int width = 0;
  int height = 0;
};

struct DisplayDescription {
  static bool ParseAndValidate(const Json::Value& value,
                               DisplayDescription* out);
  Json::Value ToJson() const;
  bool IsValid() const;

  // May exceed, be the same, or less than those mentioned in the
  // video constraints.
  absl::optional<Dimensions> dimensions;
  absl::optional<AspectRatio> aspect_ratio = {};
  absl::optional<AspectRatioConstraint> aspect_ratio_constraint = {};
};

struct Answer {
  static bool ParseAndValidate(const Json::Value& value, Answer* out);
  Json::Value ToJson() const;
  bool IsValid() const;

  int udp_port = 0;
  std::vector<int> send_indexes;
  std::vector<Ssrc> ssrcs;

  // Constraints and display descriptions are optional fields, and maybe null in
  // the valid case.
  absl::optional<Constraints> constraints;
  absl::optional<DisplayDescription> display;
  std::vector<int> receiver_rtcp_event_log;
  std::vector<int> receiver_rtcp_dscp;
  bool supports_wifi_status_reporting = false;

  // RTP extensions should be empty, but not null.
  std::vector<std::string> rtp_extensions = {};
};

}  // namespace cast
}  // namespace openscreen

#endif  // CAST_STREAMING_ANSWER_MESSAGES_H_