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

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

Issue 1990643002: Add VEAEncoder to VideoTrackRecorder (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
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"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/sys_info.h" 12 #include "base/sys_info.h"
13 #include "base/task_runner_util.h"
13 #include "base/threading/thread.h" 14 #include "base/threading/thread.h"
14 #include "base/time/time.h" 15 #include "base/time/time.h"
15 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
17 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
18 #include "content/renderer/render_thread_impl.h"
19 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/video_frame.h" 20 #include "media/base/video_frame.h"
17 #include "media/base/video_util.h" 21 #include "media/base/video_util.h"
22 #include "third_party/libyuv/include/libyuv/convert.h"
18 #include "ui/gfx/geometry/size.h" 23 #include "ui/gfx/geometry/size.h"
19 24
20 #if BUILDFLAG(RTC_USE_H264) 25 #if BUILDFLAG(RTC_USE_H264)
21 #include "third_party/openh264/src/codec/api/svc/codec_api.h" 26 #include "third_party/openh264/src/codec/api/svc/codec_api.h"
22 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h" 27 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
23 #include "third_party/openh264/src/codec/api/svc/codec_def.h" 28 #include "third_party/openh264/src/codec/api/svc/codec_def.h"
24 #endif // #if BUILDFLAG(RTC_USE_H264) 29 #endif // #if BUILDFLAG(RTC_USE_H264)
25 30
26 extern "C" { 31 extern "C" {
27 // VPX_CODEC_DISABLE_COMPAT excludes parts of the libvpx API that provide 32 // VPX_CODEC_DISABLE_COMPAT excludes parts of the libvpx API that provide
28 // backwards compatibility for legacy applications using the library. 33 // backwards compatibility for legacy applications using the library.
29 #define VPX_CODEC_DISABLE_COMPAT 1 34 #define VPX_CODEC_DISABLE_COMPAT 1
30 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h" 35 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
31 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h" 36 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
32 } 37 }
33 38
34 using media::VideoFrame; 39 using media::VideoFrame;
35 using media::VideoFrameMetadata; 40 using media::VideoFrameMetadata;
36 41
42 namespace {
43
44 const int kVEAEncoderMinResolutionWidth = 640;
45 const int kVEAEncoderMinResolutionHeight = 480;
46 const int kVEAEncoderOutputBufferCount = 4;
47
48 // Returns the preferred codec profile from VEA supported profiles. If no
49 // profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN.
50 media::VideoCodecProfile GetVEASupportedProfile(
51 content::VideoTrackRecorder::CodecId codec) {
52 media::GpuVideoAcceleratorFactories* gpu_factories =
53 content::RenderThreadImpl::current()->GetGpuFactories();
54 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
55 DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories";
56 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
57 }
58
59 const media::VideoEncodeAccelerator::SupportedProfiles& profiles =
60 gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
61 for (const auto& profile : profiles) {
62 if ((codec == content::VideoTrackRecorder::CodecId::VP8 &&
63 profile.profile >= media::VP8PROFILE_MIN &&
64 profile.profile <= media::VP8PROFILE_MAX) ||
65 (codec == content::VideoTrackRecorder::CodecId::VP9 &&
66 profile.profile >= media::VP9PROFILE_MIN &&
67 profile.profile <= media::VP9PROFILE_MAX) ||
68 (codec == content::VideoTrackRecorder::CodecId::H264 &&
69 profile.profile >= media::H264PROFILE_MIN &&
70 profile.profile <= media::H264PROFILE_MAX))
71 return profile.profile;
72 }
73 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
74 }
75
76 } // anonymous namespace
77
37 namespace content { 78 namespace content {
38 79
39 // Base class to describe a generic Encoder, encapsulating all actual encoder 80 // Base class to describe a generic Encoder, encapsulating all actual encoder
40 // (re)configurations, encoding and delivery of received frames. This class is 81 // (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 82 // 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 83 // the callback that MediaStreamVideoSink passes along) and to jump back and
43 // forth to an internal encoder thread. Moreover, this class: 84 // forth to an internal encoder thread. Moreover, this class:
44 // - is created and destroyed on its parent's thread (usually the main Render 85 // - is created and destroyed on its parent's thread (usually the main Render
45 // thread), |main_task_runner_|. 86 // thread), |main_task_runner_|.
46 // - receives VideoFrames on |origin_task_runner_| and runs OnEncodedVideoCB on 87 // - 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 88 // 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); 89 // is supposed to be the render IO thread (but this is not enforced);
49 // - uses an internal |encoding_task_runner_| for actual encoder interactions, 90 // - uses an internal |encoding_task_runner_| for actual encoder interactions,
50 // namely configuration, encoding (which might take some time) and destruction. 91 // 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 92 // This task runner can be passed on the creation. If nothing is passed, a new
52 // encoding thread is created and used. 93 // encoding thread is created and used.
53 class VideoTrackRecorder::Encoder : public base::RefCountedThreadSafe<Encoder> { 94 class VideoTrackRecorder::Encoder : public base::RefCountedThreadSafe<Encoder> {
54 public: 95 public:
55 Encoder(const OnEncodedVideoCB& on_encoded_video_callback, 96 Encoder(const OnEncodedVideoCB& on_encoded_video_callback,
56 int32_t bits_per_second, 97 int32_t bits_per_second,
57 scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner = 98 scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner =
58 nullptr) 99 nullptr)
59 : main_task_runner_(base::MessageLoop::current()->task_runner()), 100 : main_task_runner_(base::MessageLoop::current()->task_runner()),
60 encoding_task_runner_(encoding_task_runner), 101 encoding_task_runner_(encoding_task_runner),
61 paused_(false), 102 paused_(false),
62 on_encoded_video_callback_(on_encoded_video_callback), 103 on_encoded_video_callback_(on_encoded_video_callback),
63 bits_per_second_(bits_per_second) { 104 bits_per_second_(bits_per_second) {
64 DCHECK(!on_encoded_video_callback_.is_null()); 105 DCHECK(!on_encoded_video_callback_.is_null());
65 if (encoding_thread_) 106 if (encoding_task_runner_)
66 return; 107 return;
67 encoding_thread_.reset(new base::Thread("EncodingThread")); 108 encoding_thread_.reset(new base::Thread("EncodingThread"));
68 encoding_thread_->Start(); 109 encoding_thread_->Start();
69 encoding_task_runner_ = encoding_thread_->task_runner(); 110 encoding_task_runner_ = encoding_thread_->task_runner();
70 } 111 }
71 112
72 // Start encoding |frame|, returning via |on_encoded_video_callback_|. This 113 // Start encoding |frame|, returning via |on_encoded_video_callback_|. This
73 // call will also trigger a ConfigureEncoderOnEncodingTaskRunner() upon first 114 // call will also trigger a ConfigureEncoderOnEncodingTaskRunner() upon first
74 // frame arrival or parameter change, and an EncodeOnEncodingTaskRunner() to 115 // frame arrival or parameter change, and an EncodeOnEncodingTaskRunner() to
75 // actually encode the frame. 116 // actually encode the frame.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 on_encoded_video_cb.Run(frame, std::move(data), capture_timestamp, keyframe); 213 on_encoded_video_cb.Run(frame, std::move(data), capture_timestamp, keyframe);
173 } 214 }
174 215
175 static int GetNumberOfThreadsForEncoding() { 216 static int GetNumberOfThreadsForEncoding() {
176 // Do not saturate CPU utilization just for encoding. On a lower-end system 217 // Do not saturate CPU utilization just for encoding. On a lower-end system
177 // with only 1 or 2 cores, use only one thread for encoding. On systems with 218 // with only 1 or 2 cores, use only one thread for encoding. On systems with
178 // more cores, allow half of the cores to be used for encoding. 219 // more cores, allow half of the cores to be used for encoding.
179 return std::min(8, (base::SysInfo::NumberOfProcessors() + 1) / 2); 220 return std::min(8, (base::SysInfo::NumberOfProcessors() + 1) / 2);
180 } 221 }
181 222
223 // Class encapsulating VideoEncodeAccelerator interactions.
224 class VEAEncoder final : public VideoTrackRecorder::Encoder,
225 public media::VideoEncodeAccelerator::Client {
226 public:
227 VEAEncoder(
228 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
229 int32_t bits_per_second,
230 media::VideoCodecProfile codec);
231
232 // media::VideoEncodeAccelerator::Client implementation.
233 void RequireBitstreamBuffers(unsigned int input_count,
234 const gfx::Size& input_coded_size,
235 size_t output_buffer_size) override;
236 void BitstreamBufferReady(int32_t bitstream_buffer_id,
237 size_t payload_size,
238 bool key_frame) override;
239 void NotifyError(media::VideoEncodeAccelerator::Error error) override;
240
241 private:
242 void UseOutputBitstreamBufferId(int32_t bitstream_buffer_id);
243 void FrameFinished(std::unique_ptr<base::SharedMemory> shm);
244
245 // VideoTrackRecorder::Encoder
246 ~VEAEncoder() override;
247 void EncodeOnEncodingTaskRunner(const scoped_refptr<VideoFrame>& frame,
248 base::TimeTicks capture_timestamp) override;
249 void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) override;
250
251 media::GpuVideoAcceleratorFactories* const gpu_factories_;
252
253 media::VideoCodecProfile codec_;
254
255 // The underlying VEA to perform encoding on.
256 std::unique_ptr<media::VideoEncodeAccelerator> video_encoder_;
257
258 // Shared memory buffers for output with the VEA.
259 ScopedVector<base::SharedMemory> output_buffers_;
260
261 // Shared memory buffers for output with the VEA as FIFO.
262 std::queue<std::unique_ptr<base::SharedMemory>> input_buffers_;
263
264 // The number of output buffers ready to be filled.
265 int output_buffers_free_count_;
266
267 // Tracks error status.
268 bool error_notified_;
269
270 // Tracks first encode frame and its usage.
271 std::unique_ptr<std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>>
272 first_frame_;
273 bool first_frame_encoded_;
274
275 // Size used to initialize encoder.
276 gfx::Size input_size_;
277
278 // Coded size that encoder requests as input.
279 gfx::Size vea_requested_input_size_;
280
281 // Frames and corresponding timestamps in encode as FIFO.
282 std::queue<std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>>
283 frames_in_encode_;
284 };
285
182 // Class encapsulating all libvpx interactions for VP8/VP9 encoding. 286 // Class encapsulating all libvpx interactions for VP8/VP9 encoding.
183 class VpxEncoder final : public VideoTrackRecorder::Encoder { 287 class VpxEncoder final : public VideoTrackRecorder::Encoder {
184 public: 288 public:
185 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread, 289 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread,
186 ScopedVpxCodecCtxPtr encoder); 290 ScopedVpxCodecCtxPtr encoder);
187 291
188 VpxEncoder( 292 VpxEncoder(
189 bool use_vp9, 293 bool use_vp9,
190 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 294 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
191 int32_t bits_per_second); 295 int32_t bits_per_second);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 361
258 // The |VideoFrame::timestamp()| of the first received frame. Only used on 362 // The |VideoFrame::timestamp()| of the first received frame. Only used on
259 // |encoding_thread_|. 363 // |encoding_thread_|.
260 base::TimeTicks first_frame_timestamp_; 364 base::TimeTicks first_frame_timestamp_;
261 365
262 DISALLOW_COPY_AND_ASSIGN(H264Encoder); 366 DISALLOW_COPY_AND_ASSIGN(H264Encoder);
263 }; 367 };
264 368
265 #endif // #if BUILDFLAG(RTC_USE_H264) 369 #endif // #if BUILDFLAG(RTC_USE_H264)
266 370
371 VEAEncoder::VEAEncoder(
372 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
373 int32_t bits_per_second,
374 media::VideoCodecProfile codec)
375 : Encoder(on_encoded_video_callback,
376 bits_per_second,
377 RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()),
378 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()),
379 codec_(codec),
380 output_buffers_free_count_(0),
381 error_notified_(false),
382 first_frame_encoded_(false) {
383 DCHECK(gpu_factories_);
384 }
385
386 VEAEncoder::~VEAEncoder() {
387 encoding_task_runner_->PostTask(
388 FROM_HERE, base::Bind(&media::VideoEncodeAccelerator::Destroy,
389 base::Unretained(video_encoder_.release())));
390 }
391
392 void VEAEncoder::RequireBitstreamBuffers(unsigned int input_count,
393 const gfx::Size& input_coded_size,
394 size_t output_buffer_size) {
395 DVLOG(3) << __FUNCTION__;
396 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
397
398 vea_requested_input_size_ = input_coded_size;
399 output_buffers_.clear();
400 output_buffers_free_count_ = 0;
401 std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_);
402
403 for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) {
404 DCHECK(gpu_factories_);
405 std::unique_ptr<base::SharedMemory> shm =
406 gpu_factories_->CreateSharedMemory(output_buffer_size);
407 if (!shm) {
408 NOTREACHED();
409 return;
410 }
411 output_buffers_.push_back(shm.release());
412 }
413
414 for (size_t i = 0; i < output_buffers_.size(); ++i) {
415 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer(
416 i, output_buffers_[i]->handle(), output_buffers_[i]->mapped_size()));
417 output_buffers_free_count_++;
418 }
419 }
420
421 void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id,
422 size_t payload_size,
423 bool keyframe) {
424 DVLOG(3) << __FUNCTION__;
425 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
426
427 output_buffers_free_count_--;
428 base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id];
429
430 std::unique_ptr<std::string> data(new std::string);
431 data->append(reinterpret_cast<char*>(output_buffer->memory()), payload_size);
432
433 const auto front_frame = frames_in_encode_.front();
434 frames_in_encode_.pop();
435 origin_task_runner_->PostTask(
436 FROM_HERE, base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_,
437 front_frame.first, base::Passed(&data),
438 front_frame.second, keyframe));
439 UseOutputBitstreamBufferId(bitstream_buffer_id);
440 }
441
442 void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) {
443 DVLOG(3) << __FUNCTION__;
444 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
445
446 error_notified_ = true;
447 }
448
449 void VEAEncoder::UseOutputBitstreamBufferId(int32_t bitstream_buffer_id) {
450 DVLOG(3) << __FUNCTION__;
451 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
452
453 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer(
454 bitstream_buffer_id, output_buffers_[bitstream_buffer_id]->handle(),
455 output_buffers_[bitstream_buffer_id]->mapped_size()));
456 output_buffers_free_count_++;
457 }
458
459 void VEAEncoder::FrameFinished(std::unique_ptr<base::SharedMemory> shm) {
460 DVLOG(3) << __FUNCTION__;
461 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
462 input_buffers_.push(std::move(shm));
463 }
464
465 void VEAEncoder::EncodeOnEncodingTaskRunner(
466 const scoped_refptr<VideoFrame>& frame,
467 base::TimeTicks capture_timestamp) {
468 DVLOG(3) << __FUNCTION__;
469 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
470
471 if (input_size_ != frame->visible_rect().size() && video_encoder_) {
472 video_encoder_->Destroy();
473 video_encoder_.reset();
474 }
475
476 if (!video_encoder_) {
477 ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size());
478 first_frame_.reset(
479 new std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>(
480 frame, capture_timestamp));
481 }
482
483 if (error_notified_) {
484 DVLOG(3) << "An error occurred in VEA encoder";
485 return;
486 }
487
488 // Drop frames if there is no output buffers available.
489 if (output_buffers_free_count_ == 0) {
490 DVLOG(3) << "Dropped frame.";
491 return;
492 }
493
494 // If first frame hasn't been encoded, do it first.
495 if (!first_frame_encoded_ && first_frame_) {
496 std::unique_ptr<std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>>
497 first_frame(first_frame_.release());
498 EncodeOnEncodingTaskRunner(first_frame->first, first_frame->second);
499 first_frame_encoded_ = true;
500 }
501
502 // Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac.
503 // In that case, the encoder expects more frames before returning result.
504 // Therefore, a copy is necessary to release the current frame.
505 scoped_refptr<media::VideoFrame> video_frame = frame;
506 if (vea_requested_input_size_ != input_size_ ||
507 input_size_.width() < kVEAEncoderMinResolutionWidth ||
508 input_size_.height() < kVEAEncoderMinResolutionHeight) {
509 // Create SharedMemory backed input buffers as necessary. These SharedMemory
510 // instances will be shared with GPU process.
511 if (input_buffers_.empty()) {
512 std::unique_ptr<base::SharedMemory> shm =
513 gpu_factories_->CreateSharedMemory(media::VideoFrame::AllocationSize(
514 media::PIXEL_FORMAT_I420, vea_requested_input_size_));
515 input_buffers_.push(std::move(shm));
516 }
517 std::unique_ptr<base::SharedMemory> input_buffer =
518 std::move(input_buffers_.front());
519 input_buffers_.pop();
520 while (input_buffer->mapped_size() <
521 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
522 vea_requested_input_size_)) {
523 input_buffer.reset(input_buffers_.front().release());
524 input_buffers_.pop();
525 }
526 video_frame = media::VideoFrame::WrapExternalSharedMemory(
527 media::PIXEL_FORMAT_I420, vea_requested_input_size_,
528 gfx::Rect(input_size_), input_size_,
529 reinterpret_cast<uint8_t*>(input_buffer->memory()),
530 input_buffer->mapped_size(), input_buffer->handle(), 0,
531 frame->timestamp());
532 video_frame->AddDestructionObserver(media::BindToCurrentLoop(
533 base::Bind(&VEAEncoder::FrameFinished, this,
534 base::Passed(std::move(input_buffer)))));
535 libyuv::I420Copy(frame->visible_data(media::VideoFrame::kYPlane),
536 frame->stride(media::VideoFrame::kYPlane),
537 frame->visible_data(media::VideoFrame::kUPlane),
538 frame->stride(media::VideoFrame::kUPlane),
539 frame->visible_data(media::VideoFrame::kVPlane),
540 frame->stride(media::VideoFrame::kVPlane),
541 video_frame->visible_data(media::VideoFrame::kYPlane),
542 video_frame->stride(media::VideoFrame::kYPlane),
543 video_frame->visible_data(media::VideoFrame::kUPlane),
544 video_frame->stride(media::VideoFrame::kUPlane),
545 video_frame->visible_data(media::VideoFrame::kVPlane),
546 video_frame->stride(media::VideoFrame::kVPlane),
547 input_size_.width(), input_size_.height());
548 }
549 frames_in_encode_.push(std::make_pair(video_frame, capture_timestamp));
550
551 encoding_task_runner_->PostTask(
552 FROM_HERE, base::Bind(&media::VideoEncodeAccelerator::Encode,
553 base::Unretained(video_encoder_.get()), video_frame,
554 first_frame_encoded_ ? false : true));
555 }
556
557 void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) {
558 DVLOG(3) << __FUNCTION__;
559 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
560 DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread());
561
562 input_size_ = size;
563 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator();
564 if (!video_encoder_) {
565 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
566 return;
567 }
568 if (!video_encoder_->Initialize(media::PIXEL_FORMAT_I420, input_size_,
569 codec_, bits_per_second_, this)) {
570 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
571 }
572 first_frame_encoded_ = false;
573 }
574
267 // static 575 // static
268 void VpxEncoder::ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread, 576 void VpxEncoder::ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread,
269 ScopedVpxCodecCtxPtr encoder) { 577 ScopedVpxCodecCtxPtr encoder) {
270 DCHECK(encoding_thread->IsRunning()); 578 DCHECK(encoding_thread->IsRunning());
271 encoding_thread->Stop(); 579 encoding_thread->Stop();
272 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope. 580 // Both |encoding_thread| and |encoder| will be destroyed at end-of-scope.
273 } 581 }
274 582
275 VpxEncoder::VpxEncoder( 583 VpxEncoder::VpxEncoder(
276 bool use_vp9, 584 bool use_vp9,
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 VideoTrackRecorder::VideoTrackRecorder( 927 VideoTrackRecorder::VideoTrackRecorder(
620 CodecId codec, 928 CodecId codec,
621 const blink::WebMediaStreamTrack& track, 929 const blink::WebMediaStreamTrack& track,
622 const OnEncodedVideoCB& on_encoded_video_callback, 930 const OnEncodedVideoCB& on_encoded_video_callback,
623 int32_t bits_per_second) 931 int32_t bits_per_second)
624 : track_(track) { 932 : track_(track) {
625 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 933 DCHECK(main_render_thread_checker_.CalledOnValidThread());
626 DCHECK(!track_.isNull()); 934 DCHECK(!track_.isNull());
627 DCHECK(track_.getExtraData()); 935 DCHECK(track_.getExtraData());
628 936
629 switch (codec) { 937 const auto& vea_supported_profile = GetVEASupportedProfile(codec);
938 // TODO(emircan): Prioritize software based encoders in lower resolutions.
939 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN) {
940 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second,
941 vea_supported_profile);
942 } else {
mcasas 2016/05/18 21:36:09 Maybe we can still change this |else| to if (!enco
emircan 2016/05/18 21:50:14 In PS#2, when RenderThreadImpl::current() is not d
943 switch (codec) {
630 #if BUILDFLAG(RTC_USE_H264) 944 #if BUILDFLAG(RTC_USE_H264)
631 case CodecId::H264: 945 case CodecId::H264:
632 encoder_ = new H264Encoder(on_encoded_video_callback, bits_per_second); 946 encoder_ = new H264Encoder(on_encoded_video_callback, bits_per_second);
633 break; 947 break;
634 #endif 948 #endif
635 case CodecId::VP8: 949 case CodecId::VP8:
636 case CodecId::VP9: 950 case CodecId::VP9:
637 encoder_ = new VpxEncoder(codec == CodecId::VP9, 951 encoder_ = new VpxEncoder(codec == CodecId::VP9,
638 on_encoded_video_callback, bits_per_second); 952 on_encoded_video_callback, bits_per_second);
639 break; 953 break;
640 default: 954 default:
641 NOTREACHED() << "Unsupported codec"; 955 NOTREACHED() << "Unsupported codec";
956 }
642 } 957 }
643 958
644 // StartFrameEncode() will be called on Render IO thread. 959 // StartFrameEncode() will be called on Render IO thread.
645 MediaStreamVideoSink::ConnectToTrack( 960 MediaStreamVideoSink::ConnectToTrack(
646 track_, 961 track_,
647 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), 962 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
648 false); 963 false);
649 } 964 }
650 965
651 VideoTrackRecorder::~VideoTrackRecorder() { 966 VideoTrackRecorder::~VideoTrackRecorder() {
(...skipping 14 matching lines...) Expand all
666 encoder_->SetPaused(false); 981 encoder_->SetPaused(false);
667 } 982 }
668 983
669 void VideoTrackRecorder::OnVideoFrameForTesting( 984 void VideoTrackRecorder::OnVideoFrameForTesting(
670 const scoped_refptr<media::VideoFrame>& frame, 985 const scoped_refptr<media::VideoFrame>& frame,
671 base::TimeTicks timestamp) { 986 base::TimeTicks timestamp) {
672 encoder_->StartFrameEncode(frame, timestamp); 987 encoder_->StartFrameEncode(frame, timestamp);
673 } 988 }
674 989
675 } // namespace content 990 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_track_recorder.h ('k') | media/gpu/vt_video_encode_accelerator_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698