2013-03-27 05:32:51 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "MediaStreamTrack.h"
|
|
|
|
|
|
|
|
#include "DOMMediaStream.h"
|
2016-03-03 19:27:59 +03:00
|
|
|
#include "MediaStreamGraph.h"
|
2013-03-27 05:32:51 +04:00
|
|
|
#include "nsIUUIDGenerator.h"
|
|
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
|
2016-01-05 05:16:21 +03:00
|
|
|
#ifdef LOG
|
|
|
|
#undef LOG
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static PRLogModuleInfo* gMediaStreamTrackLog;
|
|
|
|
#define LOG(type, msg) MOZ_LOG(gMediaStreamTrackLog, type, msg)
|
|
|
|
|
2013-03-27 05:32:51 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2016-04-06 15:46:56 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaStreamTrackSource)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaStreamTrackSource)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaStreamTrackSource)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
|
|
NS_INTERFACE_MAP_END
|
2016-01-22 07:28:57 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION(MediaStreamTrackSource, mPrincipal)
|
2016-04-06 15:46:56 +03:00
|
|
|
|
2016-02-01 17:43:38 +03:00
|
|
|
already_AddRefed<Promise>
|
|
|
|
MediaStreamTrackSource::ApplyConstraints(nsPIDOMWindowInner* aWindow,
|
|
|
|
const dom::MediaTrackConstraints& aConstraints,
|
|
|
|
ErrorResult &aRv)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(aWindow);
|
|
|
|
RefPtr<Promise> promise = Promise::Create(go, aRv);
|
|
|
|
MOZ_RELEASE_ASSERT(!aRv.Failed());
|
|
|
|
|
|
|
|
promise->MaybeReject(new MediaStreamError(
|
|
|
|
aWindow,
|
|
|
|
NS_LITERAL_STRING("OverconstrainedError"),
|
|
|
|
NS_LITERAL_STRING(""),
|
|
|
|
NS_LITERAL_STRING("")));
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2016-04-06 15:46:56 +03:00
|
|
|
MediaStreamTrack::MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
|
2016-01-05 05:16:22 +03:00
|
|
|
TrackID aInputTrackID, const nsString& aLabel,
|
2016-04-06 15:46:56 +03:00
|
|
|
MediaStreamTrackSource* aSource)
|
2016-01-05 05:16:22 +03:00
|
|
|
: mOwningStream(aStream), mTrackID(aTrackID),
|
|
|
|
mInputTrackID(aInputTrackID), mSource(aSource), mLabel(aLabel),
|
2016-04-06 15:46:56 +03:00
|
|
|
mEnded(false), mEnabled(true), mRemote(aSource->IsRemote()), mStopped(false)
|
2013-03-27 05:32:51 +04:00
|
|
|
{
|
|
|
|
|
2016-01-05 05:16:21 +03:00
|
|
|
if (!gMediaStreamTrackLog) {
|
|
|
|
gMediaStreamTrackLog = PR_NewLogModule("MediaStreamTrack");
|
|
|
|
}
|
|
|
|
|
2016-01-22 07:28:57 +03:00
|
|
|
GetSource().RegisterSink(this);
|
2016-04-06 15:46:56 +03:00
|
|
|
|
2013-03-27 05:32:51 +04:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
|
|
|
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
2014-12-10 22:17:09 +03:00
|
|
|
|
|
|
|
nsID uuid;
|
|
|
|
memset(&uuid, 0, sizeof(uuid));
|
2013-03-27 05:32:51 +04:00
|
|
|
if (uuidgen) {
|
2014-12-10 22:17:09 +03:00
|
|
|
uuidgen->GenerateUUIDInPlace(&uuid);
|
2013-03-27 05:32:51 +04:00
|
|
|
}
|
2014-12-10 22:17:09 +03:00
|
|
|
|
|
|
|
char chars[NSID_LENGTH];
|
|
|
|
uuid.ToProvidedString(chars);
|
|
|
|
mID = NS_ConvertASCIItoUTF16(chars);
|
2013-03-27 05:32:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
MediaStreamTrack::~MediaStreamTrack()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-04-06 15:46:56 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(MediaStreamTrack)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaStreamTrack,
|
|
|
|
DOMEventTargetHelper)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningStream)
|
2016-01-22 07:28:57 +03:00
|
|
|
if (tmp->mSource) {
|
|
|
|
tmp->mSource->UnregisterSink(tmp);
|
|
|
|
}
|
2016-04-06 15:46:56 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalTrack)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaStreamTrack,
|
|
|
|
DOMEventTargetHelper)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningStream)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalTrack)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
2013-03-27 05:32:51 +04:00
|
|
|
|
2014-04-01 10:13:50 +04:00
|
|
|
NS_IMPL_ADDREF_INHERITED(MediaStreamTrack, DOMEventTargetHelper)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(MediaStreamTrack, DOMEventTargetHelper)
|
2013-03-27 05:32:51 +04:00
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaStreamTrack)
|
2014-04-01 10:13:50 +04:00
|
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
2013-03-27 05:32:51 +04:00
|
|
|
|
2016-02-01 17:48:05 +03:00
|
|
|
nsPIDOMWindowInner*
|
|
|
|
MediaStreamTrack::GetParentObject() const
|
|
|
|
{
|
|
|
|
MOZ_RELEASE_ASSERT(mOwningStream);
|
|
|
|
return mOwningStream->GetParentObject();
|
|
|
|
}
|
|
|
|
|
2013-03-27 05:32:51 +04:00
|
|
|
void
|
2014-12-10 22:17:09 +03:00
|
|
|
MediaStreamTrack::GetId(nsAString& aID) const
|
2013-03-27 05:32:51 +04:00
|
|
|
{
|
2014-12-10 22:17:09 +03:00
|
|
|
aID = mID;
|
2013-03-27 05:32:51 +04:00
|
|
|
}
|
|
|
|
|
2013-05-30 08:44:43 +04:00
|
|
|
void
|
|
|
|
MediaStreamTrack::SetEnabled(bool aEnabled)
|
|
|
|
{
|
2016-01-05 05:16:21 +03:00
|
|
|
LOG(LogLevel::Info, ("MediaStreamTrack %p %s",
|
|
|
|
this, aEnabled ? "Enabled" : "Disabled"));
|
|
|
|
|
2013-05-30 08:44:43 +04:00
|
|
|
mEnabled = aEnabled;
|
2016-01-05 05:16:30 +03:00
|
|
|
GetOwnedStream()->SetTrackEnabled(mTrackID, aEnabled);
|
2013-05-30 08:44:43 +04:00
|
|
|
}
|
|
|
|
|
2014-08-27 09:03:49 +04:00
|
|
|
void
|
|
|
|
MediaStreamTrack::Stop()
|
|
|
|
{
|
2016-01-05 05:16:21 +03:00
|
|
|
LOG(LogLevel::Info, ("MediaStreamTrack %p Stop()", this));
|
|
|
|
|
2016-04-06 15:46:56 +03:00
|
|
|
if (mStopped) {
|
|
|
|
LOG(LogLevel::Warning, ("MediaStreamTrack %p Already stopped", this));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mRemote) {
|
|
|
|
LOG(LogLevel::Warning, ("MediaStreamTrack %p is remote. Can't be stopped.", this));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mSource) {
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-22 07:28:57 +03:00
|
|
|
mSource->UnregisterSink(this);
|
2016-04-06 15:46:56 +03:00
|
|
|
mStopped = true;
|
2014-08-27 09:03:49 +04:00
|
|
|
}
|
|
|
|
|
2015-09-21 01:45:57 +03:00
|
|
|
already_AddRefed<Promise>
|
|
|
|
MediaStreamTrack::ApplyConstraints(const MediaTrackConstraints& aConstraints,
|
|
|
|
ErrorResult &aRv)
|
|
|
|
{
|
2016-01-05 05:16:21 +03:00
|
|
|
if (MOZ_LOG_TEST(gMediaStreamTrackLog, LogLevel::Info)) {
|
|
|
|
nsString str;
|
|
|
|
aConstraints.ToJSON(str);
|
|
|
|
|
|
|
|
LOG(LogLevel::Info, ("MediaStreamTrack %p ApplyConstraints() with "
|
|
|
|
"constraints %s", this, NS_ConvertUTF16toUTF8(str).get()));
|
|
|
|
}
|
|
|
|
|
2016-02-01 17:43:38 +03:00
|
|
|
nsPIDOMWindowInner* window = mOwningStream->GetParentObject();
|
|
|
|
return GetSource().ApplyConstraints(window, aConstraints, aRv);
|
2015-09-21 01:45:57 +03:00
|
|
|
}
|
|
|
|
|
2016-01-05 05:16:23 +03:00
|
|
|
MediaStreamGraph*
|
|
|
|
MediaStreamTrack::Graph()
|
|
|
|
{
|
|
|
|
return GetOwnedStream()->Graph();
|
|
|
|
}
|
|
|
|
|
2016-03-18 16:21:51 +03:00
|
|
|
MediaStreamGraphImpl*
|
|
|
|
MediaStreamTrack::GraphImpl()
|
|
|
|
{
|
|
|
|
return GetOwnedStream()->GraphImpl();
|
|
|
|
}
|
|
|
|
|
2016-01-22 07:28:57 +03:00
|
|
|
void
|
|
|
|
MediaStreamTrack::PrincipalChanged()
|
|
|
|
{
|
2016-03-16 18:08:43 +03:00
|
|
|
LOG(LogLevel::Info, ("MediaStreamTrack %p Principal changed. Now: "
|
|
|
|
"null=%d, codebase=%d, expanded=%d, system=%d", this,
|
|
|
|
GetPrincipal()->GetIsNullPrincipal(),
|
|
|
|
GetPrincipal()->GetIsCodebasePrincipal(),
|
|
|
|
GetPrincipal()->GetIsExpandedPrincipal(),
|
|
|
|
GetPrincipal()->GetIsSystemPrincipal()));
|
2016-01-22 07:28:57 +03:00
|
|
|
for (PrincipalChangeObserver<MediaStreamTrack>* observer
|
|
|
|
: mPrincipalChangeObservers) {
|
|
|
|
observer->PrincipalChanged(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-22 06:24:16 +03:00
|
|
|
bool
|
|
|
|
MediaStreamTrack::AddPrincipalChangeObserver(
|
|
|
|
PrincipalChangeObserver<MediaStreamTrack>* aObserver)
|
|
|
|
{
|
|
|
|
return mPrincipalChangeObservers.AppendElement(aObserver) != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
MediaStreamTrack::RemovePrincipalChangeObserver(
|
|
|
|
PrincipalChangeObserver<MediaStreamTrack>* aObserver)
|
|
|
|
{
|
|
|
|
return mPrincipalChangeObservers.RemoveElement(aObserver);
|
|
|
|
}
|
|
|
|
|
2016-01-22 11:27:51 +03:00
|
|
|
already_AddRefed<MediaStreamTrack>
|
|
|
|
MediaStreamTrack::Clone()
|
|
|
|
{
|
|
|
|
// MediaStreamTracks are currently governed by streams, so we need a dummy
|
|
|
|
// DOMMediaStream to own our track clone. The dummy will never see any
|
|
|
|
// dynamically created tracks (no input stream) so no need for a SourceGetter.
|
|
|
|
RefPtr<DOMMediaStream> newStream =
|
|
|
|
new DOMMediaStream(mOwningStream->GetParentObject(), nullptr);
|
|
|
|
|
|
|
|
MediaStreamGraph* graph = Graph();
|
|
|
|
newStream->InitOwnedStreamCommon(graph);
|
|
|
|
newStream->InitPlaybackStreamCommon(graph);
|
|
|
|
|
2016-01-05 05:16:26 +03:00
|
|
|
return newStream->CloneDOMTrack(*this, mTrackID);
|
2016-01-22 11:27:51 +03:00
|
|
|
}
|
|
|
|
|
2016-01-05 05:16:22 +03:00
|
|
|
DOMMediaStream*
|
|
|
|
MediaStreamTrack::GetInputDOMStream()
|
|
|
|
{
|
|
|
|
MediaStreamTrack* originalTrack =
|
|
|
|
mOriginalTrack ? mOriginalTrack.get() : this;
|
2016-02-01 17:48:05 +03:00
|
|
|
MOZ_RELEASE_ASSERT(originalTrack->mOwningStream);
|
|
|
|
return originalTrack->mOwningStream;
|
2016-01-05 05:16:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
MediaStream*
|
|
|
|
MediaStreamTrack::GetInputStream()
|
|
|
|
{
|
|
|
|
DOMMediaStream* inputDOMStream = GetInputDOMStream();
|
|
|
|
MOZ_RELEASE_ASSERT(inputDOMStream->GetInputStream());
|
|
|
|
return inputDOMStream->GetInputStream();
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessedMediaStream*
|
|
|
|
MediaStreamTrack::GetOwnedStream()
|
|
|
|
{
|
2016-02-01 17:48:05 +03:00
|
|
|
return mOwningStream->GetOwnedStream();
|
2016-01-05 05:16:22 +03:00
|
|
|
}
|
|
|
|
|
2016-03-03 19:27:59 +03:00
|
|
|
void
|
|
|
|
MediaStreamTrack::AddListener(MediaStreamTrackListener* aListener)
|
|
|
|
{
|
|
|
|
LOG(LogLevel::Debug, ("MediaStreamTrack %p adding listener %p",
|
|
|
|
this, aListener));
|
|
|
|
|
|
|
|
GetOwnedStream()->AddTrackListener(aListener, mTrackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MediaStreamTrack::RemoveListener(MediaStreamTrackListener* aListener)
|
|
|
|
{
|
|
|
|
LOG(LogLevel::Debug, ("MediaStreamTrack %p removing listener %p",
|
|
|
|
this, aListener));
|
|
|
|
|
|
|
|
GetOwnedStream()->RemoveTrackListener(aListener, mTrackID);
|
|
|
|
}
|
|
|
|
|
2016-03-03 19:28:37 +03:00
|
|
|
void
|
|
|
|
MediaStreamTrack::AddDirectListener(MediaStreamTrackDirectListener *aListener)
|
|
|
|
{
|
|
|
|
LOG(LogLevel::Debug, ("MediaStreamTrack %p (%s) adding direct listener %p to "
|
|
|
|
"stream %p, track %d",
|
|
|
|
this, AsAudioStreamTrack() ? "audio" : "video",
|
|
|
|
aListener, GetOwnedStream(), mTrackID));
|
|
|
|
|
|
|
|
GetOwnedStream()->AddDirectTrackListener(aListener, mTrackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MediaStreamTrack::RemoveDirectListener(MediaStreamTrackDirectListener *aListener)
|
|
|
|
{
|
|
|
|
LOG(LogLevel::Debug, ("MediaStreamTrack %p removing direct listener %p from stream %p",
|
|
|
|
this, aListener, GetOwnedStream()));
|
|
|
|
|
|
|
|
GetOwnedStream()->RemoveDirectTrackListener(aListener, mTrackID);
|
|
|
|
}
|
|
|
|
|
2016-01-05 05:16:27 +03:00
|
|
|
already_AddRefed<MediaInputPort>
|
|
|
|
MediaStreamTrack::ForwardTrackContentsTo(ProcessedMediaStream* aStream)
|
|
|
|
{
|
2016-01-05 05:16:29 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2016-01-05 05:16:27 +03:00
|
|
|
MOZ_RELEASE_ASSERT(aStream);
|
|
|
|
RefPtr<MediaInputPort> port =
|
|
|
|
aStream->AllocateInputPort(GetOwnedStream(), mTrackID);
|
|
|
|
return port.forget();
|
|
|
|
}
|
|
|
|
|
2016-01-05 05:16:29 +03:00
|
|
|
bool
|
|
|
|
MediaStreamTrack::IsForwardedThrough(MediaInputPort* aPort)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPort);
|
|
|
|
if (!aPort) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return aPort->GetSource() == GetOwnedStream() &&
|
|
|
|
aPort->PassTrackThrough(mTrackID);
|
|
|
|
}
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|