2 * Copyright (C) 2012 Mozilla Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "GonkRecorderProfiles.h"
18 #include <media/MediaProfiles.h>
19 #include "GonkRecorder.h"
20 #include "CameraControlImpl.h"
21 #include "CameraCommon.h"
23 using namespace mozilla
;
24 using namespace android
;
26 #define DEF_GONK_RECORDER_PROFILE(e, n) e##_INDEX,
28 #include "GonkRecorderProfiles.def"
32 #define DEF_GONK_RECORDER_PROFILE(e, n) { n, e },
37 #include "GonkRecorderProfiles.def"
41 static MediaProfiles
* sMediaProfiles
= nullptr;
44 IsQualitySupported(uint32_t aCameraId
, uint32_t aQualityIndex
)
46 if (!sMediaProfiles
) {
47 sMediaProfiles
= MediaProfiles::getInstance();
49 camcorder_quality q
= static_cast<camcorder_quality
>(ProfileList
[aQualityIndex
].quality
);
50 return sMediaProfiles
->hasCamcorderProfile(static_cast<int>(aCameraId
), q
);
54 GetProfileParam(uint32_t aCameraId
, uint32_t aQualityIndex
, const char* aParam
)
56 if (!sMediaProfiles
) {
57 sMediaProfiles
= MediaProfiles::getInstance();
59 camcorder_quality q
= static_cast<camcorder_quality
>(ProfileList
[aQualityIndex
].quality
);
60 return sMediaProfiles
->getCamcorderProfileParamByName(aParam
, static_cast<int>(aCameraId
), q
);
66 static RecorderProfile::FileFormat
67 TranslateFileFormat(output_format aFileFormat
)
69 switch (aFileFormat
) {
70 case OUTPUT_FORMAT_THREE_GPP
: return RecorderProfile::THREE_GPP
;
71 case OUTPUT_FORMAT_MPEG_4
: return RecorderProfile::MPEG4
;
72 default: return RecorderProfile::UNKNOWN
;
76 GonkRecorderProfile::GonkRecorderProfile(uint32_t aCameraId
, uint32_t aQualityIndex
)
77 : RecorderProfileBase
<GonkRecorderAudioProfile
, GonkRecorderVideoProfile
>(aCameraId
, aQualityIndex
)
79 DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__
, __LINE__
, this, mCameraId
, mQualityIndex
);
80 mPlatformOutputFormat
= static_cast<output_format
>(GetProfileParam(mCameraId
, mQualityIndex
, "file.format"));
81 mFileFormat
= TranslateFileFormat(mPlatformOutputFormat
);
82 if (aQualityIndex
< PROFILE_COUNT
) {
83 mName
= ProfileList
[aQualityIndex
].name
;
84 DOM_CAMERA_LOGI("Created camera %d profile index %d: '%s'\n", mCameraId
, mQualityIndex
, mName
);
88 GonkRecorderProfile::~GonkRecorderProfile()
90 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
94 GonkRecorderProfile::ConfigureRecorder(GonkRecorder
* aRecorder
)
97 DOM_CAMERA_LOGW("ConfigureRecorder() called with null aRecorder\n");
98 return NS_ERROR_INVALID_ARG
;
101 static const size_t SIZE
= 256;
104 // set all the params
105 CHECK_SETARG(aRecorder
->setAudioSource(AUDIO_SOURCE_CAMCORDER
));
106 CHECK_SETARG(aRecorder
->setVideoSource(VIDEO_SOURCE_CAMERA
));
107 CHECK_SETARG(aRecorder
->setOutputFormat(GetOutputFormat()));
108 CHECK_SETARG(aRecorder
->setVideoFrameRate(mVideo
.GetFramerate()));
109 CHECK_SETARG(aRecorder
->setVideoSize(mVideo
.GetWidth(), mVideo
.GetHeight()));
110 CHECK_SETARG(aRecorder
->setVideoEncoder(mVideo
.GetPlatformCodec()));
111 CHECK_SETARG(aRecorder
->setAudioEncoder(mAudio
.GetPlatformCodec()));
113 snprintf(buffer
, SIZE
, "video-param-encoding-bitrate=%d", mVideo
.GetBitrate());
114 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
116 snprintf(buffer
, SIZE
, "audio-param-encoding-bitrate=%d", mAudio
.GetBitrate());
117 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
119 snprintf(buffer
, SIZE
, "audio-param-number-of-channels=%d", mAudio
.GetChannels());
120 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
122 snprintf(buffer
, SIZE
, "audio-param-sampling-rate=%d", mAudio
.GetSamplerate());
123 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
129 * Recorder audio profile.
131 static RecorderAudioProfile::Codec
132 TranslateAudioCodec(audio_encoder aCodec
)
135 case AUDIO_ENCODER_AMR_NB
: return RecorderAudioProfile::AMRNB
;
136 case AUDIO_ENCODER_AMR_WB
: return RecorderAudioProfile::AMRWB
;
137 case AUDIO_ENCODER_AAC
: return RecorderAudioProfile::AAC
;
138 default: return RecorderAudioProfile::UNKNOWN
;
142 GonkRecorderAudioProfile::GonkRecorderAudioProfile(uint32_t aCameraId
, uint32_t aQualityIndex
)
143 : RecorderAudioProfile(aCameraId
, aQualityIndex
)
145 DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__
, __LINE__
, this, mCameraId
, mQualityIndex
);
146 mPlatformCodec
= static_cast<audio_encoder
>(GetProfileParam(mCameraId
, mQualityIndex
, "aud.codec"));
147 mCodec
= TranslateAudioCodec(mPlatformCodec
);
148 mBitrate
= GetProfileParam(mCameraId
, mQualityIndex
, "aud.bps");
149 mSamplerate
= GetProfileParam(mCameraId
, mQualityIndex
, "aud.hz");
150 mChannels
= GetProfileParam(mCameraId
, mQualityIndex
, "aud.ch");
153 GonkRecorderAudioProfile::~GonkRecorderAudioProfile()
155 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
159 * Recorder video profile.
161 static RecorderVideoProfile::Codec
162 TranslateVideoCodec(video_encoder aCodec
)
165 case VIDEO_ENCODER_H263
: return RecorderVideoProfile::H263
;
166 case VIDEO_ENCODER_H264
: return RecorderVideoProfile::H264
;
167 case VIDEO_ENCODER_MPEG_4_SP
: return RecorderVideoProfile::MPEG4SP
;
168 default: return RecorderVideoProfile::UNKNOWN
;
172 GonkRecorderVideoProfile::GonkRecorderVideoProfile(uint32_t aCameraId
, uint32_t aQualityIndex
)
173 : RecorderVideoProfile(aCameraId
, aQualityIndex
)
175 DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__
, __LINE__
, this, mCameraId
, mQualityIndex
);
176 mPlatformCodec
= static_cast<video_encoder
>(GetProfileParam(mCameraId
, mQualityIndex
, "vid.codec"));
177 mCodec
= TranslateVideoCodec(mPlatformCodec
);
178 mBitrate
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.bps");
179 mFramerate
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.fps");
180 mWidth
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.width");
181 mHeight
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.height");
184 GonkRecorderVideoProfile::~GonkRecorderVideoProfile()
186 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
189 GonkRecorderProfileManager::GonkRecorderProfileManager(uint32_t aCameraId
)
190 : RecorderProfileManager(aCameraId
)
192 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
193 mMaxQualityIndex
= sizeof(ProfileList
) / sizeof(ProfileList
[0]) - 1;
196 GonkRecorderProfileManager::~GonkRecorderProfileManager()
198 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
202 GonkRecorderProfileManager::IsSupported(uint32_t aQualityIndex
) const
204 if (!IsQualitySupported(mCameraId
, aQualityIndex
)) {
205 // This profile is not supported
209 int width
= GetProfileParam(mCameraId
, aQualityIndex
, "vid.width");
210 int height
= GetProfileParam(mCameraId
, aQualityIndex
, "vid.height");
211 if (width
== -1 || height
== -1) {
212 // This would be unexpected, but we handle it just in case
213 DOM_CAMERA_LOGE("Camera %d recorder profile %d has width=%d, height=%d\n", mCameraId
, aQualityIndex
, width
, height
);
217 for (uint32_t i
= 0; i
< mSupportedSizes
.Length(); ++i
) {
218 if (static_cast<uint32_t>(width
) == mSupportedSizes
[i
].width
&&
219 static_cast<uint32_t>(height
) == mSupportedSizes
[i
].height
)
227 already_AddRefed
<RecorderProfile
>
228 GonkRecorderProfileManager::Get(uint32_t aQualityIndex
) const
230 // This overrides virtual RecorderProfileManager::Get(...)
231 DOM_CAMERA_LOGT("%s:%d : aQualityIndex=%d\n", __func__
, __LINE__
, aQualityIndex
);
232 nsRefPtr
<RecorderProfile
> profile
= new GonkRecorderProfile(mCameraId
, aQualityIndex
);
233 return profile
.forget();
236 already_AddRefed
<GonkRecorderProfile
>
237 GonkRecorderProfileManager::Get(const char* aProfileName
) const
239 DOM_CAMERA_LOGT("%s:%d : aProfileName='%s'\n", __func__
, __LINE__
, aProfileName
);
240 for (uint32_t i
= 0; i
< mMaxQualityIndex
; ++i
) {
241 if (strcmp(ProfileList
[i
].name
, aProfileName
) == 0) {
242 nsRefPtr
<GonkRecorderProfile
> profile
= nullptr;
243 if (IsSupported(i
)) {
244 profile
= new GonkRecorderProfile(mCameraId
, i
);
245 return profile
.forget();
251 DOM_CAMERA_LOGW("Couldn't file recorder profile named '%s'\n", aProfileName
);