blob: 40c6cf6da06a95b8d888ff47ea7c5f022187dc56 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/mediastream/input_device_info.h"
#include <algorithm>
#include "build/build_config.h"
#include "media/base/sample_format.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_track.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_double_range.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_long_range.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
namespace blink {
InputDeviceInfo::InputDeviceInfo(const String& device_id,
const String& label,
const String& group_id,
mojom::blink::MediaDeviceType device_type)
: MediaDeviceInfo(device_id, label, group_id, device_type) {}
void InputDeviceInfo::SetVideoInputCapabilities(
mojom::blink::VideoInputDeviceCapabilitiesPtr video_input_capabilities) {
DCHECK_EQ(deviceId(), video_input_capabilities->device_id);
// TODO(c.padhi): Merge the common logic below with
// ComputeCapabilitiesForVideoSource() in media_stream_constraints_util.h, see
// https://crbug.com/821668.
platform_capabilities_.facing_mode =
ToPlatformFacingMode(video_input_capabilities->facing_mode);
if (!video_input_capabilities->formats.IsEmpty()) {
int max_width = 1;
int max_height = 1;
float min_frame_rate = 1.0f;
float max_frame_rate = min_frame_rate;
for (const auto& format : video_input_capabilities->formats) {
max_width = std::max(max_width, format.frame_size.width());
max_height = std::max(max_height, format.frame_size.height());
max_frame_rate = std::max(max_frame_rate, format.frame_rate);
}
platform_capabilities_.width = {1, max_width};
platform_capabilities_.height = {1, max_height};
platform_capabilities_.aspect_ratio = {1.0 / max_height,
static_cast<double>(max_width)};
platform_capabilities_.frame_rate = {min_frame_rate, max_frame_rate};
}
}
void InputDeviceInfo::SetAudioInputCapabilities(
mojom::blink::AudioInputDeviceCapabilitiesPtr audio_input_capabilities) {
DCHECK_EQ(deviceId(), audio_input_capabilities->device_id);
if (audio_input_capabilities->is_valid) {
platform_capabilities_.channel_count = {1,
audio_input_capabilities->channels};
platform_capabilities_.sample_rate = {
std::min(kAudioProcessingSampleRate,
audio_input_capabilities->sample_rate),
std::max(kAudioProcessingSampleRate,
audio_input_capabilities->sample_rate)};
double fallback_latency = kFallbackAudioLatencyMs / 1000;
platform_capabilities_.latency = {
std::min(fallback_latency,
audio_input_capabilities->latency.InSecondsF()),
std::max(fallback_latency,
audio_input_capabilities->latency.InSecondsF())};
}
}
MediaTrackCapabilities* InputDeviceInfo::getCapabilities() const {
MediaTrackCapabilities* capabilities = MediaTrackCapabilities::Create();
// If label is null, permissions have not been given and no capabilities
// should be returned.
if (label().IsEmpty())
return capabilities;
capabilities->setDeviceId(deviceId());
capabilities->setGroupId(groupId());
if (DeviceType() == mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT) {
capabilities->setEchoCancellation({true, false});
capabilities->setAutoGainControl({true, false});
capabilities->setNoiseSuppression({true, false});
// Sample size.
LongRange* sample_size = LongRange::Create();
sample_size->setMin(
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16));
sample_size->setMax(
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16));
capabilities->setSampleSize(sample_size);
// Channel count.
if (!platform_capabilities_.channel_count.IsEmpty()) {
LongRange* channel_count = LongRange::Create();
channel_count->setMin(platform_capabilities_.channel_count[0]);
channel_count->setMax(platform_capabilities_.channel_count[1]);
capabilities->setChannelCount(channel_count);
}
// Sample rate.
if (!platform_capabilities_.sample_rate.IsEmpty()) {
LongRange* sample_rate = LongRange::Create();
sample_rate->setMin(platform_capabilities_.sample_rate[0]);
sample_rate->setMax(platform_capabilities_.sample_rate[1]);
capabilities->setSampleRate(sample_rate);
}
// Latency.
if (!platform_capabilities_.latency.IsEmpty()) {
DoubleRange* latency = DoubleRange::Create();
latency->setMin(platform_capabilities_.latency[0]);
latency->setMax(platform_capabilities_.latency[1]);
capabilities->setLatency(latency);
}
}
if (DeviceType() == mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT) {
if (!platform_capabilities_.width.IsEmpty()) {
LongRange* width = LongRange::Create();
width->setMin(platform_capabilities_.width[0]);
width->setMax(platform_capabilities_.width[1]);
capabilities->setWidth(width);
}
if (!platform_capabilities_.height.IsEmpty()) {
LongRange* height = LongRange::Create();
height->setMin(platform_capabilities_.height[0]);
height->setMax(platform_capabilities_.height[1]);
capabilities->setHeight(height);
}
if (!platform_capabilities_.aspect_ratio.IsEmpty()) {
DoubleRange* aspect_ratio = DoubleRange::Create();
aspect_ratio->setMin(platform_capabilities_.aspect_ratio[0]);
aspect_ratio->setMax(platform_capabilities_.aspect_ratio[1]);
capabilities->setAspectRatio(aspect_ratio);
}
if (!platform_capabilities_.frame_rate.IsEmpty()) {
DoubleRange* frame_rate = DoubleRange::Create();
frame_rate->setMin(platform_capabilities_.frame_rate[0]);
frame_rate->setMax(platform_capabilities_.frame_rate[1]);
capabilities->setFrameRate(frame_rate);
}
Vector<String> facing_mode;
switch (platform_capabilities_.facing_mode) {
case MediaStreamTrackPlatform::FacingMode::kUser:
facing_mode.push_back("user");
break;
case MediaStreamTrackPlatform::FacingMode::kEnvironment:
facing_mode.push_back("environment");
break;
case MediaStreamTrackPlatform::FacingMode::kLeft:
facing_mode.push_back("left");
break;
case MediaStreamTrackPlatform::FacingMode::kRight:
facing_mode.push_back("right");
break;
case MediaStreamTrackPlatform::FacingMode::kNone:
break;
}
capabilities->setFacingMode(facing_mode);
capabilities->setResizeMode({WebMediaStreamTrack::kResizeModeNone,
WebMediaStreamTrack::kResizeModeRescale});
}
return capabilities;
}
} // namespace blink