Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #include "CSFLog.h" |
michael@0 | 6 | #include "timecard.h" |
michael@0 | 7 | |
michael@0 | 8 | #include "CC_Common.h" |
michael@0 | 9 | |
michael@0 | 10 | #include "CC_SIPCCCall.h" |
michael@0 | 11 | #include "CC_SIPCCCallInfo.h" |
michael@0 | 12 | #include "VcmSIPCCBinding.h" |
michael@0 | 13 | #include "CSFVideoTermination.h" |
michael@0 | 14 | #include "CSFAudioTermination.h" |
michael@0 | 15 | #include "CSFAudioControl.h" |
michael@0 | 16 | |
michael@0 | 17 | extern "C" |
michael@0 | 18 | { |
michael@0 | 19 | #include "ccapi_call.h" |
michael@0 | 20 | #include "ccapi_call_listener.h" |
michael@0 | 21 | #include "config_api.h" |
michael@0 | 22 | } |
michael@0 | 23 | |
michael@0 | 24 | using namespace std; |
michael@0 | 25 | using namespace CSF; |
michael@0 | 26 | |
michael@0 | 27 | static const char* logTag = "CC_SIPCCCall"; |
michael@0 | 28 | |
michael@0 | 29 | CSF_IMPLEMENT_WRAP(CC_SIPCCCall, cc_call_handle_t); |
michael@0 | 30 | |
michael@0 | 31 | CC_SIPCCCall::CC_SIPCCCall (cc_call_handle_t aCallHandle) : |
michael@0 | 32 | callHandle(aCallHandle), |
michael@0 | 33 | pMediaData(new CC_SIPCCCallMediaData(nullptr, false, false, -1)), |
michael@0 | 34 | m_lock("CC_SIPCCCall") |
michael@0 | 35 | { |
michael@0 | 36 | CSFLogInfo( logTag, "Creating CC_SIPCCCall %u", callHandle ); |
michael@0 | 37 | |
michael@0 | 38 | AudioControl * audioControl = VcmSIPCCBinding::getAudioControl(); |
michael@0 | 39 | |
michael@0 | 40 | if(audioControl) |
michael@0 | 41 | { |
michael@0 | 42 | pMediaData->volume = audioControl->getDefaultVolume(); |
michael@0 | 43 | } |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | |
michael@0 | 47 | /* |
michael@0 | 48 | CCAPI_CALL_EV_CAPABILITY -- From phone team: "...CCAPI_CALL_EV_CAPABILITY is generated for the capability changes but we decided to |
michael@0 | 49 | suppress it if it's due to state changes. We found it redundant as a state change implicitly implies a |
michael@0 | 50 | capability change. This event will still be generated if the capability changes without a state change. |
michael@0 | 51 | CCAPI_CALL_EV_CALLINFO -- From phone team: "...CCAPI_CALL_EV_CALLINFO is generated for any caller id related changes including |
michael@0 | 52 | called/calling/redirecting name/number etc..." |
michael@0 | 53 | CCAPI_CALL_EV_PLACED_CALLINFO -- From phone team: "CCAPI_CALL_EV_PLACED_CALLINFO was a trigger to update the placed call history and |
michael@0 | 54 | gives the actual number dialed out. I think this event can be deprecated." |
michael@0 | 55 | */ |
michael@0 | 56 | |
michael@0 | 57 | /* |
michael@0 | 58 | CallState |
michael@0 | 59 | |
michael@0 | 60 | REORDER: You get this if you misdial a number. |
michael@0 | 61 | */ |
michael@0 | 62 | |
michael@0 | 63 | // This function sets the remote window parameters for the call. Note that it currently only tolerates a single |
michael@0 | 64 | // video stream on the call and would need to be updated to handle multiple remote video streams for conferencing. |
michael@0 | 65 | void CC_SIPCCCall::setRemoteWindow (VideoWindowHandle window) |
michael@0 | 66 | { |
michael@0 | 67 | VideoTermination * pVideo = VcmSIPCCBinding::getVideoTermination(); |
michael@0 | 68 | pMediaData->remoteWindow = window; |
michael@0 | 69 | |
michael@0 | 70 | if (!pVideo) |
michael@0 | 71 | { |
michael@0 | 72 | CSFLogWarn( logTag, "setRemoteWindow: no video provider found"); |
michael@0 | 73 | return; |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 77 | { |
michael@0 | 78 | if (entry->second.isVideo) |
michael@0 | 79 | { |
michael@0 | 80 | // first video stream found |
michael@0 | 81 | int streamId = entry->first; |
michael@0 | 82 | pVideo->setRemoteWindow(streamId, pMediaData->remoteWindow); |
michael@0 | 83 | |
michael@0 | 84 | return; |
michael@0 | 85 | } |
michael@0 | 86 | } |
michael@0 | 87 | CSFLogInfo( logTag, "setRemoteWindow:no video stream found in call %u", callHandle ); |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | int CC_SIPCCCall::setExternalRenderer(VideoFormat vFormat, ExternalRendererHandle renderer) |
michael@0 | 91 | { |
michael@0 | 92 | VideoTermination * pVideo = VcmSIPCCBinding::getVideoTermination(); |
michael@0 | 93 | pMediaData->extRenderer = renderer; |
michael@0 | 94 | pMediaData->videoFormat = vFormat; |
michael@0 | 95 | |
michael@0 | 96 | if (!pVideo) |
michael@0 | 97 | { |
michael@0 | 98 | CSFLogWarn( logTag, "setExternalRenderer: no video provider found"); |
michael@0 | 99 | return -1; |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 103 | { |
michael@0 | 104 | if (entry->second.isVideo) |
michael@0 | 105 | { |
michael@0 | 106 | // first video stream found |
michael@0 | 107 | int streamId = entry->first; |
michael@0 | 108 | return pVideo->setExternalRenderer(streamId, pMediaData->videoFormat, pMediaData->extRenderer); |
michael@0 | 109 | } |
michael@0 | 110 | } |
michael@0 | 111 | CSFLogInfo( logTag, "setExternalRenderer:no video stream found in call %u", callHandle ); |
michael@0 | 112 | return -1; |
michael@0 | 113 | } |
michael@0 | 114 | |
michael@0 | 115 | void CC_SIPCCCall::sendIFrame() |
michael@0 | 116 | { |
michael@0 | 117 | VideoTermination * pVideo = VcmSIPCCBinding::getVideoTermination(); |
michael@0 | 118 | |
michael@0 | 119 | if (pVideo) |
michael@0 | 120 | { |
michael@0 | 121 | pVideo->sendIFrame(callHandle); |
michael@0 | 122 | } |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | CC_CallInfoPtr CC_SIPCCCall::getCallInfo () |
michael@0 | 126 | { |
michael@0 | 127 | cc_callinfo_ref_t callInfo = CCAPI_Call_getCallInfo(callHandle); |
michael@0 | 128 | CC_SIPCCCallInfoPtr callInfoPtr = CC_SIPCCCallInfo::wrap(callInfo); |
michael@0 | 129 | callInfoPtr->setMediaData( pMediaData); |
michael@0 | 130 | return callInfoPtr.get(); |
michael@0 | 131 | } |
michael@0 | 132 | |
michael@0 | 133 | |
michael@0 | 134 | // |
michael@0 | 135 | // Operations - The following function are actions that can be taken the execute an operation on the Call, ie calls |
michael@0 | 136 | // down to pSIPCC to originate a call, end a call etc. |
michael@0 | 137 | // |
michael@0 | 138 | |
michael@0 | 139 | bool CC_SIPCCCall::originateCall (cc_sdp_direction_t video_pref, const string & digits) |
michael@0 | 140 | { |
michael@0 | 141 | return (CCAPI_Call_originateCall(callHandle, video_pref, digits.c_str()) == CC_SUCCESS); |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | bool CC_SIPCCCall::answerCall (cc_sdp_direction_t video_pref) |
michael@0 | 145 | { |
michael@0 | 146 | return (CCAPI_Call_answerCall(callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 147 | } |
michael@0 | 148 | |
michael@0 | 149 | bool CC_SIPCCCall::hold (cc_hold_reason_t reason) |
michael@0 | 150 | { |
michael@0 | 151 | return (CCAPI_Call_hold(callHandle, reason) == CC_SUCCESS); |
michael@0 | 152 | } |
michael@0 | 153 | |
michael@0 | 154 | bool CC_SIPCCCall::resume (cc_sdp_direction_t video_pref) |
michael@0 | 155 | { |
michael@0 | 156 | return (CCAPI_Call_resume(callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | bool CC_SIPCCCall::endCall() |
michael@0 | 160 | { |
michael@0 | 161 | return (CCAPI_Call_endCall(callHandle) == CC_SUCCESS); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | bool CC_SIPCCCall::sendDigit (cc_digit_t digit) |
michael@0 | 165 | { |
michael@0 | 166 | AudioTermination * pAudio = VcmSIPCCBinding::getAudioTermination(); |
michael@0 | 167 | mozilla::MutexAutoLock lock(m_lock); |
michael@0 | 168 | |
michael@0 | 169 | // Convert public digit (as enum or char) to RFC2833 form. |
michael@0 | 170 | int digitId = -1; |
michael@0 | 171 | switch(digit) |
michael@0 | 172 | { |
michael@0 | 173 | case '0': |
michael@0 | 174 | digitId = 0; |
michael@0 | 175 | break; |
michael@0 | 176 | case '1': |
michael@0 | 177 | digitId = 1; |
michael@0 | 178 | break; |
michael@0 | 179 | case '2': |
michael@0 | 180 | digitId = 2; |
michael@0 | 181 | break; |
michael@0 | 182 | case '3': |
michael@0 | 183 | digitId = 3; |
michael@0 | 184 | break; |
michael@0 | 185 | case '4': |
michael@0 | 186 | digitId = 4; |
michael@0 | 187 | break; |
michael@0 | 188 | case '5': |
michael@0 | 189 | digitId = 5; |
michael@0 | 190 | break; |
michael@0 | 191 | case '6': |
michael@0 | 192 | digitId = 6; |
michael@0 | 193 | break; |
michael@0 | 194 | case '7': |
michael@0 | 195 | digitId = 7; |
michael@0 | 196 | break; |
michael@0 | 197 | case '8': |
michael@0 | 198 | digitId = 8; |
michael@0 | 199 | break; |
michael@0 | 200 | case '9': |
michael@0 | 201 | digitId = 9; |
michael@0 | 202 | break; |
michael@0 | 203 | case '*': |
michael@0 | 204 | digitId = 10; |
michael@0 | 205 | break; |
michael@0 | 206 | case '#': |
michael@0 | 207 | digitId = 11; |
michael@0 | 208 | break; |
michael@0 | 209 | case 'A': |
michael@0 | 210 | digitId = 12; |
michael@0 | 211 | break; |
michael@0 | 212 | case 'B': |
michael@0 | 213 | digitId = 13; |
michael@0 | 214 | break; |
michael@0 | 215 | case 'C': |
michael@0 | 216 | digitId = 14; |
michael@0 | 217 | break; |
michael@0 | 218 | case 'D': |
michael@0 | 219 | digitId = 15; |
michael@0 | 220 | break; |
michael@0 | 221 | case '+': |
michael@0 | 222 | digitId = 16; |
michael@0 | 223 | break; |
michael@0 | 224 | } |
michael@0 | 225 | |
michael@0 | 226 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 227 | { |
michael@0 | 228 | if (entry->second.isVideo == false) |
michael@0 | 229 | { |
michael@0 | 230 | // first is the streamId |
michael@0 | 231 | if (pAudio->sendDtmf(entry->first, digitId) != 0) |
michael@0 | 232 | { |
michael@0 | 233 | // We have sent a digit, done. |
michael@0 | 234 | break; |
michael@0 | 235 | } |
michael@0 | 236 | else |
michael@0 | 237 | { |
michael@0 | 238 | CSFLogWarn( logTag, "sendDigit:sendDtmf returned fail"); |
michael@0 | 239 | } |
michael@0 | 240 | } |
michael@0 | 241 | } |
michael@0 | 242 | return (CCAPI_Call_sendDigit(callHandle, digit) == CC_SUCCESS); |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | bool CC_SIPCCCall::backspace() |
michael@0 | 246 | { |
michael@0 | 247 | return (CCAPI_Call_backspace(callHandle) == CC_SUCCESS); |
michael@0 | 248 | } |
michael@0 | 249 | |
michael@0 | 250 | bool CC_SIPCCCall::redial (cc_sdp_direction_t video_pref) |
michael@0 | 251 | { |
michael@0 | 252 | return (CCAPI_Call_redial(callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | bool CC_SIPCCCall::initiateCallForwardAll() |
michael@0 | 256 | { |
michael@0 | 257 | return (CCAPI_Call_initiateCallForwardAll(callHandle) == CC_SUCCESS); |
michael@0 | 258 | } |
michael@0 | 259 | |
michael@0 | 260 | bool CC_SIPCCCall::endConsultativeCall() |
michael@0 | 261 | { |
michael@0 | 262 | return (CCAPI_Call_endConsultativeCall(callHandle) == CC_SUCCESS); |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | bool CC_SIPCCCall::conferenceStart (cc_sdp_direction_t video_pref) |
michael@0 | 266 | { |
michael@0 | 267 | return (CCAPI_Call_conferenceStart(callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | bool CC_SIPCCCall::conferenceComplete (CC_CallPtr otherLeg, cc_sdp_direction_t video_pref) |
michael@0 | 271 | { |
michael@0 | 272 | return (CCAPI_Call_conferenceComplete(callHandle, ((CC_SIPCCCall*)otherLeg.get())->callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 273 | } |
michael@0 | 274 | |
michael@0 | 275 | bool CC_SIPCCCall::transferStart (cc_sdp_direction_t video_pref) |
michael@0 | 276 | { |
michael@0 | 277 | return (CCAPI_Call_transferStart(callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 278 | } |
michael@0 | 279 | |
michael@0 | 280 | bool CC_SIPCCCall::transferComplete (CC_CallPtr otherLeg, |
michael@0 | 281 | cc_sdp_direction_t video_pref) |
michael@0 | 282 | { |
michael@0 | 283 | return (CCAPI_Call_transferComplete(callHandle, ((CC_SIPCCCall*)otherLeg.get())->callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 284 | } |
michael@0 | 285 | |
michael@0 | 286 | bool CC_SIPCCCall::cancelTransferOrConferenceFeature() |
michael@0 | 287 | { |
michael@0 | 288 | return (CCAPI_Call_cancelTransferOrConferenceFeature(callHandle) == CC_SUCCESS); |
michael@0 | 289 | } |
michael@0 | 290 | |
michael@0 | 291 | bool CC_SIPCCCall::directTransfer (CC_CallPtr target) |
michael@0 | 292 | { |
michael@0 | 293 | return (CCAPI_Call_directTransfer(callHandle, ((CC_SIPCCCall*)target.get())->callHandle) == CC_SUCCESS); |
michael@0 | 294 | } |
michael@0 | 295 | |
michael@0 | 296 | bool CC_SIPCCCall::joinAcrossLine (CC_CallPtr target) |
michael@0 | 297 | { |
michael@0 | 298 | return (CCAPI_Call_joinAcrossLine(callHandle, ((CC_SIPCCCall*)target.get())->callHandle) == CC_SUCCESS); |
michael@0 | 299 | } |
michael@0 | 300 | |
michael@0 | 301 | bool CC_SIPCCCall::blfCallPickup (cc_sdp_direction_t video_pref, const string & speed) |
michael@0 | 302 | { |
michael@0 | 303 | return (CCAPI_Call_blfCallPickup(callHandle, video_pref, speed.c_str()) == CC_SUCCESS); |
michael@0 | 304 | } |
michael@0 | 305 | |
michael@0 | 306 | bool CC_SIPCCCall::select() |
michael@0 | 307 | { |
michael@0 | 308 | return (CCAPI_Call_select(callHandle) == CC_SUCCESS); |
michael@0 | 309 | } |
michael@0 | 310 | |
michael@0 | 311 | bool CC_SIPCCCall::updateVideoMediaCap (cc_sdp_direction_t video_pref) |
michael@0 | 312 | { |
michael@0 | 313 | return (CCAPI_Call_updateVideoMediaCap(callHandle, video_pref) == CC_SUCCESS); |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | bool CC_SIPCCCall::sendInfo (const string & infopackage, const string & infotype, const string & infobody) |
michael@0 | 317 | { |
michael@0 | 318 | return (CCAPI_Call_sendInfo(callHandle, infopackage.c_str(), infotype.c_str(), infobody.c_str()) == CC_SUCCESS); |
michael@0 | 319 | } |
michael@0 | 320 | |
michael@0 | 321 | bool CC_SIPCCCall::muteAudio(void) |
michael@0 | 322 | { |
michael@0 | 323 | return setAudioMute(true); |
michael@0 | 324 | } |
michael@0 | 325 | |
michael@0 | 326 | bool CC_SIPCCCall::unmuteAudio() |
michael@0 | 327 | { |
michael@0 | 328 | return setAudioMute(false); |
michael@0 | 329 | } |
michael@0 | 330 | |
michael@0 | 331 | bool CC_SIPCCCall::muteVideo() |
michael@0 | 332 | { |
michael@0 | 333 | return setVideoMute(true); |
michael@0 | 334 | } |
michael@0 | 335 | |
michael@0 | 336 | bool CC_SIPCCCall::unmuteVideo() |
michael@0 | 337 | { |
michael@0 | 338 | return setVideoMute(false); |
michael@0 | 339 | } |
michael@0 | 340 | |
michael@0 | 341 | bool CC_SIPCCCall::setAudioMute(bool mute) |
michael@0 | 342 | { |
michael@0 | 343 | bool returnCode = false; |
michael@0 | 344 | AudioTermination * pAudio = VcmSIPCCBinding::getAudioTermination(); |
michael@0 | 345 | pMediaData->audioMuteState = mute; |
michael@0 | 346 | // we need to set the mute status of all audio streams in the map |
michael@0 | 347 | { |
michael@0 | 348 | mozilla::MutexAutoLock lock(m_lock); |
michael@0 | 349 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 350 | { |
michael@0 | 351 | if (entry->second.isVideo == false) |
michael@0 | 352 | { |
michael@0 | 353 | // first is the streamId |
michael@0 | 354 | if (pAudio->mute(entry->first, mute)) |
michael@0 | 355 | { |
michael@0 | 356 | // We have muted at least one stream |
michael@0 | 357 | returnCode = true; |
michael@0 | 358 | } |
michael@0 | 359 | else |
michael@0 | 360 | { |
michael@0 | 361 | CSFLogWarn( logTag, "setAudioMute:audio mute returned fail"); |
michael@0 | 362 | } |
michael@0 | 363 | } |
michael@0 | 364 | } |
michael@0 | 365 | } |
michael@0 | 366 | |
michael@0 | 367 | if (CCAPI_Call_setAudioMute(callHandle, mute) != CC_SUCCESS) |
michael@0 | 368 | { |
michael@0 | 369 | returnCode = false; |
michael@0 | 370 | } |
michael@0 | 371 | |
michael@0 | 372 | return returnCode; |
michael@0 | 373 | } |
michael@0 | 374 | |
michael@0 | 375 | bool CC_SIPCCCall::setVideoMute(bool mute) |
michael@0 | 376 | { |
michael@0 | 377 | bool returnCode = false; |
michael@0 | 378 | VideoTermination * pVideo = VcmSIPCCBinding::getVideoTermination(); |
michael@0 | 379 | pMediaData->videoMuteState = mute; |
michael@0 | 380 | // we need to set the mute status of all audio streams in the map |
michael@0 | 381 | { |
michael@0 | 382 | mozilla::MutexAutoLock lock(m_lock); |
michael@0 | 383 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 384 | { |
michael@0 | 385 | if (entry->second.isVideo == true) |
michael@0 | 386 | { |
michael@0 | 387 | // first is the streamId |
michael@0 | 388 | if (pVideo->mute(entry->first, mute)) |
michael@0 | 389 | { |
michael@0 | 390 | // We have muted at least one stream |
michael@0 | 391 | returnCode = true; |
michael@0 | 392 | } |
michael@0 | 393 | else |
michael@0 | 394 | { |
michael@0 | 395 | CSFLogWarn( logTag, "setVideoMute:video mute returned fail"); |
michael@0 | 396 | } |
michael@0 | 397 | } |
michael@0 | 398 | } |
michael@0 | 399 | } |
michael@0 | 400 | |
michael@0 | 401 | if (CCAPI_Call_setVideoMute(callHandle, mute) != CC_SUCCESS) |
michael@0 | 402 | { |
michael@0 | 403 | returnCode = false; |
michael@0 | 404 | } |
michael@0 | 405 | |
michael@0 | 406 | return returnCode; |
michael@0 | 407 | } |
michael@0 | 408 | |
michael@0 | 409 | void CC_SIPCCCall::addStream(int streamId, bool isVideo) |
michael@0 | 410 | { |
michael@0 | 411 | |
michael@0 | 412 | CSFLogInfo( logTag, "addStream: %d video=%s callhandle=%u", |
michael@0 | 413 | streamId, isVideo ? "TRUE" : "FALSE", callHandle); |
michael@0 | 414 | { |
michael@0 | 415 | mozilla::MutexAutoLock lock(m_lock); |
michael@0 | 416 | pMediaData->streamMap[streamId].isVideo = isVideo; |
michael@0 | 417 | } |
michael@0 | 418 | // The new stream needs to be given any properties that the call has for it. |
michael@0 | 419 | // At the moment the only candidate is the muted state |
michael@0 | 420 | if (isVideo) |
michael@0 | 421 | { |
michael@0 | 422 | #ifndef NO_WEBRTC_VIDEO |
michael@0 | 423 | VideoTermination * pVideo = VcmSIPCCBinding::getVideoTermination(); |
michael@0 | 424 | |
michael@0 | 425 | // if there is a window for this call apply it to the stream |
michael@0 | 426 | if ( pMediaData->remoteWindow != nullptr) |
michael@0 | 427 | { |
michael@0 | 428 | pVideo->setRemoteWindow(streamId, pMediaData->remoteWindow); |
michael@0 | 429 | } |
michael@0 | 430 | else |
michael@0 | 431 | { |
michael@0 | 432 | CSFLogInfo( logTag, "addStream: remoteWindow is NULL"); |
michael@0 | 433 | } |
michael@0 | 434 | |
michael@0 | 435 | if(pMediaData->extRenderer != nullptr) |
michael@0 | 436 | { |
michael@0 | 437 | pVideo->setExternalRenderer(streamId, pMediaData->videoFormat, pMediaData->extRenderer); |
michael@0 | 438 | } |
michael@0 | 439 | else |
michael@0 | 440 | { |
michael@0 | 441 | CSFLogInfo( logTag, "addStream: externalRenderer is NULL"); |
michael@0 | 442 | |
michael@0 | 443 | } |
michael@0 | 444 | |
michael@0 | 445 | |
michael@0 | 446 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 447 | { |
michael@0 | 448 | if (entry->second.isVideo == false) |
michael@0 | 449 | { |
michael@0 | 450 | // first is the streamId |
michael@0 | 451 | pVideo->setAudioStreamId(entry->first); |
michael@0 | 452 | } |
michael@0 | 453 | } |
michael@0 | 454 | if (!pVideo->mute(streamId, pMediaData->videoMuteState)) |
michael@0 | 455 | { |
michael@0 | 456 | CSFLogError( logTag, "setting video mute state failed for new stream: %d", streamId); |
michael@0 | 457 | } else |
michael@0 | 458 | { |
michael@0 | 459 | CSFLogError( logTag, "setting video mute state SUCCEEDED for new stream: %d", streamId); |
michael@0 | 460 | |
michael@0 | 461 | } |
michael@0 | 462 | #endif |
michael@0 | 463 | } |
michael@0 | 464 | else |
michael@0 | 465 | { |
michael@0 | 466 | AudioTermination * pAudio = VcmSIPCCBinding::getAudioTermination(); |
michael@0 | 467 | if (!pAudio->mute(streamId, pMediaData->audioMuteState)) |
michael@0 | 468 | { |
michael@0 | 469 | CSFLogError( logTag, "setting audio mute state failed for new stream: %d", streamId); |
michael@0 | 470 | } |
michael@0 | 471 | if (!pAudio->setVolume(streamId, pMediaData->volume)) |
michael@0 | 472 | { |
michael@0 | 473 | CSFLogError( logTag, "setting volume state failed for new stream: %d", streamId); |
michael@0 | 474 | } |
michael@0 | 475 | } |
michael@0 | 476 | } |
michael@0 | 477 | |
michael@0 | 478 | void CC_SIPCCCall::removeStream(int streamId) |
michael@0 | 479 | { |
michael@0 | 480 | mozilla::MutexAutoLock lock(m_lock); |
michael@0 | 481 | |
michael@0 | 482 | if ( pMediaData->streamMap.erase(streamId) != 1) |
michael@0 | 483 | { |
michael@0 | 484 | CSFLogError( logTag, "removeStream stream that was never in the streamMap: %d", streamId); |
michael@0 | 485 | } |
michael@0 | 486 | } |
michael@0 | 487 | |
michael@0 | 488 | bool CC_SIPCCCall::setVolume(int volume) |
michael@0 | 489 | { |
michael@0 | 490 | bool returnCode = false; |
michael@0 | 491 | |
michael@0 | 492 | AudioTermination * pAudio = VcmSIPCCBinding::getAudioTermination(); |
michael@0 | 493 | { |
michael@0 | 494 | mozilla::MutexAutoLock lock(m_lock); |
michael@0 | 495 | for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++) |
michael@0 | 496 | { |
michael@0 | 497 | if (entry->second.isVideo == false) |
michael@0 | 498 | { |
michael@0 | 499 | // first is the streamId |
michael@0 | 500 | int streamId = entry->first; |
michael@0 | 501 | if (pAudio->setVolume(streamId, volume)) |
michael@0 | 502 | { |
michael@0 | 503 | //We have changed the volume on at least one stream, |
michael@0 | 504 | //so persist the new volume as the call volume, |
michael@0 | 505 | //and report success for the volume change, even if it |
michael@0 | 506 | //fails on other streams |
michael@0 | 507 | pMediaData->volume = volume; |
michael@0 | 508 | returnCode = true; |
michael@0 | 509 | } |
michael@0 | 510 | else |
michael@0 | 511 | { |
michael@0 | 512 | CSFLogWarn( logTag, "setVolume:set volume on stream %d returned fail", |
michael@0 | 513 | streamId); |
michael@0 | 514 | } |
michael@0 | 515 | } |
michael@0 | 516 | } |
michael@0 | 517 | } |
michael@0 | 518 | return returnCode; |
michael@0 | 519 | } |
michael@0 | 520 | |
michael@0 | 521 | CC_SIPCCCallMediaDataPtr CC_SIPCCCall::getMediaData() |
michael@0 | 522 | { |
michael@0 | 523 | return pMediaData; |
michael@0 | 524 | } |
michael@0 | 525 | |
michael@0 | 526 | void CC_SIPCCCall::originateP2PCall (cc_sdp_direction_t video_pref, const std::string & digits, const std::string & ip) |
michael@0 | 527 | { |
michael@0 | 528 | CCAPI_Config_set_server_address(ip.c_str()); |
michael@0 | 529 | CCAPI_Call_originateCall(callHandle, video_pref, digits.c_str()); |
michael@0 | 530 | } |
michael@0 | 531 | |
michael@0 | 532 | /* |
michael@0 | 533 | * This method works asynchronously, is an onCallEvent with the resulting SDP |
michael@0 | 534 | */ |
michael@0 | 535 | void CC_SIPCCCall::createOffer (cc_media_constraints_t *constraints, |
michael@0 | 536 | Timecard *tc) { |
michael@0 | 537 | CCAPI_CreateOffer(callHandle, constraints, tc); |
michael@0 | 538 | } |
michael@0 | 539 | /* |
michael@0 | 540 | * This method works asynchronously, there is onCallEvent with the resulting SDP |
michael@0 | 541 | */ |
michael@0 | 542 | void CC_SIPCCCall::createAnswer (cc_media_constraints_t *constraints, |
michael@0 | 543 | Timecard *tc) { |
michael@0 | 544 | CCAPI_CreateAnswer(callHandle, constraints, tc); |
michael@0 | 545 | |
michael@0 | 546 | } |
michael@0 | 547 | |
michael@0 | 548 | void CC_SIPCCCall::setLocalDescription(cc_jsep_action_t action, |
michael@0 | 549 | const std::string & sdp, |
michael@0 | 550 | Timecard *tc) { |
michael@0 | 551 | CCAPI_SetLocalDescription(callHandle, action, sdp.c_str(), tc); |
michael@0 | 552 | } |
michael@0 | 553 | |
michael@0 | 554 | void CC_SIPCCCall::setRemoteDescription(cc_jsep_action_t action, |
michael@0 | 555 | const std::string & sdp, |
michael@0 | 556 | Timecard *tc) { |
michael@0 | 557 | CCAPI_SetRemoteDescription(callHandle, action, sdp.c_str(), tc); |
michael@0 | 558 | } |
michael@0 | 559 | |
michael@0 | 560 | void CC_SIPCCCall::setPeerConnection(const std::string& handle) |
michael@0 | 561 | { |
michael@0 | 562 | CSFLogDebug(logTag, "setPeerConnection"); |
michael@0 | 563 | |
michael@0 | 564 | peerconnection = handle; // Cache this here. we need it to make the CC_SIPCCCallInfo |
michael@0 | 565 | CCAPI_SetPeerConnection(callHandle, handle.c_str()); |
michael@0 | 566 | } |
michael@0 | 567 | |
michael@0 | 568 | const std::string& CC_SIPCCCall::getPeerConnection() const { |
michael@0 | 569 | return peerconnection; |
michael@0 | 570 | } |
michael@0 | 571 | |
michael@0 | 572 | void CC_SIPCCCall::addStream(cc_media_stream_id_t stream_id, |
michael@0 | 573 | cc_media_track_id_t track_id, |
michael@0 | 574 | cc_media_type_t media_type, |
michael@0 | 575 | cc_media_constraints_t *constraints) { |
michael@0 | 576 | CCAPI_AddStream(callHandle, stream_id, track_id, media_type, constraints); |
michael@0 | 577 | } |
michael@0 | 578 | |
michael@0 | 579 | void CC_SIPCCCall::removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) { |
michael@0 | 580 | CCAPI_RemoveStream(callHandle, stream_id, track_id, media_type); |
michael@0 | 581 | } |
michael@0 | 582 | |
michael@0 | 583 | void CC_SIPCCCall::addICECandidate(const std::string & candidate, |
michael@0 | 584 | const std::string & mid, |
michael@0 | 585 | unsigned short level, |
michael@0 | 586 | Timecard *tc) { |
michael@0 | 587 | CCAPI_AddICECandidate(callHandle, candidate.c_str(), mid.c_str(), |
michael@0 | 588 | (cc_level_t) level, tc); |
michael@0 | 589 | } |