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 <media/MediaProfiles.h>
18 #include "GonkRecorder.h"
19 #include "CameraControlImpl.h"
20 #include "GonkRecorderProfiles.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
)
96 static const size_t SIZE
= 256;
100 CHECK_SETARG(aRecorder
->setAudioSource(AUDIO_SOURCE_CAMCORDER
));
101 CHECK_SETARG(aRecorder
->setVideoSource(VIDEO_SOURCE_CAMERA
));
102 CHECK_SETARG(aRecorder
->setOutputFormat(GetOutputFormat()));
103 CHECK_SETARG(aRecorder
->setVideoFrameRate(mVideo
.GetFramerate()));
104 CHECK_SETARG(aRecorder
->setVideoSize(mVideo
.GetWidth(), mVideo
.GetHeight()));
105 CHECK_SETARG(aRecorder
->setVideoEncoder(mVideo
.GetPlatformCodec()));
106 CHECK_SETARG(aRecorder
->setAudioEncoder(mAudio
.GetPlatformCodec()));
108 snprintf(buffer
, SIZE
, "video-param-encoding-bitrate=%d", mVideo
.GetBitrate());
109 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
111 snprintf(buffer
, SIZE
, "audio-param-encoding-bitrate=%d", mAudio
.GetBitrate());
112 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
114 snprintf(buffer
, SIZE
, "audio-param-number-of-channels=%d", mAudio
.GetChannels());
115 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
117 snprintf(buffer
, SIZE
, "audio-param-sampling-rate=%d", mAudio
.GetSamplerate());
118 CHECK_SETARG(aRecorder
->setParameters(String8(buffer
)));
124 * Recorder audio profile.
126 static RecorderAudioProfile::Codec
127 TranslateAudioCodec(audio_encoder aCodec
)
130 case AUDIO_ENCODER_AMR_NB
: return RecorderAudioProfile::AMRNB
;
131 case AUDIO_ENCODER_AMR_WB
: return RecorderAudioProfile::AMRWB
;
132 case AUDIO_ENCODER_AAC
: return RecorderAudioProfile::AAC
;
133 default: return RecorderAudioProfile::UNKNOWN
;
137 GonkRecorderAudioProfile::GonkRecorderAudioProfile(uint32_t aCameraId
, uint32_t aQualityIndex
)
138 : RecorderAudioProfile(aCameraId
, aQualityIndex
)
140 DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__
, __LINE__
, this, mCameraId
, mQualityIndex
);
141 mPlatformCodec
= static_cast<audio_encoder
>(GetProfileParam(mCameraId
, mQualityIndex
, "aud.codec"));
142 mCodec
= TranslateAudioCodec(mPlatformCodec
);
143 mBitrate
= GetProfileParam(mCameraId
, mQualityIndex
, "aud.bps");
144 mSamplerate
= GetProfileParam(mCameraId
, mQualityIndex
, "aud.hz");
145 mChannels
= GetProfileParam(mCameraId
, mQualityIndex
, "aud.ch");
148 GonkRecorderAudioProfile::~GonkRecorderAudioProfile()
150 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
154 * Recorder video profile.
156 static RecorderVideoProfile::Codec
157 TranslateVideoCodec(video_encoder aCodec
)
160 case VIDEO_ENCODER_H263
: return RecorderVideoProfile::H263
;
161 case VIDEO_ENCODER_H264
: return RecorderVideoProfile::H264
;
162 case VIDEO_ENCODER_MPEG_4_SP
: return RecorderVideoProfile::MPEG4SP
;
163 default: return RecorderVideoProfile::UNKNOWN
;
167 GonkRecorderVideoProfile::GonkRecorderVideoProfile(uint32_t aCameraId
, uint32_t aQualityIndex
)
168 : RecorderVideoProfile(aCameraId
, aQualityIndex
)
170 DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraId=%d, mQualityIndex=%d\n", __func__
, __LINE__
, this, mCameraId
, mQualityIndex
);
171 mPlatformCodec
= static_cast<video_encoder
>(GetProfileParam(mCameraId
, mQualityIndex
, "vid.codec"));
172 mCodec
= TranslateVideoCodec(mPlatformCodec
);
173 mBitrate
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.bps");
174 mFramerate
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.fps");
175 mWidth
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.width");
176 mHeight
= GetProfileParam(mCameraId
, mQualityIndex
, "vid.height");
179 GonkRecorderVideoProfile::~GonkRecorderVideoProfile()
181 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
184 GonkRecorderProfileManager::GonkRecorderProfileManager(uint32_t aCameraId
)
185 : RecorderProfileManager(aCameraId
)
187 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
188 mMaxQualityIndex
= sizeof(ProfileList
) / sizeof(ProfileList
[0]) - 1;
191 GonkRecorderProfileManager::~GonkRecorderProfileManager()
193 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
197 GonkRecorderProfileManager::IsSupported(uint32_t aQualityIndex
) const
199 if (!IsQualitySupported(mCameraId
, aQualityIndex
)) {
200 // This profile is not supported
204 int width
= GetProfileParam(mCameraId
, aQualityIndex
, "vid.width");
205 int height
= GetProfileParam(mCameraId
, aQualityIndex
, "vid.height");
206 if (width
== -1 || height
== -1) {
207 // This would be unexpected, but we handle it just in case
208 DOM_CAMERA_LOGE("Camera %d recorder profile %d has width=%d, height=%d\n", mCameraId
, aQualityIndex
, width
, height
);
212 for (uint32_t i
= 0; i
< mSupportedSizes
.Length(); ++i
) {
213 if (static_cast<uint32_t>(width
) == mSupportedSizes
[i
].width
&&
214 static_cast<uint32_t>(height
) == mSupportedSizes
[i
].height
)
222 already_AddRefed
<RecorderProfile
>
223 GonkRecorderProfileManager::Get(uint32_t aQualityIndex
) const
225 // This overrides virtual RecorderProfileManager::Get(...)
226 DOM_CAMERA_LOGT("%s:%d : aQualityIndex=%d\n", __func__
, __LINE__
, aQualityIndex
);
227 nsRefPtr
<RecorderProfile
> profile
= new GonkRecorderProfile(mCameraId
, aQualityIndex
);
228 return profile
.forget();
231 already_AddRefed
<GonkRecorderProfile
>
232 GonkRecorderProfileManager::Get(const char* aProfileName
) const
234 DOM_CAMERA_LOGT("%s:%d : aProfileName='%s'\n", __func__
, __LINE__
, aProfileName
);
235 for (uint32_t i
= 0; i
< mMaxQualityIndex
; ++i
) {
236 if (strcmp(ProfileList
[i
].name
, aProfileName
) == 0) {
237 nsRefPtr
<GonkRecorderProfile
> profile
= nullptr;
238 if (IsSupported(i
)) {
239 profile
= new GonkRecorderProfile(mCameraId
, i
);
240 return profile
.forget();
246 DOM_CAMERA_LOGW("Couldn't file recorder profile named '%s'\n", aProfileName
);