리스트에 피어가 나타나고 더블클릭 후 피어에 접속하는 동작에 대해 설명
void MainWnd::OnDefaultAction() {
// ...
} else if (ui_ == LIST_PEERS) {
LRESULT sel = ::SendMessage(listbox_, LB_GETCURSEL, 0, 0);
if (sel != LB_ERR) {
LRESULT peer_id = ::SendMessage(listbox_, LB_GETITEMDATA, sel, 0);
if (peer_id != -1 && callback_) {
callback_->ConnectToPeer((int)peer_id);
}
}
}
// ...
}
void Conductor::ConnectToPeer(int peer_id) {
printf("Conductor::ConnectToPeer\n");
RTC_DCHECK(peer_id_ == -1);
RTC_DCHECK(peer_id != -1);
if (peer_connection_.get()) {
main_wnd_->MessageBox(
"Error", "We only support connecting to one peer at a time", true);
return;
}
if (InitializePeerConnection()) {
peer_id_ = peer_id;
peer_connection_->CreateOffer(
this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
} else {
main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true);
}
}
bool Conductor::InitializePeerConnection() {
printf("Conductor::InitializePeerConnection\n");
RTC_DCHECK(!peer_connection_factory_);
RTC_DCHECK(!peer_connection_);
peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
nullptr /* network_thread */, nullptr /* worker_thread */,
nullptr /* signaling_thread */, nullptr /* default_adm */,
webrtc::CreateBuiltinAudioEncoderFactory(),
webrtc::CreateBuiltinAudioDecoderFactory(),
webrtc::CreateBuiltinExternalVideoEncoderFactory(),/*webrtc::CreateBuiltinVideoEncoderFactory(),*/
webrtc::CreateBuiltinVideoDecoderFactory(), /*ffmpeg::CreateBuiltinVideoDecoderFactory(),*/
nullptr /* audio_mixer */,
nullptr /* audio_processing */);
if (!peer_connection_factory_) {
main_wnd_->MessageBox("Error", "Failed to initialize PeerConnectionFactory",
true);
DeletePeerConnection();
return false;
}
if (!CreatePeerConnection(/*dtls=*/true)) {
main_wnd_->MessageBox("Error", "CreatePeerConnection failed", true);
DeletePeerConnection();
}
AddTracks();
return peer_connection_ != nullptr;
}
bool Conductor::CreatePeerConnection(bool dtls) {
printf("Conductor::CreatePeerConnection\n");
RTC_DCHECK(peer_connection_factory_);
RTC_DCHECK(!peer_connection_);
webrtc::PeerConnectionInterface::RTCConfiguration config;
config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
config.enable_dtls_srtp = dtls;
webrtc::PeerConnectionInterface::IceServer server;
server.uri = GetPeerConnectionString();
config.servers.push_back(server);
peer_connection_ = peer_connection_factory_->CreatePeerConnection(
config, nullptr, nullptr, this);
return peer_connection_ != nullptr;
}
void Conductor::AddTracks() {
printf("Conductor::AddTracks\n");
if (!peer_connection_->GetSenders().empty()) {
return; // Already added tracks.
}
rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
peer_connection_factory_->CreateAudioTrack(
kAudioLabel, peer_connection_factory_->CreateAudioSource(
cricket::AudioOptions())));
auto result_or_error = peer_connection_->AddTrack(audio_track, {kStreamId});
if (!result_or_error.ok()) {
RTC_LOG(LS_ERROR) << "Failed to add audio track to PeerConnection: "
<< result_or_error.error().message();
}
rtc::scoped_refptr<CapturerTrackSource> video_device =
CapturerTrackSource::Create();
if (video_device) {
rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track_(
peer_connection_factory_->CreateVideoTrack(kVideoLabel, video_device));
main_wnd_->StartLocalRenderer(video_track_);
result_or_error = peer_connection_->AddTrack(video_track_, {kStreamId});
if (!result_or_error.ok()) {
RTC_LOG(LS_ERROR) << "Failed to add video track to PeerConnection: "
<< result_or_error.error().message();
}
} else {
RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed";
}
main_wnd_->SwitchToStreamingUI();
}
(참고) VideoRenderer
class VideoRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
public:
VideoRenderer(HWND wnd,
int width,
int height,
webrtc::VideoTrackInterface* track_to_render);
virtual ~VideoRenderer();
void Lock() { ::EnterCriticalSection(&buffer_lock_); }
void Unlock() { ::LeaveCriticalSection(&buffer_lock_); }
// VideoSinkInterface implementation
void OnFrame(const webrtc::VideoFrame& frame) override;
const BITMAPINFO& bmi() const { return bmi_; }
const uint8_t* image() const { return image_.get(); }
rtc::scoped_refptr<webrtc::I420BufferInterface> buffer_ = nullptr;
protected:
void SetSize(int width, int height);
enum {
SET_SIZE,
RENDER_FRAME,
};
HWND wnd_;
BITMAPINFO bmi_;
std::unique_ptr<uint8_t[]> image_;
CRITICAL_SECTION buffer_lock_;
rtc::scoped_refptr<webrtc::VideoTrackInterface> rendered_track_;
};