michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef DOM_CAMERA_CAMERA_RECORDER_PROFILES_H michael@0: #define DOM_CAMERA_CAMERA_RECORDER_PROFILES_H michael@0: michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsMimeTypes.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsTArray.h" michael@0: #include "jsapi.h" michael@0: #include "CameraCommon.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: class CameraControlImpl; michael@0: michael@0: class RecorderVideoProfile michael@0: { michael@0: public: michael@0: RecorderVideoProfile(uint32_t aCameraId, uint32_t aQualityIndex); michael@0: virtual ~RecorderVideoProfile(); michael@0: michael@0: int GetBitrate() const { return mBitrate; } michael@0: int GetFramerate() const { return mFramerate; } michael@0: int GetWidth() const { return mWidth; } michael@0: int GetHeight() const { return mHeight; } michael@0: michael@0: enum Codec { michael@0: H263, michael@0: H264, michael@0: MPEG4SP, michael@0: UNKNOWN michael@0: }; michael@0: Codec GetCodec() const { return mCodec; } michael@0: const char* GetCodecName() const michael@0: { michael@0: switch (mCodec) { michael@0: case H263: return "h263"; michael@0: case H264: return "h264"; michael@0: case MPEG4SP: return "mpeg4sp"; michael@0: default: return nullptr; michael@0: } michael@0: } michael@0: michael@0: nsresult GetJsObject(JSContext* aCx, JSObject** aObject); michael@0: michael@0: protected: michael@0: uint32_t mCameraId; michael@0: uint32_t mQualityIndex; michael@0: Codec mCodec; michael@0: int mBitrate; michael@0: int mFramerate; michael@0: int mWidth; michael@0: int mHeight; michael@0: }; michael@0: michael@0: class RecorderAudioProfile michael@0: { michael@0: public: michael@0: RecorderAudioProfile(uint32_t aCameraId, uint32_t aQualityIndex); michael@0: virtual ~RecorderAudioProfile(); michael@0: michael@0: int GetBitrate() const { return mBitrate; } michael@0: int GetSamplerate() const { return mSamplerate; } michael@0: int GetChannels() const { return mChannels; } michael@0: michael@0: enum Codec { michael@0: AMRNB, michael@0: AMRWB, michael@0: AAC, michael@0: UNKNOWN michael@0: }; michael@0: michael@0: public: michael@0: Codec GetCodec() const { return mCodec; } michael@0: const char* GetCodecName() const michael@0: { michael@0: switch (mCodec) { michael@0: case AMRNB: return "amrnb"; michael@0: case AMRWB: return "amrwb"; michael@0: case AAC: return "aac"; michael@0: default: return nullptr; michael@0: } michael@0: } michael@0: michael@0: nsresult GetJsObject(JSContext* aCx, JSObject** aObject); michael@0: michael@0: protected: michael@0: uint32_t mCameraId; michael@0: uint32_t mQualityIndex; michael@0: Codec mCodec; michael@0: int mBitrate; michael@0: int mSamplerate; michael@0: int mChannels; michael@0: }; michael@0: michael@0: class RecorderProfile michael@0: { michael@0: public: michael@0: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RecorderProfile) michael@0: michael@0: RecorderProfile(uint32_t aCameraId, uint32_t aQualityIndex); michael@0: michael@0: virtual const RecorderVideoProfile* GetVideoProfile() const = 0; michael@0: virtual const RecorderAudioProfile* GetAudioProfile() const = 0; michael@0: const char* GetName() const { return mName; } michael@0: michael@0: enum FileFormat { michael@0: THREE_GPP, michael@0: MPEG4, michael@0: UNKNOWN michael@0: }; michael@0: FileFormat GetFileFormat() const { return mFileFormat; } michael@0: const char* GetFileFormatName() const michael@0: { michael@0: switch (mFileFormat) { michael@0: case THREE_GPP: return "3gp"; michael@0: case MPEG4: return "mp4"; michael@0: default: return nullptr; michael@0: } michael@0: } michael@0: const char* GetFileMimeType() const michael@0: { michael@0: switch (mFileFormat) { michael@0: case THREE_GPP: return VIDEO_3GPP; michael@0: case MPEG4: return VIDEO_MP4; michael@0: default: return nullptr; michael@0: } michael@0: } michael@0: michael@0: virtual nsresult GetJsObject(JSContext* aCx, JSObject** aObject) = 0; michael@0: michael@0: protected: michael@0: virtual ~RecorderProfile(); michael@0: michael@0: uint32_t mCameraId; michael@0: uint32_t mQualityIndex; michael@0: const char* mName; michael@0: FileFormat mFileFormat; michael@0: }; michael@0: michael@0: template michael@0: class RecorderProfileBase : public RecorderProfile michael@0: { michael@0: public: michael@0: RecorderProfileBase(uint32_t aCameraId, uint32_t aQualityIndex) michael@0: : RecorderProfile(aCameraId, aQualityIndex) michael@0: , mVideo(aCameraId, aQualityIndex) michael@0: , mAudio(aCameraId, aQualityIndex) michael@0: { michael@0: DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); michael@0: } michael@0: michael@0: virtual ~RecorderProfileBase() michael@0: { michael@0: DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); michael@0: } michael@0: michael@0: const RecorderVideoProfile* GetVideoProfile() const { return &mVideo; } michael@0: const RecorderAudioProfile* GetAudioProfile() const { return &mAudio; } michael@0: michael@0: nsresult GetJsObject(JSContext* aCx, JSObject** aObject) michael@0: { michael@0: NS_ENSURE_TRUE(aObject, NS_ERROR_INVALID_ARG); michael@0: michael@0: const char* format = GetFileFormatName(); michael@0: if (!format) { michael@0: // the profile must have a file format michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: JS::Rooted o(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr())); michael@0: if (!o) { michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: michael@0: JS::Rooted s(aCx, JS_NewStringCopyZ(aCx, format)); michael@0: JS::Rooted v(aCx, STRING_TO_JSVAL(s)); michael@0: if (!JS_SetProperty(aCx, o, "format", v)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: JS::Rooted video(aCx); michael@0: nsresult rv = mVideo.GetJsObject(aCx, video.address()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: v = OBJECT_TO_JSVAL(video); michael@0: if (!JS_SetProperty(aCx, o, "video", v)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: JS::Rooted audio(aCx); michael@0: rv = mAudio.GetJsObject(aCx, audio.address()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: v = OBJECT_TO_JSVAL(audio); michael@0: if (!JS_SetProperty(aCx, o, "audio", v)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: *aObject = o; michael@0: return NS_OK; michael@0: } michael@0: michael@0: protected: michael@0: Video mVideo; michael@0: Audio mAudio; michael@0: }; michael@0: michael@0: class RecorderProfileManager michael@0: { michael@0: public: michael@0: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RecorderProfileManager) michael@0: michael@0: virtual bool IsSupported(uint32_t aQualityIndex) const { return true; } michael@0: virtual already_AddRefed Get(uint32_t aQualityIndex) const = 0; michael@0: michael@0: uint32_t GetMaxQualityIndex() const { return mMaxQualityIndex; } michael@0: nsresult GetJsObject(JSContext* aCx, JSObject** aObject) const; michael@0: michael@0: protected: michael@0: RecorderProfileManager(uint32_t aCameraId); michael@0: virtual ~RecorderProfileManager(); michael@0: michael@0: uint32_t mCameraId; michael@0: uint32_t mMaxQualityIndex; michael@0: }; michael@0: michael@0: } // namespace mozilla michael@0: michael@0: #endif // DOM_CAMERA_CAMERA_RECORDER_PROFILES_H