diff -r 000000000000 -r 6474c204b198 dom/camera/CameraRecorderProfiles.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/camera/CameraRecorderProfiles.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,231 @@ +/* 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; + } + } + + 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 + }; + +public: + 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; + } + } + + 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; + } + } + + virtual nsresult GetJsObject(JSContext* aCx, JSObject** aObject) = 0; + +protected: + virtual ~RecorderProfile(); + + uint32_t mCameraId; + uint32_t mQualityIndex; + const char* mName; + FileFormat mFileFormat; +}; + +template +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; } + + 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_FAILURE; + } + + JS::Rooted o(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr())); + if (!o) { + return NS_ERROR_OUT_OF_MEMORY; + } + + JS::Rooted s(aCx, JS_NewStringCopyZ(aCx, format)); + JS::Rooted v(aCx, STRING_TO_JSVAL(s)); + if (!JS_SetProperty(aCx, o, "format", v)) { + return NS_ERROR_FAILURE; + } + + JS::Rooted 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 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 Get(uint32_t aQualityIndex) const = 0; + + uint32_t GetMaxQualityIndex() const { return mMaxQualityIndex; } + nsresult GetJsObject(JSContext* aCx, JSObject** aObject) const; + +protected: + RecorderProfileManager(uint32_t aCameraId); + virtual ~RecorderProfileManager(); + + uint32_t mCameraId; + uint32_t mMaxQualityIndex; +}; + +} // namespace mozilla + +#endif // DOM_CAMERA_CAMERA_RECORDER_PROFILES_H