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

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: 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 const int32_t bits_per_second_;
Peter Beverloo 2016/01/20 18:35:35 nit: all other members have documentation
mcasas 2016/01/20 21:13:22 Done.
116
110 // Used to shutdown properly on the same thread we were created. 117 // Used to shutdown properly on the same thread we were created.
111 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 118 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
112 119
113 // Task runner where frames to encode and reply callbacks must happen. 120 // Task runner where frames to encode and reply callbacks must happen.
114 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; 121 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
115 122
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 123 // Thread for encoding. Active for the lifetime of VpxEncoder. All variables
120 // below this are used in this thread. 124 // below this are used in this thread.
121 scoped_ptr<base::Thread> encoding_thread_; 125 scoped_ptr<base::Thread> encoding_thread_;
122 // VP8 internal objects: configuration and encoder. 126 // VP8 internal objects: configuration and encoder.
123 vpx_codec_enc_cfg_t codec_config_; 127 vpx_codec_enc_cfg_t codec_config_;
124 // |encoder_| is a special scoped pointer to guarantee proper destruction. 128 // |encoder_| is a special scoped pointer to guarantee proper destruction.
125 // Again, it should only be accessed on |encoding_thread_|. 129 // Again, it should only be accessed on |encoding_thread_|.
126 ScopedVpxCodecCtxPtr encoder_; 130 ScopedVpxCodecCtxPtr encoder_;
127 131
128 // The |VideoFrame::timestamp()| of the last encoded frame. This is used to 132 // The |VideoFrame::timestamp()| of the last encoded frame. This is used to
129 // predict the duration of the next frame. 133 // predict the duration of the next frame.
130 base::TimeDelta last_frame_timestamp_; 134 base::TimeDelta last_frame_timestamp_;
131 135
132 DISALLOW_COPY_AND_ASSIGN(VpxEncoder); 136 DISALLOW_COPY_AND_ASSIGN(VpxEncoder);
133 }; 137 };
134 138
135 // static 139 // static
136 void VideoTrackRecorder::VpxEncoder::ShutdownEncoder( 140 void VideoTrackRecorder::VpxEncoder::ShutdownEncoder(
137 scoped_ptr<base::Thread> encoding_thread, 141 scoped_ptr<base::Thread> encoding_thread,
138 ScopedVpxCodecCtxPtr encoder) { 142 ScopedVpxCodecCtxPtr encoder) {
139 DCHECK(encoding_thread->IsRunning()); 143 DCHECK(encoding_thread->IsRunning());
140 encoding_thread->Stop(); 144 encoding_thread->Stop();
141 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. 145 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope.
142 } 146 }
143 147
144 VideoTrackRecorder::VpxEncoder::VpxEncoder( 148 VideoTrackRecorder::VpxEncoder::VpxEncoder(
145 bool use_vp9, 149 bool use_vp9,
146 const OnEncodedVideoCB& on_encoded_video_callback) 150 const OnEncodedVideoCB& on_encoded_video_callback,
151 int32_t bits_per_second)
147 : paused_(false), 152 : paused_(false),
148 use_vp9_(use_vp9), 153 use_vp9_(use_vp9),
154 on_encoded_video_callback_(on_encoded_video_callback),
155 bits_per_second_(bits_per_second),
149 main_task_runner_(base::MessageLoop::current()->task_runner()), 156 main_task_runner_(base::MessageLoop::current()->task_runner()),
150 on_encoded_video_callback_(on_encoded_video_callback),
151 encoding_thread_(new base::Thread("EncodingThread")) { 157 encoding_thread_(new base::Thread("EncodingThread")) {
152 DCHECK(!on_encoded_video_callback_.is_null()); 158 DCHECK(!on_encoded_video_callback_.is_null());
153 159
154 codec_config_.g_timebase.den = 0; // Not initialized. 160 codec_config_.g_timebase.den = 0; // Not initialized.
155 161
156 DCHECK(!encoding_thread_->IsRunning()); 162 DCHECK(!encoding_thread_->IsRunning());
157 encoding_thread_->Start(); 163 encoding_thread_->Start();
158 } 164 }
159 165
160 VideoTrackRecorder::VpxEncoder::~VpxEncoder() { 166 VideoTrackRecorder::VpxEncoder::~VpxEncoder() {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 encoder_.reset(); 257 encoder_.reset();
252 } 258 }
253 259
254 const vpx_codec_iface_t* interface = 260 const vpx_codec_iface_t* interface =
255 use_vp9_ ? vpx_codec_vp9_cx() : vpx_codec_vp8_cx(); 261 use_vp9_ ? vpx_codec_vp9_cx() : vpx_codec_vp8_cx();
256 const vpx_codec_err_t result = vpx_codec_enc_config_default(interface, 262 const vpx_codec_err_t result = vpx_codec_enc_config_default(interface,
257 &codec_config_, 263 &codec_config_,
258 0 /* reserved */); 264 0 /* reserved */);
259 DCHECK_EQ(VPX_CODEC_OK, result); 265 DCHECK_EQ(VPX_CODEC_OK, result);
260 266
261 // Adjust default bit rate to account for the actual size.
262 DCHECK_EQ(320u, codec_config_.g_w); 267 DCHECK_EQ(320u, codec_config_.g_w);
263 DCHECK_EQ(240u, codec_config_.g_h); 268 DCHECK_EQ(240u, codec_config_.g_h);
264 DCHECK_EQ(256u, codec_config_.rc_target_bitrate); 269 DCHECK_EQ(256u, codec_config_.rc_target_bitrate);
265 codec_config_.rc_target_bitrate = size.GetArea() * 270 // Use the selected bitrate or adjust default bit rate to account for the
266 codec_config_.rc_target_bitrate / 271 // actual size.
267 codec_config_.g_w / codec_config_.g_h; 272 if (bits_per_second_ > 0) {
273 codec_config_.rc_target_bitrate = bits_per_second_;
274 } else {
275 codec_config_.rc_target_bitrate = size.GetArea() *
276 codec_config_.rc_target_bitrate /
277 codec_config_.g_w / codec_config_.g_h;
278 }
268 // Both VP8/VP9 configuration should be Variable BitRate by default. 279 // Both VP8/VP9 configuration should be Variable BitRate by default.
269 DCHECK_EQ(VPX_VBR, codec_config_.rc_end_usage); 280 DCHECK_EQ(VPX_VBR, codec_config_.rc_end_usage);
270 if (use_vp9_) { 281 if (use_vp9_) {
271 // Number of frames to consume before producing output. 282 // Number of frames to consume before producing output.
272 codec_config_.g_lag_in_frames = 0; 283 codec_config_.g_lag_in_frames = 0;
273 284
274 // DCHECK that the profile selected by default is I420 (magic number 0). 285 // DCHECK that the profile selected by default is I420 (magic number 0).
275 DCHECK_EQ(0u, codec_config_.g_profile); 286 DCHECK_EQ(0u, codec_config_.g_profile);
276 } else { 287 } else {
277 // VP8 always produces frames instantaneously. 288 // 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. 352 // Make sure |predicted_frame_duration| is in a safe range of values.
342 const TimeDelta kMaxFrameDuration = TimeDelta::FromSecondsD(1.0 / 8); 353 const TimeDelta kMaxFrameDuration = TimeDelta::FromSecondsD(1.0 / 8);
343 const TimeDelta kMinFrameDuration = TimeDelta::FromMilliseconds(1); 354 const TimeDelta kMinFrameDuration = TimeDelta::FromMilliseconds(1);
344 return std::min(kMaxFrameDuration, std::max(predicted_frame_duration, 355 return std::min(kMaxFrameDuration, std::max(predicted_frame_duration,
345 kMinFrameDuration)); 356 kMinFrameDuration));
346 } 357 }
347 358
348 VideoTrackRecorder::VideoTrackRecorder( 359 VideoTrackRecorder::VideoTrackRecorder(
349 bool use_vp9, 360 bool use_vp9,
350 const blink::WebMediaStreamTrack& track, 361 const blink::WebMediaStreamTrack& track,
351 const OnEncodedVideoCB& on_encoded_video_callback) 362 const OnEncodedVideoCB& on_encoded_video_callback,
363 int32_t bits_per_second)
352 : track_(track), 364 : track_(track),
353 encoder_(new VpxEncoder(use_vp9, on_encoded_video_callback)) { 365 encoder_(
366 new VpxEncoder(use_vp9, on_encoded_video_callback, bits_per_second)) {
354 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 367 DCHECK(main_render_thread_checker_.CalledOnValidThread());
355 DCHECK(!track_.isNull()); 368 DCHECK(!track_.isNull());
356 DCHECK(track_.extraData()); 369 DCHECK(track_.extraData());
357 370
358 // StartFrameEncode() will be called on Render IO thread. 371 // StartFrameEncode() will be called on Render IO thread.
359 AddToVideoTrack(this, 372 AddToVideoTrack(this,
360 base::Bind(&VideoTrackRecorder::VpxEncoder::StartFrameEncode, 373 base::Bind(&VideoTrackRecorder::VpxEncoder::StartFrameEncode,
361 encoder_), 374 encoder_),
362 track_); 375 track_);
363 } 376 }
(...skipping 16 matching lines...) Expand all
380 encoder_->set_paused(false); 393 encoder_->set_paused(false);
381 } 394 }
382 395
383 void VideoTrackRecorder::OnVideoFrameForTesting( 396 void VideoTrackRecorder::OnVideoFrameForTesting(
384 const scoped_refptr<media::VideoFrame>& frame, 397 const scoped_refptr<media::VideoFrame>& frame,
385 base::TimeTicks timestamp) { 398 base::TimeTicks timestamp) {
386 encoder_->StartFrameEncode(frame, timestamp); 399 encoder_->StartFrameEncode(frame, timestamp);
387 } 400 }
388 401
389 } // namespace content 402 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698