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

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

Issue 2801803002: Android: enable H264&VP8 HW accelerator for MediaRecorder (Closed)
Patch Set: Created 3 years, 8 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_recorder/video_track_recorder.h" 5 #include "content/renderer/media_recorder/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 29 matching lines...) Expand all
40 // backwards compatibility for legacy applications using the library. 40 // backwards compatibility for legacy applications using the library.
41 #define VPX_CODEC_DISABLE_COMPAT 1 41 #define VPX_CODEC_DISABLE_COMPAT 1
42 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h" 42 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
43 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h" 43 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
44 } 44 }
45 45
46 using media::VideoFrame; 46 using media::VideoFrame;
47 using media::VideoFrameMetadata; 47 using media::VideoFrameMetadata;
48 using video_track_recorder::kVEAEncoderMinResolutionWidth; 48 using video_track_recorder::kVEAEncoderMinResolutionWidth;
49 using video_track_recorder::kVEAEncoderMinResolutionHeight; 49 using video_track_recorder::kVEAEncoderMinResolutionHeight;
50 using video_track_recorder::kVEAEncoderMinResolutionWidthAndroid;
51 using video_track_recorder::kVEAEncoderMinResolutionHeightAndroid;
50 52
51 namespace content { 53 namespace content {
52 54
53 namespace { 55 namespace {
54 56
55 // HW encoders expect a nonzero bitrate, so |kVEADefaultBitratePerPixel| is used 57 // HW encoders expect a nonzero bitrate, so |kVEADefaultBitratePerPixel| is used
56 // to estimate bits per second for ~30 fps with ~1/16 compression rate. 58 // to estimate bits per second for ~30 fps with ~1/16 compression rate.
57 const int kVEADefaultBitratePerPixel = 2; 59 const int kVEADefaultBitratePerPixel = 2;
58 // Number of output buffers used to copy the encoded data coming from HW 60 // Number of output buffers used to copy the encoded data coming from HW
59 // encoders. 61 // encoders.
60 const int kVEAEncoderOutputBufferCount = 4; 62 const int kVEAEncoderOutputBufferCount = 4;
61 63
62 using CodecId = VideoTrackRecorder::CodecId; 64 using CodecId = VideoTrackRecorder::CodecId;
63 65
64 static const struct { 66 static const struct {
65 CodecId codec_id; 67 CodecId codec_id;
66 media::VideoCodecProfile min_profile; 68 media::VideoCodecProfile min_profile;
67 media::VideoCodecProfile max_profile; 69 media::VideoCodecProfile max_profile;
68 } kPreferredCodecIdAndVEAProfiles[] = { 70 } kPreferredCodecIdAndVEAProfiles[] = {
69 {CodecId::VP8, media::VP8PROFILE_MIN, media::VP8PROFILE_MAX}, 71 {CodecId::VP8, media::VP8PROFILE_MIN, media::VP8PROFILE_MAX},
70 {CodecId::VP9, media::VP9PROFILE_MIN, media::VP9PROFILE_MAX}, 72 {CodecId::VP9, media::VP9PROFILE_MIN, media::VP9PROFILE_MAX},
71 #if BUILDFLAG(RTC_USE_H264) 73 #if BUILDFLAG(RTC_USE_H264) || defined(OS_ANDROID)
72 {CodecId::H264, media::H264PROFILE_MIN, media::H264PROFILE_MAX} 74 {CodecId::H264, media::H264PROFILE_MIN, media::H264PROFILE_MAX}
73 #endif 75 #endif
74 }; 76 };
75 77
76 static_assert(arraysize(kPreferredCodecIdAndVEAProfiles) == 78 static_assert(arraysize(kPreferredCodecIdAndVEAProfiles) ==
77 static_cast<int>(CodecId::LAST), 79 static_cast<int>(CodecId::LAST),
78 "|kPreferredCodecIdAndVEAProfiles| should consider all CodecIds"); 80 "|kPreferredCodecIdAndVEAProfiles| should consider all CodecIds");
79 81
80 // Class to encapsulate the enumeration of CodecIds/VideoCodecProfiles supported 82 // Class to encapsulate the enumeration of CodecIds/VideoCodecProfiles supported
81 // by the VEA underlying platform. Provides methods to query the preferred 83 // by the VEA underlying platform. Provides methods to query the preferred
(...skipping 22 matching lines...) Expand all
104 static CodecEnumerator* enumerator = new CodecEnumerator(); 106 static CodecEnumerator* enumerator = new CodecEnumerator();
105 return enumerator; 107 return enumerator;
106 } 108 }
107 109
108 CodecEnumerator::CodecEnumerator() { 110 CodecEnumerator::CodecEnumerator() {
109 #if defined(OS_CHROMEOS) 111 #if defined(OS_CHROMEOS)
110 // See https://crbug.com/616659. 112 // See https://crbug.com/616659.
111 return; 113 return;
112 #endif 114 #endif
113 115
114 #if defined(OS_ANDROID)
115 // See https://crbug.com/653864.
116 return;
117 #endif
118
119 content::RenderThreadImpl* const render_thread_impl = 116 content::RenderThreadImpl* const render_thread_impl =
120 content::RenderThreadImpl::current(); 117 content::RenderThreadImpl::current();
121 if (!render_thread_impl) { 118 if (!render_thread_impl) {
122 DVLOG(2) << "Couldn't access the render thread"; 119 DVLOG(2) << "Couldn't access the render thread";
123 return; 120 return;
124 } 121 }
125 122
126 media::GpuVideoAcceleratorFactories* const gpu_factories = 123 media::GpuVideoAcceleratorFactories* const gpu_factories =
127 render_thread_impl->GetGpuFactories(); 124 render_thread_impl->GetGpuFactories();
128 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { 125 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
(...skipping 22 matching lines...) Expand all
151 return codec_id_to_profile_.begin()->first; 148 return codec_id_to_profile_.begin()->first;
152 } 149 }
153 150
154 media::VideoCodecProfile CodecEnumerator::CodecIdToVEAProfile(CodecId codec) { 151 media::VideoCodecProfile CodecEnumerator::CodecIdToVEAProfile(CodecId codec) {
155 const auto profile = codec_id_to_profile_.find(codec); 152 const auto profile = codec_id_to_profile_.find(codec);
156 return profile == codec_id_to_profile_.end() 153 return profile == codec_id_to_profile_.end()
157 ? media::VIDEO_CODEC_PROFILE_UNKNOWN 154 ? media::VIDEO_CODEC_PROFILE_UNKNOWN
158 : profile->second; 155 : profile->second;
159 } 156 }
160 157
158 bool IsFrameSizeBiggerThanVEAEncoderMinResolution(const gfx::Size& input_size) {
159 #if !defined(OS_ANDROID)
160 if (input_size.width() >= input_size.height()) {
161 return input_size.width() >= kVEAEncoderMinResolutionWidth &&
162 input_size.height() >= kVEAEncoderMinResolutionHeight;
163 } else {
164 return input_size.height() >= kVEAEncoderMinResolutionWidth &&
165 input_size.width() >= kVEAEncoderMinResolutionHeight;
166 }
167 #else
168 return input_size.width() >= kVEAEncoderMinResolutionWidthAndroid &&
169 input_size.height() >= kVEAEncoderMinResolutionHeightAndroid;
170 #endif
171 }
172
161 } // anonymous namespace 173 } // anonymous namespace
162 174
163 // Base class to describe a generic Encoder, encapsulating all actual encoder 175 // Base class to describe a generic Encoder, encapsulating all actual encoder
164 // (re)configurations, encoding and delivery of received frames. This class is 176 // (re)configurations, encoding and delivery of received frames. This class is
165 // ref-counted to allow the MediaStreamVideoTrack to hold a reference to it (via 177 // ref-counted to allow the MediaStreamVideoTrack to hold a reference to it (via
166 // the callback that MediaStreamVideoSink passes along) and to jump back and 178 // the callback that MediaStreamVideoSink passes along) and to jump back and
167 // forth to an internal encoder thread. Moreover, this class: 179 // forth to an internal encoder thread. Moreover, this class:
168 // - is created on its parent's thread (usually the main Render thread), 180 // - is created on its parent's thread (usually the main Render thread),
169 // that is, |main_task_runner_|. 181 // that is, |main_task_runner_|.
170 // - receives VideoFrames on |origin_task_runner_| and runs OnEncodedVideoCB on 182 // - receives VideoFrames on |origin_task_runner_| and runs OnEncodedVideoCB on
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 media::VideoCodecProfile codec, 604 media::VideoCodecProfile codec,
593 const gfx::Size& size) 605 const gfx::Size& size)
594 : Encoder(on_encoded_video_callback, 606 : Encoder(on_encoded_video_callback,
595 bits_per_second > 0 ? bits_per_second 607 bits_per_second > 0 ? bits_per_second
596 : size.GetArea() * kVEADefaultBitratePerPixel, 608 : size.GetArea() * kVEADefaultBitratePerPixel,
597 RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()), 609 RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()),
598 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()), 610 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()),
599 codec_(codec), 611 codec_(codec),
600 error_notified_(false) { 612 error_notified_(false) {
601 DCHECK(gpu_factories_); 613 DCHECK(gpu_factories_);
602 DCHECK_GE(size.width(), kVEAEncoderMinResolutionWidth);
603 DCHECK_GE(size.height(), kVEAEncoderMinResolutionHeight);
604 614
605 encoding_task_runner_->PostTask( 615 encoding_task_runner_->PostTask(
606 FROM_HERE, base::Bind(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner, 616 FROM_HERE, base::Bind(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner,
607 this, size)); 617 this, size));
608 } 618 }
609 619
610 VEAEncoder::~VEAEncoder() { 620 VEAEncoder::~VEAEncoder() {
611 base::WaitableEvent release_waiter( 621 base::WaitableEvent release_waiter(
612 base::WaitableEvent::ResetPolicy::MANUAL, 622 base::WaitableEvent::ResetPolicy::MANUAL,
613 base::WaitableEvent::InitialState::NOT_SIGNALED); 623 base::WaitableEvent::InitialState::NOT_SIGNALED);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 } 734 }
725 735
726 // Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac. 736 // Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac.
727 // In that case, the encoder expects more frames before returning result. 737 // In that case, the encoder expects more frames before returning result.
728 // Therefore, a copy is necessary to release the current frame. 738 // Therefore, a copy is necessary to release the current frame.
729 // Only STORAGE_SHMEM backed frames can be shared with GPU process, therefore 739 // Only STORAGE_SHMEM backed frames can be shared with GPU process, therefore
730 // a copy is required for other storage types. 740 // a copy is required for other storage types.
731 scoped_refptr<media::VideoFrame> video_frame = frame; 741 scoped_refptr<media::VideoFrame> video_frame = frame;
732 if (video_frame->storage_type() != VideoFrame::STORAGE_SHMEM || 742 if (video_frame->storage_type() != VideoFrame::STORAGE_SHMEM ||
733 vea_requested_input_coded_size_ != frame->coded_size() || 743 vea_requested_input_coded_size_ != frame->coded_size() ||
734 input_visible_size_.width() < kVEAEncoderMinResolutionWidth || 744 !IsFrameSizeBiggerThanVEAEncoderMinResolution(input_visible_size_)) {
735 input_visible_size_.height() < kVEAEncoderMinResolutionHeight) {
736 // Create SharedMemory backed input buffers as necessary. These SharedMemory 745 // Create SharedMemory backed input buffers as necessary. These SharedMemory
737 // instances will be shared with GPU process. 746 // instances will be shared with GPU process.
738 std::unique_ptr<base::SharedMemory> input_buffer; 747 std::unique_ptr<base::SharedMemory> input_buffer;
739 const size_t desired_mapped_size = media::VideoFrame::AllocationSize( 748 const size_t desired_mapped_size = media::VideoFrame::AllocationSize(
740 media::PIXEL_FORMAT_I420, vea_requested_input_coded_size_); 749 media::PIXEL_FORMAT_I420, vea_requested_input_coded_size_);
741 if (input_buffers_.empty()) { 750 if (input_buffers_.empty()) {
742 input_buffer = gpu_factories_->CreateSharedMemory(desired_mapped_size); 751 input_buffer = gpu_factories_->CreateSharedMemory(desired_mapped_size);
743 } else { 752 } else {
744 do { 753 do {
745 input_buffer = std::move(input_buffers_.front()); 754 input_buffer = std::move(input_buffers_.front());
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 // sink to initialize, https://crbug.com/698441. 1307 // sink to initialize, https://crbug.com/698441.
1299 if (encoder_) 1308 if (encoder_)
1300 return; 1309 return;
1301 1310
1302 MediaStreamVideoSink::DisconnectFromTrack(); 1311 MediaStreamVideoSink::DisconnectFromTrack();
1303 1312
1304 const gfx::Size& input_size = frame->visible_rect().size(); 1313 const gfx::Size& input_size = frame->visible_rect().size();
1305 const auto& vea_supported_profile = 1314 const auto& vea_supported_profile =
1306 GetCodecEnumerator()->CodecIdToVEAProfile(codec); 1315 GetCodecEnumerator()->CodecIdToVEAProfile(codec);
1307 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN && 1316 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN &&
1308 input_size.width() >= kVEAEncoderMinResolutionWidth && 1317 IsFrameSizeBiggerThanVEAEncoderMinResolution(input_size)) {
1309 input_size.height() >= kVEAEncoderMinResolutionHeight) {
1310 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second, 1318 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second,
1311 vea_supported_profile, input_size); 1319 vea_supported_profile, input_size);
1312 } else { 1320 } else {
1313 switch (codec) { 1321 switch (codec) {
1314 #if BUILDFLAG(RTC_USE_H264) 1322 #if BUILDFLAG(RTC_USE_H264)
1315 case CodecId::H264: 1323 case CodecId::H264:
1316 encoder_ = 1324 encoder_ =
1317 new H264Encoder(on_encoded_video_callback, bits_per_second); 1325 new H264Encoder(on_encoded_video_callback, bits_per_second);
1318 break; 1326 break;
1319 #endif 1327 #endif
(...skipping 16 matching lines...) Expand all
1336 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), 1344 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
1337 false); 1345 false);
1338 } 1346 }
1339 1347
1340 bool VideoTrackRecorder::CanEncodeAlphaChannelForTesting() { 1348 bool VideoTrackRecorder::CanEncodeAlphaChannelForTesting() {
1341 DCHECK(encoder_); 1349 DCHECK(encoder_);
1342 return encoder_->CanEncodeAlphaChannel(); 1350 return encoder_->CanEncodeAlphaChannel();
1343 } 1351 }
1344 1352
1345 } // namespace content 1353 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698