Implement proxy for both audio and video tracks.

The purpose of the proxy is that all calls to MediaStreamTracks should be done on the signaling thread.

BUG=
TEST=

Review URL: http://webrtc-codereview.appspot.com/225004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@755 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
perkj@webrtc.org 2011-10-17 11:39:09 +00:00
parent 3765bd2cc2
commit 63257d4bd2
19 changed files with 655 additions and 57 deletions

View File

@ -702,8 +702,10 @@
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamprovider.h',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamimpl.h',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamimpl.cc',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamtrackproxy.h',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamtrackproxy.cc',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamproxy.h',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamproxy.cc',
'<(libjingle_mods)/source/talk/app/webrtc_dev/mediastreamproxy.cc',
'<(libjingle_mods)/source/talk/app/webrtc_dev/peerconnection.h',
'<(libjingle_mods)/source/talk/app/webrtc_dev/peerconnectionimpl.cc',
'<(libjingle_mods)/source/talk/app/webrtc_dev/peerconnectionimpl.h',

View File

@ -84,14 +84,14 @@ bool AudioTrack::set_state(TrackState new_state) {
return true;
}
scoped_refptr<AudioTrackInterface> AudioTrack::Create(
const std::string& label, uint32 ssrc) {
scoped_refptr<AudioTrack> AudioTrack::CreateRemote(const std::string& label,
uint32 ssrc) {
talk_base::RefCountImpl<AudioTrack>* track =
new talk_base::RefCountImpl<AudioTrack>(label, ssrc);
return track;
}
scoped_refptr<LocalAudioTrackInterface> CreateLocalAudioTrack(
scoped_refptr<AudioTrack> AudioTrack::CreateLocal(
const std::string& label,
AudioDeviceModule* audio_device) {
talk_base::RefCountImpl<AudioTrack>* track =

View File

@ -43,17 +43,19 @@ namespace webrtc {
class AudioTrack : public NotifierImpl<LocalAudioTrackInterface> {
public:
// Creates an audio track. This can be used in remote media streams.
// For local audio tracks use CreateLocalAudioTrack.
static scoped_refptr<AudioTrackInterface> Create(const std::string& label,
uint32 ssrc);
// Creates a remote audio track.
static scoped_refptr<AudioTrack> CreateRemote(const std::string& label,
uint32 ssrc);
// Creates a local audio track.
static scoped_refptr<AudioTrack> CreateLocal(const std::string& label,
AudioDeviceModule* audio_device);
// Get the AudioDeviceModule associated with this track.
virtual AudioDeviceModule* GetAudioDevice();
// Implement MediaStreamTrack
virtual const char* kind() const;
virtual const std::string& label() const { return label_; }
virtual const char* kind() const;
virtual std::string label() const { return label_; }
virtual TrackType type() const { return kAudio; }
virtual uint32 ssrc() const { return ssrc_; }
virtual TrackState state() const { return state_; }

View File

@ -71,12 +71,12 @@ class MediaStreamTrackInterface : public talk_base::RefCount,
};
enum TrackType {
kAudio = 0,
kAudio = 0,
kVideo = 1,
};
virtual const char* kind() const = 0;
virtual const std::string& label() const = 0;
virtual std::string label() const = 0;
virtual TrackType type() const = 0;
virtual uint32 ssrc() const = 0;
virtual bool enabled() const = 0;
@ -97,7 +97,7 @@ class VideoRendererInterface : public talk_base::RefCount {
};
// Creates a reference counted object of type webrtc::VideoRenderer.
// webrtc::VideoRenderer take ownership of cricket::VideoRenderer.
// webrtc::VideoRendererInterface take ownership of cricket::VideoRenderer.
scoped_refptr<VideoRendererInterface> CreateVideoRenderer(
cricket::VideoRenderer* renderer);
@ -123,10 +123,6 @@ class LocalVideoTrackInterface : public VideoTrackInterface {
virtual ~LocalVideoTrackInterface() {}
};
scoped_refptr<LocalVideoTrackInterface> CreateLocalVideoTrack(
const std::string& label,
VideoCaptureModule* video_device);
class AudioTrackInterface : public MediaStreamTrackInterface {
public:
protected:
@ -141,10 +137,6 @@ class LocalAudioTrackInterface : public AudioTrackInterface {
virtual ~LocalAudioTrackInterface() {}
};
scoped_refptr<LocalAudioTrackInterface> CreateLocalAudioTrack(
const std::string& label,
AudioDeviceModule* audio_device);
// List of of tracks.
class MediaStreamTrackListInterface : public talk_base::RefCount,
public Notifier {
@ -159,7 +151,7 @@ class MediaStreamTrackListInterface : public talk_base::RefCount,
class MediaStreamInterface : public talk_base::RefCount,
public Notifier {
public:
virtual const std::string& label() = 0;
virtual std::string label() const = 0;
virtual MediaStreamTrackListInterface* tracks() = 0;
enum ReadyState {

View File

@ -30,6 +30,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "talk/app/webrtc_dev/mediastreamimpl.h"
#include "talk/app/webrtc_dev/videotrackimpl.h"
#include "talk/app/webrtc_dev/mediastreamhandler.h"
#include "talk/app/webrtc_dev/streamcollectionimpl.h"
#include "talk/base/thread.h"
@ -69,7 +70,7 @@ TEST(MediaStreamHandlerTest, LocalStreams) {
std::string label(kStreamLabel1);
scoped_refptr<LocalMediaStreamInterface> stream(
MediaStreamImpl::Create(label));
scoped_refptr<LocalVideoTrackInterface> video_track(CreateLocalVideoTrack(
scoped_refptr<LocalVideoTrackInterface> video_track(VideoTrack::CreateLocal(
kVideoDeviceName, NULL));
video_track->set_ssrc(kVideoSsrc);
EXPECT_TRUE(stream->AddTrack(video_track));
@ -108,7 +109,7 @@ TEST(MediaStreamHandlerTest, RemoteStreams) {
std::string label(kStreamLabel1);
scoped_refptr<LocalMediaStreamInterface> stream(
MediaStreamImpl::Create(label));
scoped_refptr<LocalVideoTrackInterface> video_track(CreateLocalVideoTrack(
scoped_refptr<LocalVideoTrackInterface> video_track(VideoTrack::CreateLocal(
kVideoDeviceName, NULL));
video_track->set_ssrc(kVideoSsrc);
EXPECT_TRUE(stream->AddTrack(video_track));

View File

@ -58,7 +58,7 @@ class MediaStreamImpl
virtual bool AddTrack(MediaStreamTrackInterface* track);
// Implement MediaStream.
virtual const std::string& label() { return label_; }
virtual std::string label() const { return label_; }
virtual MediaStreamTrackListInterface* tracks() { return track_list_; }
virtual ReadyState ready_state() { return ready_state_; }
virtual void set_ready_state(ReadyState new_state);

View File

@ -29,6 +29,7 @@
#include "gtest/gtest.h"
#include "talk/app/webrtc_dev/mediastreamimpl.h"
#include "talk/app/webrtc_dev/videotrackimpl.h"
static const char kStreamLabel1[] = "local_stream_1";
static const char kVideoDeviceName[] = "dummy_video_cam_1";
@ -65,7 +66,7 @@ TEST(LocalStreamTest, Create) {
// Create a local Video track.
TestObserver tracklist_observer;
scoped_refptr<LocalVideoTrackInterface> video_track(CreateLocalVideoTrack(
scoped_refptr<LocalVideoTrackInterface> video_track(VideoTrack::CreateLocal(
kVideoDeviceName, NULL));
// Add an observer to the track list.
scoped_refptr<MediaStreamTrackListInterface> track_list(stream->tracks());

View File

@ -34,6 +34,7 @@ namespace {
enum {
MSG_REGISTER_OBSERVER = 1,
MSG_UNREGISTER_OBSERVER,
MSG_LABEL,
MSG_ADD_TRACK,
MSG_READY_STATE,
MSG_SET_READY_STATE,
@ -41,6 +42,7 @@ enum {
MSG_AT
};
typedef talk_base::TypedMessageData<std::string*> LabelMessageData;
typedef talk_base::TypedMessageData<size_t> SizeTMessageData;
typedef talk_base::TypedMessageData<webrtc::Observer*> ObserverMessageData;
typedef talk_base::TypedMessageData<webrtc::MediaStreamInterface::ReadyState>
@ -91,7 +93,13 @@ MediaStreamProxy::MediaStreamProxy(const std::string& label,
signaling_thread_)) {
}
const std::string& MediaStreamProxy::label() {
std::string MediaStreamProxy::label() const {
if (!signaling_thread_->IsCurrent()) {
std::string label;
LabelMessageData msg(&label);
Send(MSG_LABEL, &msg);
return label;
}
return media_stream_impl_->label();
}
@ -145,8 +153,9 @@ void MediaStreamProxy::UnregisterObserver(Observer* observer) {
media_stream_impl_->UnregisterObserver(observer);
}
void MediaStreamProxy::Send(uint32 id, talk_base::MessageData* data) {
signaling_thread_->Send(this, id, data);
void MediaStreamProxy::Send(uint32 id, talk_base::MessageData* data) const {
signaling_thread_->Send(const_cast<MediaStreamProxy*>(this), id,
data);
}
// Implement MessageHandler
@ -163,6 +172,11 @@ void MediaStreamProxy::OnMessage(talk_base::Message* msg) {
media_stream_impl_->UnregisterObserver(observer->data());
break;
}
case MSG_LABEL: {
LabelMessageData * label = static_cast<LabelMessageData*>(data);
*(label->data()) = media_stream_impl_->label();
break;
}
case MSG_ADD_TRACK: {
MediaStreamTrackMessageData * track =
static_cast<MediaStreamTrackMessageData*>(data);
@ -232,8 +246,9 @@ void MediaStreamProxy::MediaStreamTrackListProxy::UnregisterObserver(
}
void MediaStreamProxy::MediaStreamTrackListProxy::Send(
uint32 id, talk_base::MessageData* data) {
signaling_thread_->Send(this, id, data);
uint32 id, talk_base::MessageData* data) const {
signaling_thread_->Send(
const_cast<MediaStreamProxy::MediaStreamTrackListProxy*>(this), id, data);
}
// Implement MessageHandler

View File

@ -54,11 +54,11 @@ class MediaStreamProxy : public LocalMediaStreamInterface,
virtual void RegisterObserver(Observer* observer);
virtual void UnregisterObserver(Observer* observer);
private:
void Send(uint32 id, talk_base::MessageData* data);
void Send(uint32 id, talk_base::MessageData* data) const;
void OnMessage(talk_base::Message* msg);
scoped_refptr<MediaStreamTrackListInterface> track_list_;
talk_base::Thread* signaling_thread_;
mutable talk_base::Thread* signaling_thread_;
};
static scoped_refptr<MediaStreamProxy> Create(
@ -69,7 +69,7 @@ class MediaStreamProxy : public LocalMediaStreamInterface,
virtual bool AddTrack(MediaStreamTrackInterface* track);
// Implement MediaStream.
virtual const std::string& label();
virtual std::string label() const;
virtual MediaStreamTrackListInterface* tracks();
virtual ReadyState ready_state();
virtual void set_ready_state(ReadyState new_state);
@ -82,11 +82,11 @@ class MediaStreamProxy : public LocalMediaStreamInterface,
explicit MediaStreamProxy(const std::string& label,
talk_base::Thread* signaling_thread);
void Send(uint32 id, talk_base::MessageData* data);
void Send(uint32 id, talk_base::MessageData* data) const;
// Implement MessageHandler
virtual void OnMessage(talk_base::Message* msg);
talk_base::Thread* signaling_thread_;
mutable talk_base::Thread* signaling_thread_;
scoped_refptr<MediaStreamImpl> media_stream_impl_;
scoped_refptr<MediaStreamTrackListProxy> track_list_;
};

View File

@ -0,0 +1,403 @@
/*
* libjingle
* Copyright 2011, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "talk/app/webrtc_dev/mediastreamtrackproxy.h"
#include "talk/app/webrtc_dev/scoped_refptr_msg.h"
namespace {
enum {
MSG_REGISTER_OBSERVER = 1,
MSG_UNREGISTER_OBSERVER,
MSG_LABEL,
MSG_ENABLED,
MSG_SET_ENABLED,
MSG_STATE,
MSG_SSRC,
MSG_GET_AUDIODEVICE,
MSG_GET_VIDEODEVICE,
MSG_GET_VIDEORENDERER,
MSG_SET_VIDEORENDERER,
};
typedef talk_base::TypedMessageData<std::string*> LabelMessageData;
typedef talk_base::TypedMessageData<webrtc::Observer*> ObserverMessageData;
typedef talk_base::TypedMessageData
<webrtc::MediaStreamTrackInterface::TrackState> TrackStateMessageData;
typedef talk_base::TypedMessageData<uint32> SsrcMessageData;
typedef talk_base::TypedMessageData<bool> EnableMessageData;
class AudioDeviceMessageData : public talk_base::MessageData {
public:
scoped_refptr<webrtc::AudioDeviceModule> audio_device_;
};
class VideoDeviceMessageData : public talk_base::MessageData {
public:
scoped_refptr<webrtc::VideoCaptureModule> video_device_;
};
class VideoRendererMessageData : public talk_base::MessageData {
public:
scoped_refptr<webrtc::VideoRendererInterface> video_renderer_;
};
} // namespace anonymous
namespace webrtc {
template <class T>
MediaStreamTrackProxy<T>::MediaStreamTrackProxy(
talk_base::Thread* signaling_thread)
: signaling_thread_(signaling_thread) {
}
template <class T>
void MediaStreamTrackProxy<T>::Init(MediaStreamTrackInterface* track) {
track_ = track;
}
template <class T>
const char* MediaStreamTrackProxy<T>::kind() const {
return track_->kind();
}
template <class T>
MediaStreamTrackInterface::TrackType
MediaStreamTrackProxy<T>::type() const {
return track_->type();
}
template <class T>
std::string MediaStreamTrackProxy<T>::label() const {
if (!signaling_thread_->IsCurrent()) {
std::string label;
LabelMessageData msg(&label);
Send(MSG_LABEL, &msg);
return label;
}
return track_->label();
}
template <class T>
uint32 MediaStreamTrackProxy<T>::ssrc() const {
if (!signaling_thread_->IsCurrent()) {
SsrcMessageData msg(0);
Send(MSG_SSRC, &msg);
return msg.data();
}
return track_->ssrc();
}
template <class T>
MediaStreamTrackInterface::TrackState MediaStreamTrackProxy<T>::state() const {
if (!signaling_thread_->IsCurrent()) {
TrackStateMessageData msg(MediaStreamTrackInterface::kInitializing);
Send(MSG_STATE, &msg);
return msg.data();
}
return track_->state();
}
template <class T>
bool MediaStreamTrackProxy<T>::enabled() const {
if (!signaling_thread_->IsCurrent()) {
EnableMessageData msg(false);
Send(MSG_ENABLED, &msg);
return msg.data();
}
return track_->enabled();
}
template <class T>
bool MediaStreamTrackProxy<T>::set_enabled(bool enable) {
if (!signaling_thread_->IsCurrent()) {
EnableMessageData msg(enable);
Send(MSG_SET_ENABLED, &msg);
return msg.data();
}
return track_->set_enabled(enable);
}
template <class T>
bool MediaStreamTrackProxy<T>::set_state(
MediaStreamTrackInterface::TrackState new_state) {
if (!signaling_thread_->IsCurrent()) {
// State should only be allowed to be changed from the signaling thread.
ASSERT(!"Not Allowed!");
return false;
}
return track_->set_state(new_state);
}
template <class T>
bool MediaStreamTrackProxy<T>::set_ssrc(uint32 ssrc) {
if (!signaling_thread_->IsCurrent()) {
// ssrc should only be allowed to be changed from the signaling thread.
ASSERT(!"Not Allowed!");
return false;
}
return track_->set_ssrc(ssrc);
}
template <class T>
void MediaStreamTrackProxy<T>::RegisterObserver(Observer* observer) {
if (!signaling_thread_->IsCurrent()) {
ObserverMessageData msg(observer);
Send(MSG_REGISTER_OBSERVER, &msg);
return;
}
track_->RegisterObserver(observer);
}
template <class T>
void MediaStreamTrackProxy<T>::UnregisterObserver(Observer* observer) {
if (!signaling_thread_->IsCurrent()) {
ObserverMessageData msg(observer);
Send(MSG_UNREGISTER_OBSERVER, &msg);
return;
}
track_->UnregisterObserver(observer);
}
template <class T>
void MediaStreamTrackProxy<T>::Send(uint32 id,
talk_base::MessageData* data) const {
signaling_thread_->Send(const_cast<MediaStreamTrackProxy<T>*>(this), id,
data);
}
template <class T>
bool MediaStreamTrackProxy<T>::HandleMessage(talk_base::Message* msg) {
talk_base::MessageData* data = msg->pdata;
switch (msg->message_id) {
case MSG_REGISTER_OBSERVER: {
ObserverMessageData* observer = static_cast<ObserverMessageData*>(data);
track_->RegisterObserver(observer->data());
return true;
break;
}
case MSG_UNREGISTER_OBSERVER: {
ObserverMessageData* observer = static_cast<ObserverMessageData*>(data);
track_->UnregisterObserver(observer->data());
return true;
break;
}
case MSG_LABEL: {
LabelMessageData* label = static_cast<LabelMessageData*>(data);
*(label->data()) = track_->label();
return true;
}
case MSG_SSRC: {
SsrcMessageData* ssrc = static_cast<SsrcMessageData*>(data);
ssrc->data() = track_->ssrc();
return true;
break;
}
case MSG_SET_ENABLED: {
EnableMessageData* enabled = static_cast<EnableMessageData*>(data);
enabled->data() = track_->set_enabled(enabled->data());
return true;
break;
}
case MSG_ENABLED: {
EnableMessageData* enabled = static_cast<EnableMessageData*>(data);
enabled->data() = track_->enabled();
return true;
break;
}
case MSG_STATE: {
TrackStateMessageData* state = static_cast<TrackStateMessageData*>(data);
state->data() = track_->state();
return true;
break;
}
default:
return false;
}
}
AudioTrackProxy::AudioTrackProxy(
const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread)
: MediaStreamTrackProxy<LocalAudioTrackInterface>(signaling_thread),
audio_track_(AudioTrack::CreateRemote(label, ssrc)) {
Init(audio_track_);
}
AudioTrackProxy::AudioTrackProxy(
const std::string& label,
AudioDeviceModule* audio_device,
talk_base::Thread* signaling_thread)
: MediaStreamTrackProxy<LocalAudioTrackInterface>(signaling_thread),
audio_track_(AudioTrack::CreateLocal(label, audio_device)) {
Init(audio_track_);
}
scoped_refptr<AudioTrackInterface> AudioTrackProxy::CreateRemote(
const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread) {
ASSERT(signaling_thread);
talk_base::RefCountImpl<AudioTrackProxy>* track =
new talk_base::RefCountImpl<AudioTrackProxy>(label, ssrc,
signaling_thread);
return track;
}
scoped_refptr<LocalAudioTrackInterface> AudioTrackProxy::CreateLocal(
const std::string& label,
AudioDeviceModule* audio_device,
talk_base::Thread* signaling_thread) {
ASSERT(signaling_thread);
talk_base::RefCountImpl<AudioTrackProxy>* track =
new talk_base::RefCountImpl<AudioTrackProxy>(label,
audio_device,
signaling_thread);
return track;
}
AudioDeviceModule* AudioTrackProxy::GetAudioDevice() {
if (!signaling_thread_->IsCurrent()) {
AudioDeviceMessageData msg;
Send(MSG_GET_AUDIODEVICE, &msg);
return msg.audio_device_;
}
return audio_track_->GetAudioDevice();
}
void AudioTrackProxy::OnMessage(talk_base::Message* msg) {
if (!MediaStreamTrackProxy<LocalAudioTrackInterface>::HandleMessage(msg)) {
if (msg->message_id == MSG_GET_AUDIODEVICE) {
AudioDeviceMessageData* audio_device =
static_cast<AudioDeviceMessageData*>(msg->pdata);
audio_device->audio_device_ = audio_track_->GetAudioDevice();
} else {
ASSERT(!"Not Implemented!");
}
}
}
VideoTrackProxy::VideoTrackProxy(
const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread)
: MediaStreamTrackProxy<LocalVideoTrackInterface>(signaling_thread),
video_track_(VideoTrack::CreateRemote(label, ssrc)) {
Init(video_track_);
}
VideoTrackProxy::VideoTrackProxy(
const std::string& label,
VideoCaptureModule* video_device,
talk_base::Thread* signaling_thread)
: MediaStreamTrackProxy<LocalVideoTrackInterface>(signaling_thread),
video_track_(VideoTrack::CreateLocal(label, video_device)) {
Init(video_track_);
}
scoped_refptr<VideoTrackInterface> VideoTrackProxy::CreateRemote(
const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread) {
ASSERT(signaling_thread);
talk_base::RefCountImpl<VideoTrackProxy>* track =
new talk_base::RefCountImpl<VideoTrackProxy>(label, ssrc,
signaling_thread);
return track;
}
scoped_refptr<LocalVideoTrackInterface> VideoTrackProxy::CreateLocal(
const std::string& label,
VideoCaptureModule* video_device,
talk_base::Thread* signaling_thread) {
ASSERT(signaling_thread);
talk_base::RefCountImpl<VideoTrackProxy>* track =
new talk_base::RefCountImpl<VideoTrackProxy>(label, video_device,
signaling_thread);
return track;
}
VideoCaptureModule* VideoTrackProxy::GetVideoCapture() {
if (!signaling_thread_->IsCurrent()) {
VideoDeviceMessageData msg;
Send(MSG_GET_VIDEODEVICE, &msg);
return msg.video_device_;
}
return video_track_->GetVideoCapture();
}
void VideoTrackProxy::SetRenderer(VideoRendererInterface* renderer) {
if (!signaling_thread_->IsCurrent()) {
VideoRendererMessageData msg;
msg.video_renderer_ = renderer;
Send(MSG_SET_VIDEORENDERER, &msg);
return;
}
return video_track_->SetRenderer(renderer);
}
VideoRendererInterface* VideoTrackProxy::GetRenderer() {
if (!signaling_thread_->IsCurrent()) {
VideoRendererMessageData msg;
Send(MSG_GET_VIDEORENDERER, &msg);
return msg.video_renderer_;
}
return video_track_->GetRenderer();
}
void VideoTrackProxy::OnMessage(talk_base::Message* msg) {
if (!MediaStreamTrackProxy<LocalVideoTrackInterface>::HandleMessage(msg)) {
switch (msg->message_id) {
case MSG_GET_VIDEODEVICE: {
VideoDeviceMessageData* video_device =
static_cast<VideoDeviceMessageData*>(msg->pdata);
video_device->video_device_ = video_track_->GetVideoCapture();
break;
}
case MSG_GET_VIDEORENDERER: {
VideoRendererMessageData* video_renderer =
static_cast<VideoRendererMessageData*>(msg->pdata);
video_renderer->video_renderer_ = video_track_->GetRenderer();
break;
}
case MSG_SET_VIDEORENDERER: {
VideoRendererMessageData* video_renderer =
static_cast<VideoRendererMessageData*>(msg->pdata);
video_track_->SetRenderer(video_renderer->video_renderer_.get());
break;
}
default:
ASSERT(!"Not Implemented!");
break;
}
}
}
} // namespace webrtc

View File

@ -0,0 +1,139 @@
/*
* libjingle
* Copyright 2011, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This file includes proxy classes for tracks. The purpose is
// to make sure tracks are only accessed from the signaling thread.
#ifndef TALK_APP_WEBRTC_MEDIASTREAMTRACKPROXY_H_
#define TALK_APP_WEBRTC_MEDIASTREAMTRACKPROXY_H_
#include <string>
#include <vector>
#include "talk/app/webrtc_dev/audiotrackimpl.h"
#include "talk/app/webrtc_dev/mediastream.h"
#include "talk/app/webrtc_dev/videotrackimpl.h"
#include "talk/base/thread.h"
namespace webrtc {
template <class T>
class MediaStreamTrackProxy : public T,
talk_base::MessageHandler {
public:
void Init(MediaStreamTrackInterface* track);
// Implement MediaStreamTrack.
virtual const char* kind() const;
virtual MediaStreamTrackInterface::TrackType type() const;
virtual std::string label() const;
virtual uint32 ssrc() const;
virtual bool enabled() const;
virtual MediaStreamTrackInterface::TrackState state() const;
virtual bool set_enabled(bool enable);
virtual bool set_ssrc(uint32 ssrc);
virtual bool set_state(MediaStreamTrackInterface::TrackState new_state);
// Implement Notifier
virtual void RegisterObserver(Observer* observer);
virtual void UnregisterObserver(Observer* observer);
protected:
explicit MediaStreamTrackProxy(talk_base::Thread* signaling_thread);
void Send(uint32 id, talk_base::MessageData* data) const;
// Returns true if the message is handled.
bool HandleMessage(talk_base::Message* msg);
mutable talk_base::Thread* signaling_thread_;
MediaStreamTrackInterface* track_;
};
// AudioTrackProxy is a proxy for the AudioTrackInterface. The purpose is
// to make sure AudioTrack is only accessed from the signaling thread.
// It can be used as a proxy for both local and remote audio tracks.
class AudioTrackProxy : public MediaStreamTrackProxy<LocalAudioTrackInterface> {
public:
static scoped_refptr<AudioTrackInterface> CreateRemote(
const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread);
static scoped_refptr<LocalAudioTrackInterface> CreateLocal(
const std::string& label,
AudioDeviceModule* audio_device,
talk_base::Thread* signaling_thread);
virtual AudioDeviceModule* GetAudioDevice();
protected:
AudioTrackProxy(const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread);
AudioTrackProxy(const std::string& label,
AudioDeviceModule* audio_device,
talk_base::Thread* signaling_thread);
// Implement MessageHandler
virtual void OnMessage(talk_base::Message* msg);
scoped_refptr<AudioTrack> audio_track_;
};
// VideoTrackProxy is a proxy for the VideoTrackInterface and
// LocalVideoTrackInterface. The purpose is
// to make sure VideoTrack is only accessed from the signaling thread.
// It can be used as a proxy for both local and remote video tracks.
class VideoTrackProxy : public MediaStreamTrackProxy<LocalVideoTrackInterface> {
public:
static scoped_refptr<VideoTrackInterface> CreateRemote(
const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread);
static scoped_refptr<LocalVideoTrackInterface> CreateLocal(
const std::string& label,
VideoCaptureModule* video_device,
talk_base::Thread* signaling_thread);
virtual VideoCaptureModule* GetVideoCapture();
virtual void SetRenderer(VideoRendererInterface* renderer);
VideoRendererInterface* GetRenderer();
protected:
VideoTrackProxy(const std::string& label,
uint32 ssrc,
talk_base::Thread* signaling_thread);
VideoTrackProxy(const std::string& label,
VideoCaptureModule* video_device,
talk_base::Thread* signaling_thread);
// Implement MessageHandler
virtual void OnMessage(talk_base::Message* msg);
scoped_refptr<VideoTrack> video_track_;
};
} // namespace webrtc
#endif // TALK_APP_WEBRTC_MEDIASTREAMTRACKPROXY_H_

View File

@ -163,6 +163,14 @@ class PeerConnectionManager : public talk_base::RefCount {
virtual scoped_refptr<LocalMediaStreamInterface> CreateLocalMediaStream(
const std::string& label) = 0;
virtual scoped_refptr<LocalVideoTrackInterface> CreateLocalVideoTrack(
const std::string& label,
VideoCaptureModule* video_device) = 0;
virtual scoped_refptr<LocalAudioTrackInterface> CreateLocalAudioTrack(
const std::string& label,
AudioDeviceModule* audio_device) = 0;
protected:
// Dtor protected as objects shouldn't be deleted via this interface.

View File

@ -28,6 +28,7 @@
#include "talk/app/webrtc_dev/peerconnectionmanagerimpl.h"
#include "talk/app/webrtc_dev/mediastreamproxy.h"
#include "talk/app/webrtc_dev/mediastreamtrackproxy.h"
#include "talk/app/webrtc_dev/peerconnectionimpl.h"
#include "talk/app/webrtc_dev/webrtc_devicemanager.h"
#include "talk/base/basicpacketsocketfactory.h"
@ -241,4 +242,20 @@ PeerConnectionManagerImpl::CreateLocalMediaStream(
return MediaStreamProxy::Create(label, signaling_thread_ptr_);
}
scoped_refptr<LocalVideoTrackInterface>
PeerConnectionManagerImpl::CreateLocalVideoTrack(
const std::string& label,
VideoCaptureModule* video_device) {
return VideoTrackProxy::CreateLocal(label, video_device,
signaling_thread_ptr_);
}
scoped_refptr<LocalAudioTrackInterface>
PeerConnectionManagerImpl::CreateLocalAudioTrack(
const std::string& label,
AudioDeviceModule* audio_device) {
return AudioTrackProxy::CreateLocal(label, audio_device,
signaling_thread_ptr_);
}
} // namespace webrtc

View File

@ -45,9 +45,17 @@ class PeerConnectionManagerImpl : public PeerConnectionManager,
PeerConnectionObserver* observer);
bool Initialize();
scoped_refptr<LocalMediaStreamInterface> CreateLocalMediaStream(
virtual scoped_refptr<LocalMediaStreamInterface> CreateLocalMediaStream(
const std::string& label);
virtual scoped_refptr<LocalVideoTrackInterface> CreateLocalVideoTrack(
const std::string& label,
VideoCaptureModule* video_device);
virtual scoped_refptr<LocalAudioTrackInterface> CreateLocalAudioTrack(
const std::string& label,
AudioDeviceModule* audio_device);
protected:
PeerConnectionManagerImpl();
PeerConnectionManagerImpl(talk_base::Thread* worker_thread,

View File

@ -29,8 +29,7 @@
#include <utility>
#include "talk/app/webrtc_dev/audiotrackimpl.h"
#include "talk/app/webrtc_dev/videotrackimpl.h"
#include "talk/app/webrtc_dev/mediastreamtrackproxy.h"
#include "talk/app/webrtc_dev/sessiondescriptionprovider.h"
#include "talk/base/helpers.h"
#include "talk/base/messagequeue.h"
@ -357,7 +356,8 @@ void PeerConnectionSignaling::UpdateRemoteStreams(
new_streams_it = current_streams.find(it->cname);
}
scoped_refptr<AudioTrackInterface> track(
AudioTrack::Create(it->description, it->ssrc));
AudioTrackProxy::CreateRemote(it->description, it->ssrc,
signaling_thread_));
track->set_state(MediaStreamTrackInterface::kLive);
new_streams_it->second->AddTrack(track);
@ -391,7 +391,8 @@ void PeerConnectionSignaling::UpdateRemoteStreams(
new_streams_it = current_streams.find(it->cname);
}
scoped_refptr<VideoTrackInterface> track(
VideoTrack::Create(it->description, it->ssrc));
VideoTrackProxy::CreateRemote(it->description, it->ssrc,
signaling_thread_));
new_streams_it->second->AddTrack(track);
track->set_state(MediaStreamTrackInterface::kLive);

View File

@ -31,6 +31,8 @@
#include "gtest/gtest.h"
#include "talk/app/webrtc_dev/mediastreamimpl.h"
#include "talk/app/webrtc_dev/videotrackimpl.h"
#include "talk/app/webrtc_dev/audiotrackimpl.h"
#include "talk/app/webrtc_dev/peerconnectionsignaling.h"
#include "talk/app/webrtc_dev/streamcollectionimpl.h"
#include "talk/base/scoped_ptr.h"
@ -242,8 +244,8 @@ TEST_F(PeerConnectionSignalingTest, SimpleOneWayCall) {
MockMediaStreamObserver stream_observer1(stream);
// Add a local audio track.
scoped_refptr<LocalAudioTrackInterface> audio_track(
CreateLocalAudioTrack(kAudioTrackLabel1, NULL));
scoped_refptr<LocalAudioTrackInterface> audio_track(AudioTrack::CreateLocal(
kAudioTrackLabel1, NULL));
stream->AddTrack(audio_track);
MockMediaTrackObserver track_observer1(audio_track);
@ -316,8 +318,8 @@ TEST_F(PeerConnectionSignalingTest, Glare) {
MediaStreamImpl::Create(label));
// Add a local audio track.
scoped_refptr<LocalAudioTrackInterface> audio_track(
CreateLocalAudioTrack(kAudioTrackLabel1, NULL));
scoped_refptr<LocalAudioTrackInterface> audio_track(AudioTrack::CreateLocal(
kAudioTrackLabel1, NULL));
stream->AddTrack(audio_track);
// Peer 1 create an offer with only one audio track.
@ -381,16 +383,16 @@ TEST_F(PeerConnectionSignalingTest, AddRemoveStream) {
MockMediaStreamObserver stream_observer1(stream);
// Add a local audio track.
scoped_refptr<LocalAudioTrackInterface> audio_track(
CreateLocalAudioTrack(kAudioTrackLabel1, NULL));
scoped_refptr<LocalAudioTrackInterface> audio_track(AudioTrack::CreateLocal(
kAudioTrackLabel1, NULL));
stream->AddTrack(audio_track);
MockMediaTrackObserver track_observer1(audio_track);
audio_track->RegisterObserver(&track_observer1);
// Add a local video track.
scoped_refptr<LocalVideoTrackInterface> video_track(
CreateLocalVideoTrack(kAudioTrackLabel1, NULL));
stream->AddTrack(audio_track);
scoped_refptr<LocalVideoTrackInterface> video_track(VideoTrack::CreateLocal(
kVideoTrackLabel1, NULL));
stream->AddTrack(video_track);
// Peer 1 create an empty collection
scoped_refptr<StreamCollectionImpl> local_collection1(

View File

@ -92,7 +92,7 @@ bool VideoTrack::set_state(TrackState new_state) {
return true;
}
scoped_refptr<VideoTrackInterface> VideoTrack::Create(
scoped_refptr<VideoTrack> VideoTrack::CreateRemote(
const std::string& label,
uint32 ssrc) {
talk_base::RefCountImpl<VideoTrack>* track =
@ -100,7 +100,7 @@ scoped_refptr<VideoTrackInterface> VideoTrack::Create(
return track;
}
scoped_refptr<LocalVideoTrackInterface> CreateLocalVideoTrack(
scoped_refptr<VideoTrack> VideoTrack::CreateLocal(
const std::string& label,
VideoCaptureModule* video_device) {
talk_base::RefCountImpl<VideoTrack>* track =

View File

@ -44,14 +44,20 @@ namespace webrtc {
class VideoTrack : public NotifierImpl<LocalVideoTrackInterface> {
public:
static scoped_refptr<VideoTrackInterface> Create(const std::string& label,
uint32 ssrc);
// Create a video track used for remote video tracks.
static scoped_refptr<VideoTrack> CreateRemote(const std::string& label,
uint32 ssrc);
// Create a video track used for local video tracks.
static scoped_refptr<VideoTrack> CreateLocal(
const std::string& label,
VideoCaptureModule* video_device);
virtual VideoCaptureModule* GetVideoCapture();
virtual void SetRenderer(VideoRendererInterface* renderer);
VideoRendererInterface* GetRenderer();
virtual const char* kind() const;
virtual const std::string& label() const { return label_; }
virtual std::string label() const { return label_; }
virtual TrackType type() const { return kVideo; }
virtual uint32 ssrc() const { return ssrc_; }
virtual bool enabled() const { return enabled_; }

View File

@ -250,10 +250,11 @@ void Conductor::AddStreams() {
return; // Already added.
scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track(
webrtc::CreateLocalAudioTrack(kAudioLabel, NULL));
peer_connection_factory_->CreateLocalAudioTrack(kAudioLabel, NULL));
scoped_refptr<webrtc::LocalVideoTrackInterface> video_track(
webrtc::CreateLocalVideoTrack(kVideoLabel, OpenVideoCaptureDevice()));
peer_connection_factory_->CreateLocalVideoTrack(
kVideoLabel, OpenVideoCaptureDevice()));
scoped_refptr<webrtc::VideoRendererInterface> renderer(
webrtc::CreateVideoRenderer(