blob: 69d50011d16f0ac46dbd9a1610eca4f413d2eeb0 [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
Hong Teng600acf12011-07-06 18:33:09 -070048/**
49 *Set CIF as default maximum import and export resolution of video editor.
50 *The maximum import and export resolutions are platform specific,
51 *which should be defined in media_profiles.xml.
52 */
53enum videoeditor_capability {
54 VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352,
55 VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288,
56 VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352,
57 VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288,
58};
59
James Dongc3711942010-01-19 17:45:38 -080060enum video_decoder {
61 VIDEO_DECODER_WMV,
62};
63
64enum audio_decoder {
65 AUDIO_DECODER_WMA,
66};
67
68
69class MediaProfiles
70{
71public:
72
73 /**
74 * Returns the singleton instance for subsequence queries.
75 * or NULL if error.
76 */
77 static MediaProfiles* getInstance();
78
79 /**
Chih-Chung Chang09b90052010-06-22 20:50:55 +080080 * Returns the value for the given param name for the given camera at
81 * the given quality level, or -1 if error.
James Dongc3711942010-01-19 17:45:38 -080082 *
83 * Supported param name are:
James Dong9b433f02010-02-23 17:21:44 -080084 * duration - the recording duration.
James Dongc3711942010-01-19 17:45:38 -080085 * file.format - output file format. see mediarecorder.h for details
James Donge7038ac2010-02-03 16:50:18 -080086 * vid.codec - video encoder. see mediarecorder.h for details.
87 * aud.codec - audio encoder. see mediarecorder.h for details.
James Dongc3711942010-01-19 17:45:38 -080088 * vid.width - video frame width
89 * vid.height - video frame height
90 * vid.fps - video frame rate
91 * vid.bps - video bit rate
92 * aud.bps - audio bit rate
93 * aud.hz - audio sample rate
94 * aud.ch - number of audio channels
95 */
Chih-Chung Chang09b90052010-06-22 20:50:55 +080096 int getCamcorderProfileParamByName(const char *name, int cameraId,
97 camcorder_quality quality) const;
James Dongc3711942010-01-19 17:45:38 -080098
99 /**
Nipun Kwatra9d619542010-09-09 16:25:08 -0700100 * Returns true if a profile for the given camera at the given quality exists,
101 * or false if not.
102 */
103 bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const;
104
105 /**
James Dongc3711942010-01-19 17:45:38 -0800106 * Returns the output file formats supported.
107 */
108 Vector<output_format> getOutputFileFormats() const;
109
110 /**
111 * Returns the video encoders supported.
112 */
113 Vector<video_encoder> getVideoEncoders() const;
114
115 /**
116 * Returns the value for the given param name for the given video encoder
117 * returned from getVideoEncoderByIndex or -1 if error.
118 *
119 * Supported param name are:
120 * enc.vid.width.min - min video frame width
121 * enc.vid.width.max - max video frame width
122 * enc.vid.height.min - min video frame height
123 * enc.vid.height.max - max video frame height
124 * enc.vid.bps.min - min bit rate in bits per second
125 * enc.vid.bps.max - max bit rate in bits per second
126 * enc.vid.fps.min - min frame rate in frames per second
127 * enc.vid.fps.max - max frame rate in frames per second
128 */
129 int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
130
131 /**
Hong Teng600acf12011-07-06 18:33:09 -0700132 * Returns the value for the given param name for the video editor cap
133 * param or -1 if error.
134 * Supported param name are:
135 * videoeditor.input.width.max - max input video frame width
136 * videoeditor.input.height.max - max input video frame height
137 * videoeditor.output.width.max - max output video frame width
138 * videoeditor.output.height.max - max output video frame height
139 */
140 int getVideoEditorCapParamByName(const char *name) const;
141
142 /**
James Dongc3711942010-01-19 17:45:38 -0800143 * Returns the audio encoders supported.
144 */
145 Vector<audio_encoder> getAudioEncoders() const;
146
147 /**
148 * Returns the value for the given param name for the given audio encoder
149 * returned from getAudioEncoderByIndex or -1 if error.
150 *
151 * Supported param name are:
152 * enc.aud.ch.min - min number of channels
153 * enc.aud.ch.max - max number of channels
154 * enc.aud.bps.min - min bit rate in bits per second
155 * enc.aud.bps.max - max bit rate in bits per second
156 * enc.aud.hz.min - min sample rate in samples per second
157 * enc.aud.hz.max - max sample rate in samples per second
158 */
159 int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
160
161 /**
162 * Returns the video decoders supported.
163 */
164 Vector<video_decoder> getVideoDecoders() const;
165
166 /**
167 * Returns the audio decoders supported.
168 */
169 Vector<audio_decoder> getAudioDecoders() const;
170
James Dong9b433f02010-02-23 17:21:44 -0800171 /**
172 * Returns the number of image encoding quality levels supported.
173 */
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800174 Vector<int> getImageEncodingQualityLevels(int cameraId) const;
James Dong9b433f02010-02-23 17:21:44 -0800175
James Donga403a932011-05-09 18:49:31 -0700176 /**
177 * Returns the start time offset (in ms) for the given camera Id.
178 * If the given camera Id does not exist, -1 will be returned.
179 */
180 int getStartTimeOffsetMs(int cameraId) const;
181
James Dongc3711942010-01-19 17:45:38 -0800182private:
James Dong797e4f12011-02-28 21:07:39 -0800183 enum {
184 // Camcorder profiles (high/low) and timelapse profiles (high/low)
185 kNumRequiredProfiles = 4,
186 };
187
James Dongc3711942010-01-19 17:45:38 -0800188 MediaProfiles& operator=(const MediaProfiles&); // Don't call me
189 MediaProfiles(const MediaProfiles&); // Don't call me
Hong Teng600acf12011-07-06 18:33:09 -0700190 MediaProfiles() { mVideoEditorCap = NULL; } // Dummy default constructor
James Dongc3711942010-01-19 17:45:38 -0800191 ~MediaProfiles(); // Don't delete me
192
193 struct VideoCodec {
194 VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate)
195 : mCodec(codec),
196 mBitRate(bitRate),
197 mFrameWidth(frameWidth),
198 mFrameHeight(frameHeight),
199 mFrameRate(frameRate) {}
200
James Dong797e4f12011-02-28 21:07:39 -0800201 VideoCodec(const VideoCodec& copy) {
202 mCodec = copy.mCodec;
203 mBitRate = copy.mBitRate;
204 mFrameWidth = copy.mFrameWidth;
205 mFrameHeight = copy.mFrameHeight;
206 mFrameRate = copy.mFrameRate;
207 }
208
James Dongc3711942010-01-19 17:45:38 -0800209 ~VideoCodec() {}
210
211 video_encoder mCodec;
212 int mBitRate;
213 int mFrameWidth;
214 int mFrameHeight;
215 int mFrameRate;
216 };
217
218 struct AudioCodec {
219 AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
220 : mCodec(codec),
221 mBitRate(bitRate),
222 mSampleRate(sampleRate),
223 mChannels(channels) {}
224
James Dong797e4f12011-02-28 21:07:39 -0800225 AudioCodec(const AudioCodec& copy) {
226 mCodec = copy.mCodec;
227 mBitRate = copy.mBitRate;
228 mSampleRate = copy.mSampleRate;
229 mChannels = copy.mChannels;
230 }
231
James Dongc3711942010-01-19 17:45:38 -0800232 ~AudioCodec() {}
233
234 audio_encoder mCodec;
235 int mBitRate;
236 int mSampleRate;
237 int mChannels;
238 };
239
240 struct CamcorderProfile {
241 CamcorderProfile()
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800242 : mCameraId(0),
243 mFileFormat(OUTPUT_FORMAT_THREE_GPP),
James Dongc3711942010-01-19 17:45:38 -0800244 mQuality(CAMCORDER_QUALITY_HIGH),
245 mDuration(0),
246 mVideoCodec(0),
247 mAudioCodec(0) {}
248
James Dong797e4f12011-02-28 21:07:39 -0800249 CamcorderProfile(const CamcorderProfile& copy) {
250 mCameraId = copy.mCameraId;
251 mFileFormat = copy.mFileFormat;
252 mQuality = copy.mQuality;
253 mDuration = copy.mDuration;
254 mVideoCodec = new VideoCodec(*copy.mVideoCodec);
255 mAudioCodec = new AudioCodec(*copy.mAudioCodec);
256 }
257
James Dongc3711942010-01-19 17:45:38 -0800258 ~CamcorderProfile() {
259 delete mVideoCodec;
260 delete mAudioCodec;
261 }
262
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800263 int mCameraId;
James Dongc3711942010-01-19 17:45:38 -0800264 output_format mFileFormat;
265 camcorder_quality mQuality;
266 int mDuration;
267 VideoCodec *mVideoCodec;
268 AudioCodec *mAudioCodec;
269 };
270
271 struct VideoEncoderCap {
272 // Ugly constructor
273 VideoEncoderCap(video_encoder codec,
274 int minBitRate, int maxBitRate,
275 int minFrameWidth, int maxFrameWidth,
276 int minFrameHeight, int maxFrameHeight,
277 int minFrameRate, int maxFrameRate)
278 : mCodec(codec),
279 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
280 mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
281 mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
282 mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
283
284 ~VideoEncoderCap() {}
285
286 video_encoder mCodec;
287 int mMinBitRate, mMaxBitRate;
288 int mMinFrameWidth, mMaxFrameWidth;
289 int mMinFrameHeight, mMaxFrameHeight;
290 int mMinFrameRate, mMaxFrameRate;
291 };
292
293 struct AudioEncoderCap {
294 // Ugly constructor
295 AudioEncoderCap(audio_encoder codec,
296 int minBitRate, int maxBitRate,
297 int minSampleRate, int maxSampleRate,
298 int minChannels, int maxChannels)
299 : mCodec(codec),
300 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
301 mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
302 mMinChannels(minChannels), mMaxChannels(maxChannels) {}
303
304 ~AudioEncoderCap() {}
305
306 audio_encoder mCodec;
307 int mMinBitRate, mMaxBitRate;
308 int mMinSampleRate, mMaxSampleRate;
309 int mMinChannels, mMaxChannels;
310 };
311
312 struct VideoDecoderCap {
313 VideoDecoderCap(video_decoder codec): mCodec(codec) {}
314 ~VideoDecoderCap() {}
315
316 video_decoder mCodec;
317 };
318
319 struct AudioDecoderCap {
320 AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
321 ~AudioDecoderCap() {}
322
323 audio_decoder mCodec;
324 };
325
326 struct NameToTagMap {
327 const char* name;
328 int tag;
329 };
330
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800331 struct ImageEncodingQualityLevels {
332 int mCameraId;
333 Vector<int> mLevels;
334 };
335
Hong Teng600acf12011-07-06 18:33:09 -0700336 struct VideoEditorCap {
337 VideoEditorCap(int inFrameWidth, int inFrameHeight,
338 int outFrameWidth, int outFrameHeight)
339 : mMaxInputFrameWidth(inFrameWidth),
340 mMaxInputFrameHeight(inFrameHeight),
341 mMaxOutputFrameWidth(outFrameWidth),
342 mMaxOutputFrameHeight(outFrameHeight) {}
343
344 ~VideoEditorCap() {}
345
346 int mMaxInputFrameWidth;
347 int mMaxInputFrameHeight;
348 int mMaxOutputFrameWidth;
349 int mMaxOutputFrameHeight;
350 };
351
Nipun Kwatra9d619542010-09-09 16:25:08 -0700352 int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
James Dong797e4f12011-02-28 21:07:39 -0800353 void initRequiredProfileRefs(const Vector<int>& cameraIds);
354 int getRequiredProfileRefIndex(int cameraId);
Nipun Kwatra9d619542010-09-09 16:25:08 -0700355
James Dongc3711942010-01-19 17:45:38 -0800356 // Debug
357 static void logVideoCodec(const VideoCodec& codec);
358 static void logAudioCodec(const AudioCodec& codec);
359 static void logVideoEncoderCap(const VideoEncoderCap& cap);
360 static void logAudioEncoderCap(const AudioEncoderCap& cap);
361 static void logVideoDecoderCap(const VideoDecoderCap& cap);
362 static void logAudioDecoderCap(const AudioDecoderCap& cap);
Hong Teng600acf12011-07-06 18:33:09 -0700363 static void logVideoEditorCap(const VideoEditorCap& cap);
James Dongc3711942010-01-19 17:45:38 -0800364
365 // If the xml configuration file does exist, use the settings
366 // from the xml
367 static MediaProfiles* createInstanceFromXmlFile(const char *xml);
368 static output_format createEncoderOutputFileFormat(const char **atts);
369 static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles);
370 static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles);
371 static AudioDecoderCap* createAudioDecoderCap(const char **atts);
372 static VideoDecoderCap* createVideoDecoderCap(const char **atts);
373 static VideoEncoderCap* createVideoEncoderCap(const char **atts);
374 static AudioEncoderCap* createAudioEncoderCap(const char **atts);
Hong Teng600acf12011-07-06 18:33:09 -0700375 static VideoEditorCap* createVideoEditorCap(
376 const char **atts, MediaProfiles *profiles);
James Dong797e4f12011-02-28 21:07:39 -0800377
378 static CamcorderProfile* createCamcorderProfile(
379 int cameraId, const char **atts, Vector<int>& cameraIds);
380
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800381 static int getCameraId(const char **atts);
382
James Donga403a932011-05-09 18:49:31 -0700383 void addStartTimeOffset(int cameraId, const char **atts);
384
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800385 ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
386 void addImageEncodingQualityLevel(int cameraId, const char** atts);
James Dongc3711942010-01-19 17:45:38 -0800387
388 // Customized element tag handler for parsing the xml configuration file.
389 static void startElementHandler(void *userData, const char *name, const char **atts);
390
391 // If the xml configuration file does not exist, use hard-coded values
392 static MediaProfiles* createDefaultInstance();
Nipun Kwatrad48a15c2010-09-16 22:25:23 -0700393
394 static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality);
395 static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality);
396 static void createDefaultCamcorderLowProfiles(
397 MediaProfiles::CamcorderProfile **lowProfile,
398 MediaProfiles::CamcorderProfile **lowSpecificProfile);
399 static void createDefaultCamcorderHighProfiles(
400 MediaProfiles::CamcorderProfile **highProfile,
401 MediaProfiles::CamcorderProfile **highSpecificProfile);
402
403 static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality);
404 static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality);
405 static void createDefaultCamcorderTimeLapseLowProfiles(
406 MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
407 MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile);
408 static void createDefaultCamcorderTimeLapseHighProfiles(
409 MediaProfiles::CamcorderProfile **highTimeLapseProfile,
410 MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile);
411
James Dongc3711942010-01-19 17:45:38 -0800412 static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
413 static void createDefaultVideoEncoders(MediaProfiles *profiles);
414 static void createDefaultAudioEncoders(MediaProfiles *profiles);
415 static void createDefaultVideoDecoders(MediaProfiles *profiles);
416 static void createDefaultAudioDecoders(MediaProfiles *profiles);
417 static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
James Dong9b433f02010-02-23 17:21:44 -0800418 static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
419 static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
Hong Teng600acf12011-07-06 18:33:09 -0700420 static void createDefaultVideoEditorCap(MediaProfiles *profiles);
James Dongc3711942010-01-19 17:45:38 -0800421 static VideoEncoderCap* createDefaultH263VideoEncoderCap();
422 static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
423 static AudioEncoderCap* createDefaultAmrNBEncoderCap();
424
425 static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
426
James Dong797e4f12011-02-28 21:07:39 -0800427 /**
428 * Check on existing profiles with the following criteria:
429 * 1. Low quality profile must have the lowest video
430 * resolution product (width x height)
431 * 2. High quality profile must have the highest video
432 * resolution product (width x height)
433 *
434 * and add required low/high quality camcorder/timelapse
435 * profiles if they are not found. This allows to remove
436 * duplicate profile definitions in the media_profiles.xml
437 * file.
438 */
439 void checkAndAddRequiredProfilesIfNecessary();
440
441
James Dongc3711942010-01-19 17:45:38 -0800442 // Mappings from name (for instance, codec name) to enum value
443 static const NameToTagMap sVideoEncoderNameMap[];
444 static const NameToTagMap sAudioEncoderNameMap[];
445 static const NameToTagMap sFileFormatMap[];
446 static const NameToTagMap sVideoDecoderNameMap[];
447 static const NameToTagMap sAudioDecoderNameMap[];
448 static const NameToTagMap sCamcorderQualityNameMap[];
449
450 static bool sIsInitialized;
451 static MediaProfiles *sInstance;
452 static Mutex sLock;
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800453 int mCurrentCameraId;
James Dongc3711942010-01-19 17:45:38 -0800454
455 Vector<CamcorderProfile*> mCamcorderProfiles;
456 Vector<AudioEncoderCap*> mAudioEncoders;
457 Vector<VideoEncoderCap*> mVideoEncoders;
458 Vector<AudioDecoderCap*> mAudioDecoders;
459 Vector<VideoDecoderCap*> mVideoDecoders;
460 Vector<output_format> mEncoderOutputFileFormats;
Chih-Chung Chang09b90052010-06-22 20:50:55 +0800461 Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
James Donga403a932011-05-09 18:49:31 -0700462 KeyedVector<int, int> mStartTimeOffsets;
James Dong797e4f12011-02-28 21:07:39 -0800463
464 typedef struct {
465 bool mHasRefProfile; // Refers to an existing profile
466 int mRefProfileIndex; // Reference profile index
467 int mResolutionProduct; // width x height
468 } RequiredProfileRefInfo; // Required low and high profiles
469
470 typedef struct {
471 RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
472 int mCameraId;
473 } RequiredProfiles;
474
475 RequiredProfiles *mRequiredProfileRefs;
476 Vector<int> mCameraIds;
Hong Teng600acf12011-07-06 18:33:09 -0700477 VideoEditorCap* mVideoEditorCap;
James Dongc3711942010-01-19 17:45:38 -0800478};
479
480}; // namespace android
481
482#endif // ANDROID_MEDIAPROFILES_H
483