blob: e02918f52b48bc8fba1e31f8c0d1a7089a01a38b [file] [log] [blame]
James Dong1d7491b2010-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 Dong2a7e0a12011-02-28 21:07:39 -080027 CAMCORDER_QUALITY_LIST_START = 0,
James Dong0b42f252010-03-31 13:56:29 -070028 CAMCORDER_QUALITY_LOW = 0,
Nipun Kwatrac0a84782010-09-06 15:59:02 -070029 CAMCORDER_QUALITY_HIGH = 1,
30 CAMCORDER_QUALITY_QCIF = 2,
Nipun Kwatra9783ed82010-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 Dong669012d2011-09-19 16:27:31 -070035 CAMCORDER_QUALITY_QVGA = 7,
Zhijun He5f6af1a2014-06-10 08:26:33 -070036 CAMCORDER_QUALITY_2160P = 8,
37 CAMCORDER_QUALITY_LIST_END = 8,
Nipun Kwatrac0a84782010-09-06 15:59:02 -070038
James Dong2a7e0a12011-02-28 21:07:39 -080039 CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
Nipun Kwatrac0a84782010-09-06 15:59:02 -070040 CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000,
41 CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
42 CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
Nipun Kwatra9783ed82010-09-10 15:45:57 -070043 CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
44 CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
45 CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
James Dong2a7e0a12011-02-28 21:07:39 -080046 CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
James Dong669012d2011-09-19 16:27:31 -070047 CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
Zhijun He5f6af1a2014-06-10 08:26:33 -070048 CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
49 CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
Zhijun Hee0790972014-07-23 15:17:26 -070050
51 CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
52 CAMCORDER_QUALITY_HIGH_SPEED_LOW = 2000,
53 CAMCORDER_QUALITY_HIGH_SPEED_HIGH = 2001,
54 CAMCORDER_QUALITY_HIGH_SPEED_480P = 2002,
55 CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
56 CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
Zhijun He9520aa62014-09-09 16:18:31 -070057 CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
58 CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
James Dong1d7491b2010-01-19 17:45:38 -080059};
60
61enum video_decoder {
62 VIDEO_DECODER_WMV,
63};
64
65enum audio_decoder {
66 AUDIO_DECODER_WMA,
67};
68
69
70class MediaProfiles
71{
72public:
73
74 /**
75 * Returns the singleton instance for subsequence queries.
76 * or NULL if error.
77 */
78 static MediaProfiles* getInstance();
79
80 /**
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +080081 * Returns the value for the given param name for the given camera at
82 * the given quality level, or -1 if error.
James Dong1d7491b2010-01-19 17:45:38 -080083 *
84 * Supported param name are:
James Dongf5a83852010-02-23 17:21:44 -080085 * duration - the recording duration.
James Dong1d7491b2010-01-19 17:45:38 -080086 * file.format - output file format. see mediarecorder.h for details
James Dong13896b92010-02-03 16:50:18 -080087 * vid.codec - video encoder. see mediarecorder.h for details.
88 * aud.codec - audio encoder. see mediarecorder.h for details.
James Dong1d7491b2010-01-19 17:45:38 -080089 * vid.width - video frame width
90 * vid.height - video frame height
91 * vid.fps - video frame rate
92 * vid.bps - video bit rate
93 * aud.bps - audio bit rate
94 * aud.hz - audio sample rate
95 * aud.ch - number of audio channels
96 */
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +080097 int getCamcorderProfileParamByName(const char *name, int cameraId,
98 camcorder_quality quality) const;
James Dong1d7491b2010-01-19 17:45:38 -080099
100 /**
Nipun Kwatra8bb56032010-09-09 16:25:08 -0700101 * Returns true if a profile for the given camera at the given quality exists,
102 * or false if not.
103 */
104 bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const;
105
106 /**
James Dong1d7491b2010-01-19 17:45:38 -0800107 * Returns the output file formats supported.
108 */
109 Vector<output_format> getOutputFileFormats() const;
110
111 /**
112 * Returns the video encoders supported.
113 */
114 Vector<video_encoder> getVideoEncoders() const;
115
116 /**
117 * Returns the value for the given param name for the given video encoder
118 * returned from getVideoEncoderByIndex or -1 if error.
119 *
120 * Supported param name are:
121 * enc.vid.width.min - min video frame width
122 * enc.vid.width.max - max video frame width
123 * enc.vid.height.min - min video frame height
124 * enc.vid.height.max - max video frame height
125 * enc.vid.bps.min - min bit rate in bits per second
126 * enc.vid.bps.max - max bit rate in bits per second
127 * enc.vid.fps.min - min frame rate in frames per second
128 * enc.vid.fps.max - max frame rate in frames per second
129 */
130 int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
131
132 /**
133 * Returns the audio encoders supported.
134 */
135 Vector<audio_encoder> getAudioEncoders() const;
136
137 /**
138 * Returns the value for the given param name for the given audio encoder
139 * returned from getAudioEncoderByIndex or -1 if error.
140 *
141 * Supported param name are:
142 * enc.aud.ch.min - min number of channels
143 * enc.aud.ch.max - max number of channels
144 * enc.aud.bps.min - min bit rate in bits per second
145 * enc.aud.bps.max - max bit rate in bits per second
146 * enc.aud.hz.min - min sample rate in samples per second
147 * enc.aud.hz.max - max sample rate in samples per second
148 */
149 int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
150
151 /**
152 * Returns the video decoders supported.
153 */
154 Vector<video_decoder> getVideoDecoders() const;
155
156 /**
157 * Returns the audio decoders supported.
158 */
159 Vector<audio_decoder> getAudioDecoders() const;
160
James Dongf5a83852010-02-23 17:21:44 -0800161 /**
162 * Returns the number of image encoding quality levels supported.
163 */
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800164 Vector<int> getImageEncodingQualityLevels(int cameraId) const;
James Dongf5a83852010-02-23 17:21:44 -0800165
James Dong0f056292011-05-09 18:49:31 -0700166 /**
167 * Returns the start time offset (in ms) for the given camera Id.
168 * If the given camera Id does not exist, -1 will be returned.
169 */
170 int getStartTimeOffsetMs(int cameraId) const;
171
James Dong1d7491b2010-01-19 17:45:38 -0800172private:
James Dong2a7e0a12011-02-28 21:07:39 -0800173 enum {
174 // Camcorder profiles (high/low) and timelapse profiles (high/low)
175 kNumRequiredProfiles = 4,
176 };
177
James Dong1d7491b2010-01-19 17:45:38 -0800178 MediaProfiles& operator=(const MediaProfiles&); // Don't call me
179 MediaProfiles(const MediaProfiles&); // Don't call me
Chong Zhangba3e7f52015-05-27 16:52:35 -0700180 MediaProfiles() {} // Dummy default constructor
James Dong1d7491b2010-01-19 17:45:38 -0800181 ~MediaProfiles(); // Don't delete me
182
183 struct VideoCodec {
184 VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate)
185 : mCodec(codec),
186 mBitRate(bitRate),
187 mFrameWidth(frameWidth),
188 mFrameHeight(frameHeight),
189 mFrameRate(frameRate) {}
190
James Dong2a7e0a12011-02-28 21:07:39 -0800191 VideoCodec(const VideoCodec& copy) {
192 mCodec = copy.mCodec;
193 mBitRate = copy.mBitRate;
194 mFrameWidth = copy.mFrameWidth;
195 mFrameHeight = copy.mFrameHeight;
196 mFrameRate = copy.mFrameRate;
197 }
198
James Dong1d7491b2010-01-19 17:45:38 -0800199 ~VideoCodec() {}
200
201 video_encoder mCodec;
202 int mBitRate;
203 int mFrameWidth;
204 int mFrameHeight;
205 int mFrameRate;
206 };
207
208 struct AudioCodec {
209 AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
210 : mCodec(codec),
211 mBitRate(bitRate),
212 mSampleRate(sampleRate),
213 mChannels(channels) {}
214
James Dong2a7e0a12011-02-28 21:07:39 -0800215 AudioCodec(const AudioCodec& copy) {
216 mCodec = copy.mCodec;
217 mBitRate = copy.mBitRate;
218 mSampleRate = copy.mSampleRate;
219 mChannels = copy.mChannels;
220 }
221
James Dong1d7491b2010-01-19 17:45:38 -0800222 ~AudioCodec() {}
223
224 audio_encoder mCodec;
225 int mBitRate;
226 int mSampleRate;
227 int mChannels;
228 };
229
230 struct CamcorderProfile {
231 CamcorderProfile()
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800232 : mCameraId(0),
233 mFileFormat(OUTPUT_FORMAT_THREE_GPP),
James Dong1d7491b2010-01-19 17:45:38 -0800234 mQuality(CAMCORDER_QUALITY_HIGH),
235 mDuration(0),
236 mVideoCodec(0),
237 mAudioCodec(0) {}
238
James Dong2a7e0a12011-02-28 21:07:39 -0800239 CamcorderProfile(const CamcorderProfile& copy) {
240 mCameraId = copy.mCameraId;
241 mFileFormat = copy.mFileFormat;
242 mQuality = copy.mQuality;
243 mDuration = copy.mDuration;
244 mVideoCodec = new VideoCodec(*copy.mVideoCodec);
245 mAudioCodec = new AudioCodec(*copy.mAudioCodec);
246 }
247
James Dong1d7491b2010-01-19 17:45:38 -0800248 ~CamcorderProfile() {
249 delete mVideoCodec;
250 delete mAudioCodec;
251 }
252
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800253 int mCameraId;
James Dong1d7491b2010-01-19 17:45:38 -0800254 output_format mFileFormat;
255 camcorder_quality mQuality;
256 int mDuration;
257 VideoCodec *mVideoCodec;
258 AudioCodec *mAudioCodec;
259 };
260
261 struct VideoEncoderCap {
262 // Ugly constructor
263 VideoEncoderCap(video_encoder codec,
264 int minBitRate, int maxBitRate,
265 int minFrameWidth, int maxFrameWidth,
266 int minFrameHeight, int maxFrameHeight,
267 int minFrameRate, int maxFrameRate)
268 : mCodec(codec),
269 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
270 mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
271 mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
272 mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
273
274 ~VideoEncoderCap() {}
275
276 video_encoder mCodec;
277 int mMinBitRate, mMaxBitRate;
278 int mMinFrameWidth, mMaxFrameWidth;
279 int mMinFrameHeight, mMaxFrameHeight;
280 int mMinFrameRate, mMaxFrameRate;
281 };
282
283 struct AudioEncoderCap {
284 // Ugly constructor
285 AudioEncoderCap(audio_encoder codec,
286 int minBitRate, int maxBitRate,
287 int minSampleRate, int maxSampleRate,
288 int minChannels, int maxChannels)
289 : mCodec(codec),
290 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
291 mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
292 mMinChannels(minChannels), mMaxChannels(maxChannels) {}
293
294 ~AudioEncoderCap() {}
295
296 audio_encoder mCodec;
297 int mMinBitRate, mMaxBitRate;
298 int mMinSampleRate, mMaxSampleRate;
299 int mMinChannels, mMaxChannels;
300 };
301
302 struct VideoDecoderCap {
303 VideoDecoderCap(video_decoder codec): mCodec(codec) {}
304 ~VideoDecoderCap() {}
305
306 video_decoder mCodec;
307 };
308
309 struct AudioDecoderCap {
310 AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
311 ~AudioDecoderCap() {}
312
313 audio_decoder mCodec;
314 };
315
316 struct NameToTagMap {
317 const char* name;
318 int tag;
319 };
320
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800321 struct ImageEncodingQualityLevels {
322 int mCameraId;
323 Vector<int> mLevels;
324 };
Hong Tengcabd5f82011-07-06 18:33:09 -0700325
Nipun Kwatra8bb56032010-09-09 16:25:08 -0700326 int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
James Dong2a7e0a12011-02-28 21:07:39 -0800327 void initRequiredProfileRefs(const Vector<int>& cameraIds);
328 int getRequiredProfileRefIndex(int cameraId);
Nipun Kwatra8bb56032010-09-09 16:25:08 -0700329
James Dong1d7491b2010-01-19 17:45:38 -0800330 // Debug
331 static void logVideoCodec(const VideoCodec& codec);
332 static void logAudioCodec(const AudioCodec& codec);
333 static void logVideoEncoderCap(const VideoEncoderCap& cap);
334 static void logAudioEncoderCap(const AudioEncoderCap& cap);
335 static void logVideoDecoderCap(const VideoDecoderCap& cap);
336 static void logAudioDecoderCap(const AudioDecoderCap& cap);
337
338 // If the xml configuration file does exist, use the settings
339 // from the xml
340 static MediaProfiles* createInstanceFromXmlFile(const char *xml);
341 static output_format createEncoderOutputFileFormat(const char **atts);
342 static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles);
343 static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles);
344 static AudioDecoderCap* createAudioDecoderCap(const char **atts);
345 static VideoDecoderCap* createVideoDecoderCap(const char **atts);
346 static VideoEncoderCap* createVideoEncoderCap(const char **atts);
347 static AudioEncoderCap* createAudioEncoderCap(const char **atts);
James Dong2a7e0a12011-02-28 21:07:39 -0800348
349 static CamcorderProfile* createCamcorderProfile(
350 int cameraId, const char **atts, Vector<int>& cameraIds);
351
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800352 static int getCameraId(const char **atts);
353
James Dong0f056292011-05-09 18:49:31 -0700354 void addStartTimeOffset(int cameraId, const char **atts);
355
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800356 ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
357 void addImageEncodingQualityLevel(int cameraId, const char** atts);
James Dong1d7491b2010-01-19 17:45:38 -0800358
359 // Customized element tag handler for parsing the xml configuration file.
360 static void startElementHandler(void *userData, const char *name, const char **atts);
361
362 // If the xml configuration file does not exist, use hard-coded values
363 static MediaProfiles* createDefaultInstance();
Nipun Kwatrad5672bc2010-09-16 22:25:23 -0700364
365 static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality);
366 static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality);
367 static void createDefaultCamcorderLowProfiles(
368 MediaProfiles::CamcorderProfile **lowProfile,
369 MediaProfiles::CamcorderProfile **lowSpecificProfile);
370 static void createDefaultCamcorderHighProfiles(
371 MediaProfiles::CamcorderProfile **highProfile,
372 MediaProfiles::CamcorderProfile **highSpecificProfile);
373
374 static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality);
375 static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality);
376 static void createDefaultCamcorderTimeLapseLowProfiles(
377 MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
378 MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile);
379 static void createDefaultCamcorderTimeLapseHighProfiles(
380 MediaProfiles::CamcorderProfile **highTimeLapseProfile,
381 MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile);
382
James Dong1d7491b2010-01-19 17:45:38 -0800383 static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
384 static void createDefaultVideoEncoders(MediaProfiles *profiles);
385 static void createDefaultAudioEncoders(MediaProfiles *profiles);
386 static void createDefaultVideoDecoders(MediaProfiles *profiles);
387 static void createDefaultAudioDecoders(MediaProfiles *profiles);
388 static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
James Dongf5a83852010-02-23 17:21:44 -0800389 static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
390 static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
Rajneesh Chowdury8f74b712011-08-12 16:43:37 -0700391
James Dong1d7491b2010-01-19 17:45:38 -0800392 static VideoEncoderCap* createDefaultH263VideoEncoderCap();
393 static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
394 static AudioEncoderCap* createDefaultAmrNBEncoderCap();
395
396 static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
397
James Dong2a7e0a12011-02-28 21:07:39 -0800398 /**
399 * Check on existing profiles with the following criteria:
400 * 1. Low quality profile must have the lowest video
401 * resolution product (width x height)
402 * 2. High quality profile must have the highest video
403 * resolution product (width x height)
404 *
405 * and add required low/high quality camcorder/timelapse
406 * profiles if they are not found. This allows to remove
407 * duplicate profile definitions in the media_profiles.xml
408 * file.
409 */
410 void checkAndAddRequiredProfilesIfNecessary();
411
412
James Dong1d7491b2010-01-19 17:45:38 -0800413 // Mappings from name (for instance, codec name) to enum value
414 static const NameToTagMap sVideoEncoderNameMap[];
415 static const NameToTagMap sAudioEncoderNameMap[];
416 static const NameToTagMap sFileFormatMap[];
417 static const NameToTagMap sVideoDecoderNameMap[];
418 static const NameToTagMap sAudioDecoderNameMap[];
419 static const NameToTagMap sCamcorderQualityNameMap[];
420
421 static bool sIsInitialized;
422 static MediaProfiles *sInstance;
423 static Mutex sLock;
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800424 int mCurrentCameraId;
James Dong1d7491b2010-01-19 17:45:38 -0800425
426 Vector<CamcorderProfile*> mCamcorderProfiles;
427 Vector<AudioEncoderCap*> mAudioEncoders;
428 Vector<VideoEncoderCap*> mVideoEncoders;
429 Vector<AudioDecoderCap*> mAudioDecoders;
430 Vector<VideoDecoderCap*> mVideoDecoders;
431 Vector<output_format> mEncoderOutputFileFormats;
Chih-Chung Chang3eaa4e92010-06-22 20:50:55 +0800432 Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
James Dong0f056292011-05-09 18:49:31 -0700433 KeyedVector<int, int> mStartTimeOffsets;
James Dong2a7e0a12011-02-28 21:07:39 -0800434
435 typedef struct {
436 bool mHasRefProfile; // Refers to an existing profile
437 int mRefProfileIndex; // Reference profile index
438 int mResolutionProduct; // width x height
439 } RequiredProfileRefInfo; // Required low and high profiles
440
441 typedef struct {
442 RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
443 int mCameraId;
444 } RequiredProfiles;
445
446 RequiredProfiles *mRequiredProfileRefs;
447 Vector<int> mCameraIds;
James Dong1d7491b2010-01-19 17:45:38 -0800448};
449
450}; // namespace android
451
452#endif // ANDROID_MEDIAPROFILES_H