blob: ce8e2655ee7f23339ac9d9fd4d187dec491973ca [file] [log] [blame]
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2011 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "config.h"
#include "MediaStream.h"
#if ENABLE(MEDIA_STREAM)
#include "Event.h"
#include "ExceptionCode.h"
#include "MediaStreamCenter.h"
#include "MediaStreamSource.h"
#include "UUID.h"
namespace WebCore {
static void processTrackList(PassRefPtr<MediaStreamTrackList> prpTracks, const String& kind, MediaStreamSourceVector& sources, ExceptionCode& ec)
{
RefPtr<MediaStreamTrackList> tracks = prpTracks;
if (!tracks)
return;
for (unsigned i = 0; i < tracks->length(); ++i) {
MediaStreamTrack* track = tracks->item(i);
if (track->kind() != kind) {
ec = SYNTAX_ERR;
return;
}
MediaStreamSource* source = track->component()->source();
bool isDuplicate = false;
for (MediaStreamSourceVector::iterator j = sources.begin(); j < sources.end(); ++j) {
if ((*j)->id() == source->id()) {
isDuplicate = true;
break;
}
}
if (!isDuplicate)
sources.append(source);
}
}
PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackList> audioTracks, PassRefPtr<MediaStreamTrackList> videoTracks, ExceptionCode& ec)
{
MediaStreamSourceVector audioSources;
processTrackList(audioTracks, "audio", audioSources, ec);
if (ec)
return 0;
MediaStreamSourceVector videoSources;
processTrackList(videoTracks, "video", videoSources, ec);
if (ec)
return 0;
RefPtr<MediaStreamDescriptor> descriptor = MediaStreamDescriptor::create(createCanonicalUUIDString(), audioSources, videoSources);
MediaStreamCenter::instance().didCreateMediaStream(descriptor.get());
return adoptRef(new MediaStream(context, descriptor.release()));
}
PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext* context, PassRefPtr<MediaStreamDescriptor> streamDescriptor)
{
return adoptRef(new MediaStream(context, streamDescriptor));
}
MediaStream::MediaStream(ScriptExecutionContext* context, PassRefPtr<MediaStreamDescriptor> streamDescriptor)
: ContextDestructionObserver(context)
, m_descriptor(streamDescriptor)
{
m_descriptor->setOwner(this);
MediaStreamTrackVector audioTrackVector;
size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents();
audioTrackVector.reserveCapacity(numberOfAudioTracks);
for (size_t i = 0; i < numberOfAudioTracks; i++)
audioTrackVector.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->audioComponent(i)));
m_audioTracks = MediaStreamTrackList::create(this, audioTrackVector);
MediaStreamTrackVector videoTrackVector;
size_t numberOfVideoTracks = m_descriptor->numberOfVideoComponents();
videoTrackVector.reserveCapacity(numberOfVideoTracks);
for (size_t i = 0; i < numberOfVideoTracks; i++)
videoTrackVector.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->videoComponent(i)));
m_videoTracks = MediaStreamTrackList::create(this, videoTrackVector);
}
MediaStream::~MediaStream()
{
m_descriptor->setOwner(0);
m_audioTracks->detachOwner();
m_videoTracks->detachOwner();
}
MediaStream::ReadyState MediaStream::readyState() const
{
return m_descriptor->ended() ? ENDED : LIVE;
}
void MediaStream::streamEnded()
{
if (readyState() == ENDED)
return;
m_descriptor->setEnded();
m_audioTracks->detachOwner();
m_videoTracks->detachOwner();
dispatchEvent(Event::create(eventNames().endedEvent, false, false));
}
const AtomicString& MediaStream::interfaceName() const
{
return eventNames().interfaceForMediaStream;
}
ScriptExecutionContext* MediaStream::scriptExecutionContext() const
{
return ContextDestructionObserver::scriptExecutionContext();
}
EventTargetData* MediaStream::eventTargetData()
{
return &m_eventTargetData;
}
EventTargetData* MediaStream::ensureEventTargetData()
{
return &m_eventTargetData;
}
void MediaStream::addTrack(MediaStreamComponent* component)
{
RefPtr<MediaStreamTrack> track = MediaStreamTrack::create(scriptExecutionContext(), m_descriptor, component);
ExceptionCode ec = 0;
switch (component->source()->type()) {
case MediaStreamSource::TypeAudio:
m_audioTracks->add(track, ec);
break;
case MediaStreamSource::TypeVideo:
m_videoTracks->add(track, ec);
break;
}
ASSERT(!ec);
}
void MediaStream::removeTrack(MediaStreamComponent* component)
{
switch (component->source()->type()) {
case MediaStreamSource::TypeAudio:
m_audioTracks->remove(component);
break;
case MediaStreamSource::TypeVideo:
m_videoTracks->remove(component);
break;
}
}
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)