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

Side by Side Diff: content/renderer/media/video_track_recorder.cc

Issue 1610473002: MediaRecorder: wire the bitRate settings in Blink and content (2nd go) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: peter@s comments Created 4 years, 11 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/video_track_recorder.h" 5 #include "content/renderer/media/video_track_recorder.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // which is cached on first frame arrival, and is supposed to be the render IO 71 // which is cached on first frame arrival, and is supposed to be the render IO
72 // thread, but this is not enforced; 72 // thread, but this is not enforced;
73 // - uses an internal |encoding_thread_| for libvpx interactions, notably for 73 // - uses an internal |encoding_thread_| for libvpx interactions, notably for
74 // encoding (which might take some time). 74 // encoding (which might take some time).
75 class VideoTrackRecorder::VpxEncoder final 75 class VideoTrackRecorder::VpxEncoder final
76 : public base::RefCountedThreadSafe<VpxEncoder> { 76 : public base::RefCountedThreadSafe<VpxEncoder> {
77 public: 77 public:
78 static void ShutdownEncoder(scoped_ptr<base::Thread> encoding_thread, 78 static void ShutdownEncoder(scoped_ptr<base::Thread> encoding_thread,
79 ScopedVpxCodecCtxPtr encoder); 79 ScopedVpxCodecCtxPtr encoder);
80 80
81 VpxEncoder(bool use_vp9, const OnEncodedVideoCB& on_encoded_video_callback); 81 VpxEncoder(bool use_vp9,
82 const OnEncodedVideoCB& on_encoded_video_callback,
83 int32_t bits_per_second);
82 84
83 void StartFrameEncode(const scoped_refptr<VideoFrame>& frame, 85 void StartFrameEncode(const scoped_refptr<VideoFrame>& frame,
84 base::TimeTicks capture_timestamp); 86 base::TimeTicks capture_timestamp);
85 87
86 void set_paused(bool paused) { paused_ = paused; } 88 void set_paused(bool paused) { paused_ = paused; }
87 89
88 private: 90 private:
89 friend class base::RefCountedThreadSafe<VpxEncoder>; 91 friend class base::RefCountedThreadSafe<VpxEncoder>;
90 ~VpxEncoder(); 92 ~VpxEncoder();
91 93
92 void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, 94 void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame,
93 base::TimeTicks capture_timestamp); 95 base::TimeTicks capture_timestamp);
94 96
95 void ConfigureEncoding(const gfx::Size& size); 97 void ConfigureEncoding(const gfx::Size& size);
96 98
97 // Returns true if |codec_config_| has been filled in at least once. 99 // Returns true if |codec_config_| has been filled in at least once.
98 bool IsInitialized() const; 100 bool IsInitialized() const;
99 101
100 // Estimate the frame duration from |frame| and |last_frame_timestamp_|. 102 // Estimate the frame duration from |frame| and |last_frame_timestamp_|.
101 base::TimeDelta CalculateFrameDuration( 103 base::TimeDelta CalculateFrameDuration(
102 const scoped_refptr<VideoFrame>& frame); 104 const scoped_refptr<VideoFrame>& frame);
103 105
104 // While |paused_|, frames are not encoded. 106 // While |paused_|, frames are not encoded.
105 bool paused_; 107 bool paused_;
106 108
107 // Force usage of VP9 for encoding, instead of VP8 which is the default. 109 // Force usage of VP9 for encoding, instead of VP8 which is the default.
108 const bool use_vp9_; 110 const bool use_vp9_;
109 111
112 // This callback should be exercised on IO thread.
113 const OnEncodedVideoCB on_encoded_video_callback_;
114
115 // Target bitrate or video encoding. If 0, a standard bitrate is used.
116 const int32_t bits_per_second_;
117
110 // Used to shutdown properly on the same thread we were created. 118 // Used to shutdown properly on the same thread we were created.
111 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 119 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
112 120
113 // Task runner where frames to encode and reply callbacks must happen. 121 // Task runner where frames to encode and reply callbacks must happen.
114 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; 122 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
115 123
116 // This callback should be exercised on IO thread.
117 const OnEncodedVideoCB on_encoded_video_callback_;
118
119 // Thread for encoding. Active for the lifetime of VpxEncoder. All variables 124 // Thread for encoding. Active for the lifetime of VpxEncoder. All variables
120 // below this are used in this thread. 125 // below this are used in this thread.
121 scoped_ptr<base::Thread> encoding_thread_; 126 scoped_ptr<base::Thread> encoding_thread_;
122 // VP8 internal objects: configuration and encoder. 127 // VP8 internal objects: configuration and encoder.
123 vpx_codec_enc_cfg_t codec_config_; 128 vpx_codec_enc_cfg_t codec_config_;
124 // |encoder_| is a special scoped pointer to guarantee proper destruction. 129 // |encoder_| is a special scoped pointer to guarantee proper destruction.
125 // Again, it should only be accessed on |encoding_thread_|. 130 // Again, it should only be accessed on |encoding_thread_|.
126 ScopedVpxCodecCtxPtr encoder_; 131 ScopedVpxCodecCtxPtr encoder_;
127 132
128 // The |VideoFrame::timestamp()| of the last encoded frame. This is used to 133 // The |VideoFrame::timestamp()| of the last encoded frame. This is used to
129 // predict the duration of the next frame. 134 // predict the duration of the next frame.
130 base::TimeDelta last_frame_timestamp_; 135 base::TimeDelta last_frame_timestamp_;
131 136
132 DISALLOW_COPY_AND_ASSIGN(VpxEncoder); 137 DISALLOW_COPY_AND_ASSIGN(VpxEncoder);
133 }; 138 };
134 139
135 // static 140 // static
136 void VideoTrackRecorder::VpxEncoder::ShutdownEncoder( 141 void VideoTrackRecorder::VpxEncoder::ShutdownEncoder(
137 scoped_ptr<base::Thread> encoding_thread, 142 scoped_ptr<base::Thread> encoding_thread,
138 ScopedVpxCodecCtxPtr encoder) { 143 ScopedVpxCodecCtxPtr encoder) {
139 DCHECK(encoding_thread->IsRunning()); 144 DCHECK(encoding_thread->IsRunning());
140 encoding_thread->Stop(); 145 encoding_thread->Stop();
141 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. 146 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope.
142 } 147 }
143 148
144 VideoTrackRecorder::VpxEncoder::VpxEncoder( 149 VideoTrackRecorder::VpxEncoder::VpxEncoder(
145 bool use_vp9, 150 bool use_vp9,
146 const OnEncodedVideoCB& on_encoded_video_callback) 151 const OnEncodedVideoCB& on_encoded_video_callback,
152 int32_t bits_per_second)
147 : paused_(false), 153 : paused_(false),
148 use_vp9_(use_vp9), 154 use_vp9_(use_vp9),
155 on_encoded_video_callback_(on_encoded_video_callback),
156 bits_per_second_(bits_per_second),
149 main_task_runner_(base::MessageLoop::current()->task_runner()), 157 main_task_runner_(base::MessageLoop::current()->task_runner()),
150 on_encoded_video_callback_(on_encoded_video_callback),
151 encoding_thread_(new base::Thread("EncodingThread")) { 158 encoding_thread_(new base::Thread("EncodingThread")) {
152 DCHECK(!on_encoded_video_callback_.is_null()); 159 DCHECK(!on_encoded_video_callback_.is_null());
153 160
154 codec_config_.g_timebase.den = 0; // Not initialized. 161 codec_config_.g_timebase.den = 0; // Not initialized.
155 162
156 DCHECK(!encoding_thread_->IsRunning()); 163 DCHECK(!encoding_thread_->IsRunning());
157 encoding_thread_->Start(); 164 encoding_thread_->Start();
158 } 165 }
159 166
160 VideoTrackRecorder::VpxEncoder::~VpxEncoder() { 167 VideoTrackRecorder::VpxEncoder::~VpxEncoder() {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 encoder_.reset(); 258 encoder_.reset();
252 } 259 }
253 260
254 const vpx_codec_iface_t* interface = 261 const vpx_codec_iface_t* interface =
255 use_vp9_ ? vpx_codec_vp9_cx() : vpx_codec_vp8_cx(); 262 use_vp9_ ? vpx_codec_vp9_cx() : vpx_codec_vp8_cx();
256 const vpx_codec_err_t result = vpx_codec_enc_config_default(interface, 263 const vpx_codec_err_t result = vpx_codec_enc_config_default(interface,
257 &codec_config_, 264 &codec_config_,
258 0 /* reserved */); 265 0 /* reserved */);
259 DCHECK_EQ(VPX_CODEC_OK, result); 266 DCHECK_EQ(VPX_CODEC_OK, result);
260 267
261 // Adjust default bit rate to account for the actual size.
262 DCHECK_EQ(320u, codec_config_.g_w); 268 DCHECK_EQ(320u, codec_config_.g_w);
263 DCHECK_EQ(240u, codec_config_.g_h); 269 DCHECK_EQ(240u, codec_config_.g_h);
264 DCHECK_EQ(256u, codec_config_.rc_target_bitrate); 270 DCHECK_EQ(256u, codec_config_.rc_target_bitrate);
265 codec_config_.rc_target_bitrate = size.GetArea() * 271 // Use the selected bitrate or adjust default bit rate to account for the
266 codec_config_.rc_target_bitrate / 272 // actual size.
267 codec_config_.g_w / codec_config_.g_h; 273 if (bits_per_second_ > 0) {
274 codec_config_.rc_target_bitrate = bits_per_second_;
275 } else {
276 codec_config_.rc_target_bitrate = size.GetArea() *
277 codec_config_.rc_target_bitrate /
278 codec_config_.g_w / codec_config_.g_h;
279 }
268 // Both VP8/VP9 configuration should be Variable BitRate by default. 280 // Both VP8/VP9 configuration should be Variable BitRate by default.
269 DCHECK_EQ(VPX_VBR, codec_config_.rc_end_usage); 281 DCHECK_EQ(VPX_VBR, codec_config_.rc_end_usage);
270 if (use_vp9_) { 282 if (use_vp9_) {
271 // Number of frames to consume before producing output. 283 // Number of frames to consume before producing output.
272 codec_config_.g_lag_in_frames = 0; 284 codec_config_.g_lag_in_frames = 0;
273 285
274 // DCHECK that the profile selected by default is I420 (magic number 0). 286 // DCHECK that the profile selected by default is I420 (magic number 0).
275 DCHECK_EQ(0u, codec_config_.g_profile); 287 DCHECK_EQ(0u, codec_config_.g_profile);
276 } else { 288 } else {
277 // VP8 always produces frames instantaneously. 289 // VP8 always produces frames instantaneously.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // Make sure |predicted_frame_duration| is in a safe range of values. 353 // Make sure |predicted_frame_duration| is in a safe range of values.
342 const TimeDelta kMaxFrameDuration = TimeDelta::FromSecondsD(1.0 / 8); 354 const TimeDelta kMaxFrameDuration = TimeDelta::FromSecondsD(1.0 / 8);
343 const TimeDelta kMinFrameDuration = TimeDelta::FromMilliseconds(1); 355 const TimeDelta kMinFrameDuration = TimeDelta::FromMilliseconds(1);
344 return std::min(kMaxFrameDuration, std::max(predicted_frame_duration, 356 return std::min(kMaxFrameDuration, std::max(predicted_frame_duration,
345 kMinFrameDuration)); 357 kMinFrameDuration));
346 } 358 }
347 359
348 VideoTrackRecorder::VideoTrackRecorder( 360 VideoTrackRecorder::VideoTrackRecorder(
349 bool use_vp9, 361 bool use_vp9,
350 const blink::WebMediaStreamTrack& track, 362 const blink::WebMediaStreamTrack& track,
351 const OnEncodedVideoCB& on_encoded_video_callback) 363 const OnEncodedVideoCB& on_encoded_video_callback,
364 int32_t bits_per_second)
352 : track_(track), 365 : track_(track),
353 encoder_(new VpxEncoder(use_vp9, on_encoded_video_callback)) { 366 encoder_(
367 new VpxEncoder(use_vp9, on_encoded_video_callback, bits_per_second)) {
354 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 368 DCHECK(main_render_thread_checker_.CalledOnValidThread());
355 DCHECK(!track_.isNull()); 369 DCHECK(!track_.isNull());
356 DCHECK(track_.extraData()); 370 DCHECK(track_.extraData());
357 371
358 // StartFrameEncode() will be called on Render IO thread. 372 // StartFrameEncode() will be called on Render IO thread.
359 AddToVideoTrack(this, 373 AddToVideoTrack(this,
360 base::Bind(&VideoTrackRecorder::VpxEncoder::StartFrameEncode, 374 base::Bind(&VideoTrackRecorder::VpxEncoder::StartFrameEncode,
361 encoder_), 375 encoder_),
362 track_); 376 track_);
363 } 377 }
(...skipping 16 matching lines...) Expand all
380 encoder_->set_paused(false); 394 encoder_->set_paused(false);
381 } 395 }
382 396
383 void VideoTrackRecorder::OnVideoFrameForTesting( 397 void VideoTrackRecorder::OnVideoFrameForTesting(
384 const scoped_refptr<media::VideoFrame>& frame, 398 const scoped_refptr<media::VideoFrame>& frame,
385 base::TimeTicks timestamp) { 399 base::TimeTicks timestamp) {
386 encoder_->StartFrameEncode(frame, timestamp); 400 encoder_->StartFrameEncode(frame, timestamp);
387 } 401 }
388 402
389 } // namespace content 403 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698