Agora Java API Reference for Android
video_track_i.h
1 //
2 // Agora Media SDK
3 //
4 // Created by Rao Qi in 2019.
5 // Copyright (c) 2019 Agora IO. All rights reserved.
6 //
7 #pragma once
8 
9 #include <atomic>
10 #include <memory>
11 #include <mutex>
12 #include <unordered_map>
13 #include <vector>
14 
15 #include "AgoraBase.h"
16 #include "NGIAgoraVideoTrack.h"
17 #include "call/rtp_config.h"
18 
19 #include "rtc_connection_i.h"
20 #include "track_stat_i.h"
21 #include "video_config_i.h"
22 #include "common_defines.h"
23 #include "video_node_i.h"
24 
25 namespace agora {
26 namespace utils {
27 
28 enum ConfigPriority {
29  // configurations for debugging, which can overwrite anything
30  // usually used by dev/lab tuning
31  CONFIG_PRIORITY_DEBUG = 0,
32  // configurations from device capability detection
33  CONFIG_PRIORITY_DEVICE,
34  // configurations for emergency, this will overwrite user configuration.
35  // for cases like "close XXX feature immediately otherwise terrible things happen"
36  // do not use this priority level unless review board approved
37  CONFIG_PRIORITY_HIGH_FROM_SERVER,
38  // configurations from lua script
39  CONFIG_PRIORITY_LUA,
40  // configurations from user setting
41  CONFIG_PRIORITY_USER,
42  // configurations from "config service".
43  CONFIG_PRIORITY_NORMAL_FROM_SERVER,
44  // configurations from internal (usually it's default value)
45  CONFIG_PRIORITY_INTERNAL,
46  CONFIG_PRIORITY_MAX
47 };
48 
49 template <typename Observer>
51  public:
52  WeakObservers() = default;
53  ~WeakObservers() = default;
54 
55  bool add(std::shared_ptr<Observer> obs) {
56  if (!obs) {
57  return false;
58  }
59 
60  std::lock_guard<std::mutex> _(obs_mutex_);
61  observer_map_[obs.get()] = obs;
62  return true;
63  }
64 
65  int size() {
66  std::lock_guard<std::mutex> _(obs_mutex_);
67  return observer_map_.size();
68  }
69 
70  // better to remove by raw pointer since we may unregister() -> remove() in DTOR
71  bool remove(Observer* obs) {
72  if (!obs) {
73  return false;
74  }
75 
76  std::lock_guard<std::mutex> _(obs_mutex_);
77  if (observer_map_.find(obs) == observer_map_.end()) {
78  return false;
79  }
80 
81  observer_map_.erase(obs);
82  return true;
83  }
84 
85  void notify(std::function<void (std::shared_ptr<Observer>)>&& notify) {
86  std::vector<std::shared_ptr<Observer>> obs_copy;
87 
88  {
89  std::lock_guard<std::mutex> _(obs_mutex_);
90 
91  for (auto it = observer_map_.begin(); it != observer_map_.end();) {
92  auto obs_shared = it->second.lock();
93  if (!obs_shared) {
94  it = observer_map_.erase(it);
95  continue;
96  }
97 
98  obs_copy.push_back(obs_shared);
99  ++it;
100  }
101  }
102 
103  for (auto obs : obs_copy) {
104  notify(obs);
105  }
106  }
107 
108  private:
109  std::mutex obs_mutex_;
110  std::unordered_map<Observer*, std::weak_ptr<Observer>> observer_map_;
111 };
112 
113 } // namespace utils
114 
115 namespace rtc {
116 
117 class VideoNodeRtpSink;
118 class VideoNodeRtpSource;
119 class VideoTrackConfigurator;
120 
121 enum class InternalVideoSourceType : unsigned {
122  None = 0,
123  Camera = 1,
124  // Not used in NG SDK
125  Custom = 2,
126  Screen = 3,
127  CustomYuvSource = 4,
128  CustomEncodedImageSource = 5,
129  CustomPacketSource = 6,
130  MixedSource = 7,
131  TranscodedSource = 8,
132 };
133 
134 class IVideoTrackObserver : public std::enable_shared_from_this<IVideoTrackObserver> {
135  public:
136  virtual ~IVideoTrackObserver() = default;
137  virtual void onLocalVideoStateChanged(int id,
138  LOCAL_VIDEO_STREAM_STATE state,
139  LOCAL_VIDEO_STREAM_ERROR errorCode,
140  int timestamp_ms) {}
141 
142  virtual void onRemoteVideoStateChanged(uid_t uid,
143  REMOTE_VIDEO_STATE state,
144  REMOTE_VIDEO_STATE_REASON reason,
145  int timestamp_ms) {}
146 
147  virtual void onFirstVideoFrameRendered(uid_t uid, int width, int height, int timestamp_ms) {}
148 
149  virtual void onFirstVideoFrameDecoded(uid_t uid, int width, int height, int timestamp_ms) {}
150 
151  virtual void onSourceVideoSizeChanged(uid_t uid,
152  int width, int height,
153  int rotation, int timestamp_ms) {}
154  virtual void onSendSideDelay(int id, int send_delay) {}
155  virtual void onRecvSideDelay(uid_t uid, int recv_delay) {}
156  virtual void onRecvSideFps(uid_t uid, int fps) {}
157  virtual void onSetVideoEncoderConfiguration(int width, int height, int fps, int framerate) {}
158 };
159 
161  public:
162  enum DetachReason { MANUAL, TRACK_DESTROY, NETWORK_DESTROY };
163 
164  // keep the same as webrtc::RsfecConfig
165  struct RsfecConfig {
166  std::vector<int> fec_protection_factor;
167  std::vector<std::vector<int>> fec_ratioLevel;
168  std::vector<int> fec_rttThreshold;
169  bool pec_enabled;
170  };
171 
173  bool QuickAdaptNetwork;
174  int MinFramerate;
175  int MinHoldtimeAutoResizeZoomin;
176  int MinHoldtimeAutoResizeZoomout;
177  int QpAdjust;
178  int IosH265Adjust;
179  };
180 
181  struct AttachInfo {
182  uint32_t uid;
183  uint32_t cid;
184  VideoNodeRtpSink* network;
185  WeakPipelineBuilder builder;
186  uint64_t stats_space;
187  CongestionControlType cc_type;
188  bool enable_two_bytes_extension;
189  webrtc::FecConfig fec_config;
190 
191  //hardware encoder related
192  std::string enable_hw_encoder;
193  std::string hw_encoder_provider;
194 
195  //video config
196  VQCParametersCollection vqc_parameters;
197 
198  int fec_method;
199  int dm_wsize;
200  int32_t dmfec_minimum_level;
201  };
202 
203  struct DetachInfo {
204  VideoNodeRtpSink* network;
205  DetachReason reason;
206  };
207 
208  ILocalVideoTrackEx() : id_(id_generator_++) {}
209  virtual ~ILocalVideoTrackEx() {}
210 
211  virtual bool hasPublished() = 0;
212 
213  virtual int SetVideoConfigEx(const VideoConfigurationEx& configEx, utils::ConfigPriority priority = utils::CONFIG_PRIORITY_USER) = 0;
214 
215  virtual int GetConfigExs(std::vector<VideoConfigurationEx>& configs) = 0;
216 
217  virtual int setUserId(uid_t uid) { user_id_ = uid; return 0; }
218 
219  virtual uid_t getUserId() { return user_id_; }
220 
221  virtual int getObserverSize() { return track_observers_.size(); }
222 
223  virtual int GetActiveStreamsCount() = 0;
224 
225  virtual int prepareNodes() = 0;
226 
227  virtual bool attach(const AttachInfo& info) = 0;
228  virtual bool detach(const DetachInfo& info) = 0;
229 
230  virtual bool registerTrackObserver(std::shared_ptr<IVideoTrackObserver> observer) {
231  return false;
232  }
233  virtual bool unregisterTrackObserver(IVideoTrackObserver* observer) {
234  return false;
235  }
236 
237  virtual int32_t Width() const = 0;
238  virtual int32_t Height() const = 0;
239  virtual bool Enabled() const = 0;
240  // TODO(Qingyou Pan): Need refine code to remove this interface.
241  virtual int addVideoWatermark(const char* watermarkUrl, const WatermarkOptions& options) { return -ERR_NOT_SUPPORTED; };
242  virtual int clearVideoWatermarks() { return -ERR_NOT_SUPPORTED; }
243 
244  virtual VideoTrackConfigurator* GetVideoTrackConfigurator() {
245  return nullptr;
246  }
247 
248  virtual InternalVideoSourceType getInternalVideoSourceType() { return InternalVideoSourceType::None; }
249 
250  int TrackId() const { return id_; }
251 
252  public:
253  static void resetIdGenerator();
254 
255  protected:
256  int id_;
257  utils::WeakObservers<IVideoTrackObserver> track_observers_;
258  uid_t user_id_;
259 
260  private:
261  static std::atomic<int> id_generator_;
262 };
263 
265  uint64_t firstDecodingTimeTickMs = 0;
266  uint64_t firstVideoFrameRendered = 0;
267  bool isHardwareCodec = false;
268 };
269 
271  public:
272  enum DetachReason { MANUAL, TRACK_DESTROY, NETWORK_DESTROY };
273  using RemoteVideoEvents = StateEvents<REMOTE_VIDEO_STATE, REMOTE_VIDEO_STATE_REASON>;
274 
275  struct AttachInfo {
276  VideoNodeRtpSource* source;
277  VideoNodeRtpSink* rtcp_sender;
278  WeakPipelineBuilder builder;
279  bool recv_media_packet = false;
280  uint64_t stats_space = 0;
281  };
282 
283  struct DetachInfo {
284  VideoNodeRtpSource* source;
285  VideoNodeRtpSink* rtcp_sender;
286  DetachReason reason;
287  };
288 
289  IRemoteVideoTrackEx() = default;
290 
291  virtual ~IRemoteVideoTrackEx() {}
292 
293  virtual uint32_t getRemoteSsrc() = 0;
294 
295  virtual bool attach(const AttachInfo& info, REMOTE_VIDEO_STATE_REASON reason) = 0;
296  virtual bool detach(const DetachInfo& info, REMOTE_VIDEO_STATE_REASON reason) = 0;
297 
298  virtual bool getStatisticsEx(RemoteVideoTrackStatsEx& statsex) { return false; }
299 
300  virtual bool registerTrackObserver(std::shared_ptr<IVideoTrackObserver> observer) {
301  return false;
302  }
303  virtual bool unregisterTrackObserver(IVideoTrackObserver* observer) {
304  return false;
305  }
306 
307  protected:
308  utils::WeakObservers<IVideoTrackObserver> track_observers_;
309 };
310 
311 } // namespace rtc
312 } // namespace agora
agora::rtc::ILocalVideoTrackEx::VQCParametersCollection
Definition: video_track_i.h:172
agora::rtc::RemoteVideoTrackStatsEx
Definition: video_track_i.h:264
agora::rtc::ILocalVideoTrackEx
Definition: video_track_i.h:160
agora::rtc::IRemoteVideoTrackEx::DetachInfo
Definition: video_track_i.h:283
agora::rtc::IRemoteVideoTrackEx::AttachInfo
Definition: video_track_i.h:275
agora::rtc::ILocalVideoTrackEx::DetachInfo
Definition: video_track_i.h:203
agora::rtc::ILocalVideoTrack
Definition: NGIAgoraVideoTrack.h:234
agora::rtc::IRemoteVideoTrackEx
Definition: video_track_i.h:270
agora::rtc::IRemoteVideoTrack
Definition: NGIAgoraVideoTrack.h:390
agora::rtc::RemoteVideoTrackStats
Definition: NGIAgoraVideoTrack.h:314
agora::rtc::ILocalVideoTrackEx::AttachInfo
Definition: video_track_i.h:181
agora::utils::WeakObservers
Definition: video_track_i.h:50
agora::rtc::IVideoTrackObserver
Definition: video_track_i.h:134
agora::rtc::ILocalVideoTrackEx::RsfecConfig
Definition: video_track_i.h:165