How to trigger "OnSuccess" from "CreateOffer"

814 views
Skip to first unread message

William Cheung

unread,
Jul 15, 2015, 2:34:40 AM7/15/15
to discuss...@googlegroups.com
I recently synced to the new version of webrtc native and I am now unable to get the OnSuccess callback from the CreateSessionDescriptionObserver implementation when CreateOffer is called.

What is the simplest way to get an "OnSuccess"?

Below is the code I am using. OnSuccess is triggered with my old copy of webrtc, but not the most current version.

Thanks

--------------------------------------------------------------------------------------------------------------------------


#include "main.h"

class FakeConstraints : public webrtc::MediaConstraintsInterface {
public:
FakeConstraints() { }
virtual ~FakeConstraints() { }

virtual const Constraints& GetMandatory() const {
return mandatory_;
}

virtual const Constraints& GetOptional() const {
return optional_;
}

template <class T>
void AddMandatory(const std::string& key, const T& value) {
mandatory_.push_back(Constraint(key, rtc::ToString<T>(value)));
}

template <class T>
void SetMandatory(const std::string& key, const T& value) {
std::string value_str;
if (mandatory_.FindFirst(key, &value_str)) {
for (Constraints::iterator iter = mandatory_.begin();
iter != mandatory_.end(); ++iter) {
if (iter->key == key) {
mandatory_.erase(iter);
break;
}
}
}
mandatory_.push_back(Constraint(key, rtc::ToString<T>(value)));
}

template <class T>
void AddOptional(const std::string& key, const T& value) {
optional_.push_back(Constraint(key, rtc::ToString<T>(value)));
}

void SetMandatoryMinAspectRatio(double ratio) {
SetMandatory(MediaConstraintsInterface::kMinAspectRatio, ratio);
}

void SetMandatoryMinWidth(int width) {
SetMandatory(MediaConstraintsInterface::kMinWidth, width);
}

void SetMandatoryMinHeight(int height) {
SetMandatory(MediaConstraintsInterface::kMinHeight, height);
}

void SetOptionalMaxWidth(int width) {
AddOptional(MediaConstraintsInterface::kMaxWidth, width);
}

void SetMandatoryMaxFrameRate(int frame_rate) {
SetMandatory(MediaConstraintsInterface::kMaxFrameRate, frame_rate);
}

void SetMandatoryReceiveAudio(bool enable) {
SetMandatory(MediaConstraintsInterface::kOfferToReceiveAudio, enable);
}

void SetMandatoryReceiveVideo(bool enable) {
SetMandatory(MediaConstraintsInterface::kOfferToReceiveVideo, enable);
}

void SetMandatoryUseRtpMux(bool enable) {
SetMandatory(MediaConstraintsInterface::kUseRtpMux, enable);
}

void SetMandatoryIceRestart(bool enable) {
SetMandatory(MediaConstraintsInterface::kIceRestart, enable);
}

void SetAllowRtpDataChannels() {
SetMandatory(MediaConstraintsInterface::kEnableRtpDataChannels, true);
SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, false);
}

void SetOptionalVAD(bool enable) {
AddOptional(MediaConstraintsInterface::kVoiceActivityDetection, enable);
}

void SetAllowDtlsSctpDataChannels() {
SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, true);
}

private:
Constraints mandatory_;
Constraints optional_;
};

class Observer
: public webrtc::PeerConnectionObserver,
public webrtc::CreateSessionDescriptionObserver
{
public:

enum State
{
ACTIVE,
PENDING,
INACTIVE,
DELETED
};

Observer() {
peer_connection_factory_ = webrtc::CreatePeerConnectionFactory();
}
~Observer() {}

bool createPeerConnection() {
if (!peer_connection_factory_.get())
{
return false;
}
webrtc::PeerConnectionInterface::IceServers servers;
webrtc::PeerConnectionInterface::IceServer server;
constraints_.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, "true");
constraints_.SetMandatoryReceiveVideo(true);
constraints_.SetMandatoryReceiveAudio(true);

server.uri = "stun:stun.l.google.com:19302";
servers.push_back(server);

constraints_.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, "true");
peer_connection_ = peer_connection_factory_->CreatePeerConnection(servers, &constraints_, NULL, NULL, this);

if (!peer_connection_.get())
{
peer_connection_->Release();
}
std::cout << "Observer: Peer Connection Created." << std::endl;
return peer_connection_.get() != NULL;
}
void connectToPeer() {
peer_connection_->CreateOffer(this, NULL);
}
protected:
// PeerConnectionObserver implementation
virtual void OnError() {}
virtual void OnStateChange(webrtc::PeerConnectionObserver::StateType state_changed) {}
virtual void OnAddStream(webrtc::MediaStreamInterface* stream) {}
virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) {}
virtual void OnDataChannel(webrtc::DataChannelInterface* channel) {}
virtual void OnRenegotiationNeeded() {}
virtual void OnIceChange() {}
virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {}

// CreateSessionDescriptionObserver implementation.
virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) {
std::cout << "ON SUCCESS" << std::endl;
}
virtual void OnFailure(const std::string& error) {
std::cout << "ON FAILURE" << std::endl;
}

public:
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory_;
FakeConstraints constraints_;
std::map<std::string, rtc::scoped_refptr<webrtc::MediaStreamInterface> >
active_streams_;
};

int main()
{
rtc::EnsureWinsockInit();
rtc::Win32Thread w32_thread;
rtc::ThreadManager::Instance()->SetCurrentThread(&w32_thread);
rtc::InitializeSSL();
rtc::scoped_refptr<Observer> observer(new rtc::RefCountedObject<Observer>());

observer->createPeerConnection();
observer->connectToPeer();

rtc::CleanupSSL(); 
return 0;
}

Bill Yan

unread,
Jul 15, 2015, 2:43:39 AM7/15/15
to discuss...@googlegroups.com
ha!

my code saw exactly the same issue!! I just submitted my post and then I saw yours.

ok, the reason is that you are not calling webrtc::CreatePeerConnectionFactory()  from a rtc::thread. 

they expected that the thread you call webrtc::CreatePeerConnectionFactory() from has rtc::thread's message queue.

this is stupid! 

Bill Yan

unread,
Jul 15, 2015, 3:41:58 AM7/15/15
to discuss...@googlegroups.com
after looking into it more carefully, it seems that the issue is due to the signaling_thread not being started.

the signaling_thread can't process any message, so things like the following won't do anything

  signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg);

I filed a bug 

Bill Yan

unread,
Jul 15, 2015, 4:01:10 AM7/15/15
to discuss...@googlegroups.com
Ok, I modified the constructor to the following and it fixed the problem.


PeerConnectionFactory::PeerConnectionFactory()
    : owns_ptrs_(true),
      wraps_current_thread_(false),
      signaling_thread_(new rtc::Thread),
      worker_thread_(new rtc::Thread)
{
  if (!signaling_thread_) {
    signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
    wraps_current_thread_ = true;
  }
  signaling_thread_->Start();
  worker_thread_->Start();
}



you can try too, I'm certain this is a bug of webrtc
it was caused by the following change:

Author: pe...@webrtc.org <pe...@webrtc.org> 2015-01-12 00:30:16 Committer: pe...@webrtc.org <pe...@webrtc.org> 2015-01-12 00:30:16 Parent: 3987b6de506a7e72a5bdfdf8c8ad9964705c5a28 (Fix a problem in Thread::Send.) Child: 5f93d0a140515e3b8cdd1b9a4c6f5871144e5dee (Update libjingle license statements at top of talk files for consistency) Branches: master, remotes/branch-heads/42, remotes/branch-heads/42p, remotes/branch-heads/43, remotes/branch-heads/44, remotes/branch-heads/45, remotes/origin/master Follows: Precedes: Use proxy macro for PeerConnectionFactory instead of sending messages internally in PeerConnectionFactory. In order to do that, the signaling thread is also changed to wrap the current thread unless an external signaling thread thread is specified in the call to CreatePeerConnectionFactory. This cleans up the PeerConnectionFactory and makes sure a user of the API will always access the factory on the signaling thread. Note that both Chrome and the Android implementation use an external signaling thread. R=to...@webrtc.org Review URL: https://webrtc-codereview.appspot.com/35429004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8039 4adac7df-926f-26a2-2b94-8c16560cd09d

Christoffer Jansson

unread,
Jul 15, 2015, 4:07:25 AM7/15/15
to discuss...@googlegroups.com, bill...@gmail.com

William Cheung

unread,
Jul 15, 2015, 7:15:19 PM7/15/15
to discuss...@googlegroups.com
Bill, I can confirm your constructor change fixed the problem. Thanks!
Reply all
Reply to author
Forward
0 new messages