зеркало из https://github.com/mozilla/gecko-dev.git
Bug 981047 - enable torch mode in low light when video recording, r=dhylands,ehsan
This commit is contained in:
Родитель
71ed594d07
Коммит
24839a6b12
|
@ -581,7 +581,7 @@ MediaEngineWebRTCVideoSource::StartImpl(webrtc::CaptureCapability aCapability) {
|
|||
config.mPreviewSize.width = aCapability.width;
|
||||
config.mPreviewSize.height = aCapability.height;
|
||||
mCameraControl->Start(&config);
|
||||
mCameraControl->Set(CAMERA_PARAM_PICTURESIZE, config.mPreviewSize);
|
||||
mCameraControl->Set(CAMERA_PARAM_PICTURE_SIZE, config.mPreviewSize);
|
||||
|
||||
hal::RegisterScreenConfigurationObserver(this);
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ nsDOMCameraControl::GetPictureSize(JSContext* cx, ErrorResult& aRv)
|
|||
JS::Rooted<JS::Value> value(cx);
|
||||
|
||||
ICameraControl::Size size;
|
||||
aRv = mCameraControl->Get(CAMERA_PARAM_PICTURESIZE, size);
|
||||
aRv = mCameraControl->Get(CAMERA_PARAM_PICTURE_SIZE, size);
|
||||
if (aRv.Failed()) {
|
||||
return value;
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ nsDOMCameraControl::SetPictureSize(JSContext* aCx, JS::Handle<JS::Value> aSize,
|
|||
}
|
||||
|
||||
ICameraControl::Size s = { size.mWidth, size.mHeight };
|
||||
aRv = mCameraControl->Set(CAMERA_PARAM_PICTURESIZE, s);
|
||||
aRv = mCameraControl->Set(CAMERA_PARAM_PICTURE_SIZE, s);
|
||||
}
|
||||
|
||||
/* attribute any thumbnailSize */
|
||||
|
@ -764,6 +764,7 @@ nsDOMCameraControl::OnCreatedFileDescriptor(bool aSucceeded)
|
|||
o.rotation = mOptions.mRotation;
|
||||
o.maxFileSizeBytes = mOptions.mMaxFileSizeBytes;
|
||||
o.maxVideoLengthMs = mOptions.mMaxVideoLengthMs;
|
||||
o.autoEnableLowLightTorch = mOptions.mAutoEnableLowLightTorch;
|
||||
nsresult rv = mCameraControl->StartRecording(mDSFileDescriptor.get(), &o);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return;
|
||||
|
|
|
@ -65,6 +65,9 @@ nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId)
|
|||
, mLastThumbnailSize({0, 0})
|
||||
, mPreviewFps(30)
|
||||
, mResumePreviewAfterTakingPicture(false) // XXXmikeh - see bug 950102
|
||||
, mFlashSupported(false)
|
||||
, mLuminanceSupported(false)
|
||||
, mAutoFlashModeOverridden(false)
|
||||
, mDeferConfigUpdate(0)
|
||||
, mMediaProfiles(nullptr)
|
||||
, mRecorder(nullptr)
|
||||
|
@ -153,6 +156,14 @@ nsGonkCameraControl::Initialize()
|
|||
mParams.Get(CAMERA_PARAM_PREVIEWSIZE, mCurrentConfiguration.mPreviewSize);
|
||||
mParams.Get(CAMERA_PARAM_VIDEOSIZE, mLastRecorderSize);
|
||||
|
||||
nsString luminance; // check for support
|
||||
mParams.Get(CAMERA_PARAM_LUMINANCE, luminance);
|
||||
mLuminanceSupported = !luminance.IsEmpty();
|
||||
|
||||
nsString flashMode;
|
||||
mParams.Get(CAMERA_PARAM_FLASHMODE, flashMode);
|
||||
mFlashSupported = !flashMode.IsEmpty();
|
||||
|
||||
DOM_CAMERA_LOGI(" - maximum metering areas: %u\n", mCurrentConfiguration.mMaxMeteringAreas);
|
||||
DOM_CAMERA_LOGI(" - maximum focus areas: %u\n", mCurrentConfiguration.mMaxFocusAreas);
|
||||
DOM_CAMERA_LOGI(" - default picture size: %u x %u\n",
|
||||
|
@ -165,6 +176,14 @@ nsGonkCameraControl::Initialize()
|
|||
mLastRecorderSize.width, mLastRecorderSize.height);
|
||||
DOM_CAMERA_LOGI(" - default picture file format: %s\n",
|
||||
NS_ConvertUTF16toUTF8(mFileFormat).get());
|
||||
DOM_CAMERA_LOGI(" - luminance reporting: %ssupported\n",
|
||||
mLuminanceSupported ? "" : "NOT ");
|
||||
if (mFlashSupported) {
|
||||
DOM_CAMERA_LOGI(" - flash: supported, default mode '%s'\n",
|
||||
NS_ConvertUTF16toUTF8(flashMode).get());
|
||||
} else {
|
||||
DOM_CAMERA_LOGI(" - flash: NOT supported\n");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -382,9 +401,16 @@ nsGonkCameraControl::Set(uint32_t aKey, const nsAString& aValue)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (aKey == CAMERA_PARAM_PICTURE_FILEFORMAT) {
|
||||
// Picture format -- need to keep it for the TakePicture() callback.
|
||||
mFileFormat = aValue;
|
||||
switch (aKey) {
|
||||
case CAMERA_PARAM_PICTURE_FILEFORMAT:
|
||||
// Picture format -- need to keep it for the TakePicture() callback.
|
||||
mFileFormat = aValue;
|
||||
break;
|
||||
|
||||
case CAMERA_PARAM_FLASHMODE:
|
||||
// Explicit flash mode changes always win and stick.
|
||||
mAutoFlashModeOverridden = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return PushParameters();
|
||||
|
@ -440,7 +466,7 @@ nsresult
|
|||
nsGonkCameraControl::Set(uint32_t aKey, const Size& aSize)
|
||||
{
|
||||
switch (aKey) {
|
||||
case CAMERA_PARAM_PICTURESIZE:
|
||||
case CAMERA_PARAM_PICTURE_SIZE:
|
||||
DOM_CAMERA_LOGI("setting picture size to %ux%u\n", aSize.width, aSize.height);
|
||||
return SetPictureSize(aSize);
|
||||
|
||||
|
@ -752,7 +778,7 @@ nsGonkCameraControl::SetPictureSizeImpl(const Size& aSize)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = mParams.Set(CAMERA_PARAM_PICTURESIZE, size);
|
||||
nsresult rv = mParams.Set(CAMERA_PARAM_PICTURE_SIZE, size);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -865,10 +891,56 @@ nsGonkCameraControl::PullParametersImpl()
|
|||
return mCameraHw->PullParameters(mParams);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetupRecordingFlash(bool aAutoEnableLowLightTorch)
|
||||
{
|
||||
mAutoFlashModeOverridden = false;
|
||||
|
||||
if (!aAutoEnableLowLightTorch || !mLuminanceSupported || !mFlashSupported) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DOM_CAMERA_LOGI("Luminance reporting and flash supported\n");
|
||||
|
||||
nsresult rv = PullParametersImpl();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsString luminance;
|
||||
rv = mParams.Get(CAMERA_PARAM_LUMINANCE, luminance);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If we failed to get the luminance, assume it's "high"
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsString flashMode;
|
||||
rv = mParams.Get(CAMERA_PARAM_FLASHMODE, flashMode);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If we failed to get the current flash mode, swallow the error
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (luminance.EqualsASCII("low") && flashMode.EqualsASCII("auto")) {
|
||||
DOM_CAMERA_LOGI("Low luminance detected, turning on flash\n");
|
||||
rv = SetAndPush(CAMERA_PARAM_FLASHMODE, NS_LITERAL_STRING("torch"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If we failed to turn on the flash, swallow the error
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mAutoFlashModeOverridden = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
NS_ENSURE_TRUE(mRecorderProfile, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_FALSE(mRecorder, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -905,15 +977,24 @@ nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescri
|
|||
if (aOptions) {
|
||||
rv = SetupRecording(fd, aOptions->rotation, aOptions->maxFileSizeBytes,
|
||||
aOptions->maxVideoLengthMs);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = SetupRecordingFlash(aOptions->autoEnableLowLightTorch);
|
||||
}
|
||||
} else {
|
||||
rv = SetupRecording(fd, 0, 0, 0);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mRecorder->start() != OK) {
|
||||
DOM_CAMERA_LOGE("mRecorder->start() failed\n");
|
||||
// important: we MUST destroy the recorder if start() fails!
|
||||
mRecorder = nullptr;
|
||||
// put the flash back to the 'auto' state
|
||||
if (mAutoFlashModeOverridden) {
|
||||
SetAndPush(CAMERA_PARAM_FLASHMODE, NS_LITERAL_STRING("auto"));
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -956,6 +1037,10 @@ nsGonkCameraControl::StopRecordingImpl()
|
|||
mRecorder = nullptr;
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStopped);
|
||||
|
||||
if (mAutoFlashModeOverridden) {
|
||||
SetAndPush(CAMERA_PARAM_FLASHMODE, NS_LITERAL_STRING("auto"));
|
||||
}
|
||||
|
||||
// notify DeviceStorage that the new video file is closed and ready
|
||||
return NS_DispatchToMainThread(new RecordingComplete(mVideoFile), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
@ -1430,7 +1515,9 @@ nsGonkCameraControl::OnRecorderEvent(int msg, int ext1, int ext2)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs)
|
||||
nsGonkCameraControl::SetupRecording(int aFd, int aRotation,
|
||||
int64_t aMaxFileSizeBytes,
|
||||
int64_t aMaxVideoLengthMs)
|
||||
{
|
||||
RETURN_IF_NO_CAMERA_HW();
|
||||
|
||||
|
@ -1473,6 +1560,7 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation, int64_t aMaxFileSize
|
|||
// recording API needs file descriptor of output file
|
||||
CHECK_SETARG(mRecorder->setOutputFile(aFd, 0, 0));
|
||||
CHECK_SETARG(mRecorder->prepare());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1482,12 +1570,7 @@ nsGonkCameraControl::StopImpl()
|
|||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
|
||||
// if we're recording, stop recording
|
||||
if (mRecorder) {
|
||||
DOM_CAMERA_LOGI("Stopping existing video recorder\n");
|
||||
mRecorder->stop();
|
||||
mRecorder = nullptr;
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStopped);
|
||||
}
|
||||
StopRecordingImpl();
|
||||
|
||||
// stop the preview
|
||||
StopPreviewImpl();
|
||||
|
|
|
@ -117,7 +117,9 @@ protected:
|
|||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE;
|
||||
already_AddRefed<GonkRecorderProfileManager> GetGonkRecorderProfileManager();
|
||||
|
||||
nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs);
|
||||
nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes,
|
||||
int64_t aMaxVideoLengthMs);
|
||||
nsresult SetupRecordingFlash(bool aAutoEnableLowLightTorch);
|
||||
nsresult SetupVideoMode(const nsAString& aProfile);
|
||||
nsresult SetPreviewSize(const Size& aSize);
|
||||
nsresult SetVideoSize(const Size& aSize);
|
||||
|
@ -141,6 +143,9 @@ protected:
|
|||
Size mLastRecorderSize;
|
||||
uint32_t mPreviewFps;
|
||||
bool mResumePreviewAfterTakingPicture;
|
||||
bool mFlashSupported;
|
||||
bool mLuminanceSupported;
|
||||
bool mAutoFlashModeOverridden;
|
||||
|
||||
Atomic<uint32_t> mDeferConfigUpdate;
|
||||
GonkCameraParameters mParams;
|
||||
|
|
|
@ -58,8 +58,6 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
|||
return KEY_FOCUS_DISTANCES;
|
||||
case CAMERA_PARAM_EXPOSURECOMPENSATION:
|
||||
return KEY_EXPOSURE_COMPENSATION;
|
||||
case CAMERA_PARAM_PICTURESIZE:
|
||||
return KEY_PICTURE_SIZE;
|
||||
case CAMERA_PARAM_THUMBNAILQUALITY:
|
||||
return KEY_JPEG_THUMBNAIL_QUALITY;
|
||||
case CAMERA_PARAM_PICTURE_SIZE:
|
||||
|
@ -81,6 +79,8 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
|||
// Not every platform defines KEY_ISO_MODE;
|
||||
// for those that don't, we use the raw string key.
|
||||
return "iso";
|
||||
case CAMERA_PARAM_LUMINANCE:
|
||||
return "luminance-condition";
|
||||
|
||||
case CAMERA_PARAM_SUPPORTED_PREVIEWSIZES:
|
||||
return KEY_SUPPORTED_PREVIEW_SIZES;
|
||||
|
@ -266,8 +266,10 @@ GonkCameraParameters::GetTranslated(uint32_t aKey, nsAString& aValue)
|
|||
}
|
||||
if (aKey == CAMERA_PARAM_ISOMODE) {
|
||||
rv = MapIsoFromGonk(val, aValue);
|
||||
} else {
|
||||
} else if(val) {
|
||||
aValue.AssignASCII(val);
|
||||
} else {
|
||||
aValue.Truncate(0);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -46,11 +46,11 @@ enum {
|
|||
CAMERA_PARAM_FOCUSDISTANCEOPTIMUM,
|
||||
CAMERA_PARAM_FOCUSDISTANCEFAR,
|
||||
CAMERA_PARAM_EXPOSURECOMPENSATION,
|
||||
CAMERA_PARAM_PICTURESIZE,
|
||||
CAMERA_PARAM_THUMBNAILSIZE,
|
||||
CAMERA_PARAM_THUMBNAILQUALITY,
|
||||
CAMERA_PARAM_SENSORANGLE,
|
||||
CAMERA_PARAM_ISOMODE,
|
||||
CAMERA_PARAM_LUMINANCE,
|
||||
|
||||
// supported features
|
||||
CAMERA_PARAM_SUPPORTED_PREVIEWSIZES,
|
||||
|
@ -113,6 +113,7 @@ public:
|
|||
uint32_t rotation;
|
||||
uint32_t maxFileSizeBytes;
|
||||
uint32_t maxVideoLengthMs;
|
||||
bool autoEnableLowLightTorch;
|
||||
};
|
||||
|
||||
struct Configuration {
|
||||
|
|
|
@ -72,26 +72,6 @@ dictionary CameraPictureOptions
|
|||
long long dateTime = 0;
|
||||
};
|
||||
|
||||
/* These properties affect the video recording preview, e.g.
|
||||
{
|
||||
profile: "1080p",
|
||||
rotation: 0
|
||||
}
|
||||
|
||||
'profile' is one of the profiles returned by
|
||||
CameraCapabilities.recorderProfiles'; if this profile is missing,
|
||||
an arbitrary profile will be chosen.
|
||||
|
||||
'rotation' is the degrees clockwise to rotate the preview; if
|
||||
this option is not supported, it will be ignored; if this option
|
||||
is missing, the default is 0.
|
||||
*/
|
||||
dictionary CameraRecorderOptions
|
||||
{
|
||||
DOMString profile;
|
||||
long rotation;
|
||||
};
|
||||
|
||||
/* These properties affect the actual video recording, e.g.
|
||||
{
|
||||
rotation: 0,
|
||||
|
@ -117,6 +97,15 @@ dictionary CameraStartRecordingOptions
|
|||
long rotation = 0;
|
||||
long long maxFileSizeBytes = 0;
|
||||
long long maxVideoLengthMs = 0;
|
||||
|
||||
/* If startRecording() is called with flashMode set to "auto" and the
|
||||
camera has determined that the scene is poorly lit, the flash mode
|
||||
will be automatically changed to "torch" until stopRecording() is
|
||||
called. During this time, flashMode will reflect the new setting. If
|
||||
flashMode is changed while recording is in progress, the new setting
|
||||
will be left as-is on stopRecording(). If the camera does not
|
||||
support this setting, it will be ignored. */
|
||||
boolean autoEnableLowLightTorch = false;
|
||||
};
|
||||
|
||||
callback CameraSetConfigurationCallback = void (CameraConfiguration configuration);
|
||||
|
|
Загрузка…
Ссылка в новой задаче