* 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:
ronghuawu@google.com
2011-08-04 17:44:30 +00:00
parent 88bd440ef6
commit e256187f8b
68 changed files with 8798 additions and 11865 deletions

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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(),