Chromium Code Reviews| Index: third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp |
| diff --git a/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp b/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp |
| index 38f780fb1cb3d2a01f024ac5e298c19e10dfcc35..034ef7f24237a41f090a715c3a3312e195e9ec8d 100644 |
| --- a/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp |
| +++ b/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp |
| @@ -24,6 +24,59 @@ namespace blink { |
| namespace { |
| +constexpr const char* kAudioMimeTypePrefix = "audio/"; |
| +constexpr const char* kVideoMimeTypePrefix = "video/"; |
|
chcunningham
2017/05/10 21:10:13
we may need to add in the HLS prefix "application/
mlamouri (slow - plz ping)
2017/05/11 10:41:23
That means we should update the specification, rig
|
| +constexpr const char* kCodecsMimeTypeParam = "codecs"; |
| + |
| +bool IsValidMimeType(const String& content_type, const String& prefix) { |
| + ParsedContentType parsed_content_type(content_type, |
| + ParsedContentType::Mode::kStrict); |
| + if (!parsed_content_type.IsValid()) |
| + return false; |
| + |
| + if (!parsed_content_type.MimeType().StartsWith(prefix)) |
| + return false; |
| + |
| + if (parsed_content_type.ParameterCount() > 1) |
| + return false; |
| + |
| + if (parsed_content_type.ParameterCount() == 1 && |
| + parsed_content_type.ParameterValueForName(kCodecsMimeTypeParam) |
| + .IsNull()) { |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool IsValidMediaConfiguration(const MediaConfiguration& configuration) { |
| + return configuration.hasAudio() || configuration.hasVideo(); |
| +} |
| + |
| +bool IsValidVideoConfiguration(const VideoConfiguration& configuration) { |
| + DCHECK(configuration.hasContentType()); |
| + |
| + if (!IsValidMimeType(configuration.contentType(), kVideoMimeTypePrefix)) |
| + return false; |
| + |
| + DCHECK(configuration.hasFramerate()); |
| + if (!std::isfinite(configuration.framerate()) || |
| + configuration.framerate() <= 0) { |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool IsValidAudioConfiguration(const AudioConfiguration& configuration) { |
| + DCHECK(configuration.hasContentType()); |
| + |
| + if (!IsValidMimeType(configuration.contentType(), kAudioMimeTypePrefix)) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| WebAudioConfiguration ToWebAudioConfiguration( |
| const AudioConfiguration& configuration) { |
| WebAudioConfiguration web_configuration; |
| @@ -32,9 +85,7 @@ WebAudioConfiguration ToWebAudioConfiguration( |
| DCHECK(configuration.hasContentType()); |
| ParsedContentType parsed_content_type(configuration.contentType(), |
| ParsedContentType::Mode::kStrict); |
| - |
| - // TODO(chcunningham): Throw TypeError for invalid input. |
| - // DCHECK(parsed_content_type.IsValid()); |
| + DCHECK(parsed_content_type.IsValid()); |
| DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII(); |
| @@ -62,9 +113,7 @@ WebVideoConfiguration ToWebVideoConfiguration( |
| DCHECK(configuration.hasContentType()); |
| ParsedContentType parsed_content_type(configuration.contentType(), |
| ParsedContentType::Mode::kStrict); |
| - |
| - // TODO(chcunningham): Throw TypeError for invalid input. |
| - // DCHECK(parsed_content_type.IsValid()); |
| + DCHECK(parsed_content_type.IsValid()); |
| DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII(); |
| @@ -86,9 +135,37 @@ WebVideoConfiguration ToWebVideoConfiguration( |
| } |
| WebMediaConfiguration ToWebMediaConfiguration( |
| - const MediaConfiguration& configuration) { |
| + const MediaDecodingConfiguration& configuration) { |
| WebMediaConfiguration web_configuration; |
| + // |type| is mandatory. |
| + DCHECK(configuration.hasType()); |
| + if (configuration.type() == "file") |
| + web_configuration.type = MediaConfigurationType::kFile; |
| + else if (configuration.type() == "media-source") |
| + web_configuration.type = MediaConfigurationType::kMediaSource; |
| + else |
| + NOTREACHED(); |
| + |
| + if (configuration.hasAudio()) { |
| + web_configuration.audio_configuration = |
| + ToWebAudioConfiguration(configuration.audio()); |
| + } |
| + |
| + if (configuration.hasVideo()) { |
| + web_configuration.video_configuration = |
| + ToWebVideoConfiguration(configuration.video()); |
| + } |
| + |
| + return web_configuration; |
| +} |
| + |
| +WebMediaConfiguration ToWebMediaConfiguration( |
| + const MediaEncodingConfiguration& configuration) { |
| + WebMediaConfiguration web_configuration; |
| + |
| + // TODO(mcasas): parse and set the type for encoding. |
| + |
| if (configuration.hasAudio()) { |
| web_configuration.audio_configuration = |
| ToWebAudioConfiguration(configuration.audio()); |
| @@ -112,8 +189,29 @@ ScriptPromise MediaCapabilities::decodingInfo( |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); |
| ScriptPromise promise = resolver->Promise(); |
| - // |type| is mandatory. |
| - DCHECK(configuration.hasType()); |
| + if (!IsValidMediaConfiguration(configuration)) { |
| + resolver->Reject(V8ThrowException::CreateTypeError( |
| + script_state->GetIsolate(), |
| + "The configuration dictionary has neither |video| nor |audio| " |
| + "specified and needs at least one of them.")); |
| + return promise; |
| + } |
| + |
| + if (configuration.hasVideo() && |
| + !IsValidVideoConfiguration(configuration.video())) { |
| + resolver->Reject(V8ThrowException::CreateTypeError( |
| + script_state->GetIsolate(), |
| + "The video configuration dictionary is not valid.")); |
| + return promise; |
| + } |
| + |
| + if (configuration.hasAudio() && |
| + !IsValidAudioConfiguration(configuration.audio())) { |
| + resolver->Reject(V8ThrowException::CreateTypeError( |
| + script_state->GetIsolate(), |
| + "The audio configuration dictionary is not valid.")); |
| + return promise; |
| + } |
| Platform::Current()->MediaCapabilitiesClient()->DecodingInfo( |
| ToWebMediaConfiguration(configuration), |
| @@ -129,14 +227,30 @@ ScriptPromise MediaCapabilities::encodingInfo( |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); |
| ScriptPromise promise = resolver->Promise(); |
| - if (!configuration.hasVideo() && !configuration.hasAudio()) { |
| - resolver->Reject(DOMException::Create( |
| - kSyntaxError, |
| + if (!IsValidMediaConfiguration(configuration)) { |
| + resolver->Reject(V8ThrowException::CreateTypeError( |
| + script_state->GetIsolate(), |
| "The configuration dictionary has neither |video| nor |audio| " |
| "specified and needs at least one of them.")); |
| return promise; |
| } |
| + if (configuration.hasVideo() && |
| + !IsValidVideoConfiguration(configuration.video())) { |
| + resolver->Reject(V8ThrowException::CreateTypeError( |
| + script_state->GetIsolate(), |
| + "The video configuration dictionary is not valid.")); |
| + return promise; |
| + } |
| + |
| + if (configuration.hasAudio() && |
| + !IsValidAudioConfiguration(configuration.audio())) { |
| + resolver->Reject(V8ThrowException::CreateTypeError( |
| + script_state->GetIsolate(), |
| + "The audio configuration dictionary is not valid.")); |
| + return promise; |
| + } |
| + |
| std::unique_ptr<WebMediaRecorderHandler> handler = |
| Platform::Current()->CreateMediaRecorderHandler(); |
| if (!handler) { |