blob: f2107ece4c357df7baf77aafe614253b8cb7927a [file] [log] [blame]
James Dongc3711942010-01-19 17:45:38 -08001/*
2 **
3 ** Copyright 2010, The Android Open Source Project.
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18#ifndef ANDROID_MEDIAPROFILES_H
19#define ANDROID_MEDIAPROFILES_H
20
21#include <utils/threads.h>
22#include <media/mediarecorder.h>
23
24namespace android {
25
26enum camcorder_quality {
James Dong797e4f12011-02-28 21:07:39 -080027 CAMCORDER_QUALITY_LIST_START = 0,
James Donge64d9a22010-03-31 13:56:29 -070028 CAMCORDER_QUALITY_LOW = 0,
Nipun Kwatra4af0dfd2010-09-06 15:59:02 -070029 CAMCORDER_QUALITY_HIGH = 1,
30 CAMCORDER_QUALITY_QCIF = 2,
Nipun Kwatra522632c2010-09-10 15:45:57 -070031 CAMCORDER_QUALITY_CIF = 3,
32 CAMCORDER_QUALITY_480P = 4,
33 CAMCORDER_QUALITY_720P = 5,
34 CAMCORDER_QUALITY_1080P = 6,
James Dong797e4f12011-02-28 21:07:39 -080035 CAMCORDER_QUALITY_LIST_END = 6,
Nipun Kwatra4af0dfd2010-09-06 15:59:02 -070036
James Dong797e4f12011-02-28 21:07:39 -080037 CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
Nipun Kwatra4af0dfd2010-09-06 15:59:02 -070038 CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000,
39 CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
40 CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
Nipun Kwatra522632c2010-09-10 15:45:57 -070041 CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
42 CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
43 CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
James Dong797e4f12011-02-28 21:07:39 -080044 CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
45 CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1006,
James Dongc3711942010-01-19 17:45:38 -080046};
47
48enum video_decoder {
49 VIDEO_DECODER_WMV,
50};
51
52enum audio_decoder {
53 AUDIO_DECODER_WMA,
54};
55
56
57class MediaProfiles
58{
59public:
60
61 /**
62 * Returns the singleton instance for subsequence queries.
63 * or NULL if error.
64 */
65 static MediaProfiles* getInstance();
66
67 /**
Chih-Chung Chang09b90052010-06-22 20:50:55 +080068 * Returns the value for the given param name for the given camera at
69 * the given quality level, or -1 if error.
James Dongc3711942010-01-19 17:45:38 -080070 *
71 * Supported param name are:
James Dong9b433f02010-02-23 17:21:44 -080072 * duration - the recording duration.
James Dongc3711942010-01-19 17:45:38 -080073 * file.format - output file format. see mediarecorder.h for details
James Donge7038ac2010-02-03 16:50:18 -080074 * vid.codec - video encoder. see mediarecorder.h for details.
75 * aud.codec - audio encoder. see mediarecorder.h for details.
James Dongc3711942010-01-19 17:45:38 -080076 * vid.width - video frame width
77 * vid.height - video frame height
78 * vid.fps - video frame rate
79 * vid.bps - video bit rate
80 * aud.bps - audio bit rate
81 * aud.hz - audio sample rate
82 * aud.ch - number of audio channels
83 */
Chih-Chung Chang09b90052010-06-22 20:50:55 +080084 int getCamcorderProfileParamByName(const char *name, int cameraId,
85 camcorder_quality quality) const;
James Dongc3711942010-01-19 17:45:38 -080086
87 /**
Nipun Kwatra9d619542010-09-09 16:25:08 -070088 * Returns true if a profile for the given camera at the given quality exists,
89 * or false if not.
90 */
91 bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const;
92
93 /**
James Dongc3711942010-01-19 17:45:38 -080094 * Returns the output file formats supported.
95 */
96 Vector<output_format> getOutputFileFormats() const;
97
98 /**
99 * Returns the video encoders supported.
100 */
101 Vector<video_encoder> getVideoEncoders() const;
102
103 /**
104 * Returns the value for the given param name for the given video encoder
105 * returned from getVideoEncoderByIndex or -1 if error.
106 *
107 * Supported param name are:
108 * enc.vid.width.min - min video frame width
109 * enc.vid.width.max - max video frame width
110 * enc.vid.height.min - min video frame height
111 * enc.vid.height.max - max video frame height
112 * enc.vid.bps.min - min bit rate in bits per second
113 * enc.vid.bps.max - max bit rate in bits per second
114 * enc.vid.fps.min - min frame rate in frames per second
115 * enc.vid.fps.max - max frame rate in frames per second
116 */
117 int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
118
119 /**
120 * Returns the audio encoders supported.
121 */
122 Vector<audio_encoder> getAudioEncoders() const;
123
124 /**
125 * Returns the value for the given param name for the given audio encoder
126 * returned from getAudioEncoderByIndex or -1 if error.
127 *
128 * Supported param name are:
129 * enc.aud.ch.min - min number of channels
130 * enc.aud.ch.max - max number of channels
131 * enc.aud.bps.min - min bit rate in bits per second
132 * enc.aud.bps.max - max bit rate in bits per second
133 * enc.aud.hz.min - min sample rate in samples per second
134 * enc.aud.hz.max - max sample rate in samples per second
135 */
136 int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
137
138 /**
139 * Returns the video decoders supported.
140 */
141 Vector<video_decoder> getVideoDecoders() const;
142
143 /**
144 * Returns the audio decoders supported.
145 */
146 Vector<audio_decoder> getAudioDecoders() const;
147
James Dong9b433f02010-02-23 17:21:44 -0800148 /**
149 * Returns the number of image encoding quality levels supported.
150 */
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800151 Vector<int> getImageEncodingQualityLevels(int cameraId) const;
James Dong9b433f02010-02-23 17:21:44 -0800152
James Dongc3711942010-01-19 17:45:38 -0800153private:
James Dong797e4f12011-02-28 21:07:39 -0800154 enum {
155 // Camcorder profiles (high/low) and timelapse profiles (high/low)
156 kNumRequiredProfiles = 4,
157 };
158
James Dongc3711942010-01-19 17:45:38 -0800159 MediaProfiles& operator=(const MediaProfiles&); // Don't call me
160 MediaProfiles(const MediaProfiles&); // Don't call me
161 MediaProfiles() {} // Dummy default constructor
162 ~MediaProfiles(); // Don't delete me
163
164 struct VideoCodec {
165 VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate)
166 : mCodec(codec),
167 mBitRate(bitRate),
168 mFrameWidth(frameWidth),
169 mFrameHeight(frameHeight),
170 mFrameRate(frameRate) {}
171
James Dong797e4f12011-02-28 21:07:39 -0800172 VideoCodec(const VideoCodec& copy) {
173 mCodec = copy.mCodec;
174 mBitRate = copy.mBitRate;
175 mFrameWidth = copy.mFrameWidth;
176 mFrameHeight = copy.mFrameHeight;
177 mFrameRate = copy.mFrameRate;
178 }
179
James Dongc3711942010-01-19 17:45:38 -0800180 ~VideoCodec() {}
181
182 video_encoder mCodec;
183 int mBitRate;
184 int mFrameWidth;
185 int mFrameHeight;
186 int mFrameRate;
187 };
188
189 struct AudioCodec {
190 AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
191 : mCodec(codec),
192 mBitRate(bitRate),
193 mSampleRate(sampleRate),
194 mChannels(channels) {}
195
James Dong797e4f12011-02-28 21:07:39 -0800196 AudioCodec(const AudioCodec& copy) {
197 mCodec = copy.mCodec;
198 mBitRate = copy.mBitRate;
199 mSampleRate = copy.mSampleRate;
200 mChannels = copy.mChannels;
201 }
202
James Dongc3711942010-01-19 17:45:38 -0800203 ~AudioCodec() {}
204
205 audio_encoder mCodec;
206 int mBitRate;
207 int mSampleRate;
208 int mChannels;
209 };
210
211 struct CamcorderProfile {
212 CamcorderProfile()
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800213 : mCameraId(0),
214 mFileFormat(OUTPUT_FORMAT_THREE_GPP),
James Dongc3711942010-01-19 17:45:38 -0800215 mQuality(CAMCORDER_QUALITY_HIGH),
216 mDuration(0),
217 mVideoCodec(0),
218 mAudioCodec(0) {}
219
James Dong797e4f12011-02-28 21:07:39 -0800220 CamcorderProfile(const CamcorderProfile& copy) {
221 mCameraId = copy.mCameraId;
222 mFileFormat = copy.mFileFormat;
223 mQuality = copy.mQuality;
224 mDuration = copy.mDuration;
225 mVideoCodec = new VideoCodec(*copy.mVideoCodec);
226 mAudioCodec = new AudioCodec(*copy.mAudioCodec);
227 }
228
James Dongc3711942010-01-19 17:45:38 -0800229 ~CamcorderProfile() {
230 delete mVideoCodec;
231 delete mAudioCodec;
232 }
233
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800234 int mCameraId;
James Dongc3711942010-01-19 17:45:38 -0800235 output_format mFileFormat;
236 camcorder_quality mQuality;
237 int mDuration;
238 VideoCodec *mVideoCodec;
239 AudioCodec *mAudioCodec;
240 };
241
242 struct VideoEncoderCap {
243 // Ugly constructor
244 VideoEncoderCap(video_encoder codec,
245 int minBitRate, int maxBitRate,
246 int minFrameWidth, int maxFrameWidth,
247 int minFrameHeight, int maxFrameHeight,
248 int minFrameRate, int maxFrameRate)
249 : mCodec(codec),
250 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
251 mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
252 mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
253 mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
254
255 ~VideoEncoderCap() {}
256
257 video_encoder mCodec;
258 int mMinBitRate, mMaxBitRate;
259 int mMinFrameWidth, mMaxFrameWidth;
260 int mMinFrameHeight, mMaxFrameHeight;
261 int mMinFrameRate, mMaxFrameRate;
262 };
263
264 struct AudioEncoderCap {
265 // Ugly constructor
266 AudioEncoderCap(audio_encoder codec,
267 int minBitRate, int maxBitRate,
268 int minSampleRate, int maxSampleRate,
269 int minChannels, int maxChannels)
270 : mCodec(codec),
271 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
272 mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
273 mMinChannels(minChannels), mMaxChannels(maxChannels) {}
274
275 ~AudioEncoderCap() {}
276
277 audio_encoder mCodec;
278 int mMinBitRate, mMaxBitRate;
279 int mMinSampleRate, mMaxSampleRate;
280 int mMinChannels, mMaxChannels;
281 };
282
283 struct VideoDecoderCap {
284 VideoDecoderCap(video_decoder codec): mCodec(codec) {}
285 ~VideoDecoderCap() {}
286
287 video_decoder mCodec;
288 };
289
290 struct AudioDecoderCap {
291 AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
292 ~AudioDecoderCap() {}
293
294 audio_decoder mCodec;
295 };
296
297 struct NameToTagMap {
298 const char* name;
299 int tag;
300 };
301
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800302 struct ImageEncodingQualityLevels {
303 int mCameraId;
304 Vector<int> mLevels;
305 };
306
Nipun Kwatra9d619542010-09-09 16:25:08 -0700307 int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
James Dong797e4f12011-02-28 21:07:39 -0800308 void initRequiredProfileRefs(const Vector<int>& cameraIds);
309 int getRequiredProfileRefIndex(int cameraId);
Nipun Kwatra9d619542010-09-09 16:25:08 -0700310
James Dongc3711942010-01-19 17:45:38 -0800311 // Debug
312 static void logVideoCodec(const VideoCodec& codec);
313 static void logAudioCodec(const AudioCodec& codec);
314 static void logVideoEncoderCap(const VideoEncoderCap& cap);
315 static void logAudioEncoderCap(const AudioEncoderCap& cap);
316 static void logVideoDecoderCap(const VideoDecoderCap& cap);
317 static void logAudioDecoderCap(const AudioDecoderCap& cap);
318
319 // If the xml configuration file does exist, use the settings
320 // from the xml
321 static MediaProfiles* createInstanceFromXmlFile(const char *xml);
322 static output_format createEncoderOutputFileFormat(const char **atts);
323 static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles);
324 static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles);
325 static AudioDecoderCap* createAudioDecoderCap(const char **atts);
326 static VideoDecoderCap* createVideoDecoderCap(const char **atts);
327 static VideoEncoderCap* createVideoEncoderCap(const char **atts);
328 static AudioEncoderCap* createAudioEncoderCap(const char **atts);
James Dong797e4f12011-02-28 21:07:39 -0800329
330 static CamcorderProfile* createCamcorderProfile(
331 int cameraId, const char **atts, Vector<int>& cameraIds);
332
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800333 static int getCameraId(const char **atts);
334
335 ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
336 void addImageEncodingQualityLevel(int cameraId, const char** atts);
James Dongc3711942010-01-19 17:45:38 -0800337
338 // Customized element tag handler for parsing the xml configuration file.
339 static void startElementHandler(void *userData, const char *name, const char **atts);
340
341 // If the xml configuration file does not exist, use hard-coded values
342 static MediaProfiles* createDefaultInstance();
Nipun Kwatrad48a15c2010-09-16 22:25:23 -0700343
344 static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality);
345 static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality);
346 static void createDefaultCamcorderLowProfiles(
347 MediaProfiles::CamcorderProfile **lowProfile,
348 MediaProfiles::CamcorderProfile **lowSpecificProfile);
349 static void createDefaultCamcorderHighProfiles(
350 MediaProfiles::CamcorderProfile **highProfile,
351 MediaProfiles::CamcorderProfile **highSpecificProfile);
352
353 static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality);
354 static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality);
355 static void createDefaultCamcorderTimeLapseLowProfiles(
356 MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
357 MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile);
358 static void createDefaultCamcorderTimeLapseHighProfiles(
359 MediaProfiles::CamcorderProfile **highTimeLapseProfile,
360 MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile);
361
James Dongc3711942010-01-19 17:45:38 -0800362 static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
363 static void createDefaultVideoEncoders(MediaProfiles *profiles);
364 static void createDefaultAudioEncoders(MediaProfiles *profiles);
365 static void createDefaultVideoDecoders(MediaProfiles *profiles);
366 static void createDefaultAudioDecoders(MediaProfiles *profiles);
367 static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
James Dong9b433f02010-02-23 17:21:44 -0800368 static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
369 static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
James Dongc3711942010-01-19 17:45:38 -0800370 static VideoEncoderCap* createDefaultH263VideoEncoderCap();
371 static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
372 static AudioEncoderCap* createDefaultAmrNBEncoderCap();
373
374 static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
375
James Dong797e4f12011-02-28 21:07:39 -0800376 /**
377 * Check on existing profiles with the following criteria:
378 * 1. Low quality profile must have the lowest video
379 * resolution product (width x height)
380 * 2. High quality profile must have the highest video
381 * resolution product (width x height)
382 *
383 * and add required low/high quality camcorder/timelapse
384 * profiles if they are not found. This allows to remove
385 * duplicate profile definitions in the media_profiles.xml
386 * file.
387 */
388 void checkAndAddRequiredProfilesIfNecessary();
389
390
James Dongc3711942010-01-19 17:45:38 -0800391 // Mappings from name (for instance, codec name) to enum value
392 static const NameToTagMap sVideoEncoderNameMap[];
393 static const NameToTagMap sAudioEncoderNameMap[];
394 static const NameToTagMap sFileFormatMap[];
395 static const NameToTagMap sVideoDecoderNameMap[];
396 static const NameToTagMap sAudioDecoderNameMap[];
397 static const NameToTagMap sCamcorderQualityNameMap[];
398
399 static bool sIsInitialized;
400 static MediaProfiles *sInstance;
401 static Mutex sLock;
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800402 int mCurrentCameraId;
James Dongc3711942010-01-19 17:45:38 -0800403
404 Vector<CamcorderProfile*> mCamcorderProfiles;
405 Vector<AudioEncoderCap*> mAudioEncoders;
406 Vector<VideoEncoderCap*> mVideoEncoders;
407 Vector<AudioDecoderCap*> mAudioDecoders;
408 Vector<VideoDecoderCap*> mVideoDecoders;
409 Vector<output_format> mEncoderOutputFileFormats;
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800410 Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
James Dong797e4f12011-02-28 21:07:39 -0800411
412 typedef struct {
413 bool mHasRefProfile; // Refers to an existing profile
414 int mRefProfileIndex; // Reference profile index
415 int mResolutionProduct; // width x height
416 } RequiredProfileRefInfo; // Required low and high profiles
417
418 typedef struct {
419 RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
420 int mCameraId;
421 } RequiredProfiles;
422
423 RequiredProfiles *mRequiredProfileRefs;
424 Vector<int> mCameraIds;
James Dongc3711942010-01-19 17:45:38 -0800425};
426
427}; // namespace android
428
429#endif // ANDROID_MEDIAPROFILES_H
430