Backed out changeset 3fde6fc99b0a (bug 1020368) for non-unified bustage.

This commit is contained in:
Ryan VanderMeulen 2014-10-31 18:51:23 -04:00
parent e7353cb4a6
commit 418030317f
19 changed files with 947 additions and 1122 deletions

View File

@ -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'

View File

@ -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;

View File

@ -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();

View File

@ -34,8 +34,8 @@ public:
enum HardwareState
{
kHardwareClosed,
kHardwareOpen
kHardwareOpen,
kHardwareClosed
};
virtual void OnHardwareStateChange(HardwareState aState) { }

View 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;
}

View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -17,6 +17,7 @@ UNIFIED_SOURCES += [
'CameraControlImpl.cpp',
'CameraPreferences.cpp',
'CameraPreviewMediaStream.cpp',
'CameraRecorderProfiles.cpp',
'DOMCameraCapabilities.cpp',
'DOMCameraControl.cpp',
'DOMCameraControlListener.cpp',

View File

@ -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!

View File

@ -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;
};