Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1039)

Unified Diff: media/gpu/vt_video_encode_accelerator_mac.cc

Issue 1818903004: Bitrate controller for VideoToolbox Video Encode Accelerator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/gpu/vt_video_encode_accelerator_mac.h ('k') | media/media.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/vt_video_encode_accelerator_mac.cc
diff --git a/media/gpu/vt_video_encode_accelerator_mac.cc b/media/gpu/vt_video_encode_accelerator_mac.cc
index 4c996261b23f4cc37b77e49f8033ee08b1e078d2..fbe174cffcc077d0cc43c4f2a9d8f58123ca41c7 100644
--- a/media/gpu/vt_video_encode_accelerator_mac.cc
+++ b/media/gpu/vt_video_encode_accelerator_mac.cc
@@ -11,6 +11,7 @@
#include "media/base/mac/coremedia_glue.h"
#include "media/base/mac/corevideo_glue.h"
#include "media/base/mac/video_frame_mac.h"
+#include "third_party/webrtc/system_wrappers/include/clock.h"
namespace media {
@@ -63,8 +64,16 @@ struct VTVideoEncodeAccelerator::BitstreamBufferRef {
DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBufferRef);
};
+// .5 is set as a minimum to prevent overcompensating for large temporary
+// overshoots. We don't want to degrade video quality too badly.
+// .95 is set to prevent oscillations. When a lower bitrate is set on the
+// encoder than previously set, its output seems to have a brief period of
+// drastically reduced bitrate, so we want to avoid that. In steady state
+// conditions, 0.95 seems to give us better overall bitrate over long periods
+// of time.
VTVideoEncodeAccelerator::VTVideoEncodeAccelerator()
- : client_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ : bitrate_adjuster_(webrtc::Clock::GetRealTimeClock(), .5, .95),
+ client_task_runner_(base::ThreadTaskRunnerHandle::Get()),
encoder_thread_("VTEncoderThread"),
encoder_task_weak_factory_(this) {
encoder_weak_ptr_ = encoder_task_weak_factory_.GetWeakPtr();
@@ -273,6 +282,10 @@ void VTVideoEncodeAccelerator::EncodeTask(
std::unique_ptr<InProgressFrameEncode> request(
new InProgressFrameEncode(frame->timestamp(), ref_time));
+ // Update the bitrate if needed.
+ RequestEncodingParametersChangeTask(bitrate_adjuster_.GetAdjustedBitrateBps(),
+ frame_rate_);
+
// We can pass the ownership of |request| to the encode callback if
// successful. Otherwise let it fall out of scope.
OSStatus status = videotoolbox_glue_->VTCompressionSessionEncodeFrame(
@@ -308,28 +321,39 @@ void VTVideoEncodeAccelerator::RequestEncodingParametersChangeTask(
uint32_t framerate) {
DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
- frame_rate_ = framerate > 1 ? framerate : 1;
- target_bitrate_ = bitrate > 1 ? bitrate : 1;
-
if (!compression_session_) {
NotifyError(kPlatformFailureError);
return;
}
- media::video_toolbox::SessionPropertySetter session_property_setter(
- compression_session_, videotoolbox_glue_);
- // TODO(emircan): See crbug.com/425352.
- bool rv = session_property_setter.Set(
- videotoolbox_glue_->kVTCompressionPropertyKey_AverageBitRate(),
- target_bitrate_);
- rv &= session_property_setter.Set(
- videotoolbox_glue_->kVTCompressionPropertyKey_ExpectedFrameRate(),
- frame_rate_);
- rv &= session_property_setter.Set(
- videotoolbox_glue_->kVTCompressionPropertyKey_DataRateLimits(),
- media::video_toolbox::ArrayWithIntegerAndFloat(
- target_bitrate_ / kBitsPerByte, 1.0f));
- DLOG_IF(ERROR, !rv) << "Couldn't change session encoding parameters.";
+ bool rv;
+ if (framerate != static_cast<uint32_t>(frame_rate_)) {
+ frame_rate_ = framerate > 1 ? framerate : 1;
+ media::video_toolbox::SessionPropertySetter session_property_setter(
+ compression_session_, videotoolbox_glue_);
+ rv = session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_ExpectedFrameRate(),
+ frame_rate_);
+ DLOG_IF(ERROR, !rv)
+ << "Couldn't change frame rate parameters of encode session.";
+ }
+
+ if (bitrate != static_cast<uint32_t>(adjusted_bitrate_)) {
+ target_bitrate_ = bitrate > 1 ? bitrate : 1;
+ bitrate_adjuster_.SetTargetBitrateBps(target_bitrate_);
+ adjusted_bitrate_ = bitrate_adjuster_.GetAdjustedBitrateBps();
+ media::video_toolbox::SessionPropertySetter session_property_setter(
+ compression_session_, videotoolbox_glue_);
+ rv = session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_AverageBitRate(),
+ adjusted_bitrate_);
+ rv &= session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_DataRateLimits(),
+ media::video_toolbox::ArrayWithIntegerAndFloat(
+ adjusted_bitrate_ / kBitsPerByte, 1.0f));
+ DLOG_IF(ERROR, !rv)
+ << "Couldn't change bitrate parameters of encode session.";
+ }
}
void VTVideoEncodeAccelerator::DestroyTask() {
@@ -435,6 +459,7 @@ void VTVideoEncodeAccelerator::ReturnBitstreamBuffer(
DLOG(ERROR) << "Cannot copy output from SampleBuffer to AnnexBBuffer.";
used_buffer_size = 0;
}
+ bitrate_adjuster_.Update(used_buffer_size);
client_task_runner_->PostTask(
FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_,
« no previous file with comments | « media/gpu/vt_video_encode_accelerator_mac.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698