WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
154867
WebRTC: Implement MediaEndpointPeerConnection::createOffer()
https://bugs.webkit.org/show_bug.cgi?id=154867
Summary
WebRTC: Implement MediaEndpointPeerConnection::createOffer()
Adam Bergkvist
Reported
2016-03-01 11:15:53 PST
Add real implementation of MediaEndpointPeerConnection::createOffer() and test it with a mock.
Attachments
Proposed patch
(101.99 KB, patch)
2016-03-01 11:36 PST
,
Adam Bergkvist
no flags
Details
Formatted Diff
Diff
Updated patch
(102.64 KB, patch)
2016-03-02 14:10 PST
,
Adam Bergkvist
eric.carlson
: review+
Details
Formatted Diff
Diff
Candidate for landing
(104.16 KB, patch)
2016-03-07 03:00 PST
,
Adam Bergkvist
no flags
Details
Formatted Diff
Diff
Candidate for landing (rebased)
(104.06 KB, patch)
2016-03-07 05:44 PST
,
Adam Bergkvist
no flags
Details
Formatted Diff
Diff
Candidate for landing (rebased)
(104.06 KB, patch)
2016-03-07 07:29 PST
,
Adam Bergkvist
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Adam Bergkvist
Comment 1
2016-03-01 11:36:56 PST
Created
attachment 272580
[details]
Proposed patch
Adam Bergkvist
Comment 2
2016-03-01 12:28:41 PST
Comment on
attachment 272580
[details]
Proposed patch View in context:
https://bugs.webkit.org/attachment.cgi?id=272580&action=review
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:476 > + printf("SDPProcessor::callScript(): %s() threw\n", functionName.ascii().data());
This should be a LOG_ERROR.
Eric Carlson
Comment 3
2016-03-02 11:30:12 PST
Comment on
attachment 272580
[details]
Proposed patch View in context:
https://bugs.webkit.org/attachment.cgi?id=272580&action=review
> LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:19 > + debug("This test can not be run without the testRunner"); > + finishJSTest();
Nit: add this might as well return to avoid a bunch of script errors
> LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:76 > + var mline; > + > + if (mline = match(line, regexp.mline)) {
Nit: this local variable isn't used.
> LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:82 > + var msidsemantic;
Ditto.
> Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp:61 > + static Ref<WrappedSessionDescriptionPromise> create(SessionDescriptionPromise&& promise) > + {
Nit: this brace should be on the previous line.
> Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp:158 > + mediaDescription->setMediaStreamId(sender->mediaStreamIds()[0]); > + mediaDescription->setMediaStreamTrackId(track->id()); > + mediaDescription->setType(track->kind()); > + mediaDescription->setPort(9); > + mediaDescription->setAddress("0.0.0.0"); > + mediaDescription->setMode("sendrecv"); > + mediaDescription->setPayloads(track->kind() == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads); > + mediaDescription->setRtcpMux(true); > + mediaDescription->setDtlsSetup("actpass"); > + mediaDescription->setDtlsFingerprintHashFunction(m_dtlsFingerprintFunction); > + mediaDescription->setDtlsFingerprint(m_dtlsFingerprint); > + mediaDescription->setCname(m_cname); > + mediaDescription->addSsrc(cryptographicallyRandomNumber()); > + mediaDescription->setIceUfrag(m_iceUfrag); > + mediaDescription->setIcePassword(m_icePassword);
Nit: This is a lot of setup Might it make sense to add a PeerMediaDescription constructor that takes a MediaStreamTrack (or maybe RtpSender)? If "0.0.0.0" the default address, can you set it in the constructor?
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:384 > + if (!callScript("generate", configurationToJSON(configuration), sdpString)) > + return Result::InternalError;
Nit: It could be helpful to log this error.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:401 > + if (!callScript("parse", sdp, scriptOutput)) > + return Result::InternalError; > + > + if (scriptOutput == "ParseError") > + return Result::ParseError; > + > + RefPtr<MediaEndpointSessionConfiguration> configuration = configurationFromJSON(scriptOutput); > + if (!configuration) > + return Result::InternalError;
Ditto.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:411 > + if (!callScript("generateCandidateLine", iceCandidateToJSON(candidate), candidateLine)) > + return Result::InternalError;
Ditto.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:428 > + if (!callScript("parseCandidateLine", candidateLine, scriptOutput)) > + return Result::InternalError; > + > + if (scriptOutput == "ParseError") > + return Result::ParseError; > + > + RefPtr<IceCandidate> candidate = iceCandidateFromJSON(scriptOutput); > + if (!candidate) > + return Result::InternalError;
Ditto.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:469 > + if (exec->hadException()) { > + exec->clearException(); > + return false; > + } > + } > + > + JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, functionName)); > + if (!functionValue.isFunction()) > + return false; > + > + JSC::JSObject* function = functionValue.toObject(exec); > + JSC::CallData callData; > + JSC::CallType callType = function->methodTable()->getCallData(function, callData); > + if (callType == JSC::CallTypeNone) > + return false;
Ditto.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:482 > + if (!result.isString()) > + return false;
Ditto.
Adam Bergkvist
Comment 4
2016-03-02 14:10:56 PST
Created
attachment 272685
[details]
Updated patch
Adam Bergkvist
Comment 5
2016-03-02 14:13:25 PST
(In reply to
comment #3
)
> Comment on
attachment 272580
[details]
> Proposed patch
Thanks for reviewing. Find answers inline.
> View in context: >
https://bugs.webkit.org/attachment.cgi?id=272580&action=review
> > > LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:19 > > + debug("This test can not be run without the testRunner"); > > + finishJSTest(); > > Nit: add this might as well return to avoid a bunch of script errors
That's pretty much the behavior right now since the getUserMedia() request will never resolve. We could wrap everything in a function and return as well.
> > LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:76 > > + var mline; > > + > > + if (mline = match(line, regexp.mline)) { > > Nit: this local variable isn't used.
Fixed.
> > LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:82 > > + var msidsemantic; > > Ditto.
Fixed.
> > Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp:61 > > + static Ref<WrappedSessionDescriptionPromise> create(SessionDescriptionPromise&& promise) > > + { > > Nit: this brace should be on the previous line.
The style checker complains in that case.
> > Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp:158 > > + mediaDescription->setMediaStreamId(sender->mediaStreamIds()[0]); > > + mediaDescription->setMediaStreamTrackId(track->id()); > > + mediaDescription->setType(track->kind()); > > + mediaDescription->setPort(9); > > + mediaDescription->setAddress("0.0.0.0"); > > + mediaDescription->setMode("sendrecv"); > > + mediaDescription->setPayloads(track->kind() == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads); > > + mediaDescription->setRtcpMux(true); > > + mediaDescription->setDtlsSetup("actpass"); > > + mediaDescription->setDtlsFingerprintHashFunction(m_dtlsFingerprintFunction); > > + mediaDescription->setDtlsFingerprint(m_dtlsFingerprint); > > + mediaDescription->setCname(m_cname); > > + mediaDescription->addSsrc(cryptographicallyRandomNumber()); > > + mediaDescription->setIceUfrag(m_iceUfrag); > > + mediaDescription->setIcePassword(m_icePassword); > > Nit: This is a lot of setup Might it make sense to add a > PeerMediaDescription constructor that takes a MediaStreamTrack (or maybe > RtpSender)? If "0.0.0.0" the default address, can you set it in the > constructor?
My intention with the setters was to avoid having expressions like 'cryptographicallyRandomNumber()' in the middle of a long constructor argument list since it's not obvious that it's an SSRC. But as it turned out, most of the values set are stored in variables with fairly descriptive names. :) I made all constant initializations here defaults when a PeerMediaDescription is constructed as you suggested with address. That got rid of five setter-calls. Is that enough or should we go for a constructor?
> > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:384 > > + if (!callScript("generate", configurationToJSON(configuration), sdpString)) > > + return Result::InternalError; > > Nit: It could be helpful to log this error.
The error is currently propagated to the caller and logged there (e.g. MediaEndpointPeerConnection:161). We could log it here as well.
> > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:401 > > + if (!callScript("parse", sdp, scriptOutput)) > > + return Result::InternalError; > > + > > + if (scriptOutput == "ParseError") > > + return Result::ParseError; > > + > > + RefPtr<MediaEndpointSessionConfiguration> configuration = configurationFromJSON(scriptOutput); > > + if (!configuration) > > + return Result::InternalError; > > Ditto. > > > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:411 > > + if (!callScript("generateCandidateLine", iceCandidateToJSON(candidate), candidateLine)) > > + return Result::InternalError; > > Ditto. > > > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:428 > > + if (!callScript("parseCandidateLine", candidateLine, scriptOutput)) > > + return Result::InternalError; > > + > > + if (scriptOutput == "ParseError") > > + return Result::ParseError; > > + > > + RefPtr<IceCandidate> candidate = iceCandidateFromJSON(scriptOutput); > > + if (!candidate) > > + return Result::InternalError; > > Ditto. > > > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:469 > > + if (exec->hadException()) { > > + exec->clearException(); > > + return false; > > + } > > + } > > + > > + JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, functionName)); > > + if (!functionValue.isFunction()) > > + return false; > > + > > + JSC::JSObject* function = functionValue.toObject(exec); > > + JSC::CallData callData; > > + JSC::CallType callType = function->methodTable()->getCallData(function, callData); > > + if (callType == JSC::CallTypeNone) > > + return false; > > Ditto. > > > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:482 > > + if (!result.isString()) > > + return false; > > Ditto.
Eric Carlson
Comment 6
2016-03-03 06:45:19 PST
(In reply to
comment #5
)
> (In reply to
comment #3
) > > Comment on
attachment 272580
[details]
> > Proposed patch > > Thanks for reviewing. Find answers inline. > > > View in context: > >
https://bugs.webkit.org/attachment.cgi?id=272580&action=review
> > > > > LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html:19 > > > + debug("This test can not be run without the testRunner"); > > > + finishJSTest(); > > > > Nit: add this might as well return to avoid a bunch of script errors > > That's pretty much the behavior right now since the getUserMedia() request > will never resolve. We could wrap everything in a function and return as > well. >
Indeed, I didn't look close enough!
> > > Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp:158 > > > + mediaDescription->setMediaStreamId(sender->mediaStreamIds()[0]); > > > + mediaDescription->setMediaStreamTrackId(track->id()); > > > + mediaDescription->setType(track->kind()); > > > + mediaDescription->setPort(9); > > > + mediaDescription->setAddress("0.0.0.0"); > > > + mediaDescription->setMode("sendrecv"); > > > + mediaDescription->setPayloads(track->kind() == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads); > > > + mediaDescription->setRtcpMux(true); > > > + mediaDescription->setDtlsSetup("actpass"); > > > + mediaDescription->setDtlsFingerprintHashFunction(m_dtlsFingerprintFunction); > > > + mediaDescription->setDtlsFingerprint(m_dtlsFingerprint); > > > + mediaDescription->setCname(m_cname); > > > + mediaDescription->addSsrc(cryptographicallyRandomNumber()); > > > + mediaDescription->setIceUfrag(m_iceUfrag); > > > + mediaDescription->setIcePassword(m_icePassword); > > > > Nit: This is a lot of setup Might it make sense to add a > > PeerMediaDescription constructor that takes a MediaStreamTrack (or maybe > > RtpSender)? If "0.0.0.0" the default address, can you set it in the > > constructor? > > My intention with the setters was to avoid having expressions like > 'cryptographicallyRandomNumber()' in the middle of a long constructor > argument list since it's not obvious that it's an SSRC. But as it turned > out, most of the values set are stored in variables with fairly descriptive > names. :) > > I made all constant initializations here defaults when a > PeerMediaDescription is constructed as you suggested with address. That got > rid of five setter-calls. Is that enough or should we go for a constructor? >
This seems fine, thanks. This seems fine to me, but this is a large & complex patch so I have asked someone else to take a look as well.
Adam Bergkvist
Comment 7
2016-03-03 10:20:31 PST
(In reply to
comment #6
)
> This seems fine to me, but this is a large & complex patch so I have asked > someone else to take a look as well.
Thanks. That seems reasonable.
Jer Noble
Comment 8
2016-03-04 11:08:50 PST
Comment on
attachment 272580
[details]
Proposed patch View in context:
https://bugs.webkit.org/attachment.cgi?id=272580&action=review
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:74 > + candidateObject->setString(ASCIILiteral("type"), candidate.type()); > + candidateObject->setString(ASCIILiteral("foundation"), candidate.foundation()); > + candidateObject->setInteger(ASCIILiteral("componentId"), candidate.componentId()); > + candidateObject->setString(ASCIILiteral("transport"), candidate.transport()); > + candidateObject->setInteger(ASCIILiteral("priority"), candidate.priority()); > + candidateObject->setString(ASCIILiteral("address"), candidate.address()); > + candidateObject->setInteger(ASCIILiteral("port"), candidate.port()); > + if (!candidate.tcpType().isEmpty()) > + candidateObject->setString(ASCIILiteral("tcpType"), candidate.tcpType()); > + if (candidate.type().convertToASCIIUppercase() != "HOST") { > + candidateObject->setString(ASCIILiteral("relatedAddress"), candidate.relatedAddress()); > + candidateObject->setInteger(ASCIILiteral("relatedPort"), candidate.relatedPort()); > + }
It seems like a shame to have to create so many temporary String objects just for the sake of passing through to the InspectorObject here (and later in createCandidate). Could you just use some static methods returning NeverDestroyed<String> objects? E.g.: static const String& typeString() { static NeverDestroyed<const String> type { ASCIILiteral("type") }; return type; }
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:86 > + if (candidateObject.getString(ASCIILiteral("type"), stringValue)) > + candidate->setType(stringValue);
Ditto.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:153 > + if (mdescObject->getString(ASCIILiteral("type"), stringValue)) > + mdesc->setType(stringValue);
Ditto.
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:299 > + for (const RefPtr<PeerMediaDescription>& mdesc : configuration.mediaDescriptions()) {
"mdesc" is not a very, ahem, descriptive name. "description"?
> Source/WebCore/Modules/mediastream/SDPProcessor.cpp:300 > + RefPtr<InspectorObject> mdescObject = InspectorObject::create();
Same for "mdescObject".
> Source/WebCore/platform/mediastream/gtk/SDPProcessorScriptResourceGtk.cpp:45 > +String scriptString() > +{ > + return String(sdpJavaScript); > +}
This should probably return a const String&, and store it locally in a "static NeverDestroyed<const String>".
Adam Bergkvist
Comment 9
2016-03-07 03:00:55 PST
Created
attachment 273169
[details]
Candidate for landing
Adam Bergkvist
Comment 10
2016-03-07 05:44:51 PST
Created
attachment 273176
[details]
Candidate for landing (rebased) Rebased and updated to match some new style rules.
Adam Bergkvist
Comment 11
2016-03-07 05:58:51 PST
(In reply to
comment #8
)
> Comment on
attachment 272580
[details]
> Proposed patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=272580&action=review
Thanks for taking time to review. Find answers inline.
> > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:74 > > + candidateObject->setString(ASCIILiteral("type"), candidate.type()); > > + candidateObject->setString(ASCIILiteral("foundation"), candidate.foundation()); > > + candidateObject->setInteger(ASCIILiteral("componentId"), candidate.componentId()); > > + candidateObject->setString(ASCIILiteral("transport"), candidate.transport()); > > + candidateObject->setInteger(ASCIILiteral("priority"), candidate.priority()); > > + candidateObject->setString(ASCIILiteral("address"), candidate.address()); > > + candidateObject->setInteger(ASCIILiteral("port"), candidate.port()); > > + if (!candidate.tcpType().isEmpty()) > > + candidateObject->setString(ASCIILiteral("tcpType"), candidate.tcpType()); > > + if (candidate.type().convertToASCIIUppercase() != "HOST") { > > + candidateObject->setString(ASCIILiteral("relatedAddress"), candidate.relatedAddress()); > > + candidateObject->setInteger(ASCIILiteral("relatedPort"), candidate.relatedPort()); > > + } > > It seems like a shame to have to create so many temporary String objects > just for the sake of passing through to the InspectorObject here (and later > in createCandidate). Could you just use some static methods returning > NeverDestroyed<String> objects? E.g.: > > static const String& typeString() > { > static NeverDestroyed<const String> type { ASCIILiteral("type") }; > return type; > }
Yes. I created simple a macro to define a bunch of these functions.
> > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:86 > > + if (candidateObject.getString(ASCIILiteral("type"), stringValue)) > > + candidate->setType(stringValue); > > Ditto. > > > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:153 > > + if (mdescObject->getString(ASCIILiteral("type"), stringValue)) > > + mdesc->setType(stringValue); > > Ditto. > > > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:299 > > + for (const RefPtr<PeerMediaDescription>& mdesc : configuration.mediaDescriptions()) { > > "mdesc" is not a very, ahem, descriptive name. "description"?
Fixed. Went with mediaDescription.
> > Source/WebCore/Modules/mediastream/SDPProcessor.cpp:300 > > + RefPtr<InspectorObject> mdescObject = InspectorObject::create(); > > Same for "mdescObject".
Fixed. Went with mediaDescriptionObject.
> > Source/WebCore/platform/mediastream/gtk/SDPProcessorScriptResourceGtk.cpp:45 > > +String scriptString() > > +{ > > + return String(sdpJavaScript); > > +} > > This should probably return a const String&, and store it locally in a > "static NeverDestroyed<const String>".
Indeed. Fixed.
Adam Bergkvist
Comment 12
2016-03-07 07:29:09 PST
Created
attachment 273177
[details]
Candidate for landing (rebased)
WebKit Commit Bot
Comment 13
2016-03-07 13:24:53 PST
Comment on
attachment 273177
[details]
Candidate for landing (rebased) Clearing flags on attachment: 273177 Committed
r197702
: <
http://trac.webkit.org/changeset/197702
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug