Bug 1003274 - Part 2 - clue camera selection in to width/height code. r=jesup

This commit is contained in:
Jan-Ivar Bruaroey 2014-09-24 19:00:02 -04:00
Родитель e4823c6f2c
Коммит 39f5aa8cc8
8 изменённых файлов: 104 добавлений и 30 удалений

Просмотреть файл

@ -230,6 +230,10 @@ public:
/* This call reserves but does not start the device. */
virtual nsresult Allocate(const VideoTrackConstraintsN &aConstraints,
const MediaEnginePrefs &aPrefs) = 0;
virtual bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets) = 0;
protected:
explicit MediaEngineVideoSource(MediaEngineState aState)
: MediaEngineSource(aState) {}

Просмотреть файл

@ -55,6 +55,11 @@ public:
TrackID aId,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime);
virtual bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets)
{
return true;
}
virtual bool IsFake() {
return true;

Просмотреть файл

@ -64,6 +64,11 @@ public:
TrackID aId,
StreamTime aDesiredTime,
TrackTicks& aLastEndTime) MOZ_OVERRIDE;
virtual bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets)
{
return true;
}
void OnHardwareStateChange(HardwareState aState);
void GetRotation();

Просмотреть файл

@ -32,6 +32,11 @@ class MediaEngineTabVideoSource : public MediaEngineVideoSource, nsIDOMEventList
virtual const MediaSourceType GetMediaSource() {
return MediaSourceType::Browser;
}
virtual bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets)
{
return true;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback)
{

Просмотреть файл

@ -110,6 +110,9 @@ public:
void Refresh(int aIndex);
bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets);
protected:
~MediaEngineWebRTCVideoSource() { Shutdown(); }
@ -128,8 +131,8 @@ private:
int mMinFps; // Min rate we want to accept
MediaSourceType mMediaSource; // source of media (camera | application | screen)
static bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet& aConstraints,
const webrtc::CaptureCapability& aCandidate);
static bool SatisfiesConstraintSet(const dom::MediaTrackConstraintSet& aConstraints,
const webrtc::CaptureCapability& aCandidate);
void ChooseCapability(const VideoTrackConstraintsN& aConstraints,
const MediaEnginePrefs& aPrefs);
};

Просмотреть файл

@ -148,8 +148,9 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph,
}
/*static*/
bool MediaEngineWebRTCVideoSource::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints,
const webrtc::CaptureCapability& aCandidate) {
bool
MediaEngineWebRTCVideoSource::SatisfiesConstraintSet(const MediaTrackConstraintSet &aConstraints,
const webrtc::CaptureCapability& aCandidate) {
if (!MediaEngineCameraVideoSource::IsWithin(aCandidate.width, aConstraints.mWidth) ||
!MediaEngineCameraVideoSource::IsWithin(aCandidate.height, aConstraints.mHeight)) {
return false;
@ -160,6 +161,41 @@ bool MediaEngineWebRTCVideoSource::SatisfyConstraintSet(const MediaTrackConstrai
return true;
}
typedef nsTArray<uint8_t> CapabilitySet;
// SatisfiesConstraintSets (plural) answers for the capture device as a whole
// whether it can satisfy an accumulated number of capabilitySets.
bool
MediaEngineWebRTCVideoSource::SatisfiesConstraintSets(
const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets)
{
NS_ConvertUTF16toUTF8 uniqueId(mUniqueId);
int num = mViECapture->NumberOfCapabilities(uniqueId.get(), kMaxUniqueIdLength);
if (num <= 0) {
return true;
}
CapabilitySet candidateSet;
for (int i = 0; i < num; i++) {
candidateSet.AppendElement(i);
}
for (size_t j = 0; j < aConstraintSets.Length(); j++) {
for (size_t i = 0; i < candidateSet.Length(); ) {
webrtc::CaptureCapability cap;
mViECapture->GetCaptureCapability(uniqueId.get(), kMaxUniqueIdLength,
candidateSet[i], cap);
if (!SatisfiesConstraintSet(*aConstraintSets[j], cap)) {
candidateSet.RemoveElementAt(i);
} else {
++i;
}
}
}
return !!candidateSet.Length();
}
void
MediaEngineWebRTCVideoSource::ChooseCapability(
const VideoTrackConstraintsN &aConstraints,
@ -177,9 +213,7 @@ MediaEngineWebRTCVideoSource::ChooseCapability(
LOG(("ChooseCapability: prefs: %dx%d @%d-%dfps",
aPrefs.mWidth, aPrefs.mHeight, aPrefs.mFPS, aPrefs.mMinFPS));
typedef nsTArray<uint8_t> SourceSet;
SourceSet candidateSet;
CapabilitySet candidateSet;
for (int i = 0; i < num; i++) {
candidateSet.AppendElement(i);
}
@ -190,14 +224,14 @@ MediaEngineWebRTCVideoSource::ChooseCapability(
webrtc::CaptureCapability cap;
mViECapture->GetCaptureCapability(uniqueId.get(), kMaxUniqueIdLength,
candidateSet[i], cap);
if (!SatisfyConstraintSet(aConstraints.mRequired, cap)) {
if (!SatisfiesConstraintSet(aConstraints.mRequired, cap)) {
candidateSet.RemoveElementAt(i);
} else {
++i;
}
}
SourceSet tailSet;
CapabilitySet tailSet;
// Then apply advanced (formerly known as optional) constraints.
@ -205,12 +239,12 @@ MediaEngineWebRTCVideoSource::ChooseCapability(
auto &array = aConstraints.mAdvanced.Value();
for (uint32_t i = 0; i < array.Length(); i++) {
SourceSet rejects;
CapabilitySet rejects;
for (uint32_t j = 0; j < candidateSet.Length();) {
webrtc::CaptureCapability cap;
mViECapture->GetCaptureCapability(uniqueId.get(), kMaxUniqueIdLength,
candidateSet[j], cap);
if (!SatisfyConstraintSet(array[i], cap)) {
if (!SatisfiesConstraintSet(array[i], cap)) {
rejects.AppendElement(candidateSet[j]);
candidateSet.RemoveElementAt(j);
} else {

Просмотреть файл

@ -421,31 +421,37 @@ VideoDevice::VideoDevice(MediaEngineVideoSource* aSource)
// Reminder: add handling for new constraints both here and in GetSources below!
bool
VideoDevice::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints)
VideoDevice::SatisfiesConstraintSets(
const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets)
{
if (aConstraints.mFacingMode.WasPassed()) {
// Interrogate device-inherent properties first.
for (size_t i = 0; i < aConstraintSets.Length(); i++) {
auto& c = *aConstraintSets[i];
if (c.mFacingMode.WasPassed()) {
nsString s;
GetFacingMode(s);
if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
static_cast<uint32_t>(c.mFacingMode.Value())].value)) {
return false;
}
}
nsString s;
GetFacingMode(s);
if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
uint32_t(aConstraints.mFacingMode.Value())].value)) {
GetMediaSource(s);
if (!s.EqualsASCII(dom::MediaSourceEnumValues::strings[
static_cast<uint32_t>(c.mMediaSource)].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;
// Forward request to underlying object to interrogate per-mode capabilities.
return GetSource()->SatisfiesConstraintSets(aConstraintSets);
}
AudioDevice::AudioDevice(MediaEngineAudioSource* aSource)
: MediaDevice(aSource) {}
bool
AudioDevice::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints)
AudioDevice::SatisfiesConstraintSets(
const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets)
{
// TODO: Add audio-specific constraints
return true;
@ -960,16 +966,22 @@ static void
// this media-type. The spec requires these to fail, so getting them out of
// the way early provides a necessary invariant for the remaining algorithm
// which maximizes code-reuse by ignoring constraints of the other type
// (specifically, SatisfyConstraintSet is reused for the advanced algorithm
// (specifically, SatisfiesConstraintSets is reused for the advanced algorithm
// where the spec requires it to ignore constraints of the other type)
return;
}
// Now on to the actual algorithm: First apply required constraints.
// Stack constraintSets that pass, starting with the required one, because the
// whole stack must be re-satisfied each time a capability-set is ruled out
// (this avoids storing state and pushing algorithm into the lower-level code).
nsTArray<const MediaTrackConstraintSet*> aggregateConstraints;
aggregateConstraints.AppendElement(&c.mRequired);
for (uint32_t i = 0; i < candidateSet.Length();) {
// Overloading instead of template specialization keeps things local
if (!candidateSet[i]->SatisfyConstraintSet(c.mRequired)) {
if (!candidateSet[i]->SatisfiesConstraintSets(aggregateConstraints)) {
candidateSet.RemoveElementAt(i);
} else {
++i;
@ -1008,9 +1020,10 @@ static void
auto &array = c.mAdvanced.Value();
for (int i = 0; i < int(array.Length()); i++) {
aggregateConstraints.AppendElement(&array[i]);
SourceSet rejects;
for (uint32_t j = 0; j < candidateSet.Length();) {
if (!candidateSet[j]->SatisfyConstraintSet(array[i])) {
if (!candidateSet[j]->SatisfiesConstraintSets(aggregateConstraints)) {
rejects.AppendElement(candidateSet[j]);
candidateSet.RemoveElementAt(j);
} else {
@ -1018,6 +1031,9 @@ static void
}
}
(candidateSet.Length()? tailSet : candidateSet).MoveElementsFrom(rejects);
if (!candidateSet.Length()) {
aggregateConstraints.RemoveElementAt(aggregateConstraints.Length() - 1);
}
}
}

Просмотреть файл

@ -521,7 +521,8 @@ public:
explicit VideoDevice(Source* aSource);
NS_IMETHOD GetType(nsAString& aType);
Source* GetSource();
bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet &aConstraints);
bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets);
};
class AudioDevice : public MediaDevice
@ -532,7 +533,8 @@ public:
explicit AudioDevice(Source* aSource);
NS_IMETHOD GetType(nsAString& aType);
Source* GetSource();
bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet &aConstraints);
bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets);
};
// we could add MediaManager if needed