Refactor webrtcvideoengines to have the default list of supported codecs being generated in runtime.
This will allow to plugin VP9 based on a field trial. R=pbos@webrtc.org, pbos, pthatcher Review URL: https://webrtc-codereview.appspot.com/27949004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7658 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
5e160660a6
commit
82775b1396
@ -35,7 +35,9 @@ extern const int kVideoRtpBufferSize;
|
|||||||
extern const char kVp8CodecName[];
|
extern const char kVp8CodecName[];
|
||||||
extern const char kH264CodecName[];
|
extern const char kH264CodecName[];
|
||||||
|
|
||||||
extern const int kDefaultFramerate;
|
extern const int kDefaultVideoMaxWidth;
|
||||||
|
extern const int kDefaultVideoMaxHeight;
|
||||||
|
extern const int kDefaultVideoMaxFramerate;
|
||||||
extern const int kMinVideoBitrate;
|
extern const int kMinVideoBitrate;
|
||||||
extern const int kStartVideoBitrate;
|
extern const int kStartVideoBitrate;
|
||||||
extern const int kMaxVideoBitrate;
|
extern const int kMaxVideoBitrate;
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "webrtc/base/basictypes.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
#include "webrtc/base/buffer.h"
|
#include "webrtc/base/buffer.h"
|
||||||
#include "webrtc/base/byteorder.h"
|
#include "webrtc/base/byteorder.h"
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/common.h"
|
#include "webrtc/base/common.h"
|
||||||
#include "webrtc/base/cpumonitor.h"
|
#include "webrtc/base/cpumonitor.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
@ -106,7 +107,10 @@ const int kVideoRtpBufferSize = 65536;
|
|||||||
|
|
||||||
const char kVp8CodecName[] = "VP8";
|
const char kVp8CodecName[] = "VP8";
|
||||||
|
|
||||||
const int kDefaultFramerate = 30;
|
// TODO(ronghuawu): Change to 640x360.
|
||||||
|
const int kDefaultVideoMaxWidth = 640;
|
||||||
|
const int kDefaultVideoMaxHeight = 400;
|
||||||
|
const int kDefaultVideoMaxFramerate = 30;
|
||||||
const int kMinVideoBitrate = 30;
|
const int kMinVideoBitrate = 30;
|
||||||
const int kStartVideoBitrate = 300;
|
const int kStartVideoBitrate = 300;
|
||||||
const int kMaxVideoBitrate = 2000;
|
const int kMaxVideoBitrate = 2000;
|
||||||
@ -176,15 +180,57 @@ static const bool kNotSending = false;
|
|||||||
static const rtc::DiffServCodePoint kVideoDscpValue =
|
static const rtc::DiffServCodePoint kVideoDscpValue =
|
||||||
rtc::DSCP_AF41;
|
rtc::DSCP_AF41;
|
||||||
|
|
||||||
static bool IsNackEnabled(const VideoCodec& codec) {
|
bool IsNackEnabled(const VideoCodec& codec) {
|
||||||
return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack,
|
return codec.HasFeedbackParam(
|
||||||
kParamValueEmpty));
|
FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if Receiver Estimated Max Bitrate is enabled.
|
bool IsRembEnabled(const VideoCodec& codec) {
|
||||||
static bool IsRembEnabled(const VideoCodec& codec) {
|
return codec.HasFeedbackParam(
|
||||||
return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamRemb,
|
FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty));
|
||||||
kParamValueEmpty));
|
}
|
||||||
|
|
||||||
|
void AddDefaultFeedbackParams(VideoCodec* codec) {
|
||||||
|
codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir));
|
||||||
|
codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
|
||||||
|
codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli));
|
||||||
|
codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CodecNameMatches(const std::string& name1, const std::string& name2) {
|
||||||
|
return _stricmp(name1.c_str(), name2.c_str()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type,
|
||||||
|
const char* name) {
|
||||||
|
VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth,
|
||||||
|
kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0);
|
||||||
|
AddDefaultFeedbackParams(&codec);
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VideoCodec MakeVideoCodec(int payload_type, const char* name) {
|
||||||
|
return VideoCodec(payload_type, name, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VideoCodec MakeRtxCodec(int payload_type, int associated_payload_type) {
|
||||||
|
return VideoCodec::CreateRtxCodec(payload_type, associated_payload_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CodecIsInternallySupported(const std::string& codec_name) {
|
||||||
|
if (CodecNameMatches(codec_name, kVp8CodecName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VideoCodec> DefaultVideoCodecList() {
|
||||||
|
std::vector<VideoCodec> codecs;
|
||||||
|
codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(100, kVp8CodecName));
|
||||||
|
codecs.push_back(MakeRtxCodec(96, 100));
|
||||||
|
codecs.push_back(MakeVideoCodec(116, kRedCodecName));
|
||||||
|
codecs.push_back(MakeVideoCodec(117, kUlpfecCodecName));
|
||||||
|
return codecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FlushBlackFrameData : public rtc::MessageData {
|
struct FlushBlackFrameData : public rtc::MessageData {
|
||||||
@ -923,18 +969,6 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
|
|||||||
AdaptFormatType adapt_format_type_;
|
AdaptFormatType adapt_format_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
const WebRtcVideoEngine::VideoCodecPref
|
|
||||||
WebRtcVideoEngine::kVideoCodecPrefs[] = {
|
|
||||||
{kVp8CodecName, 100, -1, 0},
|
|
||||||
{kRedCodecName, 116, -1, 1},
|
|
||||||
{kUlpfecCodecName, 117, -1, 2},
|
|
||||||
{kRtxCodecName, 96, 100, 3},
|
|
||||||
};
|
|
||||||
|
|
||||||
const VideoFormatPod WebRtcVideoEngine::kDefaultMaxVideoFormat =
|
|
||||||
{640, 400, FPS_TO_INTERVAL(30), FOURCC_ANY};
|
|
||||||
// TODO(ronghuawu): Change to 640x360.
|
|
||||||
|
|
||||||
static bool GetCpuOveruseOptions(const VideoOptions& options,
|
static bool GetCpuOveruseOptions(const VideoOptions& options,
|
||||||
webrtc::CpuOveruseOptions* overuse_options) {
|
webrtc::CpuOveruseOptions* overuse_options) {
|
||||||
int underuse_threshold = 0;
|
int underuse_threshold = 0;
|
||||||
@ -1018,20 +1052,14 @@ void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper,
|
|||||||
LOG_RTCERR1(SetTraceCallback, this);
|
LOG_RTCERR1(SetTraceCallback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_video_codec_list_ = DefaultVideoCodecList();
|
||||||
|
|
||||||
// Set default quality levels for our supported codecs. We override them here
|
// Set default quality levels for our supported codecs. We override them here
|
||||||
// if we know your cpu performance is low, and they can be updated explicitly
|
// if we know your cpu performance is low, and they can be updated explicitly
|
||||||
// by calling SetDefaultCodec. For example by a flute preference setting, or
|
// by calling SetDefaultCodec. For example by a flute preference setting, or
|
||||||
// by the server with a jec in response to our reported system info.
|
// by the server with a jec in response to our reported system info.
|
||||||
VideoCodec max_codec(kVideoCodecPrefs[0].payload_type,
|
CHECK(SetDefaultCodec(default_video_codec_list_.front()))
|
||||||
kVideoCodecPrefs[0].name,
|
<< "Failed to initialize list of supported codec types.";
|
||||||
kDefaultMaxVideoFormat.width,
|
|
||||||
kDefaultMaxVideoFormat.height,
|
|
||||||
VideoFormat::IntervalToFps(
|
|
||||||
kDefaultMaxVideoFormat.interval),
|
|
||||||
0);
|
|
||||||
if (!SetDefaultCodec(max_codec)) {
|
|
||||||
LOG(LS_ERROR) << "Failed to initialize list of supported codec types";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consider jitter, packet loss, etc when rendering. This will
|
// Consider jitter, packet loss, etc when rendering. This will
|
||||||
// theoretically make rendering more smooth.
|
// theoretically make rendering more smooth.
|
||||||
@ -1214,13 +1242,12 @@ bool WebRtcVideoEngine::FindCodec(const VideoCodec& in) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t j = 0; j < ARRAY_SIZE(kVideoCodecPrefs); ++j) {
|
for (size_t j = 0; j != default_video_codec_list_.size(); ++j) {
|
||||||
VideoCodec codec(kVideoCodecPrefs[j].payload_type,
|
if (default_video_codec_list_[j].Matches(in)) {
|
||||||
kVideoCodecPrefs[j].name, 0, 0, 0, 0);
|
|
||||||
if (codec.Matches(in)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1428,17 +1455,6 @@ void WebRtcVideoEngine::SetTraceOptions(const std::string& options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddDefaultFeedbackParams(VideoCodec* codec) {
|
|
||||||
const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir);
|
|
||||||
codec->AddFeedbackParam(kFir);
|
|
||||||
const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty);
|
|
||||||
codec->AddFeedbackParam(kNack);
|
|
||||||
const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli);
|
|
||||||
codec->AddFeedbackParam(kPli);
|
|
||||||
const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty);
|
|
||||||
codec->AddFeedbackParam(kRemb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebuilds the codec list to be only those that are less intensive
|
// Rebuilds the codec list to be only those that are less intensive
|
||||||
// than the specified codec. Prefers internal codec over external with
|
// than the specified codec. Prefers internal codec over external with
|
||||||
// higher preference field.
|
// higher preference field.
|
||||||
@ -1448,27 +1464,17 @@ bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) {
|
|||||||
|
|
||||||
video_codecs_.clear();
|
video_codecs_.clear();
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
std::set<std::string> internal_codec_names;
|
std::set<std::string> internal_codec_names;
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(kVideoCodecPrefs); ++i) {
|
for (size_t i = 0; i != default_video_codec_list_.size(); ++i) {
|
||||||
const VideoCodecPref& pref(kVideoCodecPrefs[i]);
|
VideoCodec codec = default_video_codec_list_[i];
|
||||||
if (!found)
|
codec.width = in_codec.width;
|
||||||
found = (in_codec.name == pref.name);
|
codec.height = in_codec.height;
|
||||||
if (found) {
|
codec.framerate = in_codec.framerate;
|
||||||
VideoCodec codec(pref.payload_type, pref.name,
|
video_codecs_.push_back(codec);
|
||||||
in_codec.width, in_codec.height, in_codec.framerate,
|
|
||||||
static_cast<int>(ARRAY_SIZE(kVideoCodecPrefs) - i));
|
internal_codec_names.insert(codec.name);
|
||||||
if (_stricmp(kVp8CodecName, codec.name.c_str()) == 0) {
|
|
||||||
AddDefaultFeedbackParams(&codec);
|
|
||||||
}
|
|
||||||
if (pref.associated_payload_type != -1) {
|
|
||||||
codec.SetParam(kCodecParamAssociatedPayloadType,
|
|
||||||
pref.associated_payload_type);
|
|
||||||
}
|
|
||||||
video_codecs_.push_back(codec);
|
|
||||||
internal_codec_names.insert(codec.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoder_factory_) {
|
if (encoder_factory_) {
|
||||||
const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
|
const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
|
||||||
encoder_factory_->codecs();
|
encoder_factory_->codecs();
|
||||||
@ -1476,8 +1482,6 @@ bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) {
|
|||||||
bool is_internal_codec = internal_codec_names.find(codecs[i].name) !=
|
bool is_internal_codec = internal_codec_names.find(codecs[i].name) !=
|
||||||
internal_codec_names.end();
|
internal_codec_names.end();
|
||||||
if (!is_internal_codec) {
|
if (!is_internal_codec) {
|
||||||
if (!found)
|
|
||||||
found = (in_codec.name == codecs[i].name);
|
|
||||||
VideoCodec codec(
|
VideoCodec codec(
|
||||||
GetExternalVideoPayloadType(static_cast<int>(i)),
|
GetExternalVideoPayloadType(static_cast<int>(i)),
|
||||||
codecs[i].name,
|
codecs[i].name,
|
||||||
@ -1492,7 +1496,6 @@ bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT(found);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1598,12 +1601,10 @@ void WebRtcVideoEngine::SetExternalEncoderFactory(
|
|||||||
encoder_factory_ = encoder_factory;
|
encoder_factory_ = encoder_factory;
|
||||||
|
|
||||||
// Rebuild codec list while reapplying the current default codec format.
|
// Rebuild codec list while reapplying the current default codec format.
|
||||||
VideoCodec max_codec(kVideoCodecPrefs[0].payload_type,
|
VideoCodec max_codec = default_video_codec_list_[0];
|
||||||
kVideoCodecPrefs[0].name,
|
max_codec.width = video_codecs_[0].width;
|
||||||
video_codecs_[0].width,
|
max_codec.height = video_codecs_[0].height;
|
||||||
video_codecs_[0].height,
|
max_codec.framerate = video_codecs_[0].framerate;
|
||||||
video_codecs_[0].framerate,
|
|
||||||
0);
|
|
||||||
if (!RebuildCodecList(max_codec)) {
|
if (!RebuildCodecList(max_codec)) {
|
||||||
LOG(LS_ERROR) << "Failed to initialize list of supported codec types";
|
LOG(LS_ERROR) << "Failed to initialize list of supported codec types";
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,15 @@ class WebRtcVoiceEngine;
|
|||||||
struct CapturedFrame;
|
struct CapturedFrame;
|
||||||
struct Device;
|
struct Device;
|
||||||
|
|
||||||
|
// This set of methods is declared here for the sole purpose of sharing code
|
||||||
|
// between webrtc video engine v1 and v2.
|
||||||
|
std::vector<VideoCodec> DefaultVideoCodecList();
|
||||||
|
bool CodecNameMatches(const std::string& name1, const std::string& name2);
|
||||||
|
bool CodecIsInternallySupported(const std::string& codec_name);
|
||||||
|
bool IsNackEnabled(const VideoCodec& codec);
|
||||||
|
bool IsRembEnabled(const VideoCodec& codec);
|
||||||
|
void AddDefaultFeedbackParams(VideoCodec* codec);
|
||||||
|
|
||||||
class WebRtcVideoEngine : public sigslot::has_slots<>,
|
class WebRtcVideoEngine : public sigslot::has_slots<>,
|
||||||
public webrtc::TraceCallback {
|
public webrtc::TraceCallback {
|
||||||
public:
|
public:
|
||||||
@ -187,18 +196,6 @@ class WebRtcVideoEngine : public sigslot::has_slots<>,
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels;
|
typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels;
|
||||||
struct VideoCodecPref {
|
|
||||||
const char* name;
|
|
||||||
int payload_type;
|
|
||||||
// For RTX, this field is the payload-type that RTX applies to.
|
|
||||||
// For other codecs, it should be set to -1.
|
|
||||||
int associated_payload_type;
|
|
||||||
int pref;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const VideoCodecPref kVideoCodecPrefs[];
|
|
||||||
static const VideoFormatPod kVideoFormats[];
|
|
||||||
static const VideoFormatPod kDefaultMaxVideoFormat;
|
|
||||||
|
|
||||||
void Construct(ViEWrapper* vie_wrapper,
|
void Construct(ViEWrapper* vie_wrapper,
|
||||||
ViETraceWrapper* tracing,
|
ViETraceWrapper* tracing,
|
||||||
@ -225,6 +222,7 @@ class WebRtcVideoEngine : public sigslot::has_slots<>,
|
|||||||
WebRtcVideoEncoderFactory* encoder_factory_;
|
WebRtcVideoEncoderFactory* encoder_factory_;
|
||||||
WebRtcVideoDecoderFactory* decoder_factory_;
|
WebRtcVideoDecoderFactory* decoder_factory_;
|
||||||
std::vector<VideoCodec> video_codecs_;
|
std::vector<VideoCodec> video_codecs_;
|
||||||
|
std::vector<VideoCodec> default_video_codec_list_;
|
||||||
std::vector<RtpHeaderExtension> rtp_header_extensions_;
|
std::vector<RtpHeaderExtension> rtp_header_extensions_;
|
||||||
VideoFormat default_codec_format_;
|
VideoFormat default_codec_format_;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "talk/media/base/videorenderer.h"
|
#include "talk/media/base/videorenderer.h"
|
||||||
#include "talk/media/webrtc/constants.h"
|
#include "talk/media/webrtc/constants.h"
|
||||||
#include "talk/media/webrtc/webrtcvideocapturer.h"
|
#include "talk/media/webrtc/webrtcvideocapturer.h"
|
||||||
|
#include "talk/media/webrtc/webrtcvideoengine.h"
|
||||||
#include "talk/media/webrtc/webrtcvideoframe.h"
|
#include "talk/media/webrtc/webrtcvideoframe.h"
|
||||||
#include "talk/media/webrtc/webrtcvoiceengine.h"
|
#include "talk/media/webrtc/webrtcvoiceengine.h"
|
||||||
#include "webrtc/base/buffer.h"
|
#include "webrtc/base/buffer.h"
|
||||||
@ -51,26 +52,6 @@
|
|||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static bool CodecNameMatches(const std::string& name1,
|
|
||||||
const std::string& name2) {
|
|
||||||
return _stricmp(name1.c_str(), name2.c_str()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* kInternallySupportedCodecs[] = {
|
|
||||||
kVp8CodecName,
|
|
||||||
};
|
|
||||||
|
|
||||||
// True if codec is supported by a software implementation that's always
|
|
||||||
// available.
|
|
||||||
static bool CodecIsInternallySupported(const std::string& codec_name) {
|
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(kInternallySupportedCodecs); ++i) {
|
|
||||||
if (CodecNameMatches(codec_name, kInternallySupportedCodecs[i]))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) {
|
static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) {
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
out << '{';
|
out << '{';
|
||||||
@ -116,6 +97,29 @@ static std::string RtpExtensionsToString(
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merges two fec configs and logs an error if a conflict arises
|
||||||
|
// such that merging in diferent order would trigger a diferent output.
|
||||||
|
static void MergeFecConfig(const webrtc::FecConfig& other,
|
||||||
|
webrtc::FecConfig* output) {
|
||||||
|
if (other.ulpfec_payload_type != -1) {
|
||||||
|
if (output->ulpfec_payload_type != -1 &&
|
||||||
|
output->ulpfec_payload_type != other.ulpfec_payload_type) {
|
||||||
|
LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: "
|
||||||
|
<< output->ulpfec_payload_type << " and "
|
||||||
|
<< other.ulpfec_payload_type;
|
||||||
|
}
|
||||||
|
output->ulpfec_payload_type = other.ulpfec_payload_type;
|
||||||
|
}
|
||||||
|
if (other.red_payload_type != -1) {
|
||||||
|
if (output->red_payload_type != -1 &&
|
||||||
|
output->red_payload_type != other.red_payload_type) {
|
||||||
|
LOG(LS_WARNING) << "Conflict merging red_payload_type configs: "
|
||||||
|
<< output->red_payload_type << " and "
|
||||||
|
<< other.red_payload_type;
|
||||||
|
}
|
||||||
|
output->red_payload_type = other.red_payload_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// This constant is really an on/off, lower-level configurable NACK history
|
// This constant is really an on/off, lower-level configurable NACK history
|
||||||
@ -135,19 +139,8 @@ static const int kExternalVideoPayloadTypeBase = 120;
|
|||||||
static const size_t kMaxExternalVideoCodecs = 8;
|
static const size_t kMaxExternalVideoCodecs = 8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct VideoCodecPref {
|
|
||||||
int payload_type;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
const char* name;
|
|
||||||
int rtx_payload_type;
|
|
||||||
} kDefaultVideoCodecPref = {100, 640, 400, kVp8CodecName, 96};
|
|
||||||
|
|
||||||
const char kH264CodecName[] = "H264";
|
const char kH264CodecName[] = "H264";
|
||||||
|
|
||||||
VideoCodecPref kRedPref = {116, -1, -1, kRedCodecName, -1};
|
|
||||||
VideoCodecPref kUlpfecPref = {117, -1, -1, kUlpfecCodecName, -1};
|
|
||||||
|
|
||||||
static bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs,
|
static bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs,
|
||||||
const VideoCodec& requested_codec,
|
const VideoCodec& requested_codec,
|
||||||
VideoCodec* matching_codec) {
|
VideoCodec* matching_codec) {
|
||||||
@ -160,59 +153,6 @@ static bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddDefaultFeedbackParams(VideoCodec* codec) {
|
|
||||||
const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir);
|
|
||||||
codec->AddFeedbackParam(kFir);
|
|
||||||
const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty);
|
|
||||||
codec->AddFeedbackParam(kNack);
|
|
||||||
const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli);
|
|
||||||
codec->AddFeedbackParam(kPli);
|
|
||||||
const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty);
|
|
||||||
codec->AddFeedbackParam(kRemb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsNackEnabled(const VideoCodec& codec) {
|
|
||||||
return codec.HasFeedbackParam(
|
|
||||||
FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsRembEnabled(const VideoCodec& codec) {
|
|
||||||
return codec.HasFeedbackParam(
|
|
||||||
FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty));
|
|
||||||
}
|
|
||||||
|
|
||||||
static VideoCodec DefaultVideoCodec() {
|
|
||||||
VideoCodec default_codec(kDefaultVideoCodecPref.payload_type,
|
|
||||||
kDefaultVideoCodecPref.name,
|
|
||||||
kDefaultVideoCodecPref.width,
|
|
||||||
kDefaultVideoCodecPref.height,
|
|
||||||
kDefaultFramerate,
|
|
||||||
0);
|
|
||||||
AddDefaultFeedbackParams(&default_codec);
|
|
||||||
return default_codec;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VideoCodec DefaultRedCodec() {
|
|
||||||
return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VideoCodec DefaultUlpfecCodec() {
|
|
||||||
return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<VideoCodec> DefaultVideoCodecs() {
|
|
||||||
std::vector<VideoCodec> codecs;
|
|
||||||
codecs.push_back(DefaultVideoCodec());
|
|
||||||
codecs.push_back(DefaultRedCodec());
|
|
||||||
codecs.push_back(DefaultUlpfecCodec());
|
|
||||||
if (kDefaultVideoCodecPref.rtx_payload_type != -1) {
|
|
||||||
codecs.push_back(
|
|
||||||
VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type,
|
|
||||||
kDefaultVideoCodecPref.payload_type));
|
|
||||||
}
|
|
||||||
return codecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ValidateRtpHeaderExtensionIds(
|
static bool ValidateRtpHeaderExtensionIds(
|
||||||
const std::vector<RtpHeaderExtension>& extensions) {
|
const std::vector<RtpHeaderExtension>& extensions) {
|
||||||
std::set<int> extensions_used;
|
std::set<int> extensions_used;
|
||||||
@ -258,7 +198,7 @@ std::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams(
|
|||||||
stream.width = codec.width;
|
stream.width = codec.width;
|
||||||
stream.height = codec.height;
|
stream.height = codec.height;
|
||||||
stream.max_framerate =
|
stream.max_framerate =
|
||||||
codec.framerate != 0 ? codec.framerate : kDefaultFramerate;
|
codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate;
|
||||||
|
|
||||||
int min_bitrate = kMinVideoBitrate;
|
int min_bitrate = kMinVideoBitrate;
|
||||||
codec.GetParam(kCodecParamMinBitrate, &min_bitrate);
|
codec.GetParam(kCodecParamMinBitrate, &min_bitrate);
|
||||||
@ -350,9 +290,9 @@ void DefaultUnsignalledSsrcHandler::SetDefaultRenderer(
|
|||||||
WebRtcVideoEngine2::WebRtcVideoEngine2()
|
WebRtcVideoEngine2::WebRtcVideoEngine2()
|
||||||
: worker_thread_(NULL),
|
: worker_thread_(NULL),
|
||||||
voice_engine_(NULL),
|
voice_engine_(NULL),
|
||||||
default_codec_format_(kDefaultVideoCodecPref.width,
|
default_codec_format_(kDefaultVideoMaxWidth,
|
||||||
kDefaultVideoCodecPref.height,
|
kDefaultVideoMaxHeight,
|
||||||
FPS_TO_INTERVAL(kDefaultFramerate),
|
FPS_TO_INTERVAL(kDefaultVideoMaxFramerate),
|
||||||
FOURCC_ANY),
|
FOURCC_ANY),
|
||||||
initialized_(false),
|
initialized_(false),
|
||||||
cpu_monitor_(new rtc::CpuMonitor(NULL)),
|
cpu_monitor_(new rtc::CpuMonitor(NULL)),
|
||||||
@ -571,7 +511,7 @@ WebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const {
|
std::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const {
|
||||||
std::vector<VideoCodec> supported_codecs = DefaultVideoCodecs();
|
std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList();
|
||||||
|
|
||||||
if (external_encoder_factory_ == NULL) {
|
if (external_encoder_factory_ == NULL) {
|
||||||
return supported_codecs;
|
return supported_codecs;
|
||||||
@ -1097,19 +1037,19 @@ void WebRtcVideoChannel2::ConfigureReceiverRtp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < recv_codecs_.size(); ++i) {
|
for (size_t i = 0; i < recv_codecs_.size(); ++i) {
|
||||||
if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) {
|
MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec);
|
||||||
config->rtp.fec = recv_codecs_[i].fec;
|
|
||||||
uint32 rtx_ssrc;
|
|
||||||
if (recv_codecs_[i].rtx_payload_type != -1 &&
|
|
||||||
sp.GetFidSsrc(ssrc, &rtx_ssrc)) {
|
|
||||||
config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc;
|
|
||||||
config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type =
|
|
||||||
recv_codecs_[i].rtx_payload_type;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < recv_codecs_.size(); ++i) {
|
||||||
|
uint32 rtx_ssrc;
|
||||||
|
if (recv_codecs_[i].rtx_payload_type != -1 &&
|
||||||
|
sp.GetFidSsrc(ssrc, &rtx_ssrc)) {
|
||||||
|
webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx =
|
||||||
|
config->rtp.rtx[recv_codecs_[i].codec.id];
|
||||||
|
rtx.ssrc = rtx_ssrc;
|
||||||
|
rtx.payload_type = recv_codecs_[i].rtx_payload_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) {
|
bool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user