StreamManager refactoring
[platform/core/ml/aitt.git] / modules / webrtc / WebRtcStream.cc
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "WebRtcStream.h"
18
19 #include "WebRtcMessage.h"
20 #include "aitt_internal.h"
21
22 namespace AittWebRTCNamespace {
23
24 WebRtcStream::WebRtcStream() : webrtc_handle_(nullptr), channel_(nullptr), source_id_(0)
25 {
26 }
27
28 WebRtcStream::~WebRtcStream()
29 {
30     Destroy();
31     DBG("%s", __func__);
32 }
33
34 bool WebRtcStream::Create(bool is_source, bool need_display)
35 {
36     if (webrtc_handle_) {
37         ERR("Already created %p", webrtc_handle_);
38         return false;
39     }
40
41     auto ret = webrtc_create(&webrtc_handle_);
42     if (ret != WEBRTC_ERROR_NONE) {
43         ERR("Failed to create webrtc handle");
44         return false;
45     }
46
47     if (!is_source) {
48         auto add_source_ret =
49               webrtc_add_media_source(webrtc_handle_, WEBRTC_MEDIA_SOURCE_TYPE_NULL, &source_id_);
50         if (add_source_ret != WEBRTC_ERROR_NONE)
51             ERR("Failed to add media source");
52         auto set_transceiver_codec_ret = webrtc_media_source_set_transceiver_codec(webrtc_handle_,
53               source_id_, WEBRTC_MEDIA_TYPE_VIDEO, WEBRTC_TRANSCEIVER_CODEC_VP8);
54         if (set_transceiver_codec_ret != WEBRTC_ERROR_NONE)
55             ERR("Failed to set transceiver codec");
56     }
57
58     webrtc_create_data_channel(webrtc_handle_, "label", nullptr, &channel_);
59     AttachSignals(is_source, need_display);
60
61     return true;
62 }
63
64 void WebRtcStream::Destroy(void)
65 {
66     if (!webrtc_handle_) {
67         ERR("WebRTC handle is not created");
68         return;
69     }
70     auto stop_ret = webrtc_stop(webrtc_handle_);
71     if (stop_ret != WEBRTC_ERROR_NONE)
72         ERR("Failed to stop webrtc handle");
73
74     DetachSignals();
75     auto destroy_channel_ret = webrtc_destroy_data_channel(channel_);
76     if (destroy_channel_ret != WEBRTC_ERROR_NONE)
77         ERR("Failed to destroy webrtc channel");
78     auto ret = webrtc_destroy(webrtc_handle_);
79     if (ret != WEBRTC_ERROR_NONE)
80         ERR("Failed to destroy webrtc handle");
81     webrtc_handle_ = nullptr;
82
83     // TODO what should be initialized?
84 }
85
86 bool WebRtcStream::Start(void)
87 {
88     if (!webrtc_handle_) {
89         ERR("WebRTC handle is not created");
90         return false;
91     }
92
93     auto ret = webrtc_start(webrtc_handle_);
94     if (ret != WEBRTC_ERROR_NONE)
95         ERR("Failed to start webrtc handle");
96
97     return ret == WEBRTC_ERROR_NONE;
98 }
99
100 bool WebRtcStream::Stop(void)
101 {
102     if (!webrtc_handle_) {
103         ERR("WebRTC handle is not created");
104         return false;
105     }
106
107     auto ret = webrtc_stop(webrtc_handle_);
108     if (ret != WEBRTC_ERROR_NONE)
109         ERR("Failed to stop webrtc handle");
110
111     // TODO what should be initialized?
112     return ret == WEBRTC_ERROR_NONE;
113 }
114
115 bool WebRtcStream::AttachCameraSource(void)
116 {
117     if (!webrtc_handle_) {
118         ERR("WebRTC handle is not created");
119         return false;
120     }
121
122     if (source_id_) {
123         ERR("source already attached");
124         return false;
125     }
126
127     auto ret =
128           webrtc_add_media_source(webrtc_handle_, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA, &source_id_);
129     if (ret != WEBRTC_ERROR_NONE)
130         ERR("Failed to add media source");
131
132     return ret == WEBRTC_ERROR_NONE;
133 }
134
135 bool WebRtcStream::DetachCameraSource(void)
136 {
137     if (!webrtc_handle_) {
138         ERR("WebRTC handle is not created");
139         return false;
140     }
141
142     if (!source_id_) {
143         ERR("Camera source is not attached");
144         return false;
145     }
146
147     auto ret = webrtc_remove_media_source(webrtc_handle_, source_id_);
148     if (ret != WEBRTC_ERROR_NONE)
149         ERR("Failed to remove media source");
150
151     return ret == WEBRTC_ERROR_NONE;
152 }
153
154 bool WebRtcStream::CreateOfferAsync(std::function<void(std::string)> on_created_cb)
155 {
156     if (!webrtc_handle_) {
157         ERR("WebRTC handle is not created");
158         return false;
159     }
160     on_offer_created_cb_ = on_created_cb;
161     auto ret = webrtc_create_offer_async(webrtc_handle_, NULL, OnOfferCreated, this);
162     if (ret != WEBRTC_ERROR_NONE)
163         ERR("Failed to create offer async");
164
165     return ret == WEBRTC_ERROR_NONE;
166 }
167
168 void WebRtcStream::OnOfferCreated(webrtc_h webrtc, const char *description, void *user_data)
169 {
170     RET_IF(!user_data);
171
172     WebRtcStream *webrtc_stream = static_cast<WebRtcStream *>(user_data);
173
174     if (webrtc_stream->on_offer_created_cb_)
175         webrtc_stream->on_offer_created_cb_(std::string(description));
176 }
177
178 bool WebRtcStream::CreateAnswerAsync(std::function<void(std::string)> on_created_cb)
179 {
180     if (!webrtc_handle_) {
181         ERR("WebRTC handle is not created");
182         return false;
183     }
184     on_answer_created_cb_ = on_created_cb;
185     auto ret = webrtc_create_answer_async(webrtc_handle_, NULL, OnAnswerCreated, this);
186     if (ret != WEBRTC_ERROR_NONE)
187         ERR("Failed to create answer async");
188
189     return ret == WEBRTC_ERROR_NONE;
190 }
191
192 void WebRtcStream::OnAnswerCreated(webrtc_h webrtc, const char *description, void *user_data)
193 {
194     if (!user_data)
195         return;
196
197     WebRtcStream *webrtc_stream = static_cast<WebRtcStream *>(user_data);
198     if (webrtc_stream->on_answer_created_cb_)
199         webrtc_stream->on_answer_created_cb_(std::string(description));
200 }
201
202 bool WebRtcStream::SetLocalDescription(const std::string &description)
203 {
204     if (!webrtc_handle_) {
205         ERR("WebRTC handle is not created");
206         return false;
207     }
208
209     auto ret = webrtc_set_local_description(webrtc_handle_, description.c_str());
210     if (ret != WEBRTC_ERROR_NONE)
211         ERR("Failed to set local description");
212     else
213         local_description_ = description;
214
215     return ret == WEBRTC_ERROR_NONE;
216 }
217
218 bool WebRtcStream::SetRemoteDescription(const std::string &description)
219 {
220     if (!webrtc_handle_) {
221         ERR("WebRTC handle is not created");
222         return false;
223     }
224
225     auto ret = webrtc_set_remote_description(webrtc_handle_, description.c_str());
226     if (ret != WEBRTC_ERROR_NONE)
227         ERR("Failed to set remote description");
228
229     return ret == WEBRTC_ERROR_NONE;
230 }
231
232 void WebRtcStream::SetStreamId(const std::string &id)
233 {
234     id_ = id;
235 }
236
237 std::string WebRtcStream::GetStreamId(void) const
238 {
239     return id_;
240 }
241
242 void WebRtcStream::SetPeerId(const std::string &id)
243 {
244     peer_id_ = id;
245 }
246
247 std::string &WebRtcStream::GetPeerId(void)
248 {
249     return peer_id_;
250 }
251
252 bool WebRtcStream::AddIceCandidateFromMessage(const std::string &ice_message)
253 {
254     ERR("%s", __func__);
255     if (!webrtc_handle_) {
256         ERR("WebRTC handle is not created");
257         return false;
258     }
259     auto ret = webrtc_add_ice_candidate(webrtc_handle_, ice_message.c_str());
260     if (ret != WEBRTC_ERROR_NONE)
261         ERR("Failed to set add ice candidate");
262
263     return ret == WEBRTC_ERROR_NONE;
264 }
265
266 bool WebRtcStream::AddPeerInformation(const std::string &sdp,
267       const std::vector<std::string> &ice_candidates)
268 {
269     remote_description_ = sdp;
270     peer_ice_candidates_ = ice_candidates;
271     if (!IsNegotiatingState()) {
272         DBG("Not negotiable");
273         return false;
274     }
275     return SetPeerInformation();
276 }
277
278 void WebRtcStream::UpdatePeerInformation(const std::vector<std::string> &ice_candidates)
279 {
280     if (IsPlayingState()) {
281         remote_description_.clear();
282         peer_ice_candidates_.clear();
283         stored_peer_ice_candidates_.clear();
284         DBG("Now Playing");
285         return;
286     }
287
288     peer_ice_candidates_ = ice_candidates;
289     if (!IsNegotiatingState()) {
290         DBG("Not negotiable");
291         return;
292     }
293
294     SetPeerInformation();
295     return;
296 }
297
298 bool WebRtcStream::IsNegotiatingState(void)
299 {
300     webrtc_state_e state;
301     auto get_state_ret = webrtc_get_state(webrtc_handle_, &state);
302     if (get_state_ret != WEBRTC_ERROR_NONE) {
303         ERR("Failed to get state");
304         return false;
305     }
306
307     return state == WEBRTC_STATE_NEGOTIATING;
308 }
309
310 bool WebRtcStream::IsPlayingState(void)
311 {
312     webrtc_state_e state;
313     auto get_state_ret = webrtc_get_state(webrtc_handle_, &state);
314     if (get_state_ret != WEBRTC_ERROR_NONE) {
315         ERR("Failed to get state");
316         return false;
317     }
318
319     return state == WEBRTC_STATE_PLAYING;
320 }
321
322 bool WebRtcStream::SetPeerInformation(void)
323 {
324     bool res = true;
325
326     res = SetPeerSDP() && SetPeerIceCandidates();
327     DBG("Peer information is now %s", res ? "Valid" : "Invalid");
328
329     return res;
330 }
331 bool WebRtcStream::SetPeerSDP(void)
332 {
333     ERR("%s", __func__);
334     bool res = true;
335     if (remote_description_.size() == 0) {
336         DBG("Peer SDP empty");
337         return res;
338     }
339
340     if (SetRemoteDescription(remote_description_))
341         remote_description_.clear();
342     else
343         res = false;
344
345     return res;
346 }
347
348 bool WebRtcStream::SetPeerIceCandidates(void)
349 {
350     ERR("%s", __func__);
351     bool res{true};
352     for (auto itr = peer_ice_candidates_.begin(); itr != peer_ice_candidates_.end(); ++itr) {
353         if (IsRedundantCandidate(*itr))
354             continue;
355
356         if (AddIceCandidateFromMessage(*itr))
357             stored_peer_ice_candidates_.push_back(*itr);
358         else
359             res = false;
360     }
361
362     return res;
363 }
364
365 bool WebRtcStream::IsRedundantCandidate(const std::string &candidate)
366 {
367     for (const auto &stored_ice_candidate : stored_peer_ice_candidates_) {
368         if (stored_ice_candidate.compare(candidate) == 0)
369             return true;
370     }
371     return false;
372 }
373
374 void WebRtcStream::AttachSignals(bool is_source, bool need_display)
375 {
376     if (!webrtc_handle_) {
377         ERR("WebRTC handle is not created");
378         return;
379     }
380
381     int ret = WEBRTC_ERROR_NONE;
382     // TODO: ADHOC TV profile doesn't show DBG level log
383     ret = webrtc_set_error_cb(webrtc_handle_, OnError, this);
384     DBG("webrtc_set_error_cb %s", ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
385     ret = webrtc_set_state_changed_cb(webrtc_handle_, OnStateChanged, this);
386     DBG("webrtc_set_state_changed_cb %s", ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
387     ret = webrtc_set_signaling_state_change_cb(webrtc_handle_, OnSignalingStateChanged, this);
388     DBG("webrtc_set_signaling_state_change_cb %s",
389           ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
390     ret = webrtc_set_ice_gathering_state_change_cb(webrtc_handle_, OnIceGatheringStateChanged,
391           this);
392     DBG("webrtc_set_ice_gathering_state_change_cb %s",
393           ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
394     ret = webrtc_set_ice_connection_state_change_cb(webrtc_handle_, OnIceConnectionStateChanged,
395           this);
396     DBG("webrtc_set_ice_connection_state_change_cb %s",
397           ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
398     ret = webrtc_set_ice_candidate_cb(webrtc_handle_, OnIceCandiate, this);
399     DBG("webrtc_set_ice_candidate_cb %s", ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
400
401     if (!is_source && !need_display) {
402         ret = webrtc_set_encoded_video_frame_cb(webrtc_handle_, OnEncodedFrame, this);
403         ERR("webrtc_set_encoded_video_frame_cb %s",
404               ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
405     }
406
407     if (!is_source && need_display) {
408         ret = webrtc_set_track_added_cb(webrtc_handle_, OnTrackAdded, this);
409         ERR("webrtc_set_track_added_cb %s", ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
410     }
411     ret = webrtc_data_channel_set_open_cb(channel_, OnDataChannelOpen, this);
412     DBG("webrtc_data_channel_set_open_cb %s", ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
413
414     return;
415 }
416
417 void WebRtcStream::DetachSignals(void)
418 {
419     if (!webrtc_handle_) {
420         ERR("WebRTC handle is not created");
421         return;
422     }
423
424     webrtc_unset_error_cb(webrtc_handle_);
425     webrtc_unset_state_changed_cb(webrtc_handle_);
426     webrtc_unset_signaling_state_change_cb(webrtc_handle_);
427     webrtc_unset_ice_gathering_state_change_cb(webrtc_handle_);
428     webrtc_unset_ice_connection_state_change_cb(webrtc_handle_);
429     webrtc_unset_ice_candidate_cb(webrtc_handle_);
430     webrtc_unset_encoded_video_frame_cb(webrtc_handle_);
431     webrtc_unset_track_added_cb(webrtc_handle_);
432     webrtc_data_channel_unset_open_cb(channel_);
433 }
434
435 WebRtcEventHandler &WebRtcStream::GetEventHandler(void)
436 {
437     return event_handler_;
438 }
439
440 void WebRtcStream::OnError(webrtc_h webrtc, webrtc_error_e error, webrtc_state_e state,
441       void *user_data)
442 {
443     // TODO
444     ERR("%s", __func__);
445 }
446
447 void WebRtcStream::OnStateChanged(webrtc_h webrtc, webrtc_state_e previous, webrtc_state_e current,
448       void *user_data)
449 {
450     ERR("%s", __func__);
451     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
452     RET_IF(webrtc_stream == nullptr);
453
454     if (current == WEBRTC_STATE_NEGOTIATING)
455         webrtc_stream->SetPeerSDP();
456
457     webrtc_stream->GetEventHandler().CallOnStateChangedCb(WebRtcState::ToStreamState(current));
458 }
459
460 void WebRtcStream::OnSignalingStateChanged(webrtc_h webrtc, webrtc_signaling_state_e state,
461       void *user_data)
462 {
463     ERR("%s", __func__);
464     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
465     RET_IF(webrtc_stream == nullptr);
466     webrtc_stream->GetEventHandler().CallOnSignalingStateNotifyCb(
467           WebRtcState::ToSignalingState(state));
468 }
469
470 void WebRtcStream::OnIceGatheringStateChanged(webrtc_h webrtc, webrtc_ice_gathering_state_e state,
471       void *user_data)
472 {
473     ERR("%s %d", __func__, state);
474     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
475     RET_IF(webrtc_stream == nullptr);
476
477     if (state == WEBRTC_ICE_GATHERING_STATE_COMPLETE)
478         webrtc_stream->SetPeerIceCandidates();
479
480     webrtc_stream->GetEventHandler().CallOnIceGatheringStateNotifyCb(
481           WebRtcState::ToIceGatheringState(state));
482 }
483
484 void WebRtcStream::OnIceConnectionStateChanged(webrtc_h webrtc, webrtc_ice_connection_state_e state,
485       void *user_data)
486 {
487     ERR("%s %d", __func__, state);
488     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
489     RET_IF(webrtc_stream == nullptr);
490
491     webrtc_stream->GetEventHandler().CallOnIceConnectionStateNotifyCb(
492           WebRtcState::ToIceConnectionState(state));
493 }
494
495 void WebRtcStream::OnIceCandiate(webrtc_h webrtc, const char *candidate, void *user_data)
496 {
497     ERR("%s", __func__);
498     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
499     webrtc_stream->ice_candidates_.push_back(candidate);
500     webrtc_stream->GetEventHandler().CallOnIceCandidateCb(candidate);
501 }
502
503 void WebRtcStream::OnEncodedFrame(webrtc_h webrtc, webrtc_media_type_e type, unsigned int track_id,
504       media_packet_h packet, void *user_data)
505 {
506     ERR("%s", __func__);
507     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
508     RET_IF(webrtc_stream == nullptr);
509
510     if (type == WEBRTC_MEDIA_TYPE_VIDEO)
511         webrtc_stream->GetEventHandler().CallOnEncodedFrameCb();
512 }
513
514 void WebRtcStream::OnTrackAdded(webrtc_h webrtc, webrtc_media_type_e type, unsigned int id,
515       void *user_data)
516 {
517     // type AUDIO(0), VIDEO(1)
518     INFO("Added Track : id(%d), type(%s)", id, type ? "Video" : "Audio");
519
520     ERR("%s", __func__);
521     auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
522     RET_IF(webrtc_stream == nullptr);
523
524     if (type == WEBRTC_MEDIA_TYPE_VIDEO)
525         webrtc_stream->GetEventHandler().CallOnTrakAddedCb(id);
526 }
527
528 void WebRtcStream::OnDataChannelOpen(webrtc_data_channel_h channel, void *user_data)
529 {
530     ERR("%s", __func__);
531 }
532
533 }  // namespace AittWebRTCNamespace