* Push the //depotGoogle/chrome/third_party/libjingle/...@38654 to svn third_party_mods\libjingle.
* Update the peerconnection sample client accordingly. Review URL: http://webrtc-codereview.appspot.com/60008 git-svn-id: http://webrtc.googlecode.com/svn/trunk@302 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "peerconnection/samples/client/defaults.h"
|
||||
#include "talk/base/logging.h"
|
||||
#include "talk/p2p/client/basicportallocator.h"
|
||||
#include "talk/session/phone/videorendererfactory.h"
|
||||
|
||||
Conductor::Conductor(PeerConnectionClient* client, MainWnd* main_wnd)
|
||||
@@ -19,8 +20,8 @@ Conductor::Conductor(PeerConnectionClient* client, MainWnd* main_wnd)
|
||||
waiting_for_audio_(false),
|
||||
waiting_for_video_(false),
|
||||
peer_id_(-1),
|
||||
video_channel_(-1),
|
||||
audio_channel_(-1),
|
||||
video_channel_(""),
|
||||
audio_channel_(""),
|
||||
client_(client),
|
||||
main_wnd_(main_wnd) {
|
||||
// Create a window for posting notifications back to from other threads.
|
||||
@@ -37,11 +38,11 @@ Conductor::~Conductor() {
|
||||
}
|
||||
|
||||
bool Conductor::has_video() const {
|
||||
return video_channel_ != -1;
|
||||
return !video_channel_.empty();
|
||||
}
|
||||
|
||||
bool Conductor::has_audio() const {
|
||||
return audio_channel_ != -1;
|
||||
return !audio_channel_.empty();
|
||||
}
|
||||
|
||||
bool Conductor::connection_active() const {
|
||||
@@ -51,6 +52,8 @@ bool Conductor::connection_active() const {
|
||||
void Conductor::Close() {
|
||||
if (peer_connection_.get()) {
|
||||
peer_connection_->Close();
|
||||
video_channel_ = "";
|
||||
audio_channel_ = "";
|
||||
} else {
|
||||
client_->SignOut();
|
||||
}
|
||||
@@ -58,7 +61,25 @@ void Conductor::Close() {
|
||||
|
||||
bool Conductor::InitializePeerConnection() {
|
||||
ASSERT(peer_connection_.get() == NULL);
|
||||
peer_connection_.reset(new webrtc::PeerConnection(GetPeerConnectionString()));
|
||||
ASSERT(port_allocator_.get() == NULL);
|
||||
ASSERT(worker_thread_.get() == NULL);
|
||||
|
||||
port_allocator_.reset(new cricket::BasicPortAllocator(
|
||||
new talk_base::BasicNetworkManager(),
|
||||
talk_base::SocketAddress("stun.l.google.com", 19302),
|
||||
talk_base::SocketAddress(),
|
||||
talk_base::SocketAddress(), talk_base::SocketAddress()));
|
||||
|
||||
worker_thread_.reset(new talk_base::Thread());
|
||||
if (!worker_thread_->SetName("workder thread", this) ||
|
||||
!worker_thread_->Start()) {
|
||||
LOG(WARNING) << "Failed to start libjingle workder thread";
|
||||
}
|
||||
|
||||
peer_connection_.reset(
|
||||
webrtc::PeerConnection::Create(GetPeerConnectionString(),
|
||||
port_allocator_.get(),
|
||||
worker_thread_.get()));
|
||||
peer_connection_->RegisterObserver(this);
|
||||
if (!peer_connection_->Init()) {
|
||||
DeletePeerConnection();
|
||||
@@ -91,6 +112,10 @@ void Conductor::StartCaptureDevice() {
|
||||
// PeerConnectionObserver implementation.
|
||||
//
|
||||
|
||||
void Conductor::OnInitialized() {
|
||||
PostMessage(handle(), PEER_CONNECTION_ADDSTREAMS, 0, 0);
|
||||
}
|
||||
|
||||
void Conductor::OnError() {
|
||||
LOG(INFO) << __FUNCTION__;
|
||||
ASSERT(false);
|
||||
@@ -99,7 +124,7 @@ void Conductor::OnError() {
|
||||
void Conductor::OnSignalingMessage(const std::string& msg) {
|
||||
LOG(INFO) << __FUNCTION__;
|
||||
|
||||
bool shutting_down = (video_channel_ == -1 && audio_channel_ == -1);
|
||||
bool shutting_down = (video_channel_.empty() && audio_channel_.empty());
|
||||
|
||||
if (handshake_ == OFFER_RECEIVED && !shutting_down)
|
||||
StartCaptureDevice();
|
||||
@@ -120,38 +145,67 @@ void Conductor::OnSignalingMessage(const std::string& msg) {
|
||||
}
|
||||
}
|
||||
|
||||
// Called when a remote stream is added
|
||||
void Conductor::OnAddStream(const std::string& stream_id, int channel_id,
|
||||
bool video) {
|
||||
// Called when a local stream is added and initialized
|
||||
void Conductor::OnLocalStreamInitialized(const std::string& stream_id,
|
||||
bool video) {
|
||||
LOG(INFO) << __FUNCTION__ << " " << stream_id;
|
||||
bool send_notification = (waiting_for_video_ || waiting_for_audio_);
|
||||
if (video) {
|
||||
ASSERT(video_channel_ == -1);
|
||||
video_channel_ = channel_id;
|
||||
ASSERT(video_channel_.empty());
|
||||
video_channel_ = stream_id;
|
||||
waiting_for_video_ = false;
|
||||
LOG(INFO) << "Setting video renderer for channel: " << channel_id;
|
||||
LOG(INFO) << "Setting video renderer for stream: " << stream_id;
|
||||
bool ok = peer_connection_->SetVideoRenderer(stream_id,
|
||||
main_wnd_->remote_renderer());
|
||||
ASSERT(ok);
|
||||
} else {
|
||||
ASSERT(audio_channel_ == -1);
|
||||
audio_channel_ = channel_id;
|
||||
ASSERT(audio_channel_.empty());
|
||||
audio_channel_ = stream_id;
|
||||
waiting_for_audio_ = false;
|
||||
}
|
||||
|
||||
if (send_notification && !waiting_for_audio_ && !waiting_for_video_)
|
||||
PostMessage(handle(), MEDIA_CHANNELS_INITIALIZED, 0, 0);
|
||||
|
||||
if (!waiting_for_audio_ && !waiting_for_video_) {
|
||||
PostMessage(handle(), PEER_CONNECTION_CONNECT, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Conductor::OnRemoveStream(const std::string& stream_id, int channel_id,
|
||||
bool video) {
|
||||
// Called when a remote stream is added
|
||||
void Conductor::OnAddStream(const std::string& stream_id, bool video) {
|
||||
LOG(INFO) << __FUNCTION__ << " " << stream_id;
|
||||
bool send_notification = (waiting_for_video_ || waiting_for_audio_);
|
||||
if (video) {
|
||||
ASSERT(video_channel_.empty());
|
||||
video_channel_ = stream_id;
|
||||
waiting_for_video_ = false;
|
||||
LOG(INFO) << "Setting video renderer for stream: " << stream_id;
|
||||
bool ok = peer_connection_->SetVideoRenderer(stream_id,
|
||||
main_wnd_->remote_renderer());
|
||||
ASSERT(ok);
|
||||
} else {
|
||||
ASSERT(audio_channel_.empty());
|
||||
audio_channel_ = stream_id;
|
||||
waiting_for_audio_ = false;
|
||||
}
|
||||
|
||||
if (send_notification && !waiting_for_audio_ && !waiting_for_video_)
|
||||
PostMessage(handle(), MEDIA_CHANNELS_INITIALIZED, 0, 0);
|
||||
|
||||
if (!waiting_for_audio_ && !waiting_for_video_) {
|
||||
PostMessage(handle(), PEER_CONNECTION_CONNECT, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Conductor::OnRemoveStream(const std::string& stream_id, bool video) {
|
||||
LOG(INFO) << __FUNCTION__;
|
||||
if (video) {
|
||||
ASSERT(channel_id == video_channel_);
|
||||
video_channel_ = -1;
|
||||
ASSERT(video_channel_.compare(stream_id) == 0);
|
||||
video_channel_ = "";
|
||||
} else {
|
||||
ASSERT(channel_id == audio_channel_);
|
||||
audio_channel_ = -1;
|
||||
ASSERT(audio_channel_.compare(stream_id) == 0);
|
||||
audio_channel_ = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,9 +268,6 @@ void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) {
|
||||
} else if (handshake_ == INITIATOR) {
|
||||
LOG(INFO) << "Remote peer sent us an answer";
|
||||
handshake_ = ANSWER_RECEIVED;
|
||||
} else {
|
||||
LOG(INFO) << "Remote peer is disconnecting";
|
||||
handshake_ = QUIT_SENT;
|
||||
}
|
||||
|
||||
peer_connection_->SignalingMessage(message);
|
||||
@@ -255,19 +306,24 @@ void Conductor::ConnectToPeer(int peer_id) {
|
||||
|
||||
if (InitializePeerConnection()) {
|
||||
peer_id_ = peer_id;
|
||||
waiting_for_video_ = peer_connection_->AddStream(kVideoLabel, true);
|
||||
waiting_for_audio_ = peer_connection_->AddStream(kAudioLabel, false);
|
||||
if (waiting_for_video_ || waiting_for_audio_)
|
||||
handshake_ = INITIATOR;
|
||||
ASSERT(waiting_for_video_ || waiting_for_audio_);
|
||||
}
|
||||
|
||||
if (handshake_ == NONE) {
|
||||
} else {
|
||||
::MessageBoxA(main_wnd_->handle(), "Failed to initialize PeerConnection",
|
||||
"Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void Conductor::AddStreams() {
|
||||
waiting_for_video_ = peer_connection_->AddStream(kVideoLabel, true);
|
||||
waiting_for_audio_ = peer_connection_->AddStream(kAudioLabel, false);
|
||||
if (waiting_for_video_ || waiting_for_audio_)
|
||||
handshake_ = INITIATOR;
|
||||
ASSERT(waiting_for_video_ || waiting_for_audio_);
|
||||
}
|
||||
|
||||
void Conductor::PeerConnectionConnect() {
|
||||
peer_connection_->Connect();
|
||||
}
|
||||
|
||||
void Conductor::DisconnectFromCurrentPeer() {
|
||||
if (peer_connection_.get())
|
||||
peer_connection_->Close();
|
||||
@@ -295,8 +351,8 @@ bool Conductor::OnMessage(UINT msg, WPARAM wp, LPARAM lp,
|
||||
waiting_for_audio_ = false;
|
||||
waiting_for_video_ = false;
|
||||
peer_id_ = -1;
|
||||
ASSERT(video_channel_ == -1);
|
||||
ASSERT(audio_channel_ == -1);
|
||||
ASSERT(video_channel_.empty());
|
||||
ASSERT(audio_channel_.empty());
|
||||
if (main_wnd_->IsWindow()) {
|
||||
if (client_->is_connected()) {
|
||||
main_wnd_->SwitchToPeerList(client_->peers());
|
||||
@@ -313,6 +369,10 @@ bool Conductor::OnMessage(UINT msg, WPARAM wp, LPARAM lp,
|
||||
LOG(LS_ERROR) << "SendToPeer failed";
|
||||
DisconnectFromServer();
|
||||
}
|
||||
} else if (msg == PEER_CONNECTION_ADDSTREAMS) {
|
||||
AddStreams();
|
||||
} else if (msg == PEER_CONNECTION_CONNECT) {
|
||||
PeerConnectionConnect();
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "peerconnection/samples/client/main_wnd.h"
|
||||
#include "peerconnection/samples/client/peer_connection_client.h"
|
||||
#include "talk/app/peerconnection.h"
|
||||
#include "talk/app/webrtc/peerconnection.h"
|
||||
#include "talk/base/scoped_ptr.h"
|
||||
|
||||
namespace cricket {
|
||||
@@ -33,6 +33,8 @@ class Conductor
|
||||
MEDIA_CHANNELS_INITIALIZED = WM_APP + 1,
|
||||
PEER_CONNECTION_CLOSED,
|
||||
SEND_MESSAGE_TO_PEER,
|
||||
PEER_CONNECTION_ADDSTREAMS,
|
||||
PEER_CONNECTION_CONNECT,
|
||||
};
|
||||
|
||||
enum HandshakeState {
|
||||
@@ -56,20 +58,25 @@ class Conductor
|
||||
bool InitializePeerConnection();
|
||||
void DeletePeerConnection();
|
||||
void StartCaptureDevice();
|
||||
void AddStreams();
|
||||
void PeerConnectionConnect();
|
||||
|
||||
//
|
||||
// PeerConnectionObserver implementation.
|
||||
//
|
||||
|
||||
virtual void OnInitialized();
|
||||
virtual void OnError();
|
||||
virtual void OnSignalingMessage(const std::string& msg);
|
||||
|
||||
// Called when a local stream is added and initialized
|
||||
virtual void OnLocalStreamInitialized(const std::string& stream_id,
|
||||
bool video);
|
||||
|
||||
// Called when a remote stream is added
|
||||
virtual void OnAddStream(const std::string& stream_id, int channel_id,
|
||||
bool video);
|
||||
virtual void OnAddStream(const std::string& stream_id, bool video);
|
||||
|
||||
virtual void OnRemoveStream(const std::string& stream_id,
|
||||
int channel_id,
|
||||
bool video);
|
||||
|
||||
//
|
||||
@@ -111,10 +118,12 @@ class Conductor
|
||||
bool waiting_for_video_;
|
||||
int peer_id_;
|
||||
talk_base::scoped_ptr<webrtc::PeerConnection> peer_connection_;
|
||||
talk_base::scoped_ptr<cricket::PortAllocator> port_allocator_;
|
||||
talk_base::scoped_ptr<talk_base::Thread> worker_thread_;
|
||||
PeerConnectionClient* client_;
|
||||
MainWnd* main_wnd_;
|
||||
int video_channel_;
|
||||
int audio_channel_;
|
||||
std::string video_channel_;
|
||||
std::string audio_channel_;
|
||||
};
|
||||
|
||||
#endif // PEERCONNECTION_SAMPLES_CLIENT_CONDUCTOR_H_
|
||||
|
||||
@@ -168,53 +168,68 @@ void MainWnd::OnPaint() {
|
||||
long height = abs(bmi.bmiHeader.biHeight);
|
||||
long width = bmi.bmiHeader.biWidth;
|
||||
|
||||
HDC dc_mem = ::CreateCompatibleDC(ps.hdc);
|
||||
if (remote_video_.get()->image() != NULL) {
|
||||
HDC dc_mem = ::CreateCompatibleDC(ps.hdc);
|
||||
|
||||
// Set the map mode so that the ratio will be maintained for us.
|
||||
HDC all_dc[] = { ps.hdc, dc_mem };
|
||||
for (int i = 0; i < ARRAY_SIZE(all_dc); ++i) {
|
||||
SetMapMode(all_dc[i], MM_ISOTROPIC);
|
||||
SetWindowExtEx(all_dc[i], width, height, NULL);
|
||||
SetViewportExtEx(all_dc[i], rc.right, rc.bottom, NULL);
|
||||
// Set the map mode so that the ratio will be maintained for us.
|
||||
HDC all_dc[] = { ps.hdc, dc_mem };
|
||||
for (int i = 0; i < ARRAY_SIZE(all_dc); ++i) {
|
||||
SetMapMode(all_dc[i], MM_ISOTROPIC);
|
||||
SetWindowExtEx(all_dc[i], width, height, NULL);
|
||||
SetViewportExtEx(all_dc[i], rc.right, rc.bottom, NULL);
|
||||
}
|
||||
|
||||
HBITMAP bmp_mem = ::CreateCompatibleBitmap(ps.hdc, rc.right, rc.bottom);
|
||||
HGDIOBJ bmp_old = ::SelectObject(dc_mem, bmp_mem);
|
||||
|
||||
POINT logical_area = { rc.right, rc.bottom };
|
||||
DPtoLP(ps.hdc, &logical_area, 1);
|
||||
|
||||
HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
|
||||
RECT logical_rect = {0, 0, logical_area.x, logical_area.y };
|
||||
::FillRect(dc_mem, &logical_rect, brush);
|
||||
::DeleteObject(brush);
|
||||
|
||||
const uint8* image = remote_video_->image();
|
||||
int max_unit = std::max(width, height);
|
||||
int x = (logical_area.x / 2) - (width / 2);
|
||||
int y = (logical_area.y / 2) - (height / 2);
|
||||
|
||||
StretchDIBits(dc_mem, x, y, width, height,
|
||||
0, 0, width, height, image, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
|
||||
if ((rc.right - rc.left) > 200 && (rc.bottom - rc.top) > 200) {
|
||||
const BITMAPINFO& bmi = local_video_->bmi();
|
||||
image = local_video_->image();
|
||||
long thumb_width = bmi.bmiHeader.biWidth / 4;
|
||||
long thumb_height = abs(bmi.bmiHeader.biHeight) / 4;
|
||||
StretchDIBits(dc_mem,
|
||||
logical_area.x - thumb_width - 10,
|
||||
logical_area.y - thumb_height - 10,
|
||||
thumb_width, thumb_height,
|
||||
0, 0, bmi.bmiHeader.biWidth, -bmi.bmiHeader.biHeight,
|
||||
image, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
|
||||
BitBlt(ps.hdc, 0, 0, logical_area.x, logical_area.y,
|
||||
dc_mem, 0, 0, SRCCOPY);
|
||||
|
||||
// Cleanup.
|
||||
::SelectObject(dc_mem, bmp_old);
|
||||
::DeleteObject(bmp_mem);
|
||||
::DeleteDC(dc_mem);
|
||||
} else {
|
||||
// We're still waiting for the video stream to be initialized.
|
||||
HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
|
||||
::FillRect(ps.hdc, &rc, brush);
|
||||
::DeleteObject(brush);
|
||||
HGDIOBJ old_font = ::SelectObject(ps.hdc, GetDefaultFont());
|
||||
::SetTextColor(ps.hdc, RGB(0xff, 0xff, 0xff));
|
||||
::SetBkMode(ps.hdc, TRANSPARENT);
|
||||
::DrawTextA(ps.hdc, "Connecting...", -1, &rc,
|
||||
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
|
||||
::SelectObject(ps.hdc, old_font);
|
||||
}
|
||||
|
||||
HBITMAP bmp_mem = ::CreateCompatibleBitmap(ps.hdc, rc.right, rc.bottom);
|
||||
HGDIOBJ bmp_old = ::SelectObject(dc_mem, bmp_mem);
|
||||
HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
|
||||
::FillRect(dc_mem, &rc, brush);
|
||||
::DeleteObject(brush);
|
||||
|
||||
POINT logical_area = { rc.right, rc.bottom };
|
||||
DPtoLP(ps.hdc, &logical_area, 1);
|
||||
|
||||
const uint8* image = remote_video_->image();
|
||||
int max_unit = std::max(width, height);
|
||||
int x = (logical_area.x / 2) - (width / 2);
|
||||
int y = (logical_area.y / 2) - (height / 2);
|
||||
|
||||
StretchDIBits(dc_mem, x, y, width, height,
|
||||
0, 0, width, height, image, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
|
||||
if ((rc.right - rc.left) > 200 && (rc.bottom - rc.top) > 200) {
|
||||
const BITMAPINFO& bmi = local_video_->bmi();
|
||||
image = local_video_->image();
|
||||
long thumb_width = bmi.bmiHeader.biWidth / 4;
|
||||
long thumb_height = abs(bmi.bmiHeader.biHeight) / 4;
|
||||
StretchDIBits(dc_mem,
|
||||
logical_area.x - thumb_width - 10,
|
||||
logical_area.y - thumb_height - 10,
|
||||
thumb_width, thumb_height,
|
||||
0, 0, bmi.bmiHeader.biWidth, -bmi.bmiHeader.biHeight,
|
||||
image, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
|
||||
BitBlt(ps.hdc, 0, 0, logical_area.x, logical_area.y,
|
||||
dc_mem, 0, 0, SRCCOPY);
|
||||
|
||||
// Cleanup.
|
||||
::SelectObject(dc_mem, bmp_old);
|
||||
::DeleteObject(bmp_mem);
|
||||
::DeleteDC(dc_mem);
|
||||
} else {
|
||||
HBRUSH brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
|
||||
::FillRect(ps.hdc, &rc, brush);
|
||||
@@ -481,7 +496,6 @@ MainWnd::VideoRenderer::VideoRenderer(HWND wnd, int width, int height)
|
||||
bmi_.bmiHeader.biHeight = -height;
|
||||
bmi_.bmiHeader.biSizeImage = width * height *
|
||||
(bmi_.bmiHeader.biBitCount >> 3);
|
||||
image_.reset(new uint8[bmi_.bmiHeader.biSizeImage]);
|
||||
}
|
||||
|
||||
MainWnd::VideoRenderer::~VideoRenderer() {
|
||||
@@ -529,6 +543,7 @@ void MainWnd::VideoRenderer::OnMessage(const MSG& msg) {
|
||||
break;
|
||||
|
||||
case WM_PAINT: {
|
||||
ASSERT(image_.get() != NULL);
|
||||
const cricket::VideoFrame* frame =
|
||||
reinterpret_cast<const cricket::VideoFrame*>(msg.lParam);
|
||||
frame->ConvertToRgbBuffer(cricket::FOURCC_ARGB, image_.get(),
|
||||
|
||||
Reference in New Issue
Block a user