nsresult MediaPipelineFactory::CreateOrUpdateMediaPipeline( const JsepTrackPair& aTrackPair, const JsepTrack& aTrack) { #if !defined(MOZILLA_EXTERNAL_LINKAGE) // The GMP code is all the way on the other side of webrtc.org, and it is not // feasible to plumb this information all the way through. So, we set it (for // the duration of this call) in a global variable. This allows the GMP code // to report errors to the PC. WebrtcGmpPCHandleSetter setter(mPC->GetHandle()); #endif MOZ_ASSERT(aTrackPair.mRtpTransport); bool receiving = aTrack.GetDirection() == sdp::kRecv; size_t level; RefPtr<TransportFlow> rtpFlow; RefPtr<TransportFlow> rtcpFlow; nsAutoPtr<MediaPipelineFilter> filter; nsresult rv = GetTransportParameters(aTrackPair, aTrack, &level, &rtpFlow, &rtcpFlow, &filter); if (NS_FAILED(rv)) { MOZ_MTLOG(ML_ERROR, "Failed to get transport parameters for pipeline, rv=" << static_cast<unsigned>(rv)); return rv; } if (aTrack.GetMediaType() == SdpMediaSection::kApplication) { // GetTransportParameters has already done everything we need for // datachannel. return NS_OK; } // Find the stream we need SourceStreamInfo* stream; if (receiving) { stream = mPCMedia->GetRemoteStreamById(aTrack.GetStreamId()); } else { stream = mPCMedia->GetLocalStreamById(aTrack.GetStreamId()); } if (!stream) { MOZ_MTLOG(ML_ERROR, "Negotiated " << (receiving ? "recv" : "send") << " stream id " << aTrack.GetStreamId() << " was never added"); MOZ_ASSERT(false); return NS_ERROR_FAILURE; } if (!stream->HasTrack(aTrack.GetTrackId())) { MOZ_MTLOG(ML_ERROR, "Negotiated " << (receiving ? "recv" : "send") << " track id " << aTrack.GetTrackId() << " was never added"); MOZ_ASSERT(false); return NS_ERROR_FAILURE; } RefPtr<MediaSessionConduit> conduit; if (aTrack.GetMediaType() == SdpMediaSection::kAudio) { rv = GetOrCreateAudioConduit(aTrackPair, aTrack, &conduit); if (NS_FAILED(rv)) return rv; } else if (aTrack.GetMediaType() == SdpMediaSection::kVideo) { rv = GetOrCreateVideoConduit(aTrackPair, aTrack, &conduit); if (NS_FAILED(rv)) return rv; } else { // We've created the TransportFlow, nothing else to do here. return NS_OK; } RefPtr<MediaPipeline> pipeline = stream->GetPipelineByTrackId_m(aTrack.GetTrackId()); if (pipeline && pipeline->level() != static_cast<int>(level)) { MOZ_MTLOG(ML_WARNING, "Track " << aTrack.GetTrackId() << " has moved from level " << pipeline->level() << " to level " << level << ". This requires re-creating the MediaPipeline."); // Since we do not support changing the conduit on a pre-existing // MediaPipeline pipeline = nullptr; stream->RemoveTrack(aTrack.GetTrackId()); stream->AddTrack(aTrack.GetTrackId()); } if (pipeline) { pipeline->UpdateTransport_m(level, rtpFlow, rtcpFlow, filter); return NS_OK; } MOZ_MTLOG(ML_DEBUG, "Creating media pipeline" << " m-line index=" << aTrackPair.mLevel << " type=" << aTrack.GetMediaType() << " direction=" << aTrack.GetDirection()); if (receiving) { rv = CreateMediaPipelineReceiving(aTrackPair, aTrack, level, rtpFlow, rtcpFlow, filter, conduit); if (NS_FAILED(rv)) return rv; } else { rv = CreateMediaPipelineSending(aTrackPair, aTrack, level, rtpFlow, rtcpFlow, filter, conduit); if (NS_FAILED(rv)) return rv; } return NS_OK; }
nsresult MediaPipelineFactory::CreateOrUpdateMediaPipeline( const JsepTrackPair& aTrackPair, const JsepTrack& aTrack) { MOZ_ASSERT(aTrackPair.mRtpTransport); bool receiving = aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving; size_t level; RefPtr<TransportFlow> rtpFlow; RefPtr<TransportFlow> rtcpFlow; nsAutoPtr<MediaPipelineFilter> filter; nsresult rv = GetTransportParameters(aTrackPair, aTrack, &level, &rtpFlow, &rtcpFlow, &filter); if (NS_FAILED(rv)) { MOZ_MTLOG(ML_ERROR, "Failed to get transport parameters for pipeline, rv=" << static_cast<unsigned>(rv)); return rv; } if (aTrack.GetMediaType() == SdpMediaSection::kApplication) { // GetTransportParameters has already done everything we need for // datachannel. return NS_OK; } // Find the stream we need SourceStreamInfo* stream; if (receiving) { stream = mPCMedia->GetRemoteStreamById(aTrack.GetStreamId()); } else { stream = mPCMedia->GetLocalStreamById(aTrack.GetStreamId()); } if (!stream) { MOZ_MTLOG(ML_ERROR, "Negotiated " << (receiving ? "recv" : "send") << " stream id " << aTrack.GetStreamId() << " was never added"); MOZ_ASSERT(false); return NS_ERROR_FAILURE; } if (!stream->HasTrack(aTrack.GetTrackId())) { MOZ_MTLOG(ML_ERROR, "Negotiated " << (receiving ? "recv" : "send") << " track id " << aTrack.GetTrackId() << " was never added"); MOZ_ASSERT(false); return NS_ERROR_FAILURE; } RefPtr<MediaSessionConduit> conduit; if (aTrack.GetMediaType() == SdpMediaSection::kAudio) { rv = GetOrCreateAudioConduit(aTrackPair, aTrack, &conduit); if (NS_FAILED(rv)) return rv; } else if (aTrack.GetMediaType() == SdpMediaSection::kVideo) { rv = GetOrCreateVideoConduit(aTrackPair, aTrack, &conduit); if (NS_FAILED(rv)) return rv; } else { // We've created the TransportFlow, nothing else to do here. return NS_OK; } RefPtr<MediaPipeline> pipeline = stream->GetPipelineByTrackId_m(aTrack.GetTrackId()); if (pipeline && pipeline->level() != static_cast<int>(level)) { MOZ_MTLOG(ML_WARNING, "Track " << aTrack.GetTrackId() << " has moved from level " << pipeline->level() << " to level " << level << ". This requires re-creating the MediaPipeline."); // Since we do not support changing the conduit on a pre-existing // MediaPipeline pipeline = nullptr; stream->RemoveTrack(aTrack.GetTrackId()); stream->AddTrack(aTrack.GetTrackId()); } if (pipeline) { pipeline->UpdateTransport_m(level, rtpFlow, rtcpFlow, filter); return NS_OK; } MOZ_MTLOG(ML_DEBUG, "Creating media pipeline" << " m-line index=" << aTrackPair.mLevel << " type=" << aTrack.GetMediaType() << " direction=" << aTrack.GetDirection()); if (receiving) { rv = CreateMediaPipelineReceiving(aTrackPair, aTrack, level, rtpFlow, rtcpFlow, filter, conduit); if (NS_FAILED(rv)) return rv; } else { rv = CreateMediaPipelineSending(aTrackPair, aTrack, level, rtpFlow, rtcpFlow, filter, conduit); if (NS_FAILED(rv)) return rv; } return NS_OK; }