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

Unified Diff: media/cast/sender/size_adaptable_video_encoder_base.cc

Issue 906403006: [Cast] Size-Adaptable platform video encoders. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix CastStreamingApiTestWithPixelOutput.RtpStreamError test. Created 5 years, 10 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
Index: media/cast/sender/size_adaptable_video_encoder_base.cc
diff --git a/media/cast/sender/size_adaptable_video_encoder_base.cc b/media/cast/sender/size_adaptable_video_encoder_base.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a9a46b8283f431f0724fa7efcd0543d43dc76beb
--- /dev/null
+++ b/media/cast/sender/size_adaptable_video_encoder_base.cc
@@ -0,0 +1,162 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/cast/sender/size_adaptable_video_encoder_base.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "media/base/video_frame.h"
+
+namespace media {
+namespace cast {
+
+SizeAdaptableVideoEncoderBase::SizeAdaptableVideoEncoderBase(
+ const scoped_refptr<CastEnvironment>& cast_environment,
+ const VideoSenderConfig& video_config,
+ const StatusChangeCallback& status_change_cb)
+ : cast_environment_(cast_environment),
+ video_config_(video_config),
+ status_change_cb_(status_change_cb),
+ frames_in_encoder_(0),
+ last_frame_id_(kStartFrameId),
+ weak_factory_(this) {
+ cast_environment_->PostTask(
+ CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(status_change_cb_, STATUS_INITIALIZED));
+}
+
+SizeAdaptableVideoEncoderBase::~SizeAdaptableVideoEncoderBase() {
+ weak_factory_.InvalidateWeakPtrs();
hubbe 2015/02/11 00:47:54 This is kind of weird. Why invalidate weak pointer
miu 2015/02/11 02:14:23 Done. Consolidated into DestroyCurrentEncoder(),
+ DestroyCurrentEncoder();
+}
+
+bool SizeAdaptableVideoEncoderBase::EncodeVideoFrame(
+ const scoped_refptr<media::VideoFrame>& video_frame,
+ const base::TimeTicks& reference_time,
+ const FrameEncodedCallback& frame_encoded_callback) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+
+ const gfx::Size frame_size = video_frame->visible_rect().size();
+ if (frame_size.IsEmpty()) {
+ DVLOG(1) << "Rejecting empty video frame.";
+ return false;
+ }
+ if (frame_size != current_encoder_frame_size_ || !current_encoder_) {
+ VLOG(1) << "Dropping frame (of size " << frame_size.ToString()
+ << ") until a replacement encoder is spun-up. Current encoder "
+ "handles frames of size "
+ << current_encoder_frame_size_.ToString() << '.';
+ MaybeSpawnReplacementEncoder(frame_size);
+ return false;
+ }
+
+ const bool is_frame_accepted = current_encoder_->EncodeVideoFrame(
+ video_frame,
+ reference_time,
+ base::Bind(&SizeAdaptableVideoEncoderBase::OnEncodedVideoFrame,
+ weak_factory_.GetWeakPtr(),
+ frame_encoded_callback));
+ if (is_frame_accepted)
+ ++frames_in_encoder_;
+ return is_frame_accepted;
+}
+
+void SizeAdaptableVideoEncoderBase::SetBitRate(int new_bit_rate) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ video_config_.start_bitrate = new_bit_rate;
+ if (current_encoder_)
+ current_encoder_->SetBitRate(new_bit_rate);
+}
+
+void SizeAdaptableVideoEncoderBase::GenerateKeyFrame() {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ if (current_encoder_)
+ current_encoder_->GenerateKeyFrame();
+}
+
+void SizeAdaptableVideoEncoderBase::LatestFrameIdToReference(uint32 frame_id) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ if (current_encoder_)
+ current_encoder_->LatestFrameIdToReference(frame_id);
+}
+
+scoped_ptr<VideoFrameFactory>
+ SizeAdaptableVideoEncoderBase::CreateVideoFrameFactory() {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ return nullptr;
+}
+
+void SizeAdaptableVideoEncoderBase::EmitFrames() {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ if (current_encoder_)
+ current_encoder_->EmitFrames();
+}
+
+StatusChangeCallback
+ SizeAdaptableVideoEncoderBase::CreateEncoderStatusChangeCallback() {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ return base::Bind(&SizeAdaptableVideoEncoderBase::OnEncoderStatusChange,
+ weak_factory_.GetWeakPtr());
+}
+
+void SizeAdaptableVideoEncoderBase::OnEncoderReplaced(
+ VideoEncoder* replacement_encoder) {}
+
+void SizeAdaptableVideoEncoderBase::DestroyCurrentEncoder() {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ current_encoder_.reset();
+}
+
+void SizeAdaptableVideoEncoderBase::MaybeSpawnReplacementEncoder(
hubbe 2015/02/11 00:47:54 I don't like "Maybe" I think "Try" or "" would be
miu 2015/02/11 02:14:23 Done.
+ const gfx::Size& size_needed) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+
+ // If prior frames are still encoding in the current encoder, let them finish
+ // first.
+ if (frames_in_encoder_ > 0) {
+ current_encoder_->EmitFrames();
+ return;
+ }
+
+ if (next_encoder_.get())
+ return; // Already spawned.
+
+ // Prevent future callbacks from |current_encoder_| and destroy it.
+ weak_factory_.InvalidateWeakPtrs();
+ DestroyCurrentEncoder();
+
+ OnEncoderStatusChange(STATUS_CODEC_REINIT_PENDING);
+ next_encoder_frame_size_ = size_needed;
+ VLOG(1) << "Creating replacement video encoder (for frame size change from "
+ << current_encoder_frame_size_.ToString() << " to "
+ << next_encoder_frame_size_.ToString() << ").";
+ next_encoder_ = CreateReplacementEncoder().Pass();
+ DCHECK(next_encoder_.get());
+}
+
+void SizeAdaptableVideoEncoderBase::OnEncoderStatusChange(
+ OperationalStatus status) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ if (next_encoder_.get() && status == STATUS_INITIALIZED) {
+ // Begin using the replacement encoder.
+ current_encoder_ = next_encoder_.Pass();
+ current_encoder_frame_size_ = next_encoder_frame_size_;
+ OnEncoderReplaced(current_encoder_.get());
+ }
+ status_change_cb_.Run(status);
+}
+
+void SizeAdaptableVideoEncoderBase::OnEncodedVideoFrame(
+ const FrameEncodedCallback& frame_encoded_callback,
+ scoped_ptr<EncodedFrame> encoded_frame) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ --frames_in_encoder_;
+ DCHECK_GE(frames_in_encoder_, 0);
+ last_frame_id_ = encoded_frame->frame_id;
+ frame_encoded_callback.Run(encoded_frame.Pass());
+}
+
+} // namespace cast
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698