#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
+#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
namespace webrtc {
-// Pace in kbits/s until we receive first estimate.
-static const int kInitialPace = 2000;
-
-// Pacing-rate relative to our target send rate.
-// Multiplicative factor that is applied to the target bitrate to calculate the
-// number of bytes that can be transmitted per interval.
-// Increasing this factor will result in lower delays in cases of bitrate
-// overshoots from the encoder.
-static const float kPaceMultiplier = 2.5f;
-
// Margin on when we pause the encoder when the pacing buffer overflows relative
// to the configured buffer delay.
static const float kEncoderPausePacerMargin = 2.0f;
bitrate_observer_.reset(new ViEBitrateObserver(this));
pacing_callback_.reset(new ViEPacedSenderCallback(this));
paced_sender_.reset(
- new PacedSender(pacing_callback_.get(), kInitialPace, kPaceMultiplier));
+ new PacedSender(Clock::GetRealTimeClock(), pacing_callback_.get(),
+ PacedSender::kDefaultInitialPaceKbps, 0));
}
bool ViEEncoder::Init() {
qm_callback_ = new QMVideoSettingsCallback(&vpm_);
#ifdef VIDEOCODEC_VP8
+ VideoCodecType codec_type = webrtc::kVideoCodecVP8;
+#else
+ VideoCodecType codec_type = webrtc::kVideoCodecI420;
+#endif
+
VideoCodec video_codec;
- if (vcm_.Codec(webrtc::kVideoCodecVP8, &video_codec) != VCM_OK) {
+ if (vcm_.Codec(codec_type, &video_codec) != VCM_OK) {
return false;
}
{
if (default_rtp_rtcp_->RegisterSendPayload(video_codec) != 0) {
return false;
}
-#else
- VideoCodec video_codec;
- if (vcm_.Codec(webrtc::kVideoCodecI420, &video_codec) == VCM_OK) {
- {
- CriticalSectionScoped cs(data_cs_.get());
- send_padding_ = video_codec.numberOfSimulcastStreams > 1;
- }
- vcm_.RegisterSendCodec(&video_codec, number_of_cores_,
- default_rtp_rtcp_->MaxDataPayloadLength());
- default_rtp_rtcp_->RegisterSendPayload(video_codec);
- } else {
- return false;
- }
-#endif
-
if (vcm_.RegisterTransportCallback(this) != 0) {
return false;
}
current_send_codec.extra_options = NULL;
if (vcm_.RegisterSendCodec(¤t_send_codec, number_of_cores_,
max_data_payload_length) != VCM_OK) {
- return -1;
+ LOG(LS_INFO) << "De-registered the currently used external encoder ("
+ << static_cast<int>(pl_type) << ") and therefore tried to "
+ << "register the corresponding internal encoder, but none "
+ << "was supported.";
}
}
return 0;
// Set this module as sending right away, let the slave module in the channel
// start and stop sending.
- if (default_rtp_rtcp_->Sending() == false) {
- if (default_rtp_rtcp_->SetSendingStatus(true) != 0) {
- return -1;
- }
+ if (default_rtp_rtcp_->SetSendingStatus(true) != 0) {
+ return -1;
}
+
bitrate_controller_->SetBitrateObserver(bitrate_observer_.get(),
video_codec.startBitrate * 1000,
video_codec.minBitrate * 1000,
if (pad_up_to_bitrate_kbps < min_transmit_bitrate_kbps_)
pad_up_to_bitrate_kbps = min_transmit_bitrate_kbps_;
- paced_sender_->UpdateBitrate(kPaceMultiplier * video_codec.startBitrate,
- pad_up_to_bitrate_kbps);
+ paced_sender_->UpdateBitrate(
+ PacedSender::kDefaultPaceMultiplier * video_codec.startBitrate,
+ pad_up_to_bitrate_kbps);
return 0;
}
}
encoder_paused_and_dropped_frame_ = false;
}
- if (video_frame->native_handle() != NULL) {
- // TODO(wuchengli): add texture support. http://crbug.com/362437
- return;
- }
// Convert render time, in ms, to RTP timestamp.
const int kMsToRtpTimestamp = 90;
TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame->render_time_ms(),
"Encode");
video_frame->set_timestamp(time_stamp);
- {
- CriticalSectionScoped cs(callback_cs_.get());
- if (effect_filter_) {
- unsigned int length = CalcBufferSize(kI420,
- video_frame->width(),
- video_frame->height());
- scoped_ptr<uint8_t[]> video_buffer(new uint8_t[length]);
- ExtractBuffer(*video_frame, length, video_buffer.get());
- effect_filter_->Transform(length,
- video_buffer.get(),
- video_frame->ntp_time_ms(),
- video_frame->timestamp(),
- video_frame->width(),
- video_frame->height());
- }
- }
// Make sure the CSRC list is correct.
if (num_csrcs > 0) {
}
default_rtp_rtcp_->SetCSRCs(tempCSRC, (uint8_t) num_csrcs);
}
- // Pass frame via preprocessor.
+
I420VideoFrame* decimated_frame = NULL;
- const int ret = vpm_.PreprocessFrame(*video_frame, &decimated_frame);
- if (ret == 1) {
- // Drop this frame.
- return;
- }
- if (ret != VPM_OK) {
- return;
+ // TODO(wuchengli): support texture frames.
+ if (video_frame->native_handle() == NULL) {
+ {
+ CriticalSectionScoped cs(callback_cs_.get());
+ if (effect_filter_) {
+ unsigned int length =
+ CalcBufferSize(kI420, video_frame->width(), video_frame->height());
+ scoped_ptr<uint8_t[]> video_buffer(new uint8_t[length]);
+ ExtractBuffer(*video_frame, length, video_buffer.get());
+ effect_filter_->Transform(length,
+ video_buffer.get(),
+ video_frame->ntp_time_ms(),
+ video_frame->timestamp(),
+ video_frame->width(),
+ video_frame->height());
+ }
+ }
+
+ // Pass frame via preprocessor.
+ const int ret = vpm_.PreprocessFrame(*video_frame, &decimated_frame);
+ if (ret == 1) {
+ // Drop this frame.
+ return;
+ }
+ if (ret != VPM_OK) {
+ return;
+ }
}
- // Frame was not sampled => use original.
+ // If the frame was not resampled or scaled => use original.
if (decimated_frame == NULL) {
decimated_frame = video_frame;
}
pre_encode_callback_->FrameCallback(decimated_frame);
}
+ if (video_frame->native_handle() != NULL) {
+ // TODO(wuchengli): add texture support. http://crbug.com/362437
+ return;
+ }
+
#ifdef VIDEOCODEC_VP8
if (vcm_.SendCodec() == webrtc::kVideoCodecVP8) {
webrtc::CodecSpecificInfo codec_specific_info;
codec_specific_info.codecType = webrtc::kVideoCodecVP8;
- codec_specific_info.codecSpecific.VP8.hasReceivedRPSI =
- has_received_rpsi_;
- codec_specific_info.codecSpecific.VP8.hasReceivedSLI =
- has_received_sli_;
- codec_specific_info.codecSpecific.VP8.pictureIdRPSI =
- picture_id_rpsi_;
- codec_specific_info.codecSpecific.VP8.pictureIdSLI =
- picture_id_sli_;
- has_received_sli_ = false;
- has_received_rpsi_ = false;
+ {
+ CriticalSectionScoped cs(data_cs_.get());
+ codec_specific_info.codecSpecific.VP8.hasReceivedRPSI =
+ has_received_rpsi_;
+ codec_specific_info.codecSpecific.VP8.hasReceivedSLI =
+ has_received_sli_;
+ codec_specific_info.codecSpecific.VP8.pictureIdRPSI =
+ picture_id_rpsi_;
+ codec_specific_info.codecSpecific.VP8.pictureIdSLI =
+ picture_id_sli_;
+ has_received_sli_ = false;
+ has_received_rpsi_ = false;
+ }
vcm_.AddVideoFrame(*decimated_frame, vpm_.ContentMetrics(),
&codec_specific_info);
void ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/,
uint8_t picture_id) {
+ CriticalSectionScoped cs(data_cs_.get());
picture_id_sli_ = picture_id;
has_received_sli_ = true;
}
void ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/,
uint64_t picture_id) {
+ CriticalSectionScoped cs(data_cs_.get());
picture_id_rpsi_ = picture_id;
has_received_rpsi_ = true;
}
if (pad_up_to_bitrate_kbps > bitrate_kbps)
pad_up_to_bitrate_kbps = bitrate_kbps;
- paced_sender_->UpdateBitrate(kPaceMultiplier * bitrate_kbps,
- pad_up_to_bitrate_kbps);
+ paced_sender_->UpdateBitrate(
+ PacedSender::kDefaultPaceMultiplier * bitrate_kbps,
+ pad_up_to_bitrate_kbps);
default_rtp_rtcp_->SetTargetSendBitrate(stream_bitrates);
if (video_suspended_ == video_is_suspended)
return;