Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/sys_info.h" | 9 #include "base/sys_info.h" |
| 10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 : public base::RefCountedThreadSafe<VpxEncoder> { | 73 : public base::RefCountedThreadSafe<VpxEncoder> { |
| 74 public: | 74 public: |
| 75 static void ShutdownEncoder(scoped_ptr<base::Thread> encoding_thread, | 75 static void ShutdownEncoder(scoped_ptr<base::Thread> encoding_thread, |
| 76 ScopedVpxCodecCtxPtr encoder); | 76 ScopedVpxCodecCtxPtr encoder); |
| 77 | 77 |
| 78 VpxEncoder(bool use_vp9, const OnEncodedVideoCB& on_encoded_video_callback); | 78 VpxEncoder(bool use_vp9, const OnEncodedVideoCB& on_encoded_video_callback); |
| 79 | 79 |
| 80 void StartFrameEncode(const scoped_refptr<VideoFrame>& frame, | 80 void StartFrameEncode(const scoped_refptr<VideoFrame>& frame, |
| 81 base::TimeTicks capture_timestamp); | 81 base::TimeTicks capture_timestamp); |
| 82 | 82 |
| 83 void set_paused(bool paused) { paused_ = paused; } | |
| 84 | |
| 83 private: | 85 private: |
| 84 friend class base::RefCountedThreadSafe<VpxEncoder>; | 86 friend class base::RefCountedThreadSafe<VpxEncoder>; |
| 85 ~VpxEncoder(); | 87 ~VpxEncoder(); |
| 86 | 88 |
| 87 void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, | 89 void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, |
| 88 base::TimeTicks capture_timestamp); | 90 base::TimeTicks capture_timestamp); |
| 89 | 91 |
| 90 void ConfigureEncoding(const gfx::Size& size); | 92 void ConfigureEncoding(const gfx::Size& size); |
| 91 | 93 |
| 92 // Returns true if |codec_config_| has been filled in at least once. | 94 // Returns true if |codec_config_| has been filled in at least once. |
| 93 bool IsInitialized() const; | 95 bool IsInitialized() const; |
| 94 | 96 |
| 95 // Estimate the frame duration from |frame| and |last_frame_timestamp_|. | 97 // Estimate the frame duration from |frame| and |last_frame_timestamp_|. |
| 96 base::TimeDelta CalculateFrameDuration( | 98 base::TimeDelta CalculateFrameDuration( |
| 97 const scoped_refptr<VideoFrame>& frame); | 99 const scoped_refptr<VideoFrame>& frame); |
| 98 | 100 |
| 101 // While |paused_|, frames are not encoded. | |
| 102 bool paused_; | |
| 103 | |
| 99 // Force usage of VP9 for encoding, instead of VP8 which is the default. | 104 // Force usage of VP9 for encoding, instead of VP8 which is the default. |
| 100 const bool use_vp9_; | 105 const bool use_vp9_; |
| 101 | 106 |
| 102 // Used to shutdown properly on the same thread we were created. | 107 // Used to shutdown properly on the same thread we were created. |
| 103 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 108 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
| 104 | 109 |
| 105 // Task runner where frames to encode and reply callbacks must happen. | 110 // Task runner where frames to encode and reply callbacks must happen. |
| 106 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; | 111 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; |
| 107 | 112 |
| 108 // This callback should be exercised on IO thread. | 113 // This callback should be exercised on IO thread. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 129 scoped_ptr<base::Thread> encoding_thread, | 134 scoped_ptr<base::Thread> encoding_thread, |
| 130 ScopedVpxCodecCtxPtr encoder) { | 135 ScopedVpxCodecCtxPtr encoder) { |
| 131 DCHECK(encoding_thread->IsRunning()); | 136 DCHECK(encoding_thread->IsRunning()); |
| 132 encoding_thread->Stop(); | 137 encoding_thread->Stop(); |
| 133 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. | 138 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. |
| 134 } | 139 } |
| 135 | 140 |
| 136 VideoTrackRecorder::VpxEncoder::VpxEncoder( | 141 VideoTrackRecorder::VpxEncoder::VpxEncoder( |
| 137 bool use_vp9, | 142 bool use_vp9, |
| 138 const OnEncodedVideoCB& on_encoded_video_callback) | 143 const OnEncodedVideoCB& on_encoded_video_callback) |
| 139 : use_vp9_(use_vp9), | 144 : paused_(false), |
| 145 use_vp9_(use_vp9), | |
| 140 main_task_runner_(base::MessageLoop::current()->task_runner()), | 146 main_task_runner_(base::MessageLoop::current()->task_runner()), |
| 141 on_encoded_video_callback_(on_encoded_video_callback), | 147 on_encoded_video_callback_(on_encoded_video_callback), |
| 142 encoding_thread_(new base::Thread("EncodingThread")) { | 148 encoding_thread_(new base::Thread("EncodingThread")) { |
| 143 DCHECK(!on_encoded_video_callback_.is_null()); | 149 DCHECK(!on_encoded_video_callback_.is_null()); |
| 144 | 150 |
| 145 codec_config_.g_timebase.den = 0; // Not initialized. | 151 codec_config_.g_timebase.den = 0; // Not initialized. |
| 146 | 152 |
| 147 DCHECK(!encoding_thread_->IsRunning()); | 153 DCHECK(!encoding_thread_->IsRunning()); |
| 148 encoding_thread_->Start(); | 154 encoding_thread_->Start(); |
| 149 } | 155 } |
| 150 | 156 |
| 151 VideoTrackRecorder::VpxEncoder::~VpxEncoder() { | 157 VideoTrackRecorder::VpxEncoder::~VpxEncoder() { |
| 152 main_task_runner_->PostTask(FROM_HERE, | 158 main_task_runner_->PostTask(FROM_HERE, |
| 153 base::Bind(&VpxEncoder::ShutdownEncoder, | 159 base::Bind(&VpxEncoder::ShutdownEncoder, |
| 154 base::Passed(&encoding_thread_), | 160 base::Passed(&encoding_thread_), |
| 155 base::Passed(&encoder_))); | 161 base::Passed(&encoder_))); |
| 156 } | 162 } |
| 157 | 163 |
| 158 void VideoTrackRecorder::VpxEncoder::StartFrameEncode( | 164 void VideoTrackRecorder::VpxEncoder::StartFrameEncode( |
| 159 const scoped_refptr<VideoFrame>& frame, | 165 const scoped_refptr<VideoFrame>& frame, |
| 160 base::TimeTicks capture_timestamp) { | 166 base::TimeTicks capture_timestamp) { |
| 161 // Cache the thread sending frames on first frame arrival. | 167 // Cache the thread sending frames on first frame arrival. |
| 162 if (!origin_task_runner_.get()) | 168 if (!origin_task_runner_.get()) |
| 163 origin_task_runner_ = base::MessageLoop::current()->task_runner(); | 169 origin_task_runner_ = base::MessageLoop::current()->task_runner(); |
| 164 DCHECK(origin_task_runner_->BelongsToCurrentThread()); | 170 DCHECK(origin_task_runner_->BelongsToCurrentThread()); |
| 165 | 171 if (paused_) |
| 172 return; | |
|
emircan
2015/10/20 22:00:27
Move to l.167?
| |
| 166 encoding_thread_->task_runner()->PostTask( | 173 encoding_thread_->task_runner()->PostTask( |
| 167 FROM_HERE, base::Bind(&VpxEncoder::EncodeOnEncodingThread, | 174 FROM_HERE, base::Bind(&VpxEncoder::EncodeOnEncodingThread, |
| 168 this, frame, capture_timestamp)); | 175 this, frame, capture_timestamp)); |
| 169 } | 176 } |
| 170 | 177 |
| 171 void VideoTrackRecorder::VpxEncoder::EncodeOnEncodingThread( | 178 void VideoTrackRecorder::VpxEncoder::EncodeOnEncodingThread( |
| 172 const scoped_refptr<VideoFrame>& frame, | 179 const scoped_refptr<VideoFrame>& frame, |
| 173 base::TimeTicks capture_timestamp) { | 180 base::TimeTicks capture_timestamp) { |
| 174 TRACE_EVENT0("video", | 181 TRACE_EVENT0("video", |
| 175 "VideoTrackRecorder::VpxEncoder::EncodeOnEncodingThread"); | 182 "VideoTrackRecorder::VpxEncoder::EncodeOnEncodingThread"); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 encoder_), | 358 encoder_), |
| 352 track_); | 359 track_); |
| 353 } | 360 } |
| 354 | 361 |
| 355 VideoTrackRecorder::~VideoTrackRecorder() { | 362 VideoTrackRecorder::~VideoTrackRecorder() { |
| 356 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 363 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 357 RemoveFromVideoTrack(this, track_); | 364 RemoveFromVideoTrack(this, track_); |
| 358 track_.reset(); | 365 track_.reset(); |
| 359 } | 366 } |
| 360 | 367 |
| 368 void VideoTrackRecorder::Pause() { | |
| 369 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | |
| 370 DCHECK(encoder_); | |
| 371 encoder_->set_paused(true); | |
| 372 } | |
| 373 | |
| 374 void VideoTrackRecorder::Resume() { | |
| 375 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | |
| 376 DCHECK(encoder_); | |
| 377 encoder_->set_paused(false); | |
| 378 } | |
| 379 | |
| 361 void VideoTrackRecorder::OnVideoFrameForTesting( | 380 void VideoTrackRecorder::OnVideoFrameForTesting( |
| 362 const scoped_refptr<media::VideoFrame>& frame, | 381 const scoped_refptr<media::VideoFrame>& frame, |
| 363 base::TimeTicks timestamp) { | 382 base::TimeTicks timestamp) { |
| 364 encoder_->StartFrameEncode(frame, timestamp); | 383 encoder_->StartFrameEncode(frame, timestamp); |
| 365 } | 384 } |
| 366 | 385 |
| 367 } // namespace content | 386 } // namespace content |
| OLD | NEW |