| Index: webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
|
| diff --git a/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
|
| index 1a10ddfa62272d5d354c0f8866f772999f99218e..c02ae0bf4583d1c85bc69aaaca8a263e1b34a014 100644
|
| --- a/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
|
| +++ b/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
|
| @@ -21,8 +21,8 @@
|
|
|
| #include "webrtc/base/checks.h"
|
| #include "webrtc/base/logging.h"
|
| +#include "webrtc/base/timeutils.h"
|
| #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
| -#include "webrtc/media/base/mediaconstants.h"
|
| #include "webrtc/system_wrappers/include/metrics.h"
|
|
|
| namespace webrtc {
|
| @@ -167,7 +167,10 @@ H264EncoderImpl::H264EncoderImpl(const cricket::VideoCodec& codec)
|
| number_of_cores_(0),
|
| encoded_image_callback_(nullptr),
|
| has_reported_init_(false),
|
| - has_reported_error_(false) {
|
| + has_reported_error_(false),
|
| + last_timing_frame_time_ms_(-1),
|
| + timing_frames_delay_ms_(0),
|
| + timing_frames_outlier_size_percent_(0) {
|
| RTC_CHECK(cricket::CodecNamesEq(codec.name, cricket::kH264CodecName));
|
| std::string packetization_mode_string;
|
| if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
|
| @@ -231,6 +234,10 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* codec_settings,
|
| frame_dropping_on_ = codec_settings->H264().frameDroppingOn;
|
| key_frame_interval_ = codec_settings->H264().keyFrameInterval;
|
| max_payload_size_ = max_payload_size;
|
| + timing_frames_outlier_size_percent_ =
|
| + codec_settings->timingFrameTriggerThresholds.outlier_ratio_percent;
|
| + timing_frames_delay_ms_ =
|
| + codec_settings->timingFrameTriggerThresholds.delay_ms;
|
|
|
| // Codec_settings uses kbits/second; encoder uses bits/second.
|
| max_bps_ = codec_settings->maxBitrate * 1000;
|
| @@ -308,6 +315,7 @@ int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame,
|
| ReportError();
|
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
| }
|
| + int64_t encode_start_ms = rtc::TimeMillis();
|
| if (!encoded_image_callback_) {
|
| LOG(LS_WARNING) << "InitEncode() has been called, but a callback function "
|
| << "has not been set with RegisterEncodeCompleteCallback()";
|
| @@ -385,6 +393,28 @@ int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame,
|
| encoded_image_._length);
|
| h264_bitstream_parser_.GetLastSliceQp(&encoded_image_.qp_);
|
|
|
| + // Add timing information if needed. Timing delay is counted based on
|
| + // capture time to ensure that simulcast encoders will mark frames on all
|
| + // the streams together.
|
| + int64_t now_ms = rtc::TimeMillis();
|
| + bool is_time_for_timing_frame = (last_timing_frame_time_ms_ == -1) ||
|
| + (encoded_image_.capture_time_ms_ - last_timing_frame_time_ms_ >=
|
| + timing_frames_delay_ms_);
|
| + if (is_time_for_timing_frame) {
|
| + last_timing_frame_time_ms_ = encoded_image_.capture_time_ms_;
|
| + }
|
| + size_t outlier_frame_size_bytes =
|
| + timing_frames_outlier_size_percent_ / 100.0 * // outlier coefficient
|
| + target_bps_ / 8 / max_frame_rate_; // target_bps in bytes / fps
|
| + if (is_time_for_timing_frame ||
|
| + encoded_image_._length >= outlier_frame_size_bytes) {
|
| + encoded_image_.timing_.is_timing_frame = true;
|
| + encoded_image_.timing_.encode_start_ms = encode_start_ms;
|
| + encoded_image_.timing_.encode_finish_ms = now_ms;
|
| + } else {
|
| + encoded_image_.timing_.is_timing_frame = false;
|
| + }
|
| +
|
| // Deliver encoded image.
|
| CodecSpecificInfo codec_specific;
|
| codec_specific.codecType = kVideoCodecH264;
|
|
|