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

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

Issue 1981633002: Change VideoTrackRecorder to operate on a given task runner (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 28 matching lines...) Expand all
39 // Base class to describe a generic Encoder, encapsulating all actual encoder 39 // Base class to describe a generic Encoder, encapsulating all actual encoder
40 // (re)configurations, encoding and delivery of received frames. This class is 40 // (re)configurations, encoding and delivery of received frames. This class is
41 // ref-counted to allow the MediaStreamVideoTrack to hold a reference to it (via 41 // ref-counted to allow the MediaStreamVideoTrack to hold a reference to it (via
42 // the callback that MediaStreamVideoSink passes along) and to jump back and 42 // the callback that MediaStreamVideoSink passes along) and to jump back and
43 // forth to an internal encoder thread. Moreover, this class: 43 // forth to an internal encoder thread. Moreover, this class:
44 // - is created and destroyed on its parent's thread (usually the main Render 44 // - is created and destroyed on its parent's thread (usually the main Render
45 // thread), |main_task_runner_|. 45 // thread), |main_task_runner_|.
46 // - receives VideoFrames on |origin_task_runner_| and runs OnEncodedVideoCB on 46 // - receives VideoFrames on |origin_task_runner_| and runs OnEncodedVideoCB on
47 // that thread as well. This task runner is cached on first frame arrival, and 47 // that thread as well. This task runner is cached on first frame arrival, and
48 // is supposed to be the render IO thread (but this is not enforced); 48 // is supposed to be the render IO thread (but this is not enforced);
49 // - uses an internal |encoding_thread_| for actual encoder interactions, namely 49 // - uses an internal |encoding_task_runner_| for actual encoder interactions,
50 // configuration, encoding (which might take some time) and destruction. 50 // namely configuration, encoding (which might take some time) and destruction.
51 // This task runner can be passed on the creation. If nothing is passed, a new
52 // encoding thread is created and used.
51 class VideoTrackRecorder::Encoder : public base::RefCountedThreadSafe<Encoder> { 53 class VideoTrackRecorder::Encoder : public base::RefCountedThreadSafe<Encoder> {
52 public: 54 public:
53 Encoder(const OnEncodedVideoCB& on_encoded_video_callback, 55 Encoder(const OnEncodedVideoCB& on_encoded_video_callback,
54 int32_t bits_per_second) 56 int32_t bits_per_second,
57 scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner =
58 nullptr)
55 : main_task_runner_(base::MessageLoop::current()->task_runner()), 59 : main_task_runner_(base::MessageLoop::current()->task_runner()),
56 encoding_thread_(new base::Thread("EncodingThread")), 60 encoding_task_runner_(encoding_task_runner),
57 paused_(false), 61 paused_(false),
58 on_encoded_video_callback_(on_encoded_video_callback), 62 on_encoded_video_callback_(on_encoded_video_callback),
59 bits_per_second_(bits_per_second) { 63 bits_per_second_(bits_per_second) {
60 DCHECK(!on_encoded_video_callback_.is_null()); 64 DCHECK(!on_encoded_video_callback_.is_null());
65 if (!encoding_thread_) {
mcasas 2016/05/14 01:31:08 if (encoding_task_runner_) return; ?
emircan 2016/05/16 19:45:27 Done.
66 encoding_thread_.reset(new base::Thread("EncodingThread"));
67 encoding_thread_->Start();
68 encoding_task_runner_ = encoding_thread_->task_runner();
69 }
61 } 70 }
62 71
63 // Start encoding |frame|, returning via |on_encoded_video_callback_|. This 72 // Start encoding |frame|, returning via |on_encoded_video_callback_|. This
64 // call will also trigger a ConfigureEncoderOnEncodingThread() upon first 73 // call will also trigger a ConfigureEncoderOnEncodingTaskRunner() upon first
65 // frame arrival or parameter change, and an EncodeOnEncodingThread() to 74 // frame arrival or parameter change, and an EncodeOnEncodingTaskRunner() to
66 // actually encode the frame. 75 // actually encode the frame.
67 void StartFrameEncode(const scoped_refptr<VideoFrame>& frame, 76 void StartFrameEncode(const scoped_refptr<VideoFrame>& frame,
68 base::TimeTicks capture_timestamp); 77 base::TimeTicks capture_timestamp);
69 78
70 void SetPaused(bool paused); 79 void SetPaused(bool paused);
71 80
72 protected: 81 protected:
73 friend class base::RefCountedThreadSafe<Encoder>; 82 friend class base::RefCountedThreadSafe<Encoder>;
74 virtual ~Encoder() {} 83 virtual ~Encoder() {}
75 84
76 virtual void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, 85 virtual void EncodeOnEncodingTaskRunner(
77 base::TimeTicks capture_timestamp) = 0; 86 const scoped_refptr<VideoFrame>& frame,
78 virtual void ConfigureEncoderOnEncodingThread(const gfx::Size& size) = 0; 87 base::TimeTicks capture_timestamp) = 0;
88 virtual void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) = 0;
79 89
80 // Used to shutdown properly on the same thread we were created. 90 // Used to shutdown properly on the same thread we were created.
81 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 91 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
82 92
83 // Task runner where frames to encode and reply callbacks must happen. 93 // Task runner where frames to encode and reply callbacks must happen.
84 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; 94 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
85 95
86 // Thread for encoding. Active for the lifetime of VpxEncoder. 96 // Task runner where encoding interactions happen.
97 scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner_;
98
99 // Optional thread for encoding. Active for the lifetime of VpxEncoder.
87 std::unique_ptr<base::Thread> encoding_thread_; 100 std::unique_ptr<base::Thread> encoding_thread_;
88 101
89 // While |paused_|, frames are not encoded. Used only from |encoding_thread_|. 102 // While |paused_|, frames are not encoded. Used only from |encoding_thread_|.
90 bool paused_; 103 bool paused_;
91 104
92 // This callback should be exercised on IO thread. 105 // This callback should be exercised on IO thread.
93 const OnEncodedVideoCB on_encoded_video_callback_; 106 const OnEncodedVideoCB on_encoded_video_callback_;
94 107
95 // Target bitrate for video encoding. If 0, a standard bitrate is used. 108 // Target bitrate for video encoding. If 0, a standard bitrate is used.
96 const int32_t bits_per_second_; 109 const int32_t bits_per_second_;
(...skipping 15 matching lines...) Expand all
112 video_frame->format() == media::PIXEL_FORMAT_YV12 || 125 video_frame->format() == media::PIXEL_FORMAT_YV12 ||
113 video_frame->format() == media::PIXEL_FORMAT_YV12A)) { 126 video_frame->format() == media::PIXEL_FORMAT_YV12A)) {
114 NOTREACHED(); 127 NOTREACHED();
115 return; 128 return;
116 } 129 }
117 scoped_refptr<media::VideoFrame> frame = video_frame; 130 scoped_refptr<media::VideoFrame> frame = video_frame;
118 // Drop alpha channel since we do not support it yet. 131 // Drop alpha channel since we do not support it yet.
119 if (frame->format() == media::PIXEL_FORMAT_YV12A) 132 if (frame->format() == media::PIXEL_FORMAT_YV12A)
120 frame = media::WrapAsI420VideoFrame(video_frame); 133 frame = media::WrapAsI420VideoFrame(video_frame);
121 134
122 encoding_thread_->task_runner()->PostTask( 135 encoding_task_runner_->PostTask(
123 FROM_HERE, base::Bind(&Encoder::EncodeOnEncodingThread, 136 FROM_HERE, base::Bind(&Encoder::EncodeOnEncodingTaskRunner, this, frame,
124 this, frame, capture_timestamp)); 137 capture_timestamp));
125 } 138 }
126 139
127 void VideoTrackRecorder::Encoder::SetPaused(bool paused) { 140 void VideoTrackRecorder::Encoder::SetPaused(bool paused) {
128 if (!encoding_thread_->task_runner()->BelongsToCurrentThread()) { 141 if (!encoding_task_runner_->BelongsToCurrentThread()) {
129 encoding_thread_->task_runner()->PostTask( 142 encoding_task_runner_->PostTask(
130 FROM_HERE, base::Bind(&Encoder::SetPaused, this, paused)); 143 FROM_HERE, base::Bind(&Encoder::SetPaused, this, paused));
131 return; 144 return;
132 } 145 }
133 paused_ = paused; 146 paused_ = paused;
134 } 147 }
135 148
136 namespace { 149 namespace {
137 150
138 // Originally from remoting/codec/scoped_vpx_codec.h. 151 // Originally from remoting/codec/scoped_vpx_codec.h.
139 // TODO(mcasas): Refactor into a common location. 152 // TODO(mcasas): Refactor into a common location.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 ScopedVpxCodecCtxPtr encoder); 186 ScopedVpxCodecCtxPtr encoder);
174 187
175 VpxEncoder( 188 VpxEncoder(
176 bool use_vp9, 189 bool use_vp9,
177 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 190 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
178 int32_t bits_per_second); 191 int32_t bits_per_second);
179 192
180 private: 193 private:
181 // VideoTrackRecorder::Encoder 194 // VideoTrackRecorder::Encoder
182 ~VpxEncoder() override; 195 ~VpxEncoder() override;
183 void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, 196 void EncodeOnEncodingTaskRunner(const scoped_refptr<VideoFrame>& frame,
184 base::TimeTicks capture_timestamp) override; 197 base::TimeTicks capture_timestamp) override;
185 void ConfigureEncoderOnEncodingThread(const gfx::Size& size) override; 198 void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) override;
186 199
187 // Returns true if |codec_config_| has been filled in at least once. 200 // Returns true if |codec_config_| has been filled in at least once.
188 bool IsInitialized() const; 201 bool IsInitialized() const;
189 202
190 // Estimate the frame duration from |frame| and |last_frame_timestamp_|. 203 // Estimate the frame duration from |frame| and |last_frame_timestamp_|.
191 base::TimeDelta EstimateFrameDuration(const scoped_refptr<VideoFrame>& frame); 204 base::TimeDelta EstimateFrameDuration(const scoped_refptr<VideoFrame>& frame);
192 205
193 // Force usage of VP9 for encoding, instead of VP8 which is the default. 206 // Force usage of VP9 for encoding, instead of VP8 which is the default.
194 const bool use_vp9_; 207 const bool use_vp9_;
195 208
(...skipping 29 matching lines...) Expand all
225 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread, 238 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread,
226 ScopedISVCEncoderPtr encoder); 239 ScopedISVCEncoderPtr encoder);
227 240
228 H264Encoder( 241 H264Encoder(
229 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 242 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
230 int32_t bits_per_second); 243 int32_t bits_per_second);
231 244
232 private: 245 private:
233 // VideoTrackRecorder::Encoder 246 // VideoTrackRecorder::Encoder
234 ~H264Encoder() override; 247 ~H264Encoder() override;
235 void EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, 248 void EncodeOnEncodingTaskRunner(const scoped_refptr<VideoFrame>& frame,
236 base::TimeTicks capture_timestamp) override; 249 base::TimeTicks capture_timestamp) override;
237 void ConfigureEncoderOnEncodingThread(const gfx::Size& size) override; 250 void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) override;
238 251
239 // |openh264_encoder_| is a special scoped pointer to guarantee proper 252 // |openh264_encoder_| is a special scoped pointer to guarantee proper
240 // destruction, also when reconfiguring due to parameters change. Only used on 253 // destruction, also when reconfiguring due to parameters change. Only used on
241 // |encoding_thread_|. 254 // |encoding_thread_|.
242 gfx::Size configured_size_; 255 gfx::Size configured_size_;
243 ScopedISVCEncoderPtr openh264_encoder_; 256 ScopedISVCEncoderPtr openh264_encoder_;
244 257
245 // The |VideoFrame::timestamp()| of the first received frame. Only used on 258 // The |VideoFrame::timestamp()| of the first received frame. Only used on
246 // |encoding_thread_|. 259 // |encoding_thread_|.
247 base::TimeTicks first_frame_timestamp_; 260 base::TimeTicks first_frame_timestamp_;
(...skipping 11 matching lines...) Expand all
259 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. 272 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope.
260 } 273 }
261 274
262 VpxEncoder::VpxEncoder( 275 VpxEncoder::VpxEncoder(
263 bool use_vp9, 276 bool use_vp9,
264 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 277 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
265 int32_t bits_per_second) 278 int32_t bits_per_second)
266 : Encoder(on_encoded_video_callback, bits_per_second), 279 : Encoder(on_encoded_video_callback, bits_per_second),
267 use_vp9_(use_vp9) { 280 use_vp9_(use_vp9) {
268 codec_config_.g_timebase.den = 0; // Not initialized. 281 codec_config_.g_timebase.den = 0; // Not initialized.
269 282 DCHECK(encoding_thread_->IsRunning());
270 DCHECK(!encoding_thread_->IsRunning());
271 encoding_thread_->Start();
272 } 283 }
273 284
274 VpxEncoder::~VpxEncoder() { 285 VpxEncoder::~VpxEncoder() {
275 main_task_runner_->PostTask(FROM_HERE, 286 main_task_runner_->PostTask(FROM_HERE,
276 base::Bind(&VpxEncoder::ShutdownEncoder, 287 base::Bind(&VpxEncoder::ShutdownEncoder,
277 base::Passed(&encoding_thread_), 288 base::Passed(&encoding_thread_),
278 base::Passed(&encoder_))); 289 base::Passed(&encoder_)));
279 } 290 }
280 291
281 void VpxEncoder::EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, 292 void VpxEncoder::EncodeOnEncodingTaskRunner(
282 base::TimeTicks capture_timestamp) { 293 const scoped_refptr<VideoFrame>& frame,
283 TRACE_EVENT0("video", "VpxEncoder::EncodeOnEncodingThread"); 294 base::TimeTicks capture_timestamp) {
284 DCHECK(encoding_thread_->task_runner()->BelongsToCurrentThread()); 295 TRACE_EVENT0("video", "VpxEncoder::EncodeOnEncodingTaskRunner");
296 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
285 297
286 const gfx::Size frame_size = frame->visible_rect().size(); 298 const gfx::Size frame_size = frame->visible_rect().size();
287 if (!IsInitialized() || 299 if (!IsInitialized() ||
288 gfx::Size(codec_config_.g_w, codec_config_.g_h) != frame_size) { 300 gfx::Size(codec_config_.g_w, codec_config_.g_h) != frame_size) {
289 ConfigureEncoderOnEncodingThread(frame_size); 301 ConfigureEncoderOnEncodingTaskRunner(frame_size);
290 } 302 }
291 303
292 vpx_image_t vpx_image; 304 vpx_image_t vpx_image;
293 vpx_image_t* const result = vpx_img_wrap(&vpx_image, 305 vpx_image_t* const result = vpx_img_wrap(&vpx_image,
294 VPX_IMG_FMT_I420, 306 VPX_IMG_FMT_I420,
295 frame_size.width(), 307 frame_size.width(),
296 frame_size.height(), 308 frame_size.height(),
297 1 /* align */, 309 1 /* align */,
298 frame->data(VideoFrame::kYPlane)); 310 frame->data(VideoFrame::kYPlane));
299 DCHECK_EQ(result, &vpx_image); 311 DCHECK_EQ(result, &vpx_image);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 } 343 }
332 origin_task_runner_->PostTask(FROM_HERE, 344 origin_task_runner_->PostTask(FROM_HERE,
333 base::Bind(OnFrameEncodeCompleted, 345 base::Bind(OnFrameEncodeCompleted,
334 on_encoded_video_callback_, 346 on_encoded_video_callback_,
335 frame, 347 frame,
336 base::Passed(&data), 348 base::Passed(&data),
337 capture_timestamp, 349 capture_timestamp,
338 keyframe)); 350 keyframe));
339 } 351 }
340 352
341 void VpxEncoder::ConfigureEncoderOnEncodingThread(const gfx::Size& size) { 353 void VpxEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) {
342 DCHECK(encoding_thread_->task_runner()->BelongsToCurrentThread()); 354 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
343 if (IsInitialized()) { 355 if (IsInitialized()) {
344 // TODO(mcasas) VP8 quirk/optimisation: If the new |size| is strictly less- 356 // TODO(mcasas) VP8 quirk/optimisation: If the new |size| is strictly less-
345 // than-or-equal than the old size, in terms of area, the existing encoder 357 // than-or-equal than the old size, in terms of area, the existing encoder
346 // instance could be reused after changing |codec_config_.{g_w,g_h}|. 358 // instance could be reused after changing |codec_config_.{g_w,g_h}|.
347 DVLOG(1) << "Destroying/Re-Creating encoder for new frame size: " 359 DVLOG(1) << "Destroying/Re-Creating encoder for new frame size: "
348 << gfx::Size(codec_config_.g_w, codec_config_.g_h).ToString() 360 << gfx::Size(codec_config_.g_w, codec_config_.g_h).ToString()
349 << " --> " << size.ToString() << (use_vp9_ ? " vp9" : " vp8"); 361 << " --> " << size.ToString() << (use_vp9_ ? " vp9" : " vp8");
350 encoder_.reset(); 362 encoder_.reset();
351 } 363 }
352 364
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // target time spent encoding the frame. Go from 8 to 5 (values for real 433 // target time spent encoding the frame. Go from 8 to 5 (values for real
422 // time encoding) depending on the amount of cores available in the system. 434 // time encoding) depending on the amount of cores available in the system.
423 const int kCpuUsed = 435 const int kCpuUsed =
424 std::max(5, 8 - base::SysInfo::NumberOfProcessors() / 2); 436 std::max(5, 8 - base::SysInfo::NumberOfProcessors() / 2);
425 result = vpx_codec_control(encoder_.get(), VP8E_SET_CPUUSED, kCpuUsed); 437 result = vpx_codec_control(encoder_.get(), VP8E_SET_CPUUSED, kCpuUsed);
426 DLOG_IF(WARNING, VPX_CODEC_OK != result) << "VP8E_SET_CPUUSED failed"; 438 DLOG_IF(WARNING, VPX_CODEC_OK != result) << "VP8E_SET_CPUUSED failed";
427 } 439 }
428 } 440 }
429 441
430 bool VpxEncoder::IsInitialized() const { 442 bool VpxEncoder::IsInitialized() const {
431 DCHECK(encoding_thread_->task_runner()->BelongsToCurrentThread()); 443 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
432 return codec_config_.g_timebase.den != 0; 444 return codec_config_.g_timebase.den != 0;
433 } 445 }
434 446
435 base::TimeDelta VpxEncoder::EstimateFrameDuration( 447 base::TimeDelta VpxEncoder::EstimateFrameDuration(
436 const scoped_refptr<VideoFrame>& frame) { 448 const scoped_refptr<VideoFrame>& frame) {
437 DCHECK(encoding_thread_->task_runner()->BelongsToCurrentThread()); 449 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
438 450
439 using base::TimeDelta; 451 using base::TimeDelta;
440 TimeDelta predicted_frame_duration; 452 TimeDelta predicted_frame_duration;
441 if (!frame->metadata()->GetTimeDelta(VideoFrameMetadata::FRAME_DURATION, 453 if (!frame->metadata()->GetTimeDelta(VideoFrameMetadata::FRAME_DURATION,
442 &predicted_frame_duration) || 454 &predicted_frame_duration) ||
443 predicted_frame_duration <= TimeDelta()) { 455 predicted_frame_duration <= TimeDelta()) {
444 // The source of the video frame did not provide the frame duration. Use 456 // The source of the video frame did not provide the frame duration. Use
445 // the actual amount of time between the current and previous frame as a 457 // the actual amount of time between the current and previous frame as a
446 // prediction for the next frame's duration. 458 // prediction for the next frame's duration.
447 // TODO(mcasas): This duration estimation could lead to artifacts if the 459 // TODO(mcasas): This duration estimation could lead to artifacts if the
(...skipping 16 matching lines...) Expand all
464 ScopedISVCEncoderPtr encoder) { 476 ScopedISVCEncoderPtr encoder) {
465 DCHECK(encoding_thread->IsRunning()); 477 DCHECK(encoding_thread->IsRunning());
466 encoding_thread->Stop(); 478 encoding_thread->Stop();
467 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. 479 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope.
468 } 480 }
469 481
470 H264Encoder::H264Encoder( 482 H264Encoder::H264Encoder(
471 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 483 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
472 int32_t bits_per_second) 484 int32_t bits_per_second)
473 : Encoder(on_encoded_video_callback, bits_per_second) { 485 : Encoder(on_encoded_video_callback, bits_per_second) {
474 DCHECK(!encoding_thread_->IsRunning()); 486 DCHECK(encoding_thread_->IsRunning());
475 encoding_thread_->Start();
476 } 487 }
477 488
478 H264Encoder::~H264Encoder() { 489 H264Encoder::~H264Encoder() {
479 main_task_runner_->PostTask(FROM_HERE, 490 main_task_runner_->PostTask(FROM_HERE,
480 base::Bind(&H264Encoder::ShutdownEncoder, 491 base::Bind(&H264Encoder::ShutdownEncoder,
481 base::Passed(&encoding_thread_), 492 base::Passed(&encoding_thread_),
482 base::Passed(&openh264_encoder_))); 493 base::Passed(&openh264_encoder_)));
483 } 494 }
484 495
485 void H264Encoder::EncodeOnEncodingThread(const scoped_refptr<VideoFrame>& frame, 496 void H264Encoder::EncodeOnEncodingTaskRunner(
486 base::TimeTicks capture_timestamp) { 497 const scoped_refptr<VideoFrame>& frame,
487 TRACE_EVENT0("video", "H264Encoder::EncodeOnEncodingThread"); 498 base::TimeTicks capture_timestamp) {
488 DCHECK(encoding_thread_->task_runner()->BelongsToCurrentThread()); 499 TRACE_EVENT0("video", "H264Encoder::EncodeOnEncodingTaskRunner");
500 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
489 501
490 const gfx::Size frame_size = frame->visible_rect().size(); 502 const gfx::Size frame_size = frame->visible_rect().size();
491 if (!openh264_encoder_ || configured_size_ != frame_size) { 503 if (!openh264_encoder_ || configured_size_ != frame_size) {
492 ConfigureEncoderOnEncodingThread(frame_size); 504 ConfigureEncoderOnEncodingTaskRunner(frame_size);
493 first_frame_timestamp_ = capture_timestamp; 505 first_frame_timestamp_ = capture_timestamp;
494 } 506 }
495 507
496 SSourcePicture picture = {}; 508 SSourcePicture picture = {};
497 picture.iPicWidth = frame_size.width(); 509 picture.iPicWidth = frame_size.width();
498 picture.iPicHeight = frame_size.height(); 510 picture.iPicHeight = frame_size.height();
499 picture.iColorFormat = EVideoFormatType::videoFormatI420; 511 picture.iColorFormat = EVideoFormatType::videoFormatI420;
500 picture.uiTimeStamp = 512 picture.uiTimeStamp =
501 (capture_timestamp - first_frame_timestamp_).InMilliseconds(); 513 (capture_timestamp - first_frame_timestamp_).InMilliseconds();
502 picture.iStride[0] = frame->stride(VideoFrame::kYPlane); 514 picture.iStride[0] = frame->stride(VideoFrame::kYPlane);
(...skipping 29 matching lines...) Expand all
532 data->append(reinterpret_cast<char*>(layerInfo.pBsBuf), layer_len); 544 data->append(reinterpret_cast<char*>(layerInfo.pBsBuf), layer_len);
533 } 545 }
534 546
535 const bool is_key_frame = info.eFrameType == videoFrameTypeIDR; 547 const bool is_key_frame = info.eFrameType == videoFrameTypeIDR;
536 origin_task_runner_->PostTask( 548 origin_task_runner_->PostTask(
537 FROM_HERE, 549 FROM_HERE,
538 base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_, frame, 550 base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_, frame,
539 base::Passed(&data), capture_timestamp, is_key_frame)); 551 base::Passed(&data), capture_timestamp, is_key_frame));
540 } 552 }
541 553
542 void H264Encoder::ConfigureEncoderOnEncodingThread(const gfx::Size& size) { 554 void H264Encoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) {
543 DCHECK(encoding_thread_->task_runner()->BelongsToCurrentThread()); 555 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
544 ISVCEncoder* temp_encoder = nullptr; 556 ISVCEncoder* temp_encoder = nullptr;
545 if (WelsCreateSVCEncoder(&temp_encoder) != 0) { 557 if (WelsCreateSVCEncoder(&temp_encoder) != 0) {
546 NOTREACHED() << "Failed to create OpenH264 encoder"; 558 NOTREACHED() << "Failed to create OpenH264 encoder";
547 return; 559 return;
548 } 560 }
549 openh264_encoder_.reset(temp_encoder); 561 openh264_encoder_.reset(temp_encoder);
550 configured_size_ = size; 562 configured_size_ = size;
551 563
552 #if DCHECK_IS_ON() 564 #if DCHECK_IS_ON()
553 int trace_level = WELS_LOG_INFO; 565 int trace_level = WELS_LOG_INFO;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 encoder_->SetPaused(false); 666 encoder_->SetPaused(false);
655 } 667 }
656 668
657 void VideoTrackRecorder::OnVideoFrameForTesting( 669 void VideoTrackRecorder::OnVideoFrameForTesting(
658 const scoped_refptr<media::VideoFrame>& frame, 670 const scoped_refptr<media::VideoFrame>& frame,
659 base::TimeTicks timestamp) { 671 base::TimeTicks timestamp) {
660 encoder_->StartFrameEncode(frame, timestamp); 672 encoder_->StartFrameEncode(frame, timestamp);
661 } 673 }
662 674
663 } // namespace content 675 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698