Bug 1003274 - Part 1 - refactor template types. r=jesup

This commit is contained in:
Jan-Ivar Bruaroey 2014-09-24 11:17:33 -04:00
parent 8503f27bad
commit e4823c6f2c
2 changed files with 88 additions and 90 deletions

View File

@ -287,7 +287,7 @@ public:
uint64_t aWindowID, uint64_t aWindowID,
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback>& aSuccess, nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback>& aSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError, nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
nsTArray<nsCOMPtr<nsIMediaDevice> >* aDevices) nsTArray<nsRefPtr<MediaDevice>>* aDevices)
: mDevices(aDevices) : mDevices(aDevices)
, mWindowID(aWindowID) , mWindowID(aWindowID)
, mManager(MediaManager::GetInstance()) , mManager(MediaManager::GetInstance())
@ -338,7 +338,7 @@ public:
private: private:
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mSuccess; nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError; nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsAutoPtr<nsTArray<nsCOMPtr<nsIMediaDevice> > > mDevices; nsAutoPtr<nsTArray<nsRefPtr<MediaDevice>>> mDevices;
uint64_t mWindowID; uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; nsRefPtr<MediaManager> mManager;
}; };
@ -371,14 +371,6 @@ protected:
*/ */
NS_IMPL_ISUPPORTS(MediaDevice, nsIMediaDevice) NS_IMPL_ISUPPORTS(MediaDevice, nsIMediaDevice)
MediaDevice* MediaDevice::Create(MediaEngineVideoSource* source) {
return new VideoDevice(source);
}
MediaDevice* MediaDevice::Create(MediaEngineAudioSource* source) {
return new AudioDevice(source);
}
MediaDevice::MediaDevice(MediaEngineSource* aSource) MediaDevice::MediaDevice(MediaEngineSource* aSource)
: mHasFacingMode(false) : mHasFacingMode(false)
, mSource(aSource) { , mSource(aSource) {
@ -421,9 +413,44 @@ VideoDevice::VideoDevice(MediaEngineVideoSource* aSource)
mMediaSource = aSource->GetMediaSource(); mMediaSource = aSource->GetMediaSource();
} }
/**
* Helper functions that implement the constraints algorithm from
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
*/
// Reminder: add handling for new constraints both here and in GetSources below!
bool
VideoDevice::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints)
{
if (aConstraints.mFacingMode.WasPassed()) {
nsString s;
GetFacingMode(s);
if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
uint32_t(aConstraints.mFacingMode.Value())].value)) {
return false;
}
}
nsString s;
GetMediaSource(s);
if (!s.EqualsASCII(dom::MediaSourceEnumValues::strings[
uint32_t(aConstraints.mMediaSource)].value)) {
return false;
}
// TODO: Add more video-specific constraints
return true;
}
AudioDevice::AudioDevice(MediaEngineAudioSource* aSource) AudioDevice::AudioDevice(MediaEngineAudioSource* aSource)
: MediaDevice(aSource) {} : MediaDevice(aSource) {}
bool
AudioDevice::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints)
{
// TODO: Add audio-specific constraints
return true;
}
NS_IMETHODIMP NS_IMETHODIMP
MediaDevice::GetName(nsAString& aName) MediaDevice::GetName(nsAString& aName)
{ {
@ -484,16 +511,16 @@ MediaDevice::GetMediaSource(nsAString& aMediaSource)
return NS_OK; return NS_OK;
} }
MediaEngineVideoSource* VideoDevice::Source*
VideoDevice::GetSource() VideoDevice::GetSource()
{ {
return static_cast<MediaEngineVideoSource*>(&*mSource); return static_cast<Source*>(&*mSource);
} }
MediaEngineAudioSource* AudioDevice::Source*
AudioDevice::GetSource() AudioDevice::GetSource()
{ {
return static_cast<MediaEngineAudioSource*>(&*mSource); return static_cast<Source*>(&*mSource);
} }
/** /**
@ -886,61 +913,24 @@ GetInvariant(const OwningBooleanOrMediaTrackConstraints &aUnion) {
aUnion.GetAsMediaTrackConstraints() : empty; aUnion.GetAsMediaTrackConstraints() : empty;
} }
/**
* Helper functions that implement the constraints algorithm from
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
*/
// Reminder: add handling for new constraints both here and in GetSources below!
static bool SatisfyConstraintSet(const MediaEngineVideoSource *,
const MediaTrackConstraintSet &aConstraints,
nsIMediaDevice &aCandidate)
{
nsString s;
if (aConstraints.mFacingMode.WasPassed()) {
aCandidate.GetFacingMode(s);
if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
uint32_t(aConstraints.mFacingMode.Value())].value)) {
return false;
}
}
aCandidate.GetMediaSource(s);
if (!s.EqualsASCII(dom::MediaSourceEnumValues::strings[
uint32_t(aConstraints.mMediaSource)].value)) {
return false;
}
// TODO: Add more video-specific constraints
return true;
}
static bool SatisfyConstraintSet(const MediaEngineAudioSource *,
const MediaTrackConstraintSet &aConstraints,
nsIMediaDevice &aCandidate)
{
// TODO: Add audio-specific constraints
return true;
}
typedef nsTArray<nsCOMPtr<nsIMediaDevice> > SourceSet;
// Source getter that constrains list returned // Source getter that constrains list returned
template<class SourceType, class ConstraintsType> template<class DeviceType, class ConstraintsType>
static SourceSet * static void
GetSources(MediaEngine *engine, GetSources(MediaEngine *engine,
ConstraintsType &aConstraints, ConstraintsType &aConstraints,
void (MediaEngine::* aEnumerate)(MediaSourceType, nsTArray<nsRefPtr<SourceType> >*), void (MediaEngine::* aEnumerate)(MediaSourceType,
nsTArray<nsRefPtr<typename DeviceType::Source> >*),
nsTArray<nsRefPtr<DeviceType>>& aResult,
const char* media_device_name = nullptr) const char* media_device_name = nullptr)
{ {
ScopedDeletePtr<SourceSet> result(new SourceSet); typedef nsTArray<nsRefPtr<DeviceType>> SourceSet;
const SourceType * const type = nullptr;
nsString deviceName; nsString deviceName;
// First collect sources // First collect sources
SourceSet candidateSet; SourceSet candidateSet;
{ {
nsTArray<nsRefPtr<SourceType> > sources; nsTArray<nsRefPtr<typename DeviceType::Source> > sources;
// all MediaSourceEnums are contained in MediaSourceType // all MediaSourceEnums are contained in MediaSourceType
(engine->*aEnumerate)((MediaSourceType)((int)aConstraints.mMediaSource), &sources); (engine->*aEnumerate)((MediaSourceType)((int)aConstraints.mMediaSource), &sources);
/** /**
@ -953,11 +943,11 @@ static SourceSet *
sources[i]->GetName(deviceName); sources[i]->GetName(deviceName);
if (media_device_name && strlen(media_device_name) > 0) { if (media_device_name && strlen(media_device_name) > 0) {
if (deviceName.EqualsASCII(media_device_name)) { if (deviceName.EqualsASCII(media_device_name)) {
candidateSet.AppendElement(MediaDevice::Create(sources[i])); candidateSet.AppendElement(new DeviceType(sources[i]));
break; break;
} }
} else { } else {
candidateSet.AppendElement(MediaDevice::Create(sources[i])); candidateSet.AppendElement(new DeviceType(sources[i]));
} }
} }
} }
@ -972,14 +962,14 @@ static SourceSet *
// which maximizes code-reuse by ignoring constraints of the other type // which maximizes code-reuse by ignoring constraints of the other type
// (specifically, SatisfyConstraintSet is reused for the advanced algorithm // (specifically, SatisfyConstraintSet is reused for the advanced algorithm
// where the spec requires it to ignore constraints of the other type) // where the spec requires it to ignore constraints of the other type)
return result.forget(); return;
} }
// Now on to the actual algorithm: First apply required constraints. // Now on to the actual algorithm: First apply required constraints.
for (uint32_t i = 0; i < candidateSet.Length();) { for (uint32_t i = 0; i < candidateSet.Length();) {
// Overloading instead of template specialization keeps things local // Overloading instead of template specialization keeps things local
if (!SatisfyConstraintSet(type, c.mRequired, *candidateSet[i])) { if (!candidateSet[i]->SatisfyConstraintSet(c.mRequired)) {
candidateSet.RemoveElementAt(i); candidateSet.RemoveElementAt(i);
} else { } else {
++i; ++i;
@ -1020,7 +1010,7 @@ static SourceSet *
for (int i = 0; i < int(array.Length()); i++) { for (int i = 0; i < int(array.Length()); i++) {
SourceSet rejects; SourceSet rejects;
for (uint32_t j = 0; j < candidateSet.Length();) { for (uint32_t j = 0; j < candidateSet.Length();) {
if (!SatisfyConstraintSet(type, array[i], *candidateSet[j])) { if (!candidateSet[j]->SatisfyConstraintSet(array[i])) {
rejects.AppendElement(candidateSet[j]); rejects.AppendElement(candidateSet[j]);
candidateSet.RemoveElementAt(j); candidateSet.RemoveElementAt(j);
} else { } else {
@ -1033,9 +1023,8 @@ static SourceSet *
// TODO: Proper non-ordered handling of nonrequired constraints (Bug 907352) // TODO: Proper non-ordered handling of nonrequired constraints (Bug 907352)
result->MoveElementsFrom(candidateSet); aResult.MoveElementsFrom(candidateSet);
result->MoveElementsFrom(tailSet); aResult.MoveElementsFrom(tailSet);
return result.forget();
} }
/** /**
@ -1193,29 +1182,28 @@ public:
MOZ_ASSERT(mError); MOZ_ASSERT(mError);
if (IsOn(mConstraints.mVideo)) { if (IsOn(mConstraints.mVideo)) {
VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo)); VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
ScopedDeletePtr<SourceSet> sources(GetSources(backend, constraints, nsTArray<nsRefPtr<VideoDevice>> sources;
&MediaEngine::EnumerateVideoDevices)); GetSources(backend, constraints, &MediaEngine::EnumerateVideoDevices, sources);
if (!sources->Length()) { if (!sources.Length()) {
Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND")); Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Pick the first available device. // Pick the first available device.
mVideoDevice = do_QueryObject((*sources)[0]); mVideoDevice = sources[0];
LOG(("Selected video device")); LOG(("Selected video device"));
} }
if (IsOn(mConstraints.mAudio)) { if (IsOn(mConstraints.mAudio)) {
AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio)); AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio));
ScopedDeletePtr<SourceSet> sources (GetSources(backend, constraints, nsTArray<nsRefPtr<AudioDevice>> sources;
&MediaEngine::EnumerateAudioDevices)); GetSources(backend, constraints, &MediaEngine::EnumerateAudioDevices, sources);
if (!sources->Length()) { if (!sources.Length()) {
Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND")); Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Pick the first available device. // Pick the first available device.
mAudioDevice = do_QueryObject((*sources)[0]); mAudioDevice = sources[0];
LOG(("Selected audio device")); LOG(("Selected audio device"));
} }
@ -1341,20 +1329,26 @@ public:
else else
backend = mManager->GetBackend(mWindowId); backend = mManager->GetBackend(mWindowId);
typedef nsTArray<nsRefPtr<MediaDevice>> SourceSet;
ScopedDeletePtr<SourceSet> final(new SourceSet); ScopedDeletePtr<SourceSet> final(new SourceSet);
if (IsOn(mConstraints.mVideo)) { if (IsOn(mConstraints.mVideo)) {
VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo)); VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
ScopedDeletePtr<SourceSet> s(GetSources(backend, constraints, nsTArray<nsRefPtr<VideoDevice>> s;
&MediaEngine::EnumerateVideoDevices, GetSources(backend, constraints, &MediaEngine::EnumerateVideoDevices, s,
mLoopbackVideoDevice.get())); mLoopbackVideoDevice.get());
final->MoveElementsFrom(*s); for (uint32_t i = 0; i < s.Length(); i++) {
final->AppendElement(s[i]);
}
} }
if (IsOn(mConstraints.mAudio)) { if (IsOn(mConstraints.mAudio)) {
AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio)); AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio));
ScopedDeletePtr<SourceSet> s (GetSources(backend, constraints, nsTArray<nsRefPtr<AudioDevice>> s;
&MediaEngine::EnumerateAudioDevices, GetSources(backend, constraints, &MediaEngine::EnumerateAudioDevices, s,
mLoopbackAudioDevice.get())); mLoopbackAudioDevice.get());
final->MoveElementsFrom(*s); for (uint32_t i = 0; i < s.Length(); i++) {
final->AppendElement(s[i]);
}
} }
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId, NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId,

View File

@ -46,6 +46,7 @@ namespace dom {
struct MediaStreamConstraints; struct MediaStreamConstraints;
class NavigatorUserMediaSuccessCallback; class NavigatorUserMediaSuccessCallback;
class NavigatorUserMediaErrorCallback; class NavigatorUserMediaErrorCallback;
struct MediaTrackConstraintSet;
} }
#ifdef PR_LOGGING #ifdef PR_LOGGING
@ -501,9 +502,6 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEDIADEVICE NS_DECL_NSIMEDIADEVICE
static MediaDevice* Create(MediaEngineVideoSource* source);
static MediaDevice* Create(MediaEngineAudioSource* source);
protected: protected:
virtual ~MediaDevice() {} virtual ~MediaDevice() {}
explicit MediaDevice(MediaEngineSource* aSource); explicit MediaDevice(MediaEngineSource* aSource);
@ -518,17 +516,23 @@ protected:
class VideoDevice : public MediaDevice class VideoDevice : public MediaDevice
{ {
public: public:
explicit VideoDevice(MediaEngineVideoSource* aSource); typedef MediaEngineVideoSource Source;
explicit VideoDevice(Source* aSource);
NS_IMETHOD GetType(nsAString& aType); NS_IMETHOD GetType(nsAString& aType);
MediaEngineVideoSource* GetSource(); Source* GetSource();
bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet &aConstraints);
}; };
class AudioDevice : public MediaDevice class AudioDevice : public MediaDevice
{ {
public: public:
explicit AudioDevice(MediaEngineAudioSource* aSource); typedef MediaEngineAudioSource Source;
explicit AudioDevice(Source* aSource);
NS_IMETHOD GetType(nsAString& aType); NS_IMETHOD GetType(nsAString& aType);
MediaEngineAudioSource* GetSource(); Source* GetSource();
bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet &aConstraints);
}; };
// we could add MediaManager if needed // we could add MediaManager if needed