blob: 592c1ec4f4476a3870525189e05f60e2527c45af [file] [log] [blame]
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "public/platform/WebMediaStreamSource.h"
#include <memory>
#include <utility>
#include "platform/audio/AudioBus.h"
#include "platform/mediastream/MediaStreamSource.h"
#include "platform/wtf/PtrUtil.h"
#include "platform/wtf/Vector.h"
#include "public/platform/WebAudioDestinationConsumer.h"
#include "public/platform/WebMediaConstraints.h"
#include "public/platform/WebString.h"
namespace blink {
namespace {
class MediaStreamSourceExtraDataContainer
: public MediaStreamSource::ExtraData {
public:
MediaStreamSourceExtraDataContainer(
std::unique_ptr<WebMediaStreamSource::ExtraData> extra_data)
: extra_data_(std::move(extra_data)) {}
WebMediaStreamSource::ExtraData* GetExtraData() { return extra_data_.get(); }
private:
std::unique_ptr<WebMediaStreamSource::ExtraData> extra_data_;
};
} // namespace
WebMediaStreamSource WebMediaStreamSource::ExtraData::Owner() {
DCHECK(owner_);
return WebMediaStreamSource(owner_);
}
void WebMediaStreamSource::ExtraData::SetOwner(MediaStreamSource* owner) {
DCHECK(!owner_);
owner_ = owner;
}
WebMediaStreamSource::WebMediaStreamSource(
MediaStreamSource* media_stream_source)
: private_(media_stream_source) {}
WebMediaStreamSource& WebMediaStreamSource::operator=(
MediaStreamSource* media_stream_source) {
private_ = media_stream_source;
return *this;
}
void WebMediaStreamSource::Assign(const WebMediaStreamSource& other) {
private_ = other.private_;
}
void WebMediaStreamSource::Reset() {
private_.Reset();
}
WebMediaStreamSource::operator MediaStreamSource*() const {
return private_.Get();
}
void WebMediaStreamSource::Initialize(const WebString& id,
Type type,
const WebString& name) {
private_ = MediaStreamSource::Create(
id, static_cast<MediaStreamSource::StreamType>(type), name, false);
}
void WebMediaStreamSource::Initialize(const WebString& id,
Type type,
const WebString& name,
bool remote) {
private_ = MediaStreamSource::Create(
id, static_cast<MediaStreamSource::StreamType>(type), name, remote);
}
WebString WebMediaStreamSource::Id() const {
DCHECK(!private_.IsNull());
return private_.Get()->Id();
}
WebMediaStreamSource::Type WebMediaStreamSource::GetType() const {
DCHECK(!private_.IsNull());
return static_cast<Type>(private_.Get()->GetType());
}
WebString WebMediaStreamSource::GetName() const {
DCHECK(!private_.IsNull());
return private_.Get()->GetName();
}
bool WebMediaStreamSource::Remote() const {
DCHECK(!private_.IsNull());
return private_.Get()->Remote();
}
void WebMediaStreamSource::SetReadyState(ReadyState state) {
DCHECK(!private_.IsNull());
private_->SetReadyState(static_cast<MediaStreamSource::ReadyState>(state));
}
WebMediaStreamSource::ReadyState WebMediaStreamSource::GetReadyState() const {
DCHECK(!private_.IsNull());
return static_cast<ReadyState>(private_->GetReadyState());
}
WebMediaStreamSource::ExtraData* WebMediaStreamSource::GetExtraData() const {
DCHECK(!private_.IsNull());
MediaStreamSource::ExtraData* data = private_->GetExtraData();
if (!data)
return nullptr;
return static_cast<MediaStreamSourceExtraDataContainer*>(data)
->GetExtraData();
}
void WebMediaStreamSource::SetExtraData(ExtraData* extra_data) {
DCHECK(!private_.IsNull());
if (extra_data)
extra_data->SetOwner(private_.Get());
private_->SetExtraData(WTF::WrapUnique(
new MediaStreamSourceExtraDataContainer(WTF::WrapUnique(extra_data))));
}
void WebMediaStreamSource::SetEchoCancellation(bool echo_cancellation) {
DCHECK(!private_.IsNull());
private_->SetEchoCancellation(echo_cancellation);
}
WebMediaConstraints WebMediaStreamSource::Constraints() {
DCHECK(!private_.IsNull());
return private_->Constraints();
}
void WebMediaStreamSource::SetCapabilities(
const WebMediaStreamSource::Capabilities& capabilities) {
DCHECK(!private_.IsNull());
private_->SetCapabilities(capabilities);
}
bool WebMediaStreamSource::RequiresAudioConsumer() const {
DCHECK(!private_.IsNull());
return private_->RequiresAudioConsumer();
}
class ConsumerWrapper final : public AudioDestinationConsumer {
USING_FAST_MALLOC(ConsumerWrapper);
public:
static ConsumerWrapper* Create(WebAudioDestinationConsumer* consumer) {
return new ConsumerWrapper(consumer);
}
void SetFormat(size_t number_of_channels, float sample_rate) override;
void ConsumeAudio(AudioBus*, size_t number_of_frames) override;
WebAudioDestinationConsumer* Consumer() { return consumer_; }
private:
explicit ConsumerWrapper(WebAudioDestinationConsumer* consumer)
: consumer_(consumer) {}
// m_consumer is not owned by this class.
WebAudioDestinationConsumer* consumer_;
};
void ConsumerWrapper::SetFormat(size_t number_of_channels, float sample_rate) {
consumer_->SetFormat(number_of_channels, sample_rate);
}
void ConsumerWrapper::ConsumeAudio(AudioBus* bus, size_t number_of_frames) {
if (!bus)
return;
// Wrap AudioBus.
size_t number_of_channels = bus->NumberOfChannels();
WebVector<const float*> bus_vector(number_of_channels);
for (size_t i = 0; i < number_of_channels; ++i)
bus_vector[i] = bus->Channel(i)->Data();
consumer_->ConsumeAudio(bus_vector, number_of_frames);
}
void WebMediaStreamSource::AddAudioConsumer(
WebAudioDestinationConsumer* consumer) {
DCHECK(IsMainThread());
DCHECK(!private_.IsNull() && consumer);
private_->AddAudioConsumer(ConsumerWrapper::Create(consumer));
}
bool WebMediaStreamSource::RemoveAudioConsumer(
WebAudioDestinationConsumer* consumer) {
DCHECK(IsMainThread());
DCHECK(!private_.IsNull() && consumer);
const HashSet<AudioDestinationConsumer*>& consumers =
private_->AudioConsumers();
for (AudioDestinationConsumer* it : consumers) {
ConsumerWrapper* wrapper = static_cast<ConsumerWrapper*>(it);
if (wrapper->Consumer() == consumer) {
private_->RemoveAudioConsumer(wrapper);
return true;
}
}
return false;
}
} // namespace blink