/* static */ ProfileHashtable* GonkRecorderProfile::GetProfileHashtable(uint32_t aCameraId) { ProfileHashtable* profiles = sProfiles.Get(aCameraId); if (!profiles) { profiles = new ProfileHashtable; sProfiles.Put(aCameraId, profiles); for (uint32_t i = 0; ProfileList[i].name; ++i) { if (IsProfileSupported(aCameraId, i)) { DOM_CAMERA_LOGI("Profile %d '%s' supported by platform\n", i, ProfileList[i].name); nsAutoString name; name.AssignASCII(ProfileList[i].name); nsRefPtr<GonkRecorderProfile> profile = new GonkRecorderProfile(aCameraId, i, name); if (!profile->IsValid()) { DOM_CAMERA_LOGE("Profile %d '%s' is not valid\n", i, ProfileList[i].name); continue; } profiles->Put(name, profile); } else { DOM_CAMERA_LOGI("Profile %d '%s' not supported by platform\n", i, ProfileList[i].name); } } } return profiles; }
/* static */ nsresult GonkRecorderProfile::GetAll(uint32_t aCameraId, nsTArray<nsRefPtr<ICameraControl::RecorderProfile>>& aProfiles) { ProfileHashtable* profiles = GetProfileHashtable(aCameraId); if (!profiles) { return NS_ERROR_FAILURE; } aProfiles.Clear(); profiles->EnumerateRead(Enumerate, static_cast<void*>(&aProfiles)); return NS_OK; }
/* static */ nsresult GonkRecorderProfile::GetAll(uint32_t aCameraId, nsTArray<RefPtr<ICameraControl::RecorderProfile>>& aProfiles) { ProfileHashtable* profiles = GetProfileHashtable(aCameraId); if (!profiles) { return NS_ERROR_FAILURE; } aProfiles.Clear(); for (auto iter = profiles->Iter(); !iter.Done(); iter.Next()) { aProfiles.AppendElement(iter.UserData()); } return NS_OK; }
/* static */ nsresult GonkRecorderProfile::ConfigureRecorder(android::GonkRecorder& aRecorder, uint32_t aCameraId, const nsAString& aProfileName) { ProfileHashtable* profiles = GetProfileHashtable(aCameraId); if (!profiles) { return NS_ERROR_FAILURE; } GonkRecorderProfile* profile; if (!profiles->Get(aProfileName, &profile)) { return NS_ERROR_INVALID_ARG; } return profile->ConfigureRecorder(aRecorder); }
/* static */ ProfileHashtable* GonkRecorderProfile::GetProfileHashtable(uint32_t aCameraId) { ProfileHashtable* profiles = sProfiles.Get(aCameraId); if (!profiles) { profiles = new ProfileHashtable(); sProfiles.Put(aCameraId, profiles); /* First handle the profiles with a known enum. We can process those efficently because MediaProfiles indexes their profiles that way. */ int highestKnownQuality = CAMCORDER_QUALITY_LIST_START - 1; for (size_t i = 0; i < ProfileListSize; ++i) { const ProfileConfig& p = ProfileList[i]; if (p.quality > highestKnownQuality) { highestKnownQuality = p.quality; } nsRefPtr<GonkRecorderProfile> profile = CreateProfile(aCameraId, p.quality); if (!profile) { continue; } DOM_CAMERA_LOGI("Profile %d '%s' supported by platform\n", p.quality, p.name); profile->mName.AssignASCII(p.name); profiles->Put(profile->GetName(), profile); } /* However not all of the potentially supported profiles have a known enum on all of our supported platforms because some entries may be missing from MediaProfiles.h. As such, we can't rely upon having the CAMCORDER_QUALITY_* enums for those profiles. We need to map the profiles to a name by matching the width and height of the video resolution to our configured values. In theory there may be collisions given that there can be multiple resolutions sharing the same name (e.g. 800x480 and 768x480 are both wvga). In practice this should not happen because there should be only one WVGA profile given there is only one enum for it. In the situation there is a collision, it will merely select the last detected profile. */ for (int q = highestKnownQuality + 1; q <= CAMCORDER_QUALITY_LIST_END; ++q) { nsRefPtr<GonkRecorderProfile> profile = CreateProfile(aCameraId, q); if (!profile) { continue; } const ICameraControl::Size& s = profile->GetVideo().GetSize(); size_t match; for (match = 0; match < ProfileListDetectSize; ++match) { const ProfileConfigDetect& p = ProfileListDetect[match]; if (s.width == p.width && s.height == p.height) { DOM_CAMERA_LOGI("Profile %d '%s' supported by platform\n", q, p.name); profile->mName.AssignASCII(p.name); profiles->Put(profile->GetName(), profile); break; } } if (match == ProfileListDetectSize) { DOM_CAMERA_LOGW("Profile %d size %u x %u is not recognized\n", q, s.width, s.height); } } } return profiles; }