Initial wiring of new webrtc API in libjingle.
BUG=1788 R=pthatcher@google.com, pthatcher@webrtc.org TBR=juberti@webrtc.org, mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/8549005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6104 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
6b02eea6ac
commit
d266a2020f
@ -111,9 +111,9 @@ enum {
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
scoped_refptr<PeerConnectionFactoryInterface>
|
talk_base::scoped_refptr<PeerConnectionFactoryInterface>
|
||||||
CreatePeerConnectionFactory() {
|
CreatePeerConnectionFactory() {
|
||||||
scoped_refptr<PeerConnectionFactory> pc_factory(
|
talk_base::scoped_refptr<PeerConnectionFactory> pc_factory(
|
||||||
new talk_base::RefCountedObject<PeerConnectionFactory>());
|
new talk_base::RefCountedObject<PeerConnectionFactory>());
|
||||||
|
|
||||||
if (!pc_factory->Initialize()) {
|
if (!pc_factory->Initialize()) {
|
||||||
@ -122,17 +122,19 @@ CreatePeerConnectionFactory() {
|
|||||||
return pc_factory;
|
return pc_factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<PeerConnectionFactoryInterface>
|
talk_base::scoped_refptr<PeerConnectionFactoryInterface>
|
||||||
CreatePeerConnectionFactory(
|
CreatePeerConnectionFactory(
|
||||||
talk_base::Thread* worker_thread,
|
talk_base::Thread* worker_thread,
|
||||||
talk_base::Thread* signaling_thread,
|
talk_base::Thread* signaling_thread,
|
||||||
AudioDeviceModule* default_adm,
|
AudioDeviceModule* default_adm,
|
||||||
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
||||||
cricket::WebRtcVideoDecoderFactory* decoder_factory) {
|
cricket::WebRtcVideoDecoderFactory* decoder_factory) {
|
||||||
scoped_refptr<PeerConnectionFactory> pc_factory(
|
talk_base::scoped_refptr<PeerConnectionFactory> pc_factory(
|
||||||
new talk_base::RefCountedObject<PeerConnectionFactory>(
|
new talk_base::RefCountedObject<PeerConnectionFactory>(worker_thread,
|
||||||
worker_thread, signaling_thread, default_adm,
|
signaling_thread,
|
||||||
encoder_factory, decoder_factory));
|
default_adm,
|
||||||
|
encoder_factory,
|
||||||
|
decoder_factory));
|
||||||
if (!pc_factory->Initialize()) {
|
if (!pc_factory->Initialize()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -278,7 +280,7 @@ bool PeerConnectionFactory::StartAecDump_s(talk_base::PlatformFile file) {
|
|||||||
return channel_manager_->StartAecDump(file);
|
return channel_manager_->StartAecDump(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<PeerConnectionInterface>
|
talk_base::scoped_refptr<PeerConnectionInterface>
|
||||||
PeerConnectionFactory::CreatePeerConnection(
|
PeerConnectionFactory::CreatePeerConnection(
|
||||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||||
const MediaConstraintsInterface* constraints,
|
const MediaConstraintsInterface* constraints,
|
||||||
@ -314,7 +316,7 @@ PeerConnectionFactory::CreatePeerConnection_s(
|
|||||||
return PeerConnectionProxy::Create(signaling_thread(), pc);
|
return PeerConnectionProxy::Create(signaling_thread(), pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<MediaStreamInterface>
|
talk_base::scoped_refptr<MediaStreamInterface>
|
||||||
PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
|
PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
|
||||||
return MediaStreamProxy::Create(signaling_thread_,
|
return MediaStreamProxy::Create(signaling_thread_,
|
||||||
MediaStream::Create(label));
|
MediaStream::Create(label));
|
||||||
@ -348,9 +350,9 @@ PeerConnectionFactory::CreateVideoTrack(
|
|||||||
return VideoTrackProxy::Create(signaling_thread_, track);
|
return VideoTrackProxy::Create(signaling_thread_, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<AudioTrackInterface> PeerConnectionFactory::CreateAudioTrack(
|
talk_base::scoped_refptr<AudioTrackInterface>
|
||||||
const std::string& id,
|
PeerConnectionFactory::CreateAudioTrack(const std::string& id,
|
||||||
AudioSourceInterface* source) {
|
AudioSourceInterface* source) {
|
||||||
talk_base::scoped_refptr<AudioTrackInterface> track(
|
talk_base::scoped_refptr<AudioTrackInterface> track(
|
||||||
AudioTrack::Create(id, source));
|
AudioTrack::Create(id, source));
|
||||||
return AudioTrackProxy::Create(signaling_thread_, track);
|
return AudioTrackProxy::Create(signaling_thread_, track);
|
||||||
|
@ -806,7 +806,7 @@
|
|||||||
'<(DEPTH)/third_party/usrsctp/usrsctp.gyp:usrsctplib',
|
'<(DEPTH)/third_party/usrsctp/usrsctp.gyp:usrsctplib',
|
||||||
'<(webrtc_root)/modules/modules.gyp:video_capture_module',
|
'<(webrtc_root)/modules/modules.gyp:video_capture_module',
|
||||||
'<(webrtc_root)/modules/modules.gyp:video_render_module',
|
'<(webrtc_root)/modules/modules.gyp:video_render_module',
|
||||||
'<(webrtc_root)/video_engine/video_engine.gyp:video_engine_core',
|
'<(webrtc_root)/webrtc.gyp:webrtc',
|
||||||
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
|
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
|
||||||
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
|
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
|
||||||
'libjingle',
|
'libjingle',
|
||||||
@ -889,6 +889,8 @@
|
|||||||
'media/webrtc/webrtcvideoencoderfactory.h',
|
'media/webrtc/webrtcvideoencoderfactory.h',
|
||||||
'media/webrtc/webrtcvideoengine.cc',
|
'media/webrtc/webrtcvideoengine.cc',
|
||||||
'media/webrtc/webrtcvideoengine.h',
|
'media/webrtc/webrtcvideoengine.h',
|
||||||
|
'media/webrtc/webrtcvideoengine2.cc',
|
||||||
|
'media/webrtc/webrtcvideoengine2.h',
|
||||||
'media/webrtc/webrtcvideoframe.cc',
|
'media/webrtc/webrtcvideoframe.cc',
|
||||||
'media/webrtc/webrtcvideoframe.h',
|
'media/webrtc/webrtcvideoframe.h',
|
||||||
'media/webrtc/webrtcvie.h',
|
'media/webrtc/webrtcvie.h',
|
||||||
|
@ -300,6 +300,7 @@
|
|||||||
# TODO(ronghuawu): Reenable these tests.
|
# TODO(ronghuawu): Reenable these tests.
|
||||||
# 'media/devices/devicemanager_unittest.cc',
|
# 'media/devices/devicemanager_unittest.cc',
|
||||||
'media/webrtc/webrtcvideoengine_unittest.cc',
|
'media/webrtc/webrtcvideoengine_unittest.cc',
|
||||||
|
'media/webrtc/webrtcvideoengine2_unittest.cc',
|
||||||
'media/webrtc/webrtcvoiceengine_unittest.cc',
|
'media/webrtc/webrtcvoiceengine_unittest.cc',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "talk/base/common.h"
|
#include "talk/base/common.h"
|
||||||
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/stringencode.h"
|
#include "talk/base/stringencode.h"
|
||||||
#include "talk/base/stringutils.h"
|
#include "talk/base/stringutils.h"
|
||||||
|
|
||||||
@ -160,6 +161,55 @@ std::string VideoCodec::ToString() const {
|
|||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoCodec VideoCodec::CreateRtxCodec(int rtx_payload_type,
|
||||||
|
int associated_payload_type) {
|
||||||
|
VideoCodec rtx_codec(rtx_payload_type, kRtxCodecName, 0, 0, 0, 0);
|
||||||
|
rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type);
|
||||||
|
return rtx_codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoCodec::CodecType VideoCodec::GetCodecType() const {
|
||||||
|
const char* payload_name = name.c_str();
|
||||||
|
if (_stricmp(payload_name, kRedCodecName) == 0) {
|
||||||
|
return CODEC_RED;
|
||||||
|
}
|
||||||
|
if (_stricmp(payload_name, kUlpfecCodecName) == 0) {
|
||||||
|
return CODEC_ULPFEC;
|
||||||
|
}
|
||||||
|
if (_stricmp(payload_name, kRtxCodecName) == 0) {
|
||||||
|
return CODEC_RTX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CODEC_VIDEO;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoCodec::ValidateCodecFormat() const {
|
||||||
|
if (id < 0 || id > 127) {
|
||||||
|
LOG(LS_ERROR) << "Codec with invalid payload type: " << ToString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (GetCodecType() != CODEC_VIDEO) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Video validation from here on.
|
||||||
|
|
||||||
|
if (width <= 0 || height <= 0) {
|
||||||
|
LOG(LS_ERROR) << "Codec with invalid dimensions: " << ToString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int min_bitrate;
|
||||||
|
int max_bitrate;
|
||||||
|
if (GetParam(kCodecParamMinBitrate, &min_bitrate) &&
|
||||||
|
GetParam(kCodecParamMaxBitrate, &max_bitrate)) {
|
||||||
|
if (max_bitrate < min_bitrate) {
|
||||||
|
LOG(LS_ERROR) << "Codec with max < min bitrate: " << ToString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string DataCodec::ToString() const {
|
std::string DataCodec::ToString() const {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "DataCodec[" << id << ":" << name << "]";
|
os << "DataCodec[" << id << ":" << name << "]";
|
||||||
|
@ -246,6 +246,22 @@ struct VideoCodec : public Codec {
|
|||||||
bool operator!=(const VideoCodec& c) const {
|
bool operator!=(const VideoCodec& c) const {
|
||||||
return !(*this == c);
|
return !(*this == c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VideoCodec CreateRtxCodec(int rtx_payload_type,
|
||||||
|
int associated_payload_type);
|
||||||
|
|
||||||
|
enum CodecType {
|
||||||
|
CODEC_VIDEO,
|
||||||
|
CODEC_RED,
|
||||||
|
CODEC_ULPFEC,
|
||||||
|
CODEC_RTX,
|
||||||
|
};
|
||||||
|
|
||||||
|
CodecType GetCodecType() const;
|
||||||
|
// Validates a VideoCodec's payload type, dimensions and bitrates etc. If they
|
||||||
|
// don't make sense (such as max < min bitrate), and error is logged and
|
||||||
|
// ValidateCodecFormat returns false.
|
||||||
|
bool ValidateCodecFormat() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DataCodec : public Codec {
|
struct DataCodec : public Codec {
|
||||||
|
@ -34,6 +34,9 @@ using cricket::DataCodec;
|
|||||||
using cricket::FeedbackParam;
|
using cricket::FeedbackParam;
|
||||||
using cricket::VideoCodec;
|
using cricket::VideoCodec;
|
||||||
using cricket::VideoEncoderConfig;
|
using cricket::VideoEncoderConfig;
|
||||||
|
using cricket::kCodecParamAssociatedPayloadType;
|
||||||
|
using cricket::kCodecParamMaxBitrate;
|
||||||
|
using cricket::kCodecParamMinBitrate;
|
||||||
|
|
||||||
class CodecTest : public testing::Test {
|
class CodecTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
@ -312,3 +315,81 @@ TEST_F(CodecTest, TestIntersectFeedbackParams) {
|
|||||||
EXPECT_FALSE(c1.HasFeedbackParam(b2));
|
EXPECT_FALSE(c1.HasFeedbackParam(b2));
|
||||||
EXPECT_FALSE(c1.HasFeedbackParam(c3));
|
EXPECT_FALSE(c1.HasFeedbackParam(c3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CodecTest, TestGetCodecType) {
|
||||||
|
// Codec type comparison should be case insenstive on names.
|
||||||
|
const VideoCodec codec(96, "V", 320, 200, 30, 3);
|
||||||
|
const VideoCodec rtx_codec(96, "rTx", 320, 200, 30, 3);
|
||||||
|
const VideoCodec ulpfec_codec(96, "ulpFeC", 320, 200, 30, 3);
|
||||||
|
const VideoCodec red_codec(96, "ReD", 320, 200, 30, 3);
|
||||||
|
EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType());
|
||||||
|
EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
|
||||||
|
EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType());
|
||||||
|
EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CodecTest, TestCreateRtxCodec) {
|
||||||
|
VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
|
||||||
|
EXPECT_EQ(96, rtx_codec.id);
|
||||||
|
EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
|
||||||
|
int associated_payload_type;
|
||||||
|
ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
|
||||||
|
&associated_payload_type));
|
||||||
|
EXPECT_EQ(120, associated_payload_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CodecTest, TestValidateCodecFormat) {
|
||||||
|
const VideoCodec codec(96, "V", 320, 200, 30, 3);
|
||||||
|
ASSERT_TRUE(codec.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Accept 0-127 as payload types.
|
||||||
|
VideoCodec low_payload_type = codec;
|
||||||
|
low_payload_type.id = 0;
|
||||||
|
VideoCodec high_payload_type = codec;
|
||||||
|
high_payload_type.id = 127;
|
||||||
|
ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
|
||||||
|
EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Reject negative payloads.
|
||||||
|
VideoCodec negative_payload_type = codec;
|
||||||
|
negative_payload_type.id = -1;
|
||||||
|
EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Reject too-high payloads.
|
||||||
|
VideoCodec too_high_payload_type = codec;
|
||||||
|
too_high_payload_type.id = 128;
|
||||||
|
EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Reject zero-width codecs.
|
||||||
|
VideoCodec zero_width = codec;
|
||||||
|
zero_width.width = 0;
|
||||||
|
EXPECT_FALSE(zero_width.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Reject zero-height codecs.
|
||||||
|
VideoCodec zero_height = codec;
|
||||||
|
zero_height.height = 0;
|
||||||
|
EXPECT_FALSE(zero_height.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Accept non-video codecs with zero dimensions.
|
||||||
|
VideoCodec zero_width_rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
|
||||||
|
zero_width_rtx_codec.width = 0;
|
||||||
|
EXPECT_TRUE(zero_width_rtx_codec.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Reject codecs with min bitrate > max bitrate.
|
||||||
|
VideoCodec incorrect_bitrates = codec;
|
||||||
|
incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
|
||||||
|
incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
|
||||||
|
EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Accept min bitrate == max bitrate.
|
||||||
|
VideoCodec equal_bitrates = codec;
|
||||||
|
equal_bitrates.params[kCodecParamMinBitrate] = "100";
|
||||||
|
equal_bitrates.params[kCodecParamMaxBitrate] = "100";
|
||||||
|
EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
|
||||||
|
|
||||||
|
// Accept min bitrate < max bitrate.
|
||||||
|
VideoCodec different_bitrates = codec;
|
||||||
|
different_bitrates.params[kCodecParamMinBitrate] = "99";
|
||||||
|
different_bitrates.params[kCodecParamMaxBitrate] = "100";
|
||||||
|
EXPECT_TRUE(different_bitrates.ValidateCodecFormat());
|
||||||
|
}
|
||||||
|
@ -40,6 +40,8 @@ const float kLowSystemCpuThreshold = 0.65f;
|
|||||||
const float kProcessCpuThreshold = 0.10f;
|
const float kProcessCpuThreshold = 0.10f;
|
||||||
|
|
||||||
const char kRtxCodecName[] = "rtx";
|
const char kRtxCodecName[] = "rtx";
|
||||||
|
const char kRedCodecName[] = "red";
|
||||||
|
const char kUlpfecCodecName[] = "ulpfec";
|
||||||
|
|
||||||
// RTP payload type is in the 0-127 range. Use 128 to indicate "all" payload
|
// RTP payload type is in the 0-127 range. Use 128 to indicate "all" payload
|
||||||
// types.
|
// types.
|
||||||
|
@ -44,6 +44,9 @@ extern const float kLowSystemCpuThreshold;
|
|||||||
extern const float kProcessCpuThreshold;
|
extern const float kProcessCpuThreshold;
|
||||||
|
|
||||||
extern const char kRtxCodecName[];
|
extern const char kRtxCodecName[];
|
||||||
|
extern const char kRedCodecName[];
|
||||||
|
extern const char kUlpfecCodecName[];
|
||||||
|
|
||||||
|
|
||||||
// Codec parameters
|
// Codec parameters
|
||||||
extern const int kWildcardPayloadType;
|
extern const int kWildcardPayloadType;
|
||||||
|
44
talk/media/webrtc/webrtcvideochannelfactory.h
Normal file
44
talk/media/webrtc/webrtcvideochannelfactory.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2004 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TALK_MEDIA_WEBRTC_WEBRTCVIDEOCHANNEL_H_
|
||||||
|
#define TALK_MEDIA_WEBRTC_WEBRTCVIDEOCHANNEL_H_
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
class VoiceMediaChannel;
|
||||||
|
class WebRtcVideoEngine2;
|
||||||
|
class WebRtcVideoChannel2;
|
||||||
|
|
||||||
|
class WebRtcVideoChannelFactory {
|
||||||
|
public:
|
||||||
|
virtual ~WebRtcVideoChannelFactory() {}
|
||||||
|
virtual WebRtcVideoChannel2* Create(WebRtcVideoEngine2* engine,
|
||||||
|
VoiceMediaChannel* voice_channel) = 0;
|
||||||
|
};
|
||||||
|
} // namespace cricket
|
||||||
|
|
||||||
|
#endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOCHANNEL_H_
|
1658
talk/media/webrtc/webrtcvideoengine2.cc
Normal file
1658
talk/media/webrtc/webrtcvideoengine2.cc
Normal file
File diff suppressed because it is too large
Load Diff
332
talk/media/webrtc/webrtcvideoengine2.h
Normal file
332
talk/media/webrtc/webrtcvideoengine2.h
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2014 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_H_
|
||||||
|
#define TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "talk/base/cpumonitor.h"
|
||||||
|
#include "talk/base/scoped_ptr.h"
|
||||||
|
#include "talk/media/base/mediaengine.h"
|
||||||
|
#include "talk/media/webrtc/webrtcvideochannelfactory.h"
|
||||||
|
#include "webrtc/common_video/interface/i420_video_frame.h"
|
||||||
|
#include "webrtc/system_wrappers/interface/thread_annotations.h"
|
||||||
|
#include "webrtc/transport.h"
|
||||||
|
#include "webrtc/video_renderer.h"
|
||||||
|
#include "webrtc/video_send_stream.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
class Call;
|
||||||
|
class VideoCaptureModule;
|
||||||
|
class VideoDecoder;
|
||||||
|
class VideoEncoder;
|
||||||
|
class VideoRender;
|
||||||
|
class VideoSendStreamInput;
|
||||||
|
class VideoReceiveStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace talk_base {
|
||||||
|
class CpuMonitor;
|
||||||
|
class Thread;
|
||||||
|
} // namespace talk_base
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
|
class VideoCapturer;
|
||||||
|
class VideoFrame;
|
||||||
|
class VideoProcessor;
|
||||||
|
class VideoRenderer;
|
||||||
|
class VoiceMediaChannel;
|
||||||
|
class WebRtcVideoChannel2;
|
||||||
|
class WebRtcDecoderObserver;
|
||||||
|
class WebRtcEncoderObserver;
|
||||||
|
class WebRtcLocalStreamInfo;
|
||||||
|
class WebRtcRenderAdapter;
|
||||||
|
class WebRtcVideoChannelRecvInfo;
|
||||||
|
class WebRtcVideoChannelSendInfo;
|
||||||
|
class WebRtcVideoDecoderFactory;
|
||||||
|
class WebRtcVoiceEngine;
|
||||||
|
|
||||||
|
struct CapturedFrame;
|
||||||
|
struct Device;
|
||||||
|
|
||||||
|
class WebRtcVideoEngine2;
|
||||||
|
class WebRtcVideoChannel2;
|
||||||
|
|
||||||
|
class WebRtcVideoEncoderFactory2 {
|
||||||
|
public:
|
||||||
|
virtual bool CreateEncoderSettings(
|
||||||
|
webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings,
|
||||||
|
const VideoOptions& options,
|
||||||
|
const cricket::VideoCodec& codec,
|
||||||
|
size_t num_streams) = 0;
|
||||||
|
virtual bool SupportsCodec(const cricket::VideoCodec& codec) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// WebRtcVideoEngine2 is used for the new native WebRTC Video API (webrtc:1667).
|
||||||
|
class WebRtcVideoEngine2 : public sigslot::has_slots<> {
|
||||||
|
public:
|
||||||
|
// Creates the WebRtcVideoEngine2 with internal VideoCaptureModule.
|
||||||
|
WebRtcVideoEngine2();
|
||||||
|
// Custom WebRtcVideoChannelFactory for testing purposes.
|
||||||
|
explicit WebRtcVideoEngine2(WebRtcVideoChannelFactory* channel_factory);
|
||||||
|
~WebRtcVideoEngine2();
|
||||||
|
|
||||||
|
// Basic video engine implementation.
|
||||||
|
bool Init(talk_base::Thread* worker_thread);
|
||||||
|
void Terminate();
|
||||||
|
|
||||||
|
int GetCapabilities();
|
||||||
|
bool SetOptions(const VideoOptions& options);
|
||||||
|
bool SetDefaultEncoderConfig(const VideoEncoderConfig& config);
|
||||||
|
VideoEncoderConfig GetDefaultEncoderConfig() const;
|
||||||
|
|
||||||
|
WebRtcVideoChannel2* CreateChannel(VoiceMediaChannel* voice_channel);
|
||||||
|
|
||||||
|
const std::vector<VideoCodec>& codecs() const;
|
||||||
|
const std::vector<RtpHeaderExtension>& rtp_header_extensions() const;
|
||||||
|
void SetLogging(int min_sev, const char* filter);
|
||||||
|
|
||||||
|
bool EnableTimedRender();
|
||||||
|
// No-op, never used.
|
||||||
|
bool SetLocalRenderer(VideoRenderer* renderer);
|
||||||
|
// This is currently ignored.
|
||||||
|
sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange;
|
||||||
|
|
||||||
|
// Set the VoiceEngine for A/V sync. This can only be called before Init.
|
||||||
|
bool SetVoiceEngine(WebRtcVoiceEngine* voice_engine);
|
||||||
|
|
||||||
|
// Functions called by WebRtcVideoChannel2.
|
||||||
|
const VideoFormat& default_codec_format() const {
|
||||||
|
return default_codec_format_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FindCodec(const VideoCodec& in);
|
||||||
|
bool CanSendCodec(const VideoCodec& in,
|
||||||
|
const VideoCodec& current,
|
||||||
|
VideoCodec* out);
|
||||||
|
// Check whether the supplied trace should be ignored.
|
||||||
|
bool ShouldIgnoreTrace(const std::string& trace);
|
||||||
|
|
||||||
|
VideoFormat GetStartCaptureFormat() const { return default_codec_format_; }
|
||||||
|
|
||||||
|
talk_base::CpuMonitor* cpu_monitor() { return cpu_monitor_.get(); }
|
||||||
|
|
||||||
|
virtual WebRtcVideoEncoderFactory2* GetDefaultVideoEncoderFactory() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Construct(WebRtcVideoChannelFactory* channel_factory,
|
||||||
|
WebRtcVoiceEngine* voice_engine,
|
||||||
|
talk_base::CpuMonitor* cpu_monitor);
|
||||||
|
|
||||||
|
talk_base::Thread* worker_thread_;
|
||||||
|
WebRtcVoiceEngine* voice_engine_;
|
||||||
|
std::vector<VideoCodec> video_codecs_;
|
||||||
|
std::vector<RtpHeaderExtension> rtp_header_extensions_;
|
||||||
|
VideoFormat default_codec_format_;
|
||||||
|
|
||||||
|
bool initialized_;
|
||||||
|
|
||||||
|
bool capture_started_;
|
||||||
|
|
||||||
|
// Critical section to protect the media processor register/unregister
|
||||||
|
// while processing a frame
|
||||||
|
talk_base::CriticalSection signal_media_critical_;
|
||||||
|
|
||||||
|
talk_base::scoped_ptr<talk_base::CpuMonitor> cpu_monitor_;
|
||||||
|
WebRtcVideoChannelFactory* channel_factory_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Adapter between webrtc::VideoRenderer and cricket::VideoRenderer.
|
||||||
|
// The webrtc::VideoRenderer is set once, whereas the cricket::VideoRenderer can
|
||||||
|
// be set after initialization. This adapter will also convert the incoming
|
||||||
|
// webrtc::I420VideoFrame to a frame type that cricket::VideoRenderer can
|
||||||
|
// render.
|
||||||
|
class WebRtcVideoRenderer : public webrtc::VideoRenderer {
|
||||||
|
public:
|
||||||
|
WebRtcVideoRenderer();
|
||||||
|
|
||||||
|
virtual void RenderFrame(const webrtc::I420VideoFrame& frame,
|
||||||
|
int time_to_render_ms) OVERRIDE;
|
||||||
|
|
||||||
|
void SetRenderer(cricket::VideoRenderer* renderer);
|
||||||
|
cricket::VideoRenderer* GetRenderer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetSize(int width, int height);
|
||||||
|
int last_width_;
|
||||||
|
int last_height_;
|
||||||
|
talk_base::CriticalSection lock_;
|
||||||
|
cricket::VideoRenderer* renderer_ GUARDED_BY(lock_);
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebRtcVideoChannel2 : public talk_base::MessageHandler,
|
||||||
|
public VideoMediaChannel,
|
||||||
|
public webrtc::newapi::Transport {
|
||||||
|
public:
|
||||||
|
WebRtcVideoChannel2(WebRtcVideoEngine2* engine,
|
||||||
|
VoiceMediaChannel* voice_channel,
|
||||||
|
WebRtcVideoEncoderFactory2* encoder_factory);
|
||||||
|
// For testing purposes insert a pre-constructed call to verify that
|
||||||
|
// WebRtcVideoChannel2 calls the correct corresponding methods.
|
||||||
|
WebRtcVideoChannel2(webrtc::Call* call,
|
||||||
|
WebRtcVideoEngine2* engine,
|
||||||
|
WebRtcVideoEncoderFactory2* encoder_factory);
|
||||||
|
~WebRtcVideoChannel2();
|
||||||
|
bool Init();
|
||||||
|
|
||||||
|
// VideoMediaChannel implementation
|
||||||
|
virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) OVERRIDE;
|
||||||
|
virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) OVERRIDE;
|
||||||
|
virtual bool GetSendCodec(VideoCodec* send_codec) OVERRIDE;
|
||||||
|
virtual bool SetSendStreamFormat(uint32 ssrc,
|
||||||
|
const VideoFormat& format) OVERRIDE;
|
||||||
|
virtual bool SetRender(bool render) OVERRIDE;
|
||||||
|
virtual bool SetSend(bool send) OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool AddSendStream(const StreamParams& sp) OVERRIDE;
|
||||||
|
virtual bool RemoveSendStream(uint32 ssrc) OVERRIDE;
|
||||||
|
virtual bool AddRecvStream(const StreamParams& sp) OVERRIDE;
|
||||||
|
virtual bool RemoveRecvStream(uint32 ssrc) OVERRIDE;
|
||||||
|
virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) OVERRIDE;
|
||||||
|
virtual bool GetStats(const StatsOptions& options,
|
||||||
|
VideoMediaInfo* info) OVERRIDE;
|
||||||
|
virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) OVERRIDE;
|
||||||
|
virtual bool SendIntraFrame() OVERRIDE;
|
||||||
|
virtual bool RequestIntraFrame() OVERRIDE;
|
||||||
|
|
||||||
|
virtual void OnPacketReceived(talk_base::Buffer* packet,
|
||||||
|
const talk_base::PacketTime& packet_time)
|
||||||
|
OVERRIDE;
|
||||||
|
virtual void OnRtcpReceived(talk_base::Buffer* packet,
|
||||||
|
const talk_base::PacketTime& packet_time)
|
||||||
|
OVERRIDE;
|
||||||
|
virtual void OnReadyToSend(bool ready) OVERRIDE;
|
||||||
|
virtual bool MuteStream(uint32 ssrc, bool mute) OVERRIDE;
|
||||||
|
virtual bool SetRecvRtpHeaderExtensions(
|
||||||
|
const std::vector<RtpHeaderExtension>& extensions) OVERRIDE;
|
||||||
|
virtual bool SetSendRtpHeaderExtensions(
|
||||||
|
const std::vector<RtpHeaderExtension>& extensions) OVERRIDE;
|
||||||
|
virtual bool SetStartSendBandwidth(int bps) OVERRIDE;
|
||||||
|
virtual bool SetMaxSendBandwidth(int bps) OVERRIDE;
|
||||||
|
virtual bool SetOptions(const VideoOptions& options) OVERRIDE;
|
||||||
|
virtual bool GetOptions(VideoOptions* options) const OVERRIDE {
|
||||||
|
*options = options_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual void SetInterface(NetworkInterface* iface) OVERRIDE;
|
||||||
|
virtual void UpdateAspectRatio(int ratio_w, int ratio_h) OVERRIDE;
|
||||||
|
|
||||||
|
virtual void OnMessage(talk_base::Message* msg) OVERRIDE;
|
||||||
|
|
||||||
|
// Implemented for VideoMediaChannelTest.
|
||||||
|
bool sending() const { return sending_; }
|
||||||
|
uint32 GetDefaultChannelSsrc() { return default_send_ssrc_; }
|
||||||
|
bool GetRenderer(uint32 ssrc, VideoRenderer** renderer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct VideoCodecSettings {
|
||||||
|
VideoCodecSettings();
|
||||||
|
|
||||||
|
cricket::VideoCodec codec;
|
||||||
|
webrtc::FecConfig fec;
|
||||||
|
int rtx_payload_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebRtcVideoSendStream : public sigslot::has_slots<> {
|
||||||
|
public:
|
||||||
|
WebRtcVideoSendStream(webrtc::Call* call,
|
||||||
|
const webrtc::VideoSendStream::Config& config,
|
||||||
|
WebRtcVideoEncoderFactory2* encoder_factory);
|
||||||
|
~WebRtcVideoSendStream();
|
||||||
|
void SetCodec(const VideoOptions& options, const VideoCodecSettings& codec);
|
||||||
|
|
||||||
|
void InputFrame(VideoCapturer* capturer, const VideoFrame* frame);
|
||||||
|
bool SetCapturer(VideoCapturer* capturer);
|
||||||
|
bool SetVideoFormat(const VideoFormat& format);
|
||||||
|
bool MuteStream(bool mute);
|
||||||
|
bool DisconnectCapturer();
|
||||||
|
|
||||||
|
void Start();
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RecreateWebRtcStream();
|
||||||
|
void SetDimensions(int width, int height);
|
||||||
|
|
||||||
|
webrtc::Call* const call_;
|
||||||
|
WebRtcVideoEncoderFactory2* const encoder_factory_;
|
||||||
|
|
||||||
|
talk_base::CriticalSection lock_;
|
||||||
|
webrtc::VideoSendStream* stream_ GUARDED_BY(lock_);
|
||||||
|
webrtc::VideoSendStream::Config config_ GUARDED_BY(lock_);
|
||||||
|
VideoCapturer* capturer_ GUARDED_BY(lock_);
|
||||||
|
bool sending_ GUARDED_BY(lock_);
|
||||||
|
bool muted_ GUARDED_BY(lock_);
|
||||||
|
VideoFormat format_ GUARDED_BY(lock_);
|
||||||
|
|
||||||
|
talk_base::CriticalSection frame_lock_;
|
||||||
|
webrtc::I420VideoFrame video_frame_ GUARDED_BY(frame_lock_);
|
||||||
|
};
|
||||||
|
|
||||||
|
void Construct(webrtc::Call* call, WebRtcVideoEngine2* engine);
|
||||||
|
|
||||||
|
virtual bool SendRtp(const uint8_t* data, size_t len) OVERRIDE;
|
||||||
|
virtual bool SendRtcp(const uint8_t* data, size_t len) OVERRIDE;
|
||||||
|
|
||||||
|
void StartAllSendStreams();
|
||||||
|
void StopAllSendStreams();
|
||||||
|
void SetCodecForAllSendStreams(const VideoCodecSettings& codec);
|
||||||
|
static std::vector<VideoCodecSettings> MapCodecs(
|
||||||
|
const std::vector<VideoCodec>& codecs);
|
||||||
|
std::vector<VideoCodecSettings> FilterSupportedCodecs(
|
||||||
|
const std::vector<VideoCodecSettings>& mapped_codecs);
|
||||||
|
|
||||||
|
uint32_t rtcp_receiver_report_ssrc_;
|
||||||
|
bool sending_;
|
||||||
|
talk_base::scoped_ptr<webrtc::Call> call_;
|
||||||
|
std::map<uint32, WebRtcVideoRenderer*> renderers_;
|
||||||
|
VideoRenderer* default_renderer_;
|
||||||
|
uint32_t default_send_ssrc_;
|
||||||
|
uint32_t default_recv_ssrc_;
|
||||||
|
|
||||||
|
// Using primary-ssrc (first ssrc) as key.
|
||||||
|
std::map<uint32, WebRtcVideoSendStream*> send_streams_;
|
||||||
|
std::map<uint32, webrtc::VideoReceiveStream*> receive_streams_;
|
||||||
|
|
||||||
|
Settable<VideoCodecSettings> send_codec_;
|
||||||
|
WebRtcVideoEncoderFactory2* const encoder_factory_;
|
||||||
|
std::vector<VideoCodecSettings> recv_codecs_;
|
||||||
|
VideoOptions options_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cricket
|
||||||
|
|
||||||
|
#endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_H_
|
1187
talk/media/webrtc/webrtcvideoengine2_unittest.cc
Normal file
1187
talk/media/webrtc/webrtcvideoengine2_unittest.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,3 +5,8 @@ WebRtcVideoMediaChannelTest.TwoStreamsSendAndFailUnsignalledRecv
|
|||||||
WebRtcVideoMediaChannelTest.TwoStreamsSendAndFailUnsignalledRecvInOneToOne
|
WebRtcVideoMediaChannelTest.TwoStreamsSendAndFailUnsignalledRecvInOneToOne
|
||||||
WebRtcVideoMediaChannelTest.TwoStreamsSendAndReceive
|
WebRtcVideoMediaChannelTest.TwoStreamsSendAndReceive
|
||||||
WebRtcVideoMediaChannelTest.TwoStreamsSendAndUnsignalledRecv
|
WebRtcVideoMediaChannelTest.TwoStreamsSendAndUnsignalledRecv
|
||||||
|
|
||||||
|
TODO(pbos): This suppression is overly broad, but offline talks with kjellander@
|
||||||
|
indicate that we can move over to tsanv2 and deprecate tsanv1, which will remove
|
||||||
|
the need for tsanv1 suppressions.
|
||||||
|
WebRtcVideoChannel2BaseTest.*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user