MediaStream* MediaStreamTrack::GetInputStream() { DOMMediaStream* inputDOMStream = GetInputDOMStream(); MOZ_RELEASE_ASSERT(inputDOMStream->GetInputStream()); return inputDOMStream->GetInputStream(); }
nsresult PeerConnectionImpl::CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo) { MOZ_ASSERT(aInfo); PC_AUTO_ENTER_API_CALL_NO_CHECK(); nsIDOMMediaStream* stream; // We need to pass a dummy hint here because FakeMediaStream currently // needs to actually propagate a hint for local streams. // TODO([email protected]): Clean up when we have explicit track lists. // See bug 834835. nsresult res = MakeMediaStream(mWindow, 0, &stream); if (NS_FAILED(res)) { return res; } DOMMediaStream* comstream = static_cast<DOMMediaStream*>(stream); static_cast<mozilla::SourceMediaStream*>(comstream->GetStream())->SetPullEnabled(true); nsRefPtr<RemoteSourceStreamInfo> remote; remote = new RemoteSourceStreamInfo(comstream); *aInfo = remote; return NS_OK; }
nsresult PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id) { if (!aMediaStream) { CSFLogError(logTag, "%s - aMediaStream is NULL", __FUNCTION__); return NS_ERROR_FAILURE; } DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream); CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream); // Adding tracks here based on nsDOMMediaStream expectation settings uint32_t hints = stream->GetHintContents(); #ifdef MOZILLA_INTERNAL_API if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) { hints &= ~(DOMMediaStream::HINT_CONTENTS_VIDEO); } #endif if (!(hints & (DOMMediaStream::HINT_CONTENTS_AUDIO | DOMMediaStream::HINT_CONTENTS_VIDEO))) { CSFLogDebug(logTag, "Empty Stream !!"); return NS_OK; } // Now see if we already have a stream of this type, since we only // allow one of each. // TODO([email protected]): remove this when multiple of each stream // is allowed mozilla::MutexAutoLock lock(mLocalSourceStreamsLock); for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u]; if (localSourceStream->GetMediaStream()->GetHintContents() & hints) { CSFLogError(logTag, "Only one stream of any given type allowed"); return NS_ERROR_FAILURE; } } // OK, we're good to add nsRefPtr<LocalSourceStreamInfo> localSourceStream = new LocalSourceStreamInfo(stream, this); *stream_id = mLocalSourceStreams.Length(); if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) { localSourceStream->ExpectAudio(TRACK_AUDIO); } if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) { localSourceStream->ExpectVideo(TRACK_VIDEO); } mLocalSourceStreams.AppendElement(localSourceStream); return NS_OK; }
NS_IMETHOD Run() { MOZ_ASSERT(NS_IsMainThread()); DOMMediaStream* stream = mListener->GetStream(); if (!stream) { return NS_OK; } stream->TracksCreated(); return NS_OK; }
/** * Tells you if any local streams is isolated to a specific peer identity. * Obviously, we want all the streams to be isolated equally so that they can * all be sent or not. We check once when we are setting a local description * and that determines if we flip the "privacy requested" bit on. Once the bit * is on, all media originating from this peer connection is isolated. * * @returns true if any stream has a peerIdentity set on it */ bool PeerConnectionMedia::AnyLocalStreamHasPeerIdentity() const { ASSERT_ON_THREAD(mMainThread); for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { // check if we should be asking for a private call for this stream DOMMediaStream* stream = mLocalSourceStreams[u]->GetMediaStream(); if (stream->GetPeerIdentity()) { return true; } } return false; }
NS_IMETHOD Run() { NS_ASSERTION(NS_IsMainThread(), "main thread only"); DOMMediaStream* stream = mListener->GetStream(); if (!stream) { return NS_OK; } nsRefPtr<MediaStreamTrack> track; if (mEvents & MediaStreamListener::TRACK_EVENT_CREATED) { track = stream->BindDOMTrack(mID, mType); if (!track) { stream->CreateDOMTrack(mID, mType); track = stream->BindDOMTrack(mID, mType); } stream->NotifyMediaStreamTrackCreated(track); } else { track = stream->GetDOMTrackFor(mID); } if (mEvents & MediaStreamListener::TRACK_EVENT_ENDED) { if (track) { track->NotifyEnded(); stream->NotifyMediaStreamTrackEnded(track); } else { NS_ERROR("track ended but not found"); } } return NS_OK; }
NS_IMETHOD Run() { NS_ASSERTION(NS_IsMainThread(), "main thread only"); DOMMediaStream* stream = mListener->GetStream(); if (!stream) { return NS_OK; } nsRefPtr<MediaStreamTrack> track; if (mEvents & MediaStreamListener::TRACK_EVENT_CREATED) { track = stream->CreateDOMTrack(mID, mType); } else { track = stream->GetDOMTrackFor(mID); } if (mEvents & MediaStreamListener::TRACK_EVENT_ENDED) { track->NotifyEnded(); } return NS_OK; }
NS_IMETHODIMP PeerConnectionImpl::RemoveStream(nsIDOMMediaStream* aMediaStream) { PC_AUTO_ENTER_API_CALL(true); uint32_t stream_id; nsresult res = mMedia->RemoveStream(aMediaStream, &stream_id); if (NS_FAILED(res)) return res; DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream); uint32_t hints = stream->GetHintContents(); if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) { mCall->removeStream(stream_id, 0, AUDIO); } if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) { mCall->removeStream(stream_id, 1, VIDEO); } return NS_OK; }
NS_IMETHODIMP PeerConnectionImpl::AddStream(nsIDOMMediaStream* aMediaStream) { PC_AUTO_ENTER_API_CALL(true); uint32_t stream_id; nsresult res = mMedia->AddStream(aMediaStream, &stream_id); if (NS_FAILED(res)) return res; DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream); uint32_t hints = stream->GetHintContents(); // TODO([email protected]): these integers should be the track IDs if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) { mCall->addStream(stream_id, 0, AUDIO); } if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) { mCall->addStream(stream_id, 1, VIDEO); } return NS_OK; }
/* static */ already_AddRefed<DOMMediaStream> DOMMediaStream::Constructor(const GlobalObject& aGlobal, const DOMMediaStream& aStream, ErrorResult& aRv) { nsTArray<RefPtr<MediaStreamTrack>> tracks; aStream.GetTracks(tracks); Sequence<OwningNonNull<MediaStreamTrack>> nonNullTrackSeq; if (!nonNullTrackSeq.SetLength(tracks.Length(), fallible)) { MOZ_ASSERT(false); aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } for (size_t i = 0; i < tracks.Length(); ++i) { nonNullTrackSeq[i] = tracks[i]; } return Constructor(aGlobal, nonNullTrackSeq, aRv); }
NS_IMETHOD Run() { CSFLogInfo(logTag, "PeerConnectionObserverDispatch processing " "mCallState = %d (%s)", mCallState, mStateStr.c_str()); if (mCallState == SETLOCALDESCERROR || mCallState == SETREMOTEDESCERROR) { const std::vector<std::string> &errors = mPC->GetSdpParseErrors(); std::vector<std::string>::const_iterator i; for (i = errors.begin(); i != errors.end(); ++i) { mReason += " | SDP Parsing Error: " + *i; } if (errors.size()) { mCode = PeerConnectionImpl::kInvalidSessionDescription; } mPC->ClearSdpParseErrorMessages(); } if (mReason.length()) { CSFLogInfo(logTag, "Message contains error: %d: %s", mCode, mReason.c_str()); } switch (mCallState) { case CREATEOFFERSUCCESS: mObserver->OnCreateOfferSuccess(mSdpStr.c_str()); break; case CREATEANSWERSUCCESS: mObserver->OnCreateAnswerSuccess(mSdpStr.c_str()); break; case CREATEOFFERERROR: mObserver->OnCreateOfferError(mCode, mReason.c_str()); break; case CREATEANSWERERROR: mObserver->OnCreateAnswerError(mCode, mReason.c_str()); break; case SETLOCALDESCSUCCESS: // TODO: The SDP Parse error list should be copied out and sent up // to the Javascript layer before being cleared here. Even though // there was not a failure, it is possible that the SDP parse generated // warnings. The WebRTC spec does not currently have a mechanism for // providing non-fatal warnings. mPC->ClearSdpParseErrorMessages(); mObserver->OnSetLocalDescriptionSuccess(); break; case SETREMOTEDESCSUCCESS: // TODO: The SDP Parse error list should be copied out and sent up // to the Javascript layer before being cleared here. Even though // there was not a failure, it is possible that the SDP parse generated // warnings. The WebRTC spec does not currently have a mechanism for // providing non-fatal warnings. mPC->ClearSdpParseErrorMessages(); mObserver->OnSetRemoteDescriptionSuccess(); break; case SETLOCALDESCERROR: mObserver->OnSetLocalDescriptionError(mCode, mReason.c_str()); break; case SETREMOTEDESCERROR: mObserver->OnSetRemoteDescriptionError(mCode, mReason.c_str()); break; case ADDICECANDIDATE: mObserver->OnAddIceCandidateSuccess(); break; case ADDICECANDIDATEERROR: mObserver->OnAddIceCandidateError(mCode, mReason.c_str()); break; case REMOTESTREAMADD: { DOMMediaStream* stream = nullptr; if (!mRemoteStream) { CSFLogError(logTag, "%s: GetRemoteStream returned NULL", __FUNCTION__); } else { stream = mRemoteStream->GetMediaStream(); } if (!stream) { CSFLogError(logTag, "%s: GetMediaStream returned NULL", __FUNCTION__); } else { #ifdef MOZILLA_INTERNAL_API TracksAvailableCallback* tracksAvailableCallback = new TracksAvailableCallback(mRemoteStream->mTrackTypeHints, mObserver); stream->OnTracksAvailable(tracksAvailableCallback); #else mObserver->OnAddStream(stream); #endif } break; } case UPDATELOCALDESC: /* No action necessary */ break; default: CSFLogError(logTag, ": **** UNHANDLED CALL STATE : %d (%s)", mCallState, mStateStr.c_str()); break; } return NS_OK; }
NS_IMETHOD Run() { CSFLogInfo(logTag, "PeerConnectionObserverDispatch processing " "mCallState = %d (%s), mFsmState = %d (%s)", mCallState, mStateStr.c_str(), mFsmState, mFsmStateStr.c_str()); if (mCallState == SETLOCALDESCERROR || mCallState == SETREMOTEDESCERROR) { const std::vector<std::string> &errors = mPC->GetSdpParseErrors(); std::vector<std::string>::const_iterator i; for (i = errors.begin(); i != errors.end(); ++i) { mReason += " | SDP Parsing Error: " + *i; } if (errors.size()) { mCode = PeerConnectionImpl::kInvalidSessionDescription; } mPC->ClearSdpParseErrorMessages(); } if (mReason.length()) { CSFLogInfo(logTag, "Message contains error: %d: %s", mCode, mReason.c_str()); } /* * While the fsm_states_t (FSM_DEF_*) constants are a proper superset * of SignalingState, and the order in which the SignalingState values * appear matches the order they appear in fsm_states_t, their underlying * numeric representation is different. Hence, we need to perform an * offset calculation to map from one to the other. */ if (mFsmState >= FSMDEF_S_STABLE && mFsmState <= FSMDEF_S_CLOSED) { int offset = FSMDEF_S_STABLE - PeerConnectionImpl::kSignalingStable; mPC->SetSignalingState_m( static_cast<PeerConnectionImpl::SignalingState>(mFsmState - offset)); } else { CSFLogError(logTag, ": **** UNHANDLED SIGNALING STATE : %d (%s)", mFsmState, mFsmStateStr.c_str()); } switch (mCallState) { case CREATEOFFERSUCCESS: mObserver->OnCreateOfferSuccess(mSdpStr.c_str()); break; case CREATEANSWERSUCCESS: mObserver->OnCreateAnswerSuccess(mSdpStr.c_str()); break; case CREATEOFFERERROR: mObserver->OnCreateOfferError(mCode, mReason.c_str()); break; case CREATEANSWERERROR: mObserver->OnCreateAnswerError(mCode, mReason.c_str()); break; case SETLOCALDESCSUCCESS: // TODO: The SDP Parse error list should be copied out and sent up // to the Javascript layer before being cleared here. Even though // there was not a failure, it is possible that the SDP parse generated // warnings. The WebRTC spec does not currently have a mechanism for // providing non-fatal warnings. mPC->ClearSdpParseErrorMessages(); mObserver->OnSetLocalDescriptionSuccess(); break; case SETREMOTEDESCSUCCESS: // TODO: The SDP Parse error list should be copied out and sent up // to the Javascript layer before being cleared here. Even though // there was not a failure, it is possible that the SDP parse generated // warnings. The WebRTC spec does not currently have a mechanism for // providing non-fatal warnings. mPC->ClearSdpParseErrorMessages(); mObserver->OnSetRemoteDescriptionSuccess(); break; case SETLOCALDESCERROR: mObserver->OnSetLocalDescriptionError(mCode, mReason.c_str()); break; case SETREMOTEDESCERROR: mObserver->OnSetRemoteDescriptionError(mCode, mReason.c_str()); break; case ADDICECANDIDATE: mObserver->OnAddIceCandidateSuccess(); break; case ADDICECANDIDATEERROR: mObserver->OnAddIceCandidateError(mCode, mReason.c_str()); break; case REMOTESTREAMADD: { DOMMediaStream* stream = nullptr; if (!mRemoteStream) { CSFLogError(logTag, "%s: GetRemoteStream returned NULL", __FUNCTION__); } else { stream = mRemoteStream->GetMediaStream(); } if (!stream) { CSFLogError(logTag, "%s: GetMediaStream returned NULL", __FUNCTION__); } else { #ifdef MOZILLA_INTERNAL_API TracksAvailableCallback* tracksAvailableCallback = new TracksAvailableCallback(mRemoteStream->mTrackTypeHints, mObserver); stream->OnTracksAvailable(tracksAvailableCallback); #else mObserver->OnAddStream(stream); #endif } break; } case UPDATELOCALDESC: /* No action necessary */ break; default: CSFLogError(logTag, ": **** UNHANDLED CALL STATE : %d (%s)", mCallState, mStateStr.c_str()); break; } return NS_OK; }