зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1003274 - Part 2 - clue camera selection in to width/height code. r=jesup
This commit is contained in:
Родитель
e4823c6f2c
Коммит
39f5aa8cc8
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче