| Index: webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc
|
| diff --git a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc
|
| index 5f6a231288d9350a523205f88da2e0cc829fe2fa..ab05191d5ce868dd6f476abb5b89ec3602d70380 100644
|
| --- a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc
|
| +++ b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc
|
| @@ -225,10 +225,18 @@ int H264VideoToolboxEncoder::InitEncode(const VideoCodec* codec_settings,
|
| size_t max_payload_size) {
|
| RTC_DCHECK(codec_settings);
|
| RTC_DCHECK_EQ(codec_settings->codecType, kVideoCodecH264);
|
| - // TODO(tkchin): We may need to enforce width/height dimension restrictions
|
| - // to match what the encoder supports.
|
| - width_ = codec_settings->width;
|
| - height_ = codec_settings->height;
|
| + {
|
| + rtc::CritScope lock(&quality_scaler_crit_);
|
| + quality_scaler_.Init(QualityScaler::kLowH264QpThreshold,
|
| + QualityScaler::kBadH264QpThreshold,
|
| + codec_settings->startBitrate, codec_settings->width,
|
| + codec_settings->height, codec_settings->maxFramerate);
|
| + QualityScaler::Resolution res = quality_scaler_.GetScaledResolution();
|
| + // TODO(tkchin): We may need to enforce width/height dimension restrictions
|
| + // to match what the encoder supports.
|
| + width_ = res.width;
|
| + height_ = res.height;
|
| + }
|
| // We can only set average bitrate on the HW encoder.
|
| target_bitrate_bps_ = codec_settings->startBitrate;
|
| bitrate_adjuster_.SetTargetBitrateBps(target_bitrate_bps_);
|
| @@ -239,17 +247,18 @@ int H264VideoToolboxEncoder::InitEncode(const VideoCodec* codec_settings,
|
| return ResetCompressionSession();
|
| }
|
|
|
| +const VideoFrame& H264VideoToolboxEncoder::GetScaledFrameOnEncode(
|
| + const VideoFrame& frame) {
|
| + rtc::CritScope lock(&quality_scaler_crit_);
|
| + quality_scaler_.OnEncodeFrame(frame);
|
| + return quality_scaler_.GetScaledFrame(frame);
|
| +}
|
| +
|
| int H264VideoToolboxEncoder::Encode(
|
| - const VideoFrame& input_image,
|
| + const VideoFrame& frame,
|
| const CodecSpecificInfo* codec_specific_info,
|
| const std::vector<FrameType>* frame_types) {
|
| - if (input_image.IsZeroSize()) {
|
| - // It's possible to get zero sizes as a signal to produce keyframes (this
|
| - // happens for internal sources). But this shouldn't happen in
|
| - // webrtcvideoengine2.
|
| - RTC_NOTREACHED();
|
| - return WEBRTC_VIDEO_CODEC_OK;
|
| - }
|
| + RTC_DCHECK(!frame.IsZeroSize());
|
| if (!callback_ || !compression_session_) {
|
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
| }
|
| @@ -261,6 +270,16 @@ int H264VideoToolboxEncoder::Encode(
|
| }
|
| #endif
|
| bool is_keyframe_required = false;
|
| + const VideoFrame& input_image = GetScaledFrameOnEncode(frame);
|
| +
|
| + if (input_image.width() != width_ || input_image.height() != height_) {
|
| + width_ = input_image.width();
|
| + height_ = input_image.height();
|
| + int ret = ResetCompressionSession();
|
| + if (ret < 0)
|
| + return ret;
|
| + }
|
| +
|
| // Get a pixel buffer from the pool and copy frame data over.
|
| CVPixelBufferPoolRef pixel_buffer_pool =
|
| VTCompressionSessionGetPixelBufferPool(compression_session_);
|
| @@ -345,6 +364,11 @@ int H264VideoToolboxEncoder::RegisterEncodeCompleteCallback(
|
| return WEBRTC_VIDEO_CODEC_OK;
|
| }
|
|
|
| +void H264VideoToolboxEncoder::OnDroppedFrame() {
|
| + rtc::CritScope lock(&quality_scaler_crit_);
|
| + quality_scaler_.ReportDroppedFrame();
|
| +}
|
| +
|
| int H264VideoToolboxEncoder::SetChannelParameters(uint32_t packet_loss,
|
| int64_t rtt) {
|
| // Encoder doesn't know anything about packet loss or rtt so just return.
|
| @@ -357,6 +381,9 @@ int H264VideoToolboxEncoder::SetRates(uint32_t new_bitrate_kbit,
|
| bitrate_adjuster_.SetTargetBitrateBps(target_bitrate_bps_);
|
| SetBitrateBps(bitrate_adjuster_.GetAdjustedBitrateBps());
|
|
|
| + rtc::CritScope lock(&quality_scaler_crit_);
|
| + quality_scaler_.ReportFramerate(frame_rate);
|
| +
|
| return WEBRTC_VIDEO_CODEC_OK;
|
| }
|
|
|
| @@ -491,6 +518,9 @@ void H264VideoToolboxEncoder::OnEncodedFrame(
|
| }
|
| if (info_flags & kVTEncodeInfo_FrameDropped) {
|
| LOG(LS_INFO) << "H264 encode dropped frame.";
|
| + rtc::CritScope lock(&quality_scaler_crit_);
|
| + quality_scaler_.ReportDroppedFrame();
|
| + return;
|
| }
|
|
|
| bool is_keyframe = false;
|
| @@ -526,6 +556,13 @@ void H264VideoToolboxEncoder::OnEncodedFrame(
|
| frame._timeStamp = timestamp;
|
| frame.rotation_ = rotation;
|
|
|
| + h264_bitstream_parser_.ParseBitstream(buffer->data(), buffer->size());
|
| + int qp;
|
| + if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
|
| + rtc::CritScope lock(&quality_scaler_crit_);
|
| + quality_scaler_.ReportQP(qp);
|
| + }
|
| +
|
| int result = callback_->Encoded(frame, &codec_specific_info, header.get());
|
| if (result != 0) {
|
| LOG(LS_ERROR) << "Encode callback failed: " << result;
|
|
|