mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 3fde6fc99b0a (bug 1020368) for non-unified bustage.
This commit is contained in:
parent
e7353cb4a6
commit
418030317f
@ -208,22 +208,6 @@ DOMInterfaces = {
|
||||
'headerFile': 'DOMCameraManager.h'
|
||||
},
|
||||
|
||||
'CameraRecorderAudioProfile': {
|
||||
'headerFile': 'DOMCameraCapabilities.h'
|
||||
},
|
||||
|
||||
'CameraRecorderProfile': {
|
||||
'headerFile': 'DOMCameraCapabilities.h'
|
||||
},
|
||||
|
||||
'CameraRecorderProfiles': {
|
||||
'headerFile': 'DOMCameraCapabilities.h'
|
||||
},
|
||||
|
||||
'CameraRecorderVideoProfile': {
|
||||
'headerFile': 'DOMCameraCapabilities.h'
|
||||
},
|
||||
|
||||
'CanvasRenderingContext2D': {
|
||||
'implicitJSContext': [
|
||||
'createImageData', 'getImageData'
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "CameraRecorderProfiles.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
@ -64,6 +65,12 @@ CameraControlImpl::~CameraControlImpl()
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<RecorderProfileManager>
|
||||
CameraControlImpl::GetRecorderProfileManager()
|
||||
{
|
||||
return GetRecorderProfileManagerImpl();
|
||||
}
|
||||
|
||||
void
|
||||
CameraControlImpl::Shutdown()
|
||||
{
|
||||
@ -107,7 +114,7 @@ CameraControlImpl::OnConfigurationChange()
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
RwLockAutoEnterRead lock(mListenerLock);
|
||||
|
||||
DOM_CAMERA_LOGI("OnConfigurationChange : %zu listeners\n", mListeners.Length());
|
||||
DOM_CAMERA_LOGI("OnConfigurationChange : %d listeners\n", mListeners.Length());
|
||||
|
||||
for (uint32_t i = 0; i < mListeners.Length(); ++i) {
|
||||
CameraControlListener* l = mListeners[i];
|
||||
@ -262,7 +269,7 @@ CameraControlImpl::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uin
|
||||
// On Gonk, it is called from the camera driver's preview thread.
|
||||
RwLockAutoEnterRead lock(mListenerLock);
|
||||
|
||||
DOM_CAMERA_LOGI("OnNewPreviewFrame: we have %zu preview frame listener(s)\n",
|
||||
DOM_CAMERA_LOGI("OnNewPreviewFrame: we have %d preview frame listener(s)\n",
|
||||
mListeners.Length());
|
||||
|
||||
bool consumed = false;
|
||||
|
@ -25,6 +25,8 @@ namespace layers {
|
||||
class Image;
|
||||
}
|
||||
|
||||
class RecorderProfileManager;
|
||||
|
||||
class CameraControlImpl : public ICameraControl
|
||||
{
|
||||
public:
|
||||
@ -47,6 +49,7 @@ public:
|
||||
virtual nsresult StopRecording() MOZ_OVERRIDE;
|
||||
virtual nsresult ResumeContinuousFocus() MOZ_OVERRIDE;
|
||||
|
||||
already_AddRefed<RecorderProfileManager> GetRecorderProfileManager();
|
||||
uint32_t GetCameraId() { return mCameraId; }
|
||||
|
||||
virtual void Shutdown() MOZ_OVERRIDE;
|
||||
@ -125,6 +128,8 @@ protected:
|
||||
virtual nsresult PushParametersImpl() = 0;
|
||||
virtual nsresult PullParametersImpl() = 0;
|
||||
|
||||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() = 0;
|
||||
|
||||
void OnShutterInternal();
|
||||
void OnClosedInternal();
|
||||
|
||||
|
@ -34,8 +34,8 @@ public:
|
||||
|
||||
enum HardwareState
|
||||
{
|
||||
kHardwareClosed,
|
||||
kHardwareOpen
|
||||
kHardwareOpen,
|
||||
kHardwareClosed
|
||||
};
|
||||
virtual void OnHardwareStateChange(HardwareState aState) { }
|
||||
|
||||
|
195
dom/camera/CameraRecorderProfiles.cpp
Normal file
195
dom/camera/CameraRecorderProfiles.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CameraRecorderProfiles.h"
|
||||
#include "jsapi.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/**
|
||||
* Video profile implementation.
|
||||
*/
|
||||
RecorderVideoProfile::RecorderVideoProfile(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: mCameraId(aCameraId)
|
||||
, mQualityIndex(aQualityIndex)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
RecorderVideoProfile::~RecorderVideoProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RecorderVideoProfile::GetJsObject(JSContext* aCx, JSObject** aObject)
|
||||
{
|
||||
NS_ENSURE_TRUE(aObject, NS_ERROR_INVALID_ARG);
|
||||
|
||||
JS::Rooted<JSObject*> o(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
NS_ENSURE_TRUE(o, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
const char* codec = GetCodecName();
|
||||
NS_ENSURE_TRUE(codec, NS_ERROR_FAILURE);
|
||||
|
||||
JS::Rooted<JSString*> s(aCx, JS_NewStringCopyZ(aCx, codec));
|
||||
JS::Rooted<JS::Value> v(aCx, STRING_TO_JSVAL(s));
|
||||
if (!JS_SetProperty(aCx, o, "codec", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mBitrate != -1) {
|
||||
v = INT_TO_JSVAL(mBitrate);
|
||||
if (!JS_SetProperty(aCx, o, "bitrate", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
if (mFramerate != -1) {
|
||||
v = INT_TO_JSVAL(mFramerate);
|
||||
if (!JS_SetProperty(aCx, o, "framerate", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
if (mWidth != -1) {
|
||||
v = INT_TO_JSVAL(mWidth);
|
||||
if (!JS_SetProperty(aCx, o, "width", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
if (mHeight != -1) {
|
||||
v = INT_TO_JSVAL(mHeight);
|
||||
if (!JS_SetProperty(aCx, o, "height", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
*aObject = o;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Audio profile implementation.
|
||||
*/
|
||||
RecorderAudioProfile::RecorderAudioProfile(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: mCameraId(aCameraId)
|
||||
, mQualityIndex(aQualityIndex)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
RecorderAudioProfile::~RecorderAudioProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RecorderAudioProfile::GetJsObject(JSContext* aCx, JSObject** aObject)
|
||||
{
|
||||
NS_ENSURE_TRUE(aObject, NS_ERROR_INVALID_ARG);
|
||||
|
||||
JS::Rooted<JSObject*> o(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
NS_ENSURE_TRUE(o, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
const char* codec = GetCodecName();
|
||||
NS_ENSURE_TRUE(codec, NS_ERROR_FAILURE);
|
||||
|
||||
JS::Rooted<JSString*> s(aCx, JS_NewStringCopyZ(aCx, codec));
|
||||
JS::Rooted<JS::Value> v(aCx, STRING_TO_JSVAL(s));
|
||||
if (!JS_SetProperty(aCx, o, "codec", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mBitrate != -1) {
|
||||
v = INT_TO_JSVAL(mBitrate);
|
||||
if (!JS_SetProperty(aCx, o, "bitrate", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
if (mSamplerate != -1) {
|
||||
v = INT_TO_JSVAL(mSamplerate);
|
||||
if (!JS_SetProperty(aCx, o, "samplerate", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
if (mChannels != -1) {
|
||||
v = INT_TO_JSVAL(mChannels);
|
||||
if (!JS_SetProperty(aCx, o, "channels", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
*aObject = o;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recorder Profile
|
||||
*/
|
||||
RecorderProfile::RecorderProfile(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: mCameraId(aCameraId)
|
||||
, mQualityIndex(aQualityIndex)
|
||||
, mName(nullptr)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
RecorderProfile::~RecorderProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recorder profile manager implementation.
|
||||
*/
|
||||
RecorderProfileManager::RecorderProfileManager(uint32_t aCameraId)
|
||||
: mCameraId(aCameraId)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
RecorderProfileManager::~RecorderProfileManager()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RecorderProfileManager::GetJsObject(JSContext* aCx, JSObject** aObject) const
|
||||
{
|
||||
NS_ENSURE_TRUE(aObject, NS_ERROR_INVALID_ARG);
|
||||
|
||||
JS::Rooted<JSObject*> o(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
if (!o) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (uint32_t q = 0; q < GetMaxQualityIndex(); ++q) {
|
||||
if (!IsSupported(q)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsRefPtr<RecorderProfile> profile = Get(q);
|
||||
if (!profile) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
const char* profileName = profile->GetName();
|
||||
if (!profileName) {
|
||||
// don't allow anonymous recorder profiles
|
||||
continue;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> p(aCx);
|
||||
nsresult rv = profile->GetJsObject(aCx, p.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
JS::Rooted<JS::Value> v(aCx, OBJECT_TO_JSVAL(p));
|
||||
|
||||
if (!JS_SetProperty(aCx, o, profileName, v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
*aObject = o;
|
||||
return NS_OK;
|
||||
}
|
274
dom/camera/CameraRecorderProfiles.h
Normal file
274
dom/camera/CameraRecorderProfiles.h
Normal file
@ -0,0 +1,274 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DOM_CAMERA_CAMERA_RECORDER_PROFILES_H
|
||||
#define DOM_CAMERA_CAMERA_RECORDER_PROFILES_H
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "jsapi.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class CameraControlImpl;
|
||||
|
||||
class RecorderVideoProfile
|
||||
{
|
||||
public:
|
||||
RecorderVideoProfile(uint32_t aCameraId, uint32_t aQualityIndex);
|
||||
virtual ~RecorderVideoProfile();
|
||||
|
||||
int GetBitrate() const { return mBitrate; }
|
||||
int GetFramerate() const { return mFramerate; }
|
||||
int GetWidth() const { return mWidth; }
|
||||
int GetHeight() const { return mHeight; }
|
||||
|
||||
enum Codec {
|
||||
H263,
|
||||
H264,
|
||||
MPEG4SP,
|
||||
UNKNOWN
|
||||
};
|
||||
Codec GetCodec() const { return mCodec; }
|
||||
const char* GetCodecName() const
|
||||
{
|
||||
switch (mCodec) {
|
||||
case H263: return "h263";
|
||||
case H264: return "h264";
|
||||
case MPEG4SP: return "mpeg4sp";
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Get a representation of this video profile that can be returned
|
||||
// to JS, possibly as a child member of another object.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if 'aObject' is null;
|
||||
// - NS_ERROR_OUT_OF_MEMORY if a new object could not be allocated;
|
||||
// - NS_ERROR_FAILURE if construction of the JS object fails.
|
||||
nsresult GetJsObject(JSContext* aCx, JSObject** aObject);
|
||||
|
||||
protected:
|
||||
uint32_t mCameraId;
|
||||
uint32_t mQualityIndex;
|
||||
Codec mCodec;
|
||||
int mBitrate;
|
||||
int mFramerate;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
};
|
||||
|
||||
class RecorderAudioProfile
|
||||
{
|
||||
public:
|
||||
RecorderAudioProfile(uint32_t aCameraId, uint32_t aQualityIndex);
|
||||
virtual ~RecorderAudioProfile();
|
||||
|
||||
int GetBitrate() const { return mBitrate; }
|
||||
int GetSamplerate() const { return mSamplerate; }
|
||||
int GetChannels() const { return mChannels; }
|
||||
|
||||
enum Codec {
|
||||
AMRNB,
|
||||
AMRWB,
|
||||
AAC,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
Codec GetCodec() const { return mCodec; }
|
||||
const char* GetCodecName() const
|
||||
{
|
||||
switch (mCodec) {
|
||||
case AMRNB: return "amrnb";
|
||||
case AMRWB: return "amrwb";
|
||||
case AAC: return "aac";
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Get a representation of this audio profile that can be returned
|
||||
// to JS, possibly as a child member of another object.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if 'aObject' is null;
|
||||
// - NS_ERROR_OUT_OF_MEMORY if a new object could not be allocated;
|
||||
// - NS_ERROR_FAILURE if construction of the JS object fails.
|
||||
nsresult GetJsObject(JSContext* aCx, JSObject** aObject);
|
||||
|
||||
protected:
|
||||
uint32_t mCameraId;
|
||||
uint32_t mQualityIndex;
|
||||
Codec mCodec;
|
||||
int mBitrate;
|
||||
int mSamplerate;
|
||||
int mChannels;
|
||||
};
|
||||
|
||||
class RecorderProfile
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RecorderProfile)
|
||||
|
||||
RecorderProfile(uint32_t aCameraId, uint32_t aQualityIndex);
|
||||
|
||||
virtual const RecorderVideoProfile* GetVideoProfile() const = 0;
|
||||
virtual const RecorderAudioProfile* GetAudioProfile() const = 0;
|
||||
const char* GetName() const { return mName; }
|
||||
|
||||
enum FileFormat {
|
||||
THREE_GPP,
|
||||
MPEG4,
|
||||
UNKNOWN
|
||||
};
|
||||
FileFormat GetFileFormat() const { return mFileFormat; }
|
||||
const char* GetFileFormatName() const
|
||||
{
|
||||
switch (mFileFormat) {
|
||||
case THREE_GPP: return "3gp";
|
||||
case MPEG4: return "mp4";
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
const char* GetFileMimeType() const
|
||||
{
|
||||
switch (mFileFormat) {
|
||||
case THREE_GPP: return VIDEO_3GPP;
|
||||
case MPEG4: return VIDEO_MP4;
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Get a representation of this recorder profile that can be returned
|
||||
// to JS, possibly as a child member of another object.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if 'aObject' is null;
|
||||
// - NS_ERROR_OUT_OF_MEMORY if a new object could not be allocated;
|
||||
// - NS_ERROR_FAILURE if construction of the JS object fails.
|
||||
virtual nsresult GetJsObject(JSContext* aCx, JSObject** aObject) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~RecorderProfile();
|
||||
|
||||
uint32_t mCameraId;
|
||||
uint32_t mQualityIndex;
|
||||
const char* mName;
|
||||
FileFormat mFileFormat;
|
||||
};
|
||||
|
||||
template <class Audio, class Video>
|
||||
class RecorderProfileBase : public RecorderProfile
|
||||
{
|
||||
public:
|
||||
RecorderProfileBase(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: RecorderProfile(aCameraId, aQualityIndex)
|
||||
, mVideo(aCameraId, aQualityIndex)
|
||||
, mAudio(aCameraId, aQualityIndex)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
virtual ~RecorderProfileBase()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
const RecorderVideoProfile* GetVideoProfile() const { return &mVideo; }
|
||||
const RecorderAudioProfile* GetAudioProfile() const { return &mAudio; }
|
||||
|
||||
// Get a representation of this recorder profile that can be returned
|
||||
// to JS, possibly as a child member of another object.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if 'aObject' is null;
|
||||
// - NS_ERROR_OUT_OF_MEMORY if a new object could not be allocated;
|
||||
// - NS_ERROR_NOT_AVAILABLE if the profile has no file format name;
|
||||
// - NS_ERROR_FAILURE if construction of the JS object fails.
|
||||
nsresult
|
||||
GetJsObject(JSContext* aCx, JSObject** aObject)
|
||||
{
|
||||
NS_ENSURE_TRUE(aObject, NS_ERROR_INVALID_ARG);
|
||||
|
||||
const char* format = GetFileFormatName();
|
||||
if (!format) {
|
||||
// the profile must have a file format
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> o(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
if (!o) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS::Rooted<JSString*> s(aCx, JS_NewStringCopyZ(aCx, format));
|
||||
JS::Rooted<JS::Value> v(aCx, STRING_TO_JSVAL(s));
|
||||
if (!JS_SetProperty(aCx, o, "format", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> video(aCx);
|
||||
nsresult rv = mVideo.GetJsObject(aCx, video.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
v = OBJECT_TO_JSVAL(video);
|
||||
if (!JS_SetProperty(aCx, o, "video", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> audio(aCx);
|
||||
rv = mAudio.GetJsObject(aCx, audio.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
v = OBJECT_TO_JSVAL(audio);
|
||||
if (!JS_SetProperty(aCx, o, "audio", v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aObject = o;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
Video mVideo;
|
||||
Audio mAudio;
|
||||
};
|
||||
|
||||
class RecorderProfileManager
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RecorderProfileManager)
|
||||
|
||||
virtual bool IsSupported(uint32_t aQualityIndex) const { return true; }
|
||||
virtual already_AddRefed<RecorderProfile> Get(uint32_t aQualityIndex) const = 0;
|
||||
|
||||
uint32_t GetMaxQualityIndex() const { return mMaxQualityIndex; }
|
||||
|
||||
// Get a representation of all supported recorder profiles that can be
|
||||
// returned to JS.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if 'aObject' is null;
|
||||
// - NS_ERROR_OUT_OF_MEMORY if a new object could not be allocated;
|
||||
// - NS_ERROR_NOT_AVAILABLE if the profile has no file format name;
|
||||
// - NS_ERROR_FAILURE if construction of the JS object fails.
|
||||
nsresult GetJsObject(JSContext* aCx, JSObject** aObject) const;
|
||||
|
||||
protected:
|
||||
explicit RecorderProfileManager(uint32_t aCameraId);
|
||||
virtual ~RecorderProfileManager();
|
||||
|
||||
uint32_t mCameraId;
|
||||
uint32_t mMaxQualityIndex;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // DOM_CAMERA_CAMERA_RECORDER_PROFILES_H
|
@ -12,202 +12,28 @@
|
||||
#include "Navigator.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "CameraRecorderProfiles.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* CameraRecorderVideoProfile
|
||||
*/
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CameraRecorderVideoProfile, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(CameraCapabilities)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRecorderVideoProfile)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderVideoProfile)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CameraCapabilities)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
|
||||
tmp->mRecorderProfiles = JS::UndefinedValue();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderVideoProfile)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CameraCapabilities)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
JSObject*
|
||||
CameraRecorderVideoProfile::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return CameraRecorderVideoProfileBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
CameraRecorderVideoProfile::CameraRecorderVideoProfile(nsISupports* aParent,
|
||||
const ICameraControl::RecorderProfile::Video& aProfile)
|
||||
: mParent(aParent)
|
||||
, mCodec(aProfile.GetCodec())
|
||||
, mBitrate(aProfile.GetBitsPerSecond())
|
||||
, mFramerate(aProfile.GetFramesPerSecond())
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
|
||||
mSize.mWidth = aProfile.GetSize().width;
|
||||
mSize.mHeight = aProfile.GetSize().height;
|
||||
|
||||
DOM_CAMERA_LOGI(" video: '%s' %ux%u bps=%u fps=%u\n",
|
||||
NS_ConvertUTF16toUTF8(mCodec).get(), mSize.mWidth, mSize.mHeight, mBitrate, mFramerate);
|
||||
}
|
||||
|
||||
CameraRecorderVideoProfile::~CameraRecorderVideoProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* CameraRecorderAudioProfile
|
||||
*/
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CameraRecorderAudioProfile, mParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRecorderAudioProfile)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderAudioProfile)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderAudioProfile)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
JSObject*
|
||||
CameraRecorderAudioProfile::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return CameraRecorderAudioProfileBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
CameraRecorderAudioProfile::CameraRecorderAudioProfile(nsISupports* aParent,
|
||||
const ICameraControl::RecorderProfile::Audio& aProfile)
|
||||
: mParent(aParent)
|
||||
, mCodec(aProfile.GetCodec())
|
||||
, mBitrate(aProfile.GetBitsPerSecond())
|
||||
, mSamplerate(aProfile.GetSamplesPerSecond())
|
||||
, mChannels(aProfile.GetChannels())
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
DOM_CAMERA_LOGI(" audio: '%s' bps=%u samples/s=%u channels=%u\n",
|
||||
NS_ConvertUTF16toUTF8(mCodec).get(), mBitrate, mSamplerate, mChannels);
|
||||
}
|
||||
|
||||
CameraRecorderAudioProfile::~CameraRecorderAudioProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* CameraRecorderProfile
|
||||
*/
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CameraRecorderProfile, mParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRecorderProfile)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderProfile)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderProfile)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
JSObject*
|
||||
CameraRecorderProfile::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return CameraRecorderProfileBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
CameraRecorderProfile::CameraRecorderProfile(nsISupports* aParent,
|
||||
const ICameraControl::RecorderProfile& aProfile)
|
||||
: mParent(aParent)
|
||||
, mName(aProfile.GetName())
|
||||
, mContainerFormat(aProfile.GetContainer())
|
||||
, mMimeType(aProfile.GetMimeType())
|
||||
, mVideo(new CameraRecorderVideoProfile(this, aProfile.GetVideo()))
|
||||
, mAudio(new CameraRecorderAudioProfile(this, aProfile.GetAudio()))
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
DOM_CAMERA_LOGI("profile: '%s' container=%s mime-type=%s\n",
|
||||
NS_ConvertUTF16toUTF8(mName).get(),
|
||||
NS_ConvertUTF16toUTF8(mContainerFormat).get(),
|
||||
NS_ConvertUTF16toUTF8(mMimeType).get());
|
||||
}
|
||||
|
||||
CameraRecorderProfile::~CameraRecorderProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* CameraRecorderProfiles
|
||||
*/
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CameraRecorderProfiles, mParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRecorderProfiles)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderProfiles)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderProfiles)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
JSObject*
|
||||
CameraRecorderProfiles::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return CameraRecorderProfilesBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
CameraRecorderProfiles::CameraRecorderProfiles(nsISupports* aParent,
|
||||
ICameraControl* aCameraControl)
|
||||
: mParent(aParent)
|
||||
, mCameraControl(aCameraControl)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
CameraRecorderProfiles::~CameraRecorderProfiles()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
void
|
||||
CameraRecorderProfiles::GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, flags=0x%x\n",
|
||||
__func__, __LINE__, this, aFlags);
|
||||
|
||||
nsresult rv = mCameraControl->GetRecorderProfiles(aNames);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aNames.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
CameraRecorderProfile*
|
||||
CameraRecorderProfiles::NamedGetter(const nsAString& aName, bool& aFound)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, name='%s'\n", __func__, __LINE__, this,
|
||||
NS_ConvertUTF16toUTF8(aName).get());
|
||||
|
||||
CameraRecorderProfile* profile = mProfiles.GetWeak(aName, &aFound);
|
||||
if (!aFound || !profile) {
|
||||
nsRefPtr<ICameraControl::RecorderProfile> p = mCameraControl->GetProfileInfo(aName);
|
||||
if (p) {
|
||||
profile = new CameraRecorderProfile(this, *p);
|
||||
mProfiles.Put(aName, profile);
|
||||
aFound = true;
|
||||
}
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
bool
|
||||
CameraRecorderProfiles::NameIsEnumerable(const nsAString& aName)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, name='%s' (always returns true)\n",
|
||||
__func__, __LINE__, this, NS_ConvertUTF16toUTF8(aName).get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* CameraCapabilities
|
||||
*/
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CameraCapabilities, mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CameraCapabilities)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mRecorderProfiles)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraCapabilities)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraCapabilities)
|
||||
@ -224,24 +50,20 @@ CameraCapabilities::HasSupport(JSContext* aCx, JSObject* aGlobal)
|
||||
return Navigator::HasCameraSupport(aCx, aGlobal);
|
||||
}
|
||||
|
||||
CameraCapabilities::CameraCapabilities(nsPIDOMWindow* aWindow,
|
||||
ICameraControl* aCameraControl)
|
||||
: mMaxFocusAreas(0)
|
||||
, mMaxMeteringAreas(0)
|
||||
, mMaxDetectedFaces(0)
|
||||
, mMinExposureCompensation(0.0)
|
||||
, mMaxExposureCompensation(0.0)
|
||||
, mExposureCompensationStep(0.0)
|
||||
CameraCapabilities::CameraCapabilities(nsPIDOMWindow* aWindow)
|
||||
: mRecorderProfiles(JS::UndefinedValue())
|
||||
, mWindow(aWindow)
|
||||
, mCameraControl(aCameraControl)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
MOZ_COUNT_CTOR(CameraCapabilities);
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
CameraCapabilities::~CameraCapabilities()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
mRecorderProfiles = JS::UndefinedValue();
|
||||
mozilla::DropJSObjects(this);
|
||||
MOZ_COUNT_DTOR(CameraCapabilities);
|
||||
}
|
||||
|
||||
@ -260,12 +82,13 @@ CameraCapabilities::WrapObject(JSContext* aCx)
|
||||
} while(0)
|
||||
|
||||
nsresult
|
||||
CameraCapabilities::TranslateToDictionary(uint32_t aKey, nsTArray<CameraSize>& aSizes)
|
||||
CameraCapabilities::TranslateToDictionary(ICameraControl* aCameraControl,
|
||||
uint32_t aKey, nsTArray<CameraSize>& aSizes)
|
||||
{
|
||||
nsresult rv;
|
||||
nsTArray<ICameraControl::Size> sizes;
|
||||
|
||||
rv = mCameraControl->Get(aKey, sizes);
|
||||
rv = aCameraControl->Get(aKey, sizes);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -281,218 +104,205 @@ CameraCapabilities::TranslateToDictionary(uint32_t aKey, nsTArray<CameraSize>& a
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetPreviewSizes(nsTArray<dom::CameraSize>& retval)
|
||||
nsresult
|
||||
CameraCapabilities::Populate(ICameraControl* aCameraControl)
|
||||
{
|
||||
if (mPreviewSizes.Length() == 0) {
|
||||
nsresult rv = TranslateToDictionary(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES,
|
||||
mPreviewSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES);
|
||||
NS_ENSURE_TRUE(aCameraControl, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, mPreviewSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES);
|
||||
|
||||
rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_PICTURESIZES, mPictureSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PICTURESIZES);
|
||||
|
||||
rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES, mThumbnailSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES);
|
||||
|
||||
rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_VIDEOSIZES, mVideoSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_VIDEOSIZES);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_PICTUREFORMATS, mFileFormats);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PICTUREFORMATS);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_WHITEBALANCES, mWhiteBalanceModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_WHITEBALANCES);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_SCENEMODES, mSceneModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_SCENEMODES);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_EFFECTS, mEffects);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_EFFECTS);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_FLASHMODES, mFlashModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_FLASHMODES);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_FOCUSMODES, mFocusModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_FOCUSMODES);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_ISOMODES, mIsoModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_ISOMODES);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_ZOOMRATIOS, mZoomRatios);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_ZOOMRATIOS);
|
||||
|
||||
int32_t areas;
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS, areas);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS);
|
||||
mMaxFocusAreas = areas < 0 ? 0 : areas;
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS, areas);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS);
|
||||
mMaxMeteringAreas = areas < 0 ? 0 : areas;
|
||||
|
||||
int32_t faces;
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES, faces);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES);
|
||||
mMaxDetectedFaces = faces < 0 ? 0 : faces;
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION, mMinExposureCompensation);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION, mMaxExposureCompensation);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION);
|
||||
|
||||
rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP, mExposureCompensationStep);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP);
|
||||
|
||||
mRecorderProfileManager = aCameraControl->GetRecorderProfileManager();
|
||||
if (!mRecorderProfileManager) {
|
||||
DOM_CAMERA_LOGW("Unable to get recorder profile manager\n");
|
||||
} else {
|
||||
AutoJSContext js;
|
||||
|
||||
JS::Rooted<JSObject*> o(js);
|
||||
nsresult rv = mRecorderProfileManager->GetJsObject(js, o.address());
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to JS-objectify profile manager (0x%x)\n", rv);
|
||||
} else {
|
||||
mRecorderProfiles = JS::ObjectValue(*o);
|
||||
}
|
||||
}
|
||||
|
||||
// For now, always return success, since the presence or absence of capabilities
|
||||
// indicates whether or not they are supported.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetPreviewSizes(nsTArray<dom::CameraSize>& retval) const
|
||||
{
|
||||
retval = mPreviewSizes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetPictureSizes(nsTArray<dom::CameraSize>& retval)
|
||||
CameraCapabilities::GetPictureSizes(nsTArray<dom::CameraSize>& retval) const
|
||||
{
|
||||
if (mPictureSizes.Length() == 0) {
|
||||
nsresult rv = TranslateToDictionary(CAMERA_PARAM_SUPPORTED_PICTURESIZES,
|
||||
mPictureSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PICTURESIZES);
|
||||
}
|
||||
retval = mPictureSizes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetThumbnailSizes(nsTArray<dom::CameraSize>& retval)
|
||||
CameraCapabilities::GetThumbnailSizes(nsTArray<dom::CameraSize>& retval) const
|
||||
{
|
||||
if (mThumbnailSizes.Length() == 0) {
|
||||
nsresult rv = TranslateToDictionary(CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES,
|
||||
mThumbnailSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES);
|
||||
}
|
||||
retval = mThumbnailSizes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetVideoSizes(nsTArray<dom::CameraSize>& retval)
|
||||
CameraCapabilities::GetVideoSizes(nsTArray<dom::CameraSize>& retval) const
|
||||
{
|
||||
if (mVideoSizes.Length() == 0) {
|
||||
nsresult rv = TranslateToDictionary(CAMERA_PARAM_SUPPORTED_VIDEOSIZES,
|
||||
mVideoSizes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_VIDEOSIZES);
|
||||
}
|
||||
retval = mVideoSizes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetFileFormats(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetFileFormats(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mFileFormats.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_PICTUREFORMATS,
|
||||
mFileFormats);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PICTUREFORMATS);
|
||||
}
|
||||
retval = mFileFormats;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetWhiteBalanceModes(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetWhiteBalanceModes(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mWhiteBalanceModes.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_WHITEBALANCES,
|
||||
mWhiteBalanceModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_WHITEBALANCES);
|
||||
}
|
||||
retval = mWhiteBalanceModes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetSceneModes(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetSceneModes(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mSceneModes.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_SCENEMODES,
|
||||
mSceneModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_SCENEMODES);
|
||||
}
|
||||
retval = mSceneModes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetEffects(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetEffects(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mEffects.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_EFFECTS,
|
||||
mEffects);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_EFFECTS);
|
||||
}
|
||||
retval = mEffects;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetFlashModes(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetFlashModes(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mFlashModes.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_FLASHMODES,
|
||||
mFlashModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_FLASHMODES);
|
||||
}
|
||||
retval = mFlashModes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetFocusModes(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetFocusModes(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mFocusModes.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_FOCUSMODES,
|
||||
mFocusModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_FOCUSMODES);
|
||||
}
|
||||
retval = mFocusModes;
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetZoomRatios(nsTArray<double>& retval)
|
||||
CameraCapabilities::GetZoomRatios(nsTArray<double>& retval) const
|
||||
{
|
||||
if (mZoomRatios.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_ZOOMRATIOS,
|
||||
mZoomRatios);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_ZOOMRATIOS);
|
||||
}
|
||||
retval = mZoomRatios;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CameraCapabilities::MaxFocusAreas()
|
||||
CameraCapabilities::MaxFocusAreas() const
|
||||
{
|
||||
if (mMaxFocusAreas == 0) {
|
||||
int32_t areas;
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS,
|
||||
areas);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS);
|
||||
mMaxFocusAreas = areas < 0 ? 0 : areas;
|
||||
}
|
||||
return mMaxFocusAreas;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CameraCapabilities::MaxMeteringAreas()
|
||||
CameraCapabilities::MaxMeteringAreas() const
|
||||
{
|
||||
if (mMaxMeteringAreas == 0) {
|
||||
int32_t areas;
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS,
|
||||
areas);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS);
|
||||
mMaxMeteringAreas = areas < 0 ? 0 : areas;
|
||||
}
|
||||
return mMaxMeteringAreas;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CameraCapabilities::MaxDetectedFaces()
|
||||
CameraCapabilities::MaxDetectedFaces() const
|
||||
{
|
||||
if (mMaxDetectedFaces == 0) {
|
||||
int32_t faces;
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES,
|
||||
faces);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES);
|
||||
mMaxDetectedFaces = faces < 0 ? 0 : faces;
|
||||
}
|
||||
return mMaxDetectedFaces;
|
||||
}
|
||||
|
||||
double
|
||||
CameraCapabilities::MinExposureCompensation()
|
||||
CameraCapabilities::MinExposureCompensation() const
|
||||
{
|
||||
if (mMinExposureCompensation == 0.0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION,
|
||||
mMinExposureCompensation);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION);
|
||||
}
|
||||
return mMinExposureCompensation;
|
||||
}
|
||||
|
||||
double
|
||||
CameraCapabilities::MaxExposureCompensation()
|
||||
CameraCapabilities::MaxExposureCompensation() const
|
||||
{
|
||||
if (mMaxExposureCompensation == 0.0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION,
|
||||
mMaxExposureCompensation);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION);
|
||||
}
|
||||
return mMaxExposureCompensation;
|
||||
}
|
||||
|
||||
double
|
||||
CameraCapabilities::ExposureCompensationStep()
|
||||
CameraCapabilities::ExposureCompensationStep() const
|
||||
{
|
||||
if (mExposureCompensationStep == 0.0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP,
|
||||
mExposureCompensationStep);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP);
|
||||
}
|
||||
return mExposureCompensationStep;
|
||||
}
|
||||
|
||||
CameraRecorderProfiles*
|
||||
CameraCapabilities::RecorderProfiles()
|
||||
void
|
||||
CameraCapabilities::GetRecorderProfiles(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aRetval) const
|
||||
{
|
||||
nsRefPtr<CameraRecorderProfiles> profiles = mRecorderProfiles;
|
||||
if (!mRecorderProfiles) {
|
||||
profiles = new CameraRecorderProfiles(this, mCameraControl);
|
||||
mRecorderProfiles = profiles;
|
||||
}
|
||||
return profiles;
|
||||
JS::ExposeValueToActiveJS(mRecorderProfiles);
|
||||
aRetval.set(mRecorderProfiles);
|
||||
}
|
||||
|
||||
void
|
||||
CameraCapabilities::GetIsoModes(nsTArray<nsString>& retval)
|
||||
CameraCapabilities::GetIsoModes(nsTArray<nsString>& retval) const
|
||||
{
|
||||
if (mIsoModes.Length() == 0) {
|
||||
nsresult rv = mCameraControl->Get(CAMERA_PARAM_SUPPORTED_ISOMODES,
|
||||
mIsoModes);
|
||||
LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_ISOMODES);
|
||||
}
|
||||
retval = mIsoModes;
|
||||
}
|
||||
|
||||
|
@ -9,173 +9,23 @@
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/CameraManagerBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "ICameraControl.h"
|
||||
|
||||
struct JSContext;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ICameraControl;
|
||||
class RecorderProfileManager;
|
||||
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* CameraRecorderVideoProfile
|
||||
*/
|
||||
class CameraRecorderVideoProfile MOZ_FINAL : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderVideoProfile)
|
||||
|
||||
explicit CameraRecorderVideoProfile(nsISupports* aParent,
|
||||
const ICameraControl::RecorderProfile::Video& aProfile);
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
uint32_t BitsPerSecond() const { return mBitrate; }
|
||||
uint32_t FramesPerSecond() const { return mFramerate; }
|
||||
void GetCodec(nsAString& aCodec) const { aCodec = mCodec; }
|
||||
|
||||
void GetSize(dom::CameraSize& aSize) const { aSize = mSize; }
|
||||
|
||||
// XXXmikeh - legacy, remove these when the Camera app is updated
|
||||
uint32_t Width() const { return mSize.mWidth; }
|
||||
uint32_t Height() const { return mSize.mHeight; }
|
||||
|
||||
protected:
|
||||
virtual ~CameraRecorderVideoProfile();
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
const nsString mCodec;
|
||||
uint32_t mBitrate;
|
||||
uint32_t mFramerate;
|
||||
dom::CameraSize mSize;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CameraRecorderVideoProfile);
|
||||
};
|
||||
|
||||
/**
|
||||
* CameraRecorderAudioProfile
|
||||
*/
|
||||
class CameraRecorderAudioProfile MOZ_FINAL : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderAudioProfile)
|
||||
|
||||
explicit CameraRecorderAudioProfile(nsISupports* aParent,
|
||||
const ICameraControl::RecorderProfile::Audio& aProfile);
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
uint32_t BitsPerSecond() const { return mBitrate; }
|
||||
uint32_t SamplesPerSecond() const { return mSamplerate; }
|
||||
uint32_t Channels() const { return mChannels; }
|
||||
void GetCodec(nsAString& aCodec) const { aCodec = mCodec; }
|
||||
|
||||
protected:
|
||||
virtual ~CameraRecorderAudioProfile();
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
const nsString mCodec;
|
||||
uint32_t mBitrate;
|
||||
uint32_t mSamplerate;
|
||||
uint32_t mChannels;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CameraRecorderAudioProfile);
|
||||
};
|
||||
|
||||
/**
|
||||
* CameraRecorderProfile
|
||||
*/
|
||||
class CameraRecorderProfile MOZ_FINAL : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderProfile)
|
||||
|
||||
explicit CameraRecorderProfile(nsISupports* aParent,
|
||||
const ICameraControl::RecorderProfile& aProfile);
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void GetMimeType(nsAString& aMimeType) const { aMimeType = mMimeType; }
|
||||
|
||||
CameraRecorderVideoProfile* Video() { return mVideo; }
|
||||
CameraRecorderAudioProfile* Audio() { return mAudio; }
|
||||
|
||||
void GetName(nsAString& aName) const { aName = mName; }
|
||||
|
||||
void
|
||||
GetContainerFormat(nsAString& aContainerFormat) const
|
||||
{
|
||||
aContainerFormat = mContainerFormat;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~CameraRecorderProfile();
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
const nsString mName;
|
||||
const nsString mContainerFormat;
|
||||
const nsString mMimeType;
|
||||
|
||||
nsRefPtr<CameraRecorderVideoProfile> mVideo;
|
||||
nsRefPtr<CameraRecorderAudioProfile> mAudio;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CameraRecorderProfile);
|
||||
};
|
||||
|
||||
/**
|
||||
* CameraRecorderProfiles
|
||||
*/
|
||||
class CameraRecorderProfiles MOZ_FINAL : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderProfiles)
|
||||
|
||||
explicit CameraRecorderProfiles(nsISupports* aParent,
|
||||
ICameraControl* aCameraControl);
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
CameraRecorderProfile* NamedGetter(const nsAString& aName, bool& aFound);
|
||||
bool NameIsEnumerable(const nsAString& aName);
|
||||
void GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames);
|
||||
|
||||
protected:
|
||||
virtual ~CameraRecorderProfiles();
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsRefPtr<ICameraControl> mCameraControl;
|
||||
nsRefPtrHashtable<nsStringHashKey, CameraRecorderProfile> mProfiles;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CameraRecorderProfiles);
|
||||
};
|
||||
|
||||
/**
|
||||
* CameraCapabilities
|
||||
*/
|
||||
class CameraCapabilities MOZ_FINAL : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
@ -190,38 +40,45 @@ public:
|
||||
// Great Renaming proposed in bug 983177.
|
||||
static bool HasSupport(JSContext* aCx, JSObject* aGlobal);
|
||||
|
||||
explicit CameraCapabilities(nsPIDOMWindow* aWindow,
|
||||
ICameraControl* aCameraControl);
|
||||
explicit CameraCapabilities(nsPIDOMWindow* aWindow);
|
||||
|
||||
// Populate the camera capabilities interface from the specific
|
||||
// camera control object.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if 'aCameraControl' is null.
|
||||
nsresult Populate(ICameraControl* aCameraControl);
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const { return mWindow; }
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void GetPreviewSizes(nsTArray<CameraSize>& aRetVal);
|
||||
void GetPictureSizes(nsTArray<CameraSize>& aRetVal);
|
||||
void GetThumbnailSizes(nsTArray<CameraSize>& aRetVal);
|
||||
void GetVideoSizes(nsTArray<CameraSize>& aRetVal);
|
||||
void GetFileFormats(nsTArray<nsString>& aRetVal);
|
||||
void GetWhiteBalanceModes(nsTArray<nsString>& aRetVal);
|
||||
void GetSceneModes(nsTArray<nsString>& aRetVal);
|
||||
void GetEffects(nsTArray<nsString>& aRetVal);
|
||||
void GetFlashModes(nsTArray<nsString>& aRetVal);
|
||||
void GetFocusModes(nsTArray<nsString>& aRetVal);
|
||||
void GetZoomRatios(nsTArray<double>& aRetVal);
|
||||
uint32_t MaxFocusAreas();
|
||||
uint32_t MaxMeteringAreas();
|
||||
uint32_t MaxDetectedFaces();
|
||||
double MinExposureCompensation();
|
||||
double MaxExposureCompensation();
|
||||
double ExposureCompensationStep();
|
||||
void GetIsoModes(nsTArray<nsString>& aRetVal);
|
||||
|
||||
CameraRecorderProfiles* RecorderProfiles();
|
||||
void GetPreviewSizes(nsTArray<CameraSize>& aRetVal) const;
|
||||
void GetPictureSizes(nsTArray<CameraSize>& aRetVal) const;
|
||||
void GetThumbnailSizes(nsTArray<CameraSize>& aRetVal) const;
|
||||
void GetVideoSizes(nsTArray<CameraSize>& aRetVal) const;
|
||||
void GetFileFormats(nsTArray<nsString>& aRetVal) const;
|
||||
void GetWhiteBalanceModes(nsTArray<nsString>& aRetVal) const;
|
||||
void GetSceneModes(nsTArray<nsString>& aRetVal) const;
|
||||
void GetEffects(nsTArray<nsString>& aRetVal) const;
|
||||
void GetFlashModes(nsTArray<nsString>& aRetVal) const;
|
||||
void GetFocusModes(nsTArray<nsString>& aRetVal) const;
|
||||
void GetZoomRatios(nsTArray<double>& aRetVal) const;
|
||||
uint32_t MaxFocusAreas() const;
|
||||
uint32_t MaxMeteringAreas() const;
|
||||
uint32_t MaxDetectedFaces() const;
|
||||
double MinExposureCompensation() const;
|
||||
double MaxExposureCompensation() const;
|
||||
double ExposureCompensationStep() const;
|
||||
void GetRecorderProfiles(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval) const;
|
||||
void GetIsoModes(nsTArray<nsString>& aRetVal) const;
|
||||
|
||||
protected:
|
||||
~CameraCapabilities();
|
||||
|
||||
nsresult TranslateToDictionary(uint32_t aKey, nsTArray<CameraSize>& aSizes);
|
||||
nsresult TranslateToDictionary(ICameraControl* aCameraControl,
|
||||
uint32_t aKey, nsTArray<CameraSize>& aSizes);
|
||||
|
||||
nsTArray<CameraSize> mPreviewSizes;
|
||||
nsTArray<CameraSize> mPictureSizes;
|
||||
@ -246,12 +103,10 @@ protected:
|
||||
double mMaxExposureCompensation;
|
||||
double mExposureCompensationStep;
|
||||
|
||||
nsRefPtr<nsPIDOMWindow> mWindow;
|
||||
nsRefPtr<ICameraControl> mCameraControl;
|
||||
nsRefPtr<CameraRecorderProfiles> mRecorderProfiles;
|
||||
nsRefPtr<RecorderProfileManager> mRecorderProfileManager;
|
||||
JS::Heap<JS::Value> mRecorderProfiles;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CameraCapabilities);
|
||||
nsRefPtr<nsPIDOMWindow> mWindow;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -664,7 +664,12 @@ nsDOMCameraControl::Capabilities()
|
||||
nsRefPtr<CameraCapabilities> caps = mCapabilities;
|
||||
|
||||
if (!caps) {
|
||||
caps = new CameraCapabilities(mWindow, mCameraControl);
|
||||
caps = new CameraCapabilities(mWindow);
|
||||
nsresult rv = caps->Populate(mCameraControl);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGW("Failed to populate camera capabilities (%d)\n", rv);
|
||||
return nullptr;
|
||||
}
|
||||
mCapabilities = caps;
|
||||
}
|
||||
|
||||
@ -1135,9 +1140,10 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ErrorResult ignored;
|
||||
|
||||
DOM_CAMERA_LOGI("DOM OnHardwareStateChange(%d)\n", aState);
|
||||
|
||||
switch (aState) {
|
||||
case CameraControlListener::kHardwareOpen:
|
||||
DOM_CAMERA_LOGI("DOM OnHardwareStateChange: open\n");
|
||||
{
|
||||
// The hardware is open, so we can return a camera to JS, even if
|
||||
// the preview hasn't started yet.
|
||||
@ -1158,7 +1164,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
||||
break;
|
||||
|
||||
case CameraControlListener::kHardwareClosed:
|
||||
DOM_CAMERA_LOGI("DOM OnHardwareStateChange: closed\n");
|
||||
{
|
||||
nsRefPtr<Promise> promise = mReleasePromise.forget();
|
||||
if (promise || mReleaseOnSuccessCb) {
|
||||
@ -1183,7 +1188,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
||||
break;
|
||||
|
||||
default:
|
||||
DOM_CAMERA_LOGE("DOM OnHardwareStateChange: UNKNOWN=%d\n", aState);
|
||||
MOZ_ASSERT_UNREACHABLE("Unanticipated camera hardware state");
|
||||
}
|
||||
}
|
||||
@ -1398,7 +1402,7 @@ nsDOMCameraControl::OnAutoFocusMoving(bool aIsMoving)
|
||||
void
|
||||
nsDOMCameraControl::OnFacesDetected(const nsTArray<ICameraControl::Face>& aFaces)
|
||||
{
|
||||
DOM_CAMERA_LOGI("DOM OnFacesDetected %zu face(s)\n", aFaces.Length());
|
||||
DOM_CAMERA_LOGI("DOM OnFacesDetected %u face(s)\n", aFaces.Length());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
Sequence<OwningNonNull<DOMCameraDetectedFace> > faces;
|
||||
|
@ -59,7 +59,7 @@ nsDOMCameraManager::nsDOMCameraManager(nsPIDOMWindow* aWindow)
|
||||
, mWindow(aWindow)
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, windowId=%" PRIx64 "\n", __func__, __LINE__, this, mWindowId);
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, windowId=%llx\n", __func__, __LINE__, this, mWindowId);
|
||||
MOZ_COUNT_CTOR(nsDOMCameraManager);
|
||||
}
|
||||
|
||||
@ -364,7 +364,7 @@ nsDOMCameraManager::PermissionCancelled(uint32_t aCameraId,
|
||||
void
|
||||
nsDOMCameraManager::Register(nsDOMCameraControl* aDOMCameraControl)
|
||||
{
|
||||
DOM_CAMERA_LOGI(">>> Register( aDOMCameraControl = %p ) mWindowId = 0x%" PRIx64 "\n", aDOMCameraControl, mWindowId);
|
||||
DOM_CAMERA_LOGI(">>> Register( aDOMCameraControl = %p ) mWindowId = 0x%llx\n", aDOMCameraControl, mWindowId);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Put the camera control into the hash table
|
||||
@ -379,7 +379,7 @@ nsDOMCameraManager::Register(nsDOMCameraControl* aDOMCameraControl)
|
||||
void
|
||||
nsDOMCameraManager::Shutdown(uint64_t aWindowId)
|
||||
{
|
||||
DOM_CAMERA_LOGI(">>> Shutdown( aWindowId = 0x%" PRIx64 " )\n", aWindowId);
|
||||
DOM_CAMERA_LOGI(">>> Shutdown( aWindowId = 0x%llx )\n", aWindowId);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
CameraControls* controls = sActiveWindows->Get(aWindowId);
|
||||
|
@ -45,9 +45,6 @@ public:
|
||||
virtual nsresult Get(uint32_t aKey, nsTArray<nsString>& aValues) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
virtual nsresult Get(uint32_t aKey, nsTArray<double>& aValues) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
virtual nsresult GetRecorderProfiles(nsTArray<nsString>& aProfiles) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
virtual RecorderProfile* GetProfileInfo(const nsAString& aProfile) MOZ_OVERRIDE { return nullptr; }
|
||||
|
||||
nsresult PushParameters() { return NS_ERROR_NOT_INITIALIZED; }
|
||||
nsresult PullParameters() { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
@ -66,6 +63,7 @@ protected:
|
||||
virtual nsresult StopRecordingImpl() { return NS_ERROR_NOT_INITIALIZED; }
|
||||
virtual nsresult PushParametersImpl() { return NS_ERROR_NOT_INITIALIZED; }
|
||||
virtual nsresult PullParametersImpl() { return NS_ERROR_NOT_INITIALIZED; }
|
||||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE { return nullptr; }
|
||||
|
||||
private:
|
||||
FallbackCameraControl(const FallbackCameraControl&) MOZ_DELETE;
|
||||
|
@ -71,8 +71,11 @@ nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId)
|
||||
, mAutoFlashModeOverridden(false)
|
||||
, mSeparateVideoAndPreviewSizesSupported(false)
|
||||
, mDeferConfigUpdate(0)
|
||||
, mMediaProfiles(nullptr)
|
||||
, mRecorder(nullptr)
|
||||
, mRecorderMonitor("GonkCameraControl::mRecorder.Monitor")
|
||||
, mProfileManager(nullptr)
|
||||
, mRecorderProfile(nullptr)
|
||||
, mVideoFile(nullptr)
|
||||
, mReentrantMonitor("GonkCameraControl::OnTakePicture.Monitor")
|
||||
{
|
||||
@ -142,7 +145,6 @@ nsGonkCameraControl::Initialize()
|
||||
}
|
||||
|
||||
DOM_CAMERA_LOGI("Initializing camera %d (this=%p, mCameraHw=%p)\n", mCameraId, this, mCameraHw.get());
|
||||
mCurrentConfiguration.mRecorderProfile.Truncate();
|
||||
|
||||
// Initialize our camera configuration database.
|
||||
PullParametersImpl();
|
||||
@ -303,6 +305,9 @@ nsGonkCameraControl::SetPictureConfiguration(const Configuration& aConfig)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
// remove any existing recorder profile
|
||||
mRecorderProfile = nullptr;
|
||||
|
||||
nsresult rv = SetPreviewSize(aConfig.mPreviewSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
@ -955,7 +960,7 @@ nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescri
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mRecorderMonitor);
|
||||
|
||||
NS_ENSURE_TRUE(!mCurrentConfiguration.mRecorderProfile.IsEmpty(), NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mRecorderProfile, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_FALSE(mRecorder, NS_ERROR_FAILURE);
|
||||
|
||||
/**
|
||||
@ -1363,25 +1368,32 @@ nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
RecorderProfile* profile;
|
||||
if (!mRecorderProfiles.Get(aConfig.mRecorderProfile, &profile)) {
|
||||
DOM_CAMERA_LOGE("Recorder profile '%s' is not supported\n",
|
||||
NS_ConvertUTF16toUTF8(aConfig.mRecorderProfile).get());
|
||||
// read preferences for camcorder
|
||||
mMediaProfiles = MediaProfiles::getInstance();
|
||||
|
||||
nsAutoCString profile = NS_ConvertUTF16toUTF8(aConfig.mRecorderProfile);
|
||||
mRecorderProfile = GetGonkRecorderProfileManager().take()->Get(profile.get());
|
||||
if (!mRecorderProfile) {
|
||||
DOM_CAMERA_LOGE("Recorder profile '%s' is not supported\n", profile.get());
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mCurrentConfiguration.mRecorderProfile = aConfig.mRecorderProfile;
|
||||
const RecorderProfile::Video& video(profile->GetVideo());
|
||||
const Size& size = video.GetSize();
|
||||
int fps = video.GetFramesPerSecond();
|
||||
if (fps <= 0 || size.width <= 0 || size.height <= 0) {
|
||||
DOM_CAMERA_LOGE("Can't configure video with fps=%d, width=%d, height=%d\n",
|
||||
fps, size.width, size.height);
|
||||
const GonkRecorderVideoProfile* video = mRecorderProfile->GetGonkVideoProfile();
|
||||
int width = video->GetWidth();
|
||||
int height = video->GetHeight();
|
||||
int fps = video->GetFramerate();
|
||||
if (fps == -1 || width < 0 || height < 0) {
|
||||
DOM_CAMERA_LOGE("Can't configure preview with fps=%d, width=%d, height=%d\n",
|
||||
fps, width, height);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PullParametersImpl();
|
||||
|
||||
Size size;
|
||||
size.width = static_cast<uint32_t>(width);
|
||||
size.height = static_cast<uint32_t>(height);
|
||||
|
||||
{
|
||||
ICameraControlParameterSetAutoEnter set(this);
|
||||
nsresult rv;
|
||||
@ -1587,12 +1599,8 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation,
|
||||
mRecorder = new GonkRecorder();
|
||||
CHECK_SETARG_RETURN(mRecorder->init(), NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv =
|
||||
GonkRecorderProfile::ConfigureRecorder(*mRecorder, mCameraId,
|
||||
mCurrentConfiguration.mRecorderProfile);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsresult rv = mRecorderProfile->ConfigureRecorder(mRecorder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CHECK_SETARG_RETURN(mRecorder->setCamera(mCameraHw), NS_ERROR_FAILURE);
|
||||
|
||||
@ -1663,76 +1671,27 @@ nsGonkCameraControl::StopImpl()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::LoadRecorderProfiles()
|
||||
already_AddRefed<GonkRecorderProfileManager>
|
||||
nsGonkCameraControl::GetGonkRecorderProfileManager()
|
||||
{
|
||||
if (mRecorderProfiles.Count() == 0) {
|
||||
nsTArray<nsRefPtr<RecorderProfile>> profiles;
|
||||
nsresult rv = GonkRecorderProfile::GetAll(mCameraId, profiles);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mProfileManager) {
|
||||
nsTArray<Size> sizes;
|
||||
rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
// Limit profiles to those video sizes supported by the camera hardware...
|
||||
for (nsTArray<RecorderProfile>::size_type i = 0; i < profiles.Length(); ++i) {
|
||||
int width = profiles[i]->GetVideo().GetSize().width;
|
||||
int height = profiles[i]->GetVideo().GetSize().height;
|
||||
if (width < 0 || height < 0) {
|
||||
DOM_CAMERA_LOGW("Ignoring weird profile '%s' with width and/or height < 0\n",
|
||||
NS_ConvertUTF16toUTF8(profiles[i]->GetName()).get());
|
||||
continue;
|
||||
}
|
||||
for (nsTArray<Size>::size_type n = 0; n < sizes.Length(); ++n) {
|
||||
if (static_cast<uint32_t>(width) == sizes[n].width &&
|
||||
static_cast<uint32_t>(height) == sizes[n].height) {
|
||||
mRecorderProfiles.Put(profiles[i]->GetName(), profiles[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mProfileManager = new GonkRecorderProfileManager(mCameraId);
|
||||
mProfileManager->SetSupportedResolutions(sizes);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
nsRefPtr<GonkRecorderProfileManager> profileMgr = mProfileManager;
|
||||
return profileMgr.forget();
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
nsGonkCameraControl::Enumerate(const nsAString& aProfileName,
|
||||
RecorderProfile* aProfile,
|
||||
void* aUserArg)
|
||||
already_AddRefed<RecorderProfileManager>
|
||||
nsGonkCameraControl::GetRecorderProfileManagerImpl()
|
||||
{
|
||||
nsTArray<nsString>* profiles = static_cast<nsTArray<nsString>*>(aUserArg);
|
||||
MOZ_ASSERT(profiles);
|
||||
profiles->AppendElement(aProfileName);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::GetRecorderProfiles(nsTArray<nsString>& aProfiles)
|
||||
{
|
||||
nsresult rv = LoadRecorderProfiles();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
aProfiles.Clear();
|
||||
mRecorderProfiles.EnumerateRead(Enumerate, static_cast<void*>(&aProfiles));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ICameraControl::RecorderProfile*
|
||||
nsGonkCameraControl::GetProfileInfo(const nsAString& aProfile)
|
||||
{
|
||||
RecorderProfile* profile;
|
||||
if (!mRecorderProfiles.Get(aProfile, &profile)) {
|
||||
return nullptr;
|
||||
}
|
||||
return profile;
|
||||
nsRefPtr<RecorderProfileManager> profileMgr = GetGonkRecorderProfileManager();
|
||||
return profileMgr.forget();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -18,7 +18,6 @@
|
||||
#define DOM_CAMERA_GONKCAMERACONTROL_H
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "DeviceStorage.h"
|
||||
@ -80,10 +79,6 @@ public:
|
||||
virtual nsresult Get(uint32_t aKey, nsTArray<nsString>& aValues) MOZ_OVERRIDE;
|
||||
virtual nsresult Get(uint32_t aKey, nsTArray<double>& aValues) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetRecorderProfiles(nsTArray<nsString>& aProfiles) MOZ_OVERRIDE;
|
||||
virtual ICameraControl::RecorderProfile*
|
||||
GetProfileInfo(const nsAString& aProfile) MOZ_OVERRIDE;
|
||||
|
||||
nsresult PushParameters();
|
||||
nsresult PullParameters();
|
||||
|
||||
@ -125,6 +120,8 @@ protected:
|
||||
virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE;
|
||||
virtual nsresult PushParametersImpl() MOZ_OVERRIDE;
|
||||
virtual nsresult PullParametersImpl() MOZ_OVERRIDE;
|
||||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE;
|
||||
already_AddRefed<GonkRecorderProfileManager> GetGonkRecorderProfileManager();
|
||||
|
||||
nsresult SetupRecording(int aFd, int aRotation, uint64_t aMaxFileSizeBytes,
|
||||
uint64_t aMaxVideoLengthMs);
|
||||
@ -134,11 +131,6 @@ protected:
|
||||
nsresult PausePreview();
|
||||
nsresult GetSupportedSize(const Size& aSize, const nsTArray<Size>& supportedSizes, Size& best);
|
||||
|
||||
nsresult LoadRecorderProfiles();
|
||||
static PLDHashOperator Enumerate(const nsAString& aProfileName,
|
||||
RecorderProfile* aProfile,
|
||||
void* aUserArg);
|
||||
|
||||
friend class SetPictureSize;
|
||||
friend class SetThumbnailSize;
|
||||
nsresult SetPictureSize(const Size& aSize);
|
||||
@ -165,14 +157,16 @@ protected:
|
||||
|
||||
nsRefPtr<mozilla::layers::ImageContainer> mImageContainer;
|
||||
|
||||
android::MediaProfiles* mMediaProfiles;
|
||||
nsRefPtr<android::GonkRecorder> mRecorder;
|
||||
// Touching mRecorder happens inside this monitor because the destructor
|
||||
// can run on any thread, and we need to be able to clean up properly if
|
||||
// GonkCameraControl goes away.
|
||||
ReentrantMonitor mRecorderMonitor;
|
||||
|
||||
// Supported recorder profiles
|
||||
nsRefPtrHashtable<nsStringHashKey, RecorderProfile> mRecorderProfiles;
|
||||
// Camcorder profile settings for the desired quality level
|
||||
nsRefPtr<GonkRecorderProfileManager> mProfileManager;
|
||||
nsRefPtr<GonkRecorderProfile> mRecorderProfile;
|
||||
|
||||
nsRefPtr<DeviceStorageFile> mVideoFile;
|
||||
nsString mFileFormat;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Mozilla Foundation
|
||||
* Copyright (C) 2012 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,7 +16,6 @@
|
||||
|
||||
#include "GonkRecorderProfiles.h"
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "nsMimeTypes.h"
|
||||
#include "GonkRecorder.h"
|
||||
#include "CameraControlImpl.h"
|
||||
#include "CameraCommon.h"
|
||||
@ -39,318 +38,216 @@ static struct {
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
/* static */ nsClassHashtable<nsUint32HashKey, ProfileHashtable> GonkRecorderProfile::sProfiles;
|
||||
/* static */ android::MediaProfiles* sMediaProfiles = nullptr;
|
||||
static MediaProfiles* sMediaProfiles = nullptr;
|
||||
|
||||
static MediaProfiles*
|
||||
GetMediaProfiles()
|
||||
static bool
|
||||
IsQualitySupported(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
{
|
||||
if (!sMediaProfiles) {
|
||||
sMediaProfiles = MediaProfiles::getInstance();
|
||||
}
|
||||
MOZ_ASSERT(sMediaProfiles);
|
||||
return sMediaProfiles;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsProfileSupported(uint32_t aCameraId, uint32_t aProfileIndex)
|
||||
{
|
||||
MediaProfiles* profiles = GetMediaProfiles();
|
||||
camcorder_quality q = static_cast<camcorder_quality>(ProfileList[aProfileIndex].quality);
|
||||
return profiles->hasCamcorderProfile(static_cast<int>(aCameraId), q);
|
||||
camcorder_quality q = static_cast<camcorder_quality>(ProfileList[aQualityIndex].quality);
|
||||
return sMediaProfiles->hasCamcorderProfile(static_cast<int>(aCameraId), q);
|
||||
}
|
||||
|
||||
static int
|
||||
GetProfileParameter(uint32_t aCameraId, uint32_t aProfileIndex, const char* aParameter)
|
||||
GetProfileParam(uint32_t aCameraId, uint32_t aQualityIndex, const char* aParam)
|
||||
{
|
||||
MediaProfiles* profiles = GetMediaProfiles();
|
||||
camcorder_quality q = static_cast<camcorder_quality>(ProfileList[aProfileIndex].quality);
|
||||
return profiles->getCamcorderProfileParamByName(aParameter, static_cast<int>(aCameraId), q);
|
||||
if (!sMediaProfiles) {
|
||||
sMediaProfiles = MediaProfiles::getInstance();
|
||||
}
|
||||
camcorder_quality q = static_cast<camcorder_quality>(ProfileList[aQualityIndex].quality);
|
||||
return sMediaProfiles->getCamcorderProfileParamByName(aParam, static_cast<int>(aCameraId), q);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GonkRecorderVideo::Translate(video_encoder aCodec, nsAString& aCodecName)
|
||||
/**
|
||||
* Recorder profile.
|
||||
*/
|
||||
static RecorderProfile::FileFormat
|
||||
TranslateFileFormat(output_format aFileFormat)
|
||||
{
|
||||
switch (aCodec) {
|
||||
case VIDEO_ENCODER_H263:
|
||||
aCodecName.AssignASCII("h263");
|
||||
break;
|
||||
|
||||
case VIDEO_ENCODER_H264:
|
||||
aCodecName.AssignASCII("h264");
|
||||
break;
|
||||
|
||||
case VIDEO_ENCODER_MPEG_4_SP:
|
||||
aCodecName.AssignASCII("mpeg4sp");
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
switch (aFileFormat) {
|
||||
case OUTPUT_FORMAT_THREE_GPP: return RecorderProfile::THREE_GPP;
|
||||
case OUTPUT_FORMAT_MPEG_4: return RecorderProfile::MPEG4;
|
||||
default: return RecorderProfile::UNKNOWN;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
GonkRecorderVideo::GetProfileParameter(const char* aParameter)
|
||||
GonkRecorderProfile::GonkRecorderProfile(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: RecorderProfileBase<GonkRecorderAudioProfile, GonkRecorderVideoProfile>(aCameraId, aQualityIndex)
|
||||
{
|
||||
return ::GetProfileParameter(mCameraId, mProfileIndex, aParameter);
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__, __LINE__, this, mCameraId, mQualityIndex);
|
||||
mPlatformOutputFormat = static_cast<output_format>(GetProfileParam(mCameraId, mQualityIndex, "file.format"));
|
||||
mFileFormat = TranslateFileFormat(mPlatformOutputFormat);
|
||||
if (aQualityIndex < PROFILE_COUNT) {
|
||||
mName = ProfileList[aQualityIndex].name;
|
||||
DOM_CAMERA_LOGI("Created camera %d profile index %d: '%s'\n", mCameraId, mQualityIndex, mName);
|
||||
}
|
||||
}
|
||||
|
||||
GonkRecorderVideo::GonkRecorderVideo(uint32_t aCameraId, uint32_t aProfileIndex)
|
||||
: mCameraId(aCameraId)
|
||||
, mProfileIndex(aProfileIndex)
|
||||
, mIsValid(false)
|
||||
GonkRecorderProfile::~GonkRecorderProfile()
|
||||
{
|
||||
mPlatformEncoder = static_cast<video_encoder>(GetProfileParameter("vid.codec"));
|
||||
bool isValid = Translate(mPlatformEncoder, mCodec);
|
||||
|
||||
int v = GetProfileParameter("vid.width");
|
||||
if (v >= 0) {
|
||||
mSize.width = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
v = GetProfileParameter("vid.height");
|
||||
if (v >= 0) {
|
||||
mSize.height = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
v = GetProfileParameter("vid.bps");
|
||||
if (v >= 0) {
|
||||
mBitsPerSecond = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
v = GetProfileParameter("vid.fps");
|
||||
if (v >= 0) {
|
||||
mFramesPerSecond = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
mIsValid = isValid;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GonkRecorderAudio::Translate(audio_encoder aCodec, nsAString& aCodecName)
|
||||
{
|
||||
switch (aCodec) {
|
||||
case AUDIO_ENCODER_AMR_NB:
|
||||
aCodecName.AssignASCII("amrnb");
|
||||
break;
|
||||
|
||||
case AUDIO_ENCODER_AMR_WB:
|
||||
aCodecName.AssignASCII("amrwb");
|
||||
break;
|
||||
|
||||
case AUDIO_ENCODER_AAC:
|
||||
aCodecName.AssignASCII("aac");
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
GonkRecorderAudio::GetProfileParameter(const char* aParameter)
|
||||
{
|
||||
return ::GetProfileParameter(mCameraId, mProfileIndex, aParameter);
|
||||
}
|
||||
|
||||
GonkRecorderAudio::GonkRecorderAudio(uint32_t aCameraId, uint32_t aProfileIndex)
|
||||
: mCameraId(aCameraId)
|
||||
, mProfileIndex(aProfileIndex)
|
||||
, mIsValid(false)
|
||||
{
|
||||
mPlatformEncoder = static_cast<audio_encoder>(GetProfileParameter("aud.codec"));
|
||||
bool isValid = Translate(mPlatformEncoder, mCodec);
|
||||
|
||||
int v = GetProfileParameter("aud.ch");
|
||||
if (v >= 0) {
|
||||
mChannels = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
v = GetProfileParameter("aud.bps");
|
||||
if (v >= 0) {
|
||||
mBitsPerSecond = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
v = GetProfileParameter("aud.hz");
|
||||
if (v >= 0) {
|
||||
mSamplesPerSecond = v;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
mIsValid = isValid;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GonkRecorderProfile::Translate(output_format aContainer, nsAString& aContainerName)
|
||||
{
|
||||
switch (aContainer) {
|
||||
case OUTPUT_FORMAT_THREE_GPP:
|
||||
aContainerName.AssignASCII("3gp");
|
||||
break;
|
||||
|
||||
case OUTPUT_FORMAT_MPEG_4:
|
||||
aContainerName.AssignASCII("mp4");
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GonkRecorderProfile::GetMimeType(output_format aContainer, nsAString& aMimeType)
|
||||
{
|
||||
switch (aContainer) {
|
||||
case OUTPUT_FORMAT_THREE_GPP:
|
||||
aMimeType.AssignASCII(VIDEO_3GPP);
|
||||
break;
|
||||
|
||||
case OUTPUT_FORMAT_MPEG_4:
|
||||
aMimeType.AssignASCII(VIDEO_MP4);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
GonkRecorderProfile::GetProfileParameter(const char* aParameter)
|
||||
{
|
||||
return ::GetProfileParameter(mCameraId, mProfileIndex, aParameter);
|
||||
}
|
||||
|
||||
GonkRecorderProfile::GonkRecorderProfile(uint32_t aCameraId,
|
||||
uint32_t aProfileIndex,
|
||||
const nsAString& aName)
|
||||
: GonkRecorderProfileBase<GonkRecorderAudio, GonkRecorderVideo>(aCameraId,
|
||||
aProfileIndex, aName)
|
||||
, mCameraId(aCameraId)
|
||||
, mProfileIndex(aProfileIndex)
|
||||
, mIsValid(false)
|
||||
{
|
||||
mOutputFormat = static_cast<output_format>(GetProfileParameter("file.format"));
|
||||
bool isValid = Translate(mOutputFormat, mContainer);
|
||||
isValid = GetMimeType(mOutputFormat, mMimeType) ? isValid : false;
|
||||
|
||||
mIsValid = isValid && mAudio.IsValid() && mVideo.IsValid();
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
GonkRecorderProfile::Enumerate(const nsAString& aProfileName,
|
||||
GonkRecorderProfile* aProfile,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsTArray<nsRefPtr<ICameraControl::RecorderProfile>>* profiles =
|
||||
static_cast<nsTArray<nsRefPtr<ICameraControl::RecorderProfile>>*>(aUserArg);
|
||||
MOZ_ASSERT(profiles);
|
||||
profiles->AppendElement(aProfile);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkRecorderProfile::ConfigureRecorder(GonkRecorder& aRecorder)
|
||||
GonkRecorderProfile::ConfigureRecorder(GonkRecorder* aRecorder)
|
||||
{
|
||||
if (!aRecorder) {
|
||||
DOM_CAMERA_LOGW("ConfigureRecorder() called with null aRecorder\n");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
static const size_t SIZE = 256;
|
||||
char buffer[SIZE];
|
||||
|
||||
// set all the params
|
||||
CHECK_SETARG(aRecorder.setAudioSource(AUDIO_SOURCE_CAMCORDER));
|
||||
CHECK_SETARG(aRecorder.setVideoSource(VIDEO_SOURCE_CAMERA));
|
||||
CHECK_SETARG(aRecorder.setOutputFormat(mOutputFormat));
|
||||
CHECK_SETARG(aRecorder.setVideoFrameRate(mVideo.GetFramesPerSecond()));
|
||||
CHECK_SETARG(aRecorder.setVideoSize(mVideo.GetSize().width, mVideo.GetSize().height));
|
||||
CHECK_SETARG(aRecorder.setVideoEncoder(mVideo.GetPlatformEncoder()));
|
||||
CHECK_SETARG(aRecorder.setAudioEncoder(mAudio.GetPlatformEncoder()));
|
||||
CHECK_SETARG(aRecorder->setAudioSource(AUDIO_SOURCE_CAMCORDER));
|
||||
CHECK_SETARG(aRecorder->setVideoSource(VIDEO_SOURCE_CAMERA));
|
||||
CHECK_SETARG(aRecorder->setOutputFormat(GetOutputFormat()));
|
||||
CHECK_SETARG(aRecorder->setVideoFrameRate(mVideo.GetFramerate()));
|
||||
CHECK_SETARG(aRecorder->setVideoSize(mVideo.GetWidth(), mVideo.GetHeight()));
|
||||
CHECK_SETARG(aRecorder->setVideoEncoder(mVideo.GetPlatformCodec()));
|
||||
CHECK_SETARG(aRecorder->setAudioEncoder(mAudio.GetPlatformCodec()));
|
||||
|
||||
snprintf(buffer, SIZE, "video-param-encoding-bitrate=%d", mVideo.GetBitsPerSecond());
|
||||
CHECK_SETARG(aRecorder.setParameters(String8(buffer)));
|
||||
snprintf(buffer, SIZE, "video-param-encoding-bitrate=%d", mVideo.GetBitrate());
|
||||
CHECK_SETARG(aRecorder->setParameters(String8(buffer)));
|
||||
|
||||
snprintf(buffer, SIZE, "audio-param-encoding-bitrate=%d", mAudio.GetBitsPerSecond());
|
||||
CHECK_SETARG(aRecorder.setParameters(String8(buffer)));
|
||||
snprintf(buffer, SIZE, "audio-param-encoding-bitrate=%d", mAudio.GetBitrate());
|
||||
CHECK_SETARG(aRecorder->setParameters(String8(buffer)));
|
||||
|
||||
snprintf(buffer, SIZE, "audio-param-number-of-channels=%d", mAudio.GetChannels());
|
||||
CHECK_SETARG(aRecorder.setParameters(String8(buffer)));
|
||||
CHECK_SETARG(aRecorder->setParameters(String8(buffer)));
|
||||
|
||||
snprintf(buffer, SIZE, "audio-param-sampling-rate=%d", mAudio.GetSamplesPerSecond());
|
||||
CHECK_SETARG(aRecorder.setParameters(String8(buffer)));
|
||||
snprintf(buffer, SIZE, "audio-param-sampling-rate=%d", mAudio.GetSamplerate());
|
||||
CHECK_SETARG(aRecorder->setParameters(String8(buffer)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
GonkRecorderProfile::ConfigureRecorder(android::GonkRecorder& aRecorder,
|
||||
uint32_t aCameraId,
|
||||
const nsAString& aProfileName)
|
||||
/**
|
||||
* Recorder audio profile.
|
||||
*/
|
||||
static RecorderAudioProfile::Codec
|
||||
TranslateAudioCodec(audio_encoder aCodec)
|
||||
{
|
||||
ProfileHashtable* profiles = GetProfileHashtable(aCameraId);
|
||||
if (!profiles) {
|
||||
return NS_ERROR_FAILURE;
|
||||
switch (aCodec) {
|
||||
case AUDIO_ENCODER_AMR_NB: return RecorderAudioProfile::AMRNB;
|
||||
case AUDIO_ENCODER_AMR_WB: return RecorderAudioProfile::AMRWB;
|
||||
case AUDIO_ENCODER_AAC: return RecorderAudioProfile::AAC;
|
||||
default: return RecorderAudioProfile::UNKNOWN;
|
||||
}
|
||||
|
||||
GonkRecorderProfile* profile;
|
||||
if (!profiles->Get(aProfileName, &profile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return profile->ConfigureRecorder(aRecorder);
|
||||
}
|
||||
|
||||
GonkRecorderAudioProfile::GonkRecorderAudioProfile(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: RecorderAudioProfile(aCameraId, aQualityIndex)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__, __LINE__, this, mCameraId, mQualityIndex);
|
||||
mPlatformCodec = static_cast<audio_encoder>(GetProfileParam(mCameraId, mQualityIndex, "aud.codec"));
|
||||
mCodec = TranslateAudioCodec(mPlatformCodec);
|
||||
mBitrate = GetProfileParam(mCameraId, mQualityIndex, "aud.bps");
|
||||
mSamplerate = GetProfileParam(mCameraId, mQualityIndex, "aud.hz");
|
||||
mChannels = GetProfileParam(mCameraId, mQualityIndex, "aud.ch");
|
||||
}
|
||||
|
||||
GonkRecorderAudioProfile::~GonkRecorderAudioProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recorder video profile.
|
||||
*/
|
||||
static RecorderVideoProfile::Codec
|
||||
TranslateVideoCodec(video_encoder aCodec)
|
||||
{
|
||||
switch (aCodec) {
|
||||
case VIDEO_ENCODER_H263: return RecorderVideoProfile::H263;
|
||||
case VIDEO_ENCODER_H264: return RecorderVideoProfile::H264;
|
||||
case VIDEO_ENCODER_MPEG_4_SP: return RecorderVideoProfile::MPEG4SP;
|
||||
default: return RecorderVideoProfile::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
GonkRecorderVideoProfile::GonkRecorderVideoProfile(uint32_t aCameraId, uint32_t aQualityIndex)
|
||||
: RecorderVideoProfile(aCameraId, aQualityIndex)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__, __LINE__, this, mCameraId, mQualityIndex);
|
||||
mPlatformCodec = static_cast<video_encoder>(GetProfileParam(mCameraId, mQualityIndex, "vid.codec"));
|
||||
mCodec = TranslateVideoCodec(mPlatformCodec);
|
||||
mBitrate = GetProfileParam(mCameraId, mQualityIndex, "vid.bps");
|
||||
mFramerate = GetProfileParam(mCameraId, mQualityIndex, "vid.fps");
|
||||
mWidth = GetProfileParam(mCameraId, mQualityIndex, "vid.width");
|
||||
mHeight = GetProfileParam(mCameraId, mQualityIndex, "vid.height");
|
||||
}
|
||||
|
||||
GonkRecorderVideoProfile::~GonkRecorderVideoProfile()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
GonkRecorderProfileManager::GonkRecorderProfileManager(uint32_t aCameraId)
|
||||
: RecorderProfileManager(aCameraId)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
mMaxQualityIndex = sizeof(ProfileList) / sizeof(ProfileList[0]) - 1;
|
||||
}
|
||||
|
||||
GonkRecorderProfileManager::~GonkRecorderProfileManager()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
bool
|
||||
GonkRecorderProfileManager::IsSupported(uint32_t aQualityIndex) const
|
||||
{
|
||||
if (!IsQualitySupported(mCameraId, aQualityIndex)) {
|
||||
// This profile is not supported
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = GetProfileParam(mCameraId, aQualityIndex, "vid.width");
|
||||
int height = GetProfileParam(mCameraId, aQualityIndex, "vid.height");
|
||||
if (width == -1 || height == -1) {
|
||||
// This would be unexpected, but we handle it just in case
|
||||
DOM_CAMERA_LOGE("Camera %d recorder profile %d has width=%d, height=%d\n", mCameraId, aQualityIndex, width, height);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mSupportedSizes.Length(); ++i) {
|
||||
if (static_cast<uint32_t>(width) == mSupportedSizes[i].width &&
|
||||
static_cast<uint32_t>(height) == mSupportedSizes[i].height)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<RecorderProfile>
|
||||
GonkRecorderProfileManager::Get(uint32_t aQualityIndex) const
|
||||
{
|
||||
// This overrides virtual RecorderProfileManager::Get(...)
|
||||
DOM_CAMERA_LOGT("%s:%d : aQualityIndex=%d\n", __func__, __LINE__, aQualityIndex);
|
||||
nsRefPtr<RecorderProfile> profile = new GonkRecorderProfile(mCameraId, aQualityIndex);
|
||||
return profile.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GonkRecorderProfile>
|
||||
GonkRecorderProfileManager::Get(const char* aProfileName) const
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : aProfileName='%s'\n", __func__, __LINE__, aProfileName);
|
||||
for (uint32_t i = 0; i < mMaxQualityIndex; ++i) {
|
||||
if (strcmp(ProfileList[i].name, aProfileName) == 0) {
|
||||
nsRefPtr<GonkRecorderProfile> profile = nullptr;
|
||||
if (IsSupported(i)) {
|
||||
profile = new GonkRecorderProfile(mCameraId, i);
|
||||
return profile.forget();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DOM_CAMERA_LOGW("Couldn't file recorder profile named '%s'\n", aProfileName);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define DOM_CAMERA_GONK_RECORDER_PROFILES_H
|
||||
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "CameraRecorderProfiles.h"
|
||||
#include "ICameraControl.h"
|
||||
|
||||
#ifndef CHECK_SETARG_RETURN
|
||||
@ -23,125 +24,97 @@
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
class GonkRecorder;
|
||||
class GonkRecorder;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* class GonkRecorderProfileBase
|
||||
* Gonk-specific video profile.
|
||||
*/
|
||||
template<class A, class V>
|
||||
class GonkRecorderProfileBase : public ICameraControl::RecorderProfile
|
||||
class GonkRecorderVideoProfile : public RecorderVideoProfile
|
||||
{
|
||||
public:
|
||||
GonkRecorderProfileBase(uint32_t aCameraId, uint32_t aProfileIndex, const nsAString& aName)
|
||||
: RecorderProfile(aName)
|
||||
, mAudio(aCameraId, aProfileIndex)
|
||||
, mVideo(aCameraId, aProfileIndex)
|
||||
{ }
|
||||
|
||||
virtual const Audio& GetAudio() const MOZ_OVERRIDE { return mAudio; }
|
||||
virtual const Video& GetVideo() const MOZ_OVERRIDE { return mVideo; }
|
||||
GonkRecorderVideoProfile(uint32_t aCameraId, uint32_t aQualityIndex);
|
||||
~GonkRecorderVideoProfile();
|
||||
android::video_encoder GetPlatformCodec() const { return mPlatformCodec; }
|
||||
|
||||
protected:
|
||||
virtual ~GonkRecorderProfileBase() { }
|
||||
A mAudio;
|
||||
V mVideo;
|
||||
android::video_encoder mPlatformCodec;
|
||||
};
|
||||
|
||||
/**
|
||||
* class GonkRecorderVideo
|
||||
* Gonk-specific audio profile.
|
||||
*/
|
||||
class GonkRecorderVideo : public ICameraControl::RecorderProfile::Video
|
||||
class GonkRecorderAudioProfile : public RecorderAudioProfile
|
||||
{
|
||||
public:
|
||||
GonkRecorderVideo(uint32_t aCameraId, uint32_t aProfileIndex);
|
||||
virtual ~GonkRecorderVideo() { }
|
||||
|
||||
android::video_encoder GetPlatformEncoder() const { return mPlatformEncoder; }
|
||||
bool IsValid() const { return mIsValid; }
|
||||
GonkRecorderAudioProfile(uint32_t aCameraId, uint32_t aQualityIndex);
|
||||
~GonkRecorderAudioProfile();
|
||||
android::audio_encoder GetPlatformCodec() const { return mPlatformCodec; }
|
||||
|
||||
protected:
|
||||
int GetProfileParameter(const char* aParameter);
|
||||
static bool Translate(android::video_encoder aCodec, nsAString& aCodecName);
|
||||
|
||||
uint32_t mCameraId;
|
||||
uint32_t mProfileIndex;
|
||||
bool mIsValid;
|
||||
android::video_encoder mPlatformEncoder;
|
||||
android::audio_encoder mPlatformCodec;
|
||||
};
|
||||
|
||||
/**
|
||||
* class GonkRecorderAudio
|
||||
* Gonk-specific recorder profile.
|
||||
*/
|
||||
class GonkRecorderAudio : public ICameraControl::RecorderProfile::Audio
|
||||
class GonkRecorderProfile : public RecorderProfileBase<GonkRecorderAudioProfile, GonkRecorderVideoProfile>
|
||||
{
|
||||
public:
|
||||
GonkRecorderAudio(uint32_t aCameraId, uint32_t aProfileIndex);
|
||||
virtual ~GonkRecorderAudio() { }
|
||||
GonkRecorderProfile(uint32_t aCameraId, uint32_t aQualityIndex);
|
||||
|
||||
android::audio_encoder GetPlatformEncoder() const { return mPlatformEncoder; }
|
||||
bool IsValid() const { return mIsValid; }
|
||||
GonkRecorderAudioProfile* GetGonkAudioProfile() { return &mAudio; }
|
||||
GonkRecorderVideoProfile* GetGonkVideoProfile() { return &mVideo; }
|
||||
|
||||
protected:
|
||||
int GetProfileParameter(const char* aParameter);
|
||||
static bool Translate(android::audio_encoder aCodec, nsAString& aCodecName);
|
||||
android::output_format GetOutputFormat() const { return mPlatformOutputFormat; }
|
||||
|
||||
uint32_t mCameraId;
|
||||
uint32_t mProfileIndex;
|
||||
bool mIsValid;
|
||||
android::audio_encoder mPlatformEncoder;
|
||||
};
|
||||
|
||||
/**
|
||||
* class GonkRecorderProfile
|
||||
*/
|
||||
typedef nsRefPtrHashtable<nsStringHashKey, GonkRecorderProfile> ProfileHashtable;
|
||||
|
||||
class GonkRecorderProfile
|
||||
: public GonkRecorderProfileBase<GonkRecorderAudio, GonkRecorderVideo>
|
||||
{
|
||||
public:
|
||||
static nsresult GetAll(uint32_t aCameraId,
|
||||
nsTArray<nsRefPtr<ICameraControl::RecorderProfile>>& aProfiles);
|
||||
|
||||
// Configures the specified recorder using the specified profile.
|
||||
// Configures the specified recorder using this profile.
|
||||
//
|
||||
// Return values:
|
||||
// - NS_OK on success;
|
||||
// - NS_ERROR_INVALID_ARG if the profile isn't supported;
|
||||
// - NS_ERROR_NOT_AVAILABLE if the recorder rejected the profile.
|
||||
static nsresult ConfigureRecorder(android::GonkRecorder& aRecorder,
|
||||
uint32_t aCameraId,
|
||||
const nsAString& aProfileName);
|
||||
// - NS_ERROR_INVALID_ARG if 'aRecorder' is null;
|
||||
// - NS_ERROR_NOT_AVAILABLE if the recorder rejected this profile.
|
||||
nsresult ConfigureRecorder(android::GonkRecorder* aRecorder);
|
||||
|
||||
protected:
|
||||
GonkRecorderProfile(uint32_t aCameraId,
|
||||
uint32_t aProfileIndex,
|
||||
const nsAString& aName);
|
||||
virtual ~GonkRecorderProfile();
|
||||
|
||||
int GetProfileParameter(const char* aParameter);
|
||||
android::output_format mPlatformOutputFormat;
|
||||
};
|
||||
|
||||
bool Translate(android::output_format aContainer, nsAString& aContainerName);
|
||||
bool GetMimeType(android::output_format aContainer, nsAString& aMimeType);
|
||||
bool IsValid() const { return mIsValid; };
|
||||
/**
|
||||
* Gonk-specific profile manager.
|
||||
*/
|
||||
class GonkRecorderProfileManager : public RecorderProfileManager
|
||||
{
|
||||
public:
|
||||
GonkRecorderProfileManager(uint32_t aCameraId);
|
||||
|
||||
nsresult ConfigureRecorder(android::GonkRecorder& aRecorder);
|
||||
static ProfileHashtable* GetProfileHashtable(uint32_t aCameraId);
|
||||
static PLDHashOperator Enumerate(const nsAString& aProfileName,
|
||||
GonkRecorderProfile* aProfile,
|
||||
void* aUserArg);
|
||||
/**
|
||||
* Call this function to indicate that the specified resolutions are in fact
|
||||
* supported by the camera hardware. (Just because it appears in a recorder
|
||||
* profile doesn't mean the hardware can handle it.)
|
||||
*/
|
||||
void SetSupportedResolutions(const nsTArray<ICameraControl::Size>& aSizes)
|
||||
{ mSupportedSizes = aSizes; }
|
||||
|
||||
uint32_t mCameraId;
|
||||
uint32_t mProfileIndex;
|
||||
bool mIsValid;
|
||||
android::output_format mOutputFormat;
|
||||
/**
|
||||
* Call this function to remove all resolutions set by calling
|
||||
* SetSupportedResolutions().
|
||||
*/
|
||||
void ClearSupportedResolutions() { mSupportedSizes.Clear(); }
|
||||
|
||||
static nsClassHashtable<nsUint32HashKey, ProfileHashtable> sProfiles;
|
||||
bool IsSupported(uint32_t aQualityIndex) const;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(GonkRecorderProfile);
|
||||
already_AddRefed<RecorderProfile> Get(uint32_t aQualityIndex) const;
|
||||
already_AddRefed<GonkRecorderProfile> Get(const char* aProfileName) const;
|
||||
|
||||
protected:
|
||||
virtual ~GonkRecorderProfileManager();
|
||||
|
||||
nsTArray<ICameraControl::Size> mSupportedSizes;
|
||||
};
|
||||
|
||||
}; // namespace mozilla
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "nsString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "base/basictypes.h"
|
||||
|
||||
struct DeviceStorageFileDescriptor;
|
||||
|
||||
@ -18,6 +17,7 @@ class nsIFile;
|
||||
namespace mozilla {
|
||||
|
||||
class CameraControlListener;
|
||||
class RecorderProfileManager;
|
||||
|
||||
// XXXmikeh - In some future patch this should move into the ICameraControl
|
||||
// class as well, and the names updated to the 'k'-style;
|
||||
@ -162,76 +162,6 @@ public:
|
||||
Point mouth;
|
||||
};
|
||||
|
||||
class RecorderProfile
|
||||
{
|
||||
public:
|
||||
class Video
|
||||
{
|
||||
public:
|
||||
Video() { }
|
||||
virtual ~Video() { }
|
||||
|
||||
const nsString& GetCodec() const { return mCodec; }
|
||||
const Size& GetSize() const { return mSize; }
|
||||
uint32_t GetBitsPerSecond() const { return mBitsPerSecond; }
|
||||
uint32_t GetFramesPerSecond() const { return mFramesPerSecond; }
|
||||
|
||||
protected:
|
||||
nsString mCodec;
|
||||
Size mSize;
|
||||
uint32_t mBitsPerSecond;
|
||||
uint32_t mFramesPerSecond;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Video);
|
||||
};
|
||||
|
||||
class Audio
|
||||
{
|
||||
public:
|
||||
Audio() { }
|
||||
virtual ~Audio() { }
|
||||
|
||||
const nsString& GetCodec() const { return mCodec; }
|
||||
|
||||
uint32_t GetChannels() const { return mChannels; }
|
||||
uint32_t GetBitsPerSecond() const { return mBitsPerSecond; }
|
||||
uint32_t GetSamplesPerSecond() const { return mSamplesPerSecond; }
|
||||
|
||||
protected:
|
||||
nsString mCodec;
|
||||
uint32_t mChannels;
|
||||
uint32_t mBitsPerSecond;
|
||||
uint32_t mSamplesPerSecond;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Audio);
|
||||
};
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RecorderProfile)
|
||||
|
||||
RecorderProfile(const nsAString& aName)
|
||||
: mName(aName)
|
||||
{ }
|
||||
|
||||
const nsString& GetName() const { return mName; }
|
||||
const nsString& GetContainer() const { return mContainer; }
|
||||
const nsString& GetMimeType() const { return mMimeType; }
|
||||
|
||||
virtual const Video& GetVideo() const = 0;
|
||||
virtual const Audio& GetAudio() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~RecorderProfile() { }
|
||||
|
||||
nsString mName;
|
||||
nsString mContainer;
|
||||
nsString mMimeType;
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(RecorderProfile);
|
||||
};
|
||||
|
||||
static already_AddRefed<ICameraControl> Create(uint32_t aCameraId);
|
||||
|
||||
virtual void AddListener(CameraControlListener* aListener) = 0;
|
||||
@ -290,9 +220,7 @@ public:
|
||||
virtual nsresult Get(uint32_t aKey, nsTArray<nsString>& aValues) = 0;
|
||||
virtual nsresult Get(uint32_t aKey, nsTArray<double>& aValues) = 0;
|
||||
|
||||
virtual nsresult GetRecorderProfiles(nsTArray<nsString>& aProfiles) = 0;
|
||||
virtual RecorderProfile* GetProfileInfo(const nsAString& aProfile) = 0;
|
||||
|
||||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManager() = 0;
|
||||
virtual uint32_t GetCameraId() = 0;
|
||||
|
||||
virtual void Shutdown() = 0;
|
||||
|
@ -17,6 +17,7 @@ UNIFIED_SOURCES += [
|
||||
'CameraControlImpl.cpp',
|
||||
'CameraPreferences.cpp',
|
||||
'CameraPreviewMediaStream.cpp',
|
||||
'CameraRecorderProfiles.cpp',
|
||||
'DOMCameraCapabilities.cpp',
|
||||
'DOMCameraControl.cpp',
|
||||
'DOMCameraControlListener.cpp',
|
||||
|
@ -211,14 +211,6 @@ var interfaceNamesInGlobalScope =
|
||||
{name: "CameraFacesDetectedEvent", b2g: true, pref: "camera.control.face_detection.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CameraManager", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CameraRecorderAudioProfile", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CameraRecorderProfile", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CameraRecorderProfiles", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CameraRecorderVideoProfile", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CameraStateChangeEvent", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -5,55 +5,6 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/* The capabilities of the video recorder. These are guaranteed not to change
|
||||
over the lifetime of that partcicular instance.
|
||||
*/
|
||||
[Func="CameraCapabilities::HasSupport"]
|
||||
interface CameraRecorderAudioProfile
|
||||
{
|
||||
[Constant, Cached] readonly attribute DOMString codec;
|
||||
[Constant, Cached] readonly attribute unsigned long bitsPerSecond;
|
||||
[Constant, Cached] readonly attribute unsigned long samplesPerSecond;
|
||||
[Constant, Cached] readonly attribute unsigned long channels;
|
||||
|
||||
jsonifier;
|
||||
};
|
||||
|
||||
[Func="CameraCapabilities::HasSupport"]
|
||||
interface CameraRecorderVideoProfile
|
||||
{
|
||||
[Constant, Cached] readonly attribute DOMString codec;
|
||||
[Constant, Cached] readonly attribute unsigned long bitsPerSecond;
|
||||
[Constant, Cached] readonly attribute unsigned long framesPerSecond;
|
||||
[Constant, Cached] readonly attribute CameraSize size;
|
||||
|
||||
[Constant, Cached] readonly attribute unsigned long width;
|
||||
[Constant, Cached] readonly attribute unsigned long height;
|
||||
|
||||
jsonifier;
|
||||
};
|
||||
|
||||
[Func="CameraCapabilities::HasSupport"]
|
||||
interface CameraRecorderProfile
|
||||
{
|
||||
[Constant, Cached] readonly attribute DOMString name;
|
||||
[Constant, Cached] readonly attribute DOMString containerFormat;
|
||||
[Constant, Cached] readonly attribute DOMString mimeType;
|
||||
|
||||
[Constant, Cached] readonly attribute CameraRecorderAudioProfile audio;
|
||||
[Constant, Cached] readonly attribute CameraRecorderVideoProfile video;
|
||||
|
||||
jsonifier;
|
||||
};
|
||||
|
||||
[Func="CameraCapabilities::HasSupport"]
|
||||
interface CameraRecorderProfiles
|
||||
{
|
||||
getter CameraRecorderProfile(DOMString profile);
|
||||
|
||||
jsonifier;
|
||||
};
|
||||
|
||||
/* The capabilities of a CameraControl instance. These are guaranteed
|
||||
not to change over the lifetime of that particular instance.
|
||||
*/
|
||||
@ -83,9 +34,7 @@ interface CameraCapabilities
|
||||
[Constant, Cached] readonly attribute double maxExposureCompensation;
|
||||
[Constant, Cached] readonly attribute double exposureCompensationStep;
|
||||
|
||||
[Constant, Cached] readonly attribute CameraRecorderProfiles recorderProfiles;
|
||||
[Constant, Cached] readonly attribute any recorderProfiles;
|
||||
|
||||
[Constant, Cached] readonly attribute sequence<DOMString> isoModes;
|
||||
|
||||
jsonifier;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user