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

Side by Side 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: Addressed jfroy's comments. 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/cast/sender/size_adaptable_video_encoder_base.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "media/base/video_frame.h"
10
11 namespace media {
12 namespace cast {
13
14 SizeAdaptableVideoEncoderBase::SizeAdaptableVideoEncoderBase(
15 const scoped_refptr<CastEnvironment>& cast_environment,
16 const VideoSenderConfig& video_config,
17 const StatusChangeCallback& status_change_cb)
18 : cast_environment_(cast_environment),
19 video_config_(video_config),
20 status_change_cb_(status_change_cb),
21 frames_in_encoder_(0),
22 last_frame_id_(kStartFrameId),
23 weak_factory_(this) {
24 cast_environment_->PostTask(
25 CastEnvironment::MAIN,
26 FROM_HERE,
27 base::Bind(status_change_cb_, STATUS_INITIALIZED));
28 }
29
30 SizeAdaptableVideoEncoderBase::~SizeAdaptableVideoEncoderBase() {
31 weak_factory_.InvalidateWeakPtrs();
32 DestroyCurrentEncoder();
33 }
34
35 bool SizeAdaptableVideoEncoderBase::EncodeVideoFrame(
36 const scoped_refptr<media::VideoFrame>& video_frame,
37 const base::TimeTicks& reference_time,
38 const FrameEncodedCallback& frame_encoded_callback) {
39 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
40
41 const gfx::Size frame_size = video_frame->visible_rect().size();
42 if (frame_size.IsEmpty()) {
43 DVLOG(1) << "Rejecting empty video frame.";
44 return false;
45 }
46 if (frame_size != current_encoder_frame_size_ || !current_encoder_) {
47 VLOG(1) << "Dropping frame (of size " << frame_size.ToString()
48 << ") until a replacement encoder is spun-up. Current encoder "
49 "handles frames of size "
50 << current_encoder_frame_size_.ToString() << '.';
51 MaybeSpawnReplacementEncoder(frame_size);
52 return false;
53 }
54
55 const bool is_frame_accepted = current_encoder_->EncodeVideoFrame(
56 video_frame,
57 reference_time,
58 base::Bind(&SizeAdaptableVideoEncoderBase::OnEncodedVideoFrame,
59 weak_factory_.GetWeakPtr(),
60 frame_encoded_callback));
61 if (is_frame_accepted)
62 ++frames_in_encoder_;
63 return is_frame_accepted;
64 }
65
66 void SizeAdaptableVideoEncoderBase::SetBitRate(int new_bit_rate) {
67 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
68 video_config_.start_bitrate = new_bit_rate;
69 if (current_encoder_)
70 current_encoder_->SetBitRate(new_bit_rate);
71 }
72
73 void SizeAdaptableVideoEncoderBase::GenerateKeyFrame() {
74 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
75 if (current_encoder_)
76 current_encoder_->GenerateKeyFrame();
77 }
78
79 void SizeAdaptableVideoEncoderBase::LatestFrameIdToReference(uint32 frame_id) {
80 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
81 if (current_encoder_)
82 current_encoder_->LatestFrameIdToReference(frame_id);
83 }
84
85 scoped_ptr<VideoFrameFactory>
86 SizeAdaptableVideoEncoderBase::CreateVideoFrameFactory() {
87 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
88 return nullptr;
89 }
90
91 void SizeAdaptableVideoEncoderBase::EmitFrames() {
92 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
93 if (current_encoder_)
94 current_encoder_->EmitFrames();
95 }
96
97 StatusChangeCallback
98 SizeAdaptableVideoEncoderBase::CreateEncoderStatusChangeCallback() {
99 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
100 return base::Bind(&SizeAdaptableVideoEncoderBase::OnEncoderStatusChange,
101 weak_factory_.GetWeakPtr());
102 }
103
104 void SizeAdaptableVideoEncoderBase::OnEncoderReplaced(
105 VideoEncoder* replacement_encoder) {}
106
107 void SizeAdaptableVideoEncoderBase::DestroyCurrentEncoder() {
108 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
109 current_encoder_.reset();
110 }
111
112 void SizeAdaptableVideoEncoderBase::MaybeSpawnReplacementEncoder(
113 const gfx::Size& size_needed) {
114 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
115
116 // If prior frames are still encoding in the current encoder, let them finish
117 // first.
118 if (frames_in_encoder_ > 0) {
119 current_encoder_->EmitFrames();
120 // Check again, since EmitFrames() is a synchronous operation with some
121 // encoders.
122 if (frames_in_encoder_ > 0)
123 return;
124 }
125
126 if (next_encoder_.get())
127 return; // Already spawned.
128
129 // Prevent future callbacks from |current_encoder_| and destroy it.
130 weak_factory_.InvalidateWeakPtrs();
131 DestroyCurrentEncoder();
132
133 OnEncoderStatusChange(STATUS_CODEC_REINIT_PENDING);
134 next_encoder_frame_size_ = size_needed;
135 VLOG(1) << "Creating replacement video encoder (for frame size change from "
136 << current_encoder_frame_size_.ToString() << " to "
137 << next_encoder_frame_size_.ToString() << ").";
138 next_encoder_ = CreateReplacementEncoder().Pass();
139 DCHECK(next_encoder_.get());
140 }
141
142 void SizeAdaptableVideoEncoderBase::OnEncoderStatusChange(
143 OperationalStatus status) {
144 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
145 if (next_encoder_.get() && status == STATUS_INITIALIZED) {
146 // Begin using the replacement encoder.
147 current_encoder_ = next_encoder_.Pass();
148 current_encoder_frame_size_ = next_encoder_frame_size_;
149 OnEncoderReplaced(current_encoder_.get());
150 }
151 status_change_cb_.Run(status);
152 }
153
154 void SizeAdaptableVideoEncoderBase::OnEncodedVideoFrame(
155 const FrameEncodedCallback& frame_encoded_callback,
156 scoped_ptr<EncodedFrame> encoded_frame) {
157 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
158 --frames_in_encoder_;
159 DCHECK_GE(frames_in_encoder_, 0);
160 last_frame_id_ = encoded_frame->frame_id;
161 frame_encoded_callback.Run(encoded_frame.Pass());
162 }
163
164 } // namespace cast
165 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698