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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |