VideoStreamEncoder: Don't crop and scales frames for external encoders

Bug: none
Change-Id: I1edc0314450793c0ae3fb471aa8936a102773a96
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/154424
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29319}
This commit is contained in:
Ilya Nikolaevskiy
2019-09-25 16:05:47 +02:00
committed by Commit Bot
parent 482d26ce9d
commit abd9e0f5c2

View File

@ -1365,9 +1365,65 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
TraceFrameDropEnd(); TraceFrameDropEnd();
// Encoder metadata needs to be updated before encode complete callback.
VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
if (info.implementation_name != encoder_info_.implementation_name) {
encoder_stats_observer_->OnEncoderImplementationChanged(
info.implementation_name);
if (bitrate_adjuster_) {
// Encoder implementation changed, reset overshoot detector states.
bitrate_adjuster_->Reset();
}
}
if (bitrate_adjuster_) {
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
if (info.fps_allocation[si] != encoder_info_.fps_allocation[si]) {
bitrate_adjuster_->OnEncoderInfo(info);
break;
}
}
}
encoder_info_ = info;
last_encode_info_ms_ = clock_->TimeInMilliseconds();
VideoFrame out_frame(video_frame); VideoFrame out_frame(video_frame);
const VideoFrameBuffer::Type buffer_type =
out_frame.video_frame_buffer()->type();
const bool is_buffer_type_supported =
buffer_type == VideoFrameBuffer::Type::kI420 ||
(buffer_type == VideoFrameBuffer::Type::kNative &&
info.supports_native_handle);
if (!is_buffer_type_supported) {
// This module only supports software encoding.
rtc::scoped_refptr<I420BufferInterface> converted_buffer(
out_frame.video_frame_buffer()->ToI420());
if (!converted_buffer) {
RTC_LOG(LS_ERROR) << "Frame conversion failed, dropping frame.";
return;
}
VideoFrame::UpdateRect update_rect = out_frame.update_rect();
if (!update_rect.IsEmpty() &&
out_frame.video_frame_buffer()->GetI420() == nullptr) {
// UpdatedRect is reset to full update if it's not empty, and buffer was
// converted, therefore we can't guarantee that pixels outside of
// UpdateRect didn't change comparing to the previous frame.
update_rect =
VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
}
out_frame.set_video_frame_buffer(converted_buffer);
out_frame.set_update_rect(update_rect);
}
// Crop frame if needed. // Crop frame if needed.
if (crop_width_ > 0 || crop_height_ > 0) { if ((crop_width_ > 0 || crop_height_ > 0) &&
out_frame.video_frame_buffer()->type() !=
VideoFrameBuffer::Type::kNative) {
// If the frame can't be converted to I420, drop it. // If the frame can't be converted to I420, drop it.
auto i420_buffer = video_frame.video_frame_buffer()->ToI420(); auto i420_buffer = video_frame.video_frame_buffer()->ToI420();
if (!i420_buffer) { if (!i420_buffer) {
@ -1424,60 +1480,14 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
overuse_detector_->FrameCaptured(out_frame, time_when_posted_us); overuse_detector_->FrameCaptured(out_frame, time_when_posted_us);
// Encoder metadata needs to be updated before encode complete callback. RTC_DCHECK_LE(send_codec_.width, out_frame.width());
VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo(); RTC_DCHECK_LE(send_codec_.height, out_frame.height());
if (info.implementation_name != encoder_info_.implementation_name) { // Native frames should be scaled by the client.
encoder_stats_observer_->OnEncoderImplementationChanged( // For internal encoders we scale everything in one place here.
info.implementation_name); RTC_DCHECK((out_frame.video_frame_buffer()->type() ==
if (bitrate_adjuster_) { VideoFrameBuffer::Type::kNative) ||
// Encoder implementation changed, reset overshoot detector states. (send_codec_.width == out_frame.width() &&
bitrate_adjuster_->Reset(); send_codec_.height == out_frame.height()));
}
}
if (bitrate_adjuster_) {
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
if (info.fps_allocation[si] != encoder_info_.fps_allocation[si]) {
bitrate_adjuster_->OnEncoderInfo(info);
break;
}
}
}
encoder_info_ = info;
last_encode_info_ms_ = clock_->TimeInMilliseconds();
RTC_DCHECK_EQ(send_codec_.width, out_frame.width());
RTC_DCHECK_EQ(send_codec_.height, out_frame.height());
const VideoFrameBuffer::Type buffer_type =
out_frame.video_frame_buffer()->type();
const bool is_buffer_type_supported =
buffer_type == VideoFrameBuffer::Type::kI420 ||
(buffer_type == VideoFrameBuffer::Type::kNative &&
info.supports_native_handle);
if (!is_buffer_type_supported) {
// This module only supports software encoding.
rtc::scoped_refptr<I420BufferInterface> converted_buffer(
out_frame.video_frame_buffer()->ToI420());
if (!converted_buffer) {
RTC_LOG(LS_ERROR) << "Frame conversion failed, dropping frame.";
return;
}
VideoFrame::UpdateRect update_rect = out_frame.update_rect();
if (!update_rect.IsEmpty() &&
out_frame.video_frame_buffer()->GetI420() == nullptr) {
// UpdatedRect is reset to full update if it's not empty, and buffer was
// converted, therefore we can't guarantee that pixels outside of
// UpdateRect didn't change comparing to the previous frame.
update_rect =
VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
}
out_frame.set_video_frame_buffer(converted_buffer);
out_frame.set_update_rect(update_rect);
}
TRACE_EVENT1("webrtc", "VCMGenericEncoder::Encode", "timestamp", TRACE_EVENT1("webrtc", "VCMGenericEncoder::Encode", "timestamp",
out_frame.timestamp()); out_frame.timestamp());