1 /* 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 24 namespace android { 25 26 enum camcorder_quality { 27 CAMCORDER_QUALITY_LIST_START = 0, 28 CAMCORDER_QUALITY_LOW = 0, 29 CAMCORDER_QUALITY_HIGH = 1, 30 CAMCORDER_QUALITY_QCIF = 2, 31 CAMCORDER_QUALITY_CIF = 3, 32 CAMCORDER_QUALITY_480P = 4, 33 CAMCORDER_QUALITY_720P = 5, 34 CAMCORDER_QUALITY_1080P = 6, 35 CAMCORDER_QUALITY_QVGA = 7, 36 CAMCORDER_QUALITY_2160P = 8, 37 CAMCORDER_QUALITY_LIST_END = 8, 38 39 CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000, 40 CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000, 41 CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001, 42 CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002, 43 CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003, 44 CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004, 45 CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005, 46 CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006, 47 CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007, 48 CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008, 49 CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008, 50 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, 57 CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005, 58 CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005, 59 }; 60 61 enum video_decoder { 62 VIDEO_DECODER_WMV, 63 }; 64 65 enum audio_decoder { 66 AUDIO_DECODER_WMA, 67 }; 68 69 70 class MediaProfiles 71 { 72 public: 73 74 /** 75 * Returns the singleton instance for subsequence queries. 76 * or NULL if error. 77 */ 78 static MediaProfiles* getInstance(); 79 80 /** 81 * Returns the value for the given param name for the given camera at 82 * the given quality level, or -1 if error. 83 * 84 * Supported param name are: 85 * duration - the recording duration. 86 * file.format - output file format. see mediarecorder.h for details 87 * vid.codec - video encoder. see mediarecorder.h for details. 88 * aud.codec - audio encoder. see mediarecorder.h for details. 89 * 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 */ 97 int getCamcorderProfileParamByName(const char *name, int cameraId, 98 camcorder_quality quality) const; 99 100 /** 101 * 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 /** 107 * 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 161 /** 162 * Returns the number of image encoding quality levels supported. 163 */ 164 Vector<int> getImageEncodingQualityLevels(int cameraId) const; 165 166 /** 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 172 private: 173 enum { 174 // Camcorder profiles (high/low) and timelapse profiles (high/low) 175 kNumRequiredProfiles = 4, 176 }; 177 178 MediaProfiles& operator=(const MediaProfiles&); // Don't call me 179 MediaProfiles(const MediaProfiles&); // Don't call me MediaProfiles()180 MediaProfiles() {} // Dummy default constructor 181 ~MediaProfiles(); // Don't delete me 182 183 struct VideoCodec { VideoCodecVideoCodec184 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 VideoCodecVideoCodec191 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 ~VideoCodecVideoCodec199 ~VideoCodec() {} 200 201 video_encoder mCodec; 202 int mBitRate; 203 int mFrameWidth; 204 int mFrameHeight; 205 int mFrameRate; 206 }; 207 208 struct AudioCodec { AudioCodecAudioCodec209 AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels) 210 : mCodec(codec), 211 mBitRate(bitRate), 212 mSampleRate(sampleRate), 213 mChannels(channels) {} 214 AudioCodecAudioCodec215 AudioCodec(const AudioCodec& copy) { 216 mCodec = copy.mCodec; 217 mBitRate = copy.mBitRate; 218 mSampleRate = copy.mSampleRate; 219 mChannels = copy.mChannels; 220 } 221 ~AudioCodecAudioCodec222 ~AudioCodec() {} 223 224 audio_encoder mCodec; 225 int mBitRate; 226 int mSampleRate; 227 int mChannels; 228 }; 229 230 struct CamcorderProfile { CamcorderProfileCamcorderProfile231 CamcorderProfile() 232 : mCameraId(0), 233 mFileFormat(OUTPUT_FORMAT_THREE_GPP), 234 mQuality(CAMCORDER_QUALITY_HIGH), 235 mDuration(0), 236 mVideoCodec(0), 237 mAudioCodec(0) {} 238 CamcorderProfileCamcorderProfile239 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 ~CamcorderProfileCamcorderProfile248 ~CamcorderProfile() { 249 delete mVideoCodec; 250 delete mAudioCodec; 251 } 252 253 int mCameraId; 254 output_format mFileFormat; 255 camcorder_quality mQuality; 256 int mDuration; 257 VideoCodec *mVideoCodec; 258 AudioCodec *mAudioCodec; 259 }; 260 261 struct VideoEncoderCap { 262 // Ugly constructor VideoEncoderCapVideoEncoderCap263 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 ~VideoEncoderCapVideoEncoderCap274 ~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 AudioEncoderCapAudioEncoderCap285 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 ~AudioEncoderCapAudioEncoderCap294 ~AudioEncoderCap() {} 295 296 audio_encoder mCodec; 297 int mMinBitRate, mMaxBitRate; 298 int mMinSampleRate, mMaxSampleRate; 299 int mMinChannels, mMaxChannels; 300 }; 301 302 struct VideoDecoderCap { VideoDecoderCapVideoDecoderCap303 VideoDecoderCap(video_decoder codec): mCodec(codec) {} ~VideoDecoderCapVideoDecoderCap304 ~VideoDecoderCap() {} 305 306 video_decoder mCodec; 307 }; 308 309 struct AudioDecoderCap { AudioDecoderCapAudioDecoderCap310 AudioDecoderCap(audio_decoder codec): mCodec(codec) {} ~AudioDecoderCapAudioDecoderCap311 ~AudioDecoderCap() {} 312 313 audio_decoder mCodec; 314 }; 315 316 struct NameToTagMap { 317 const char* name; 318 int tag; 319 }; 320 321 struct ImageEncodingQualityLevels { 322 int mCameraId; 323 Vector<int> mLevels; 324 }; 325 326 int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const; 327 void initRequiredProfileRefs(const Vector<int>& cameraIds); 328 int getRequiredProfileRefIndex(int cameraId); 329 330 // 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); 348 349 static CamcorderProfile* createCamcorderProfile( 350 int cameraId, const char **atts, Vector<int>& cameraIds); 351 352 static int getCameraId(const char **atts); 353 354 void addStartTimeOffset(int cameraId, const char **atts); 355 356 ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const; 357 void addImageEncodingQualityLevel(int cameraId, const char** atts); 358 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(); 364 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 383 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); 389 static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles); 390 static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles); 391 392 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 398 /** 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 413 // 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; 424 int mCurrentCameraId; 425 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; 432 Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels; 433 KeyedVector<int, int> mStartTimeOffsets; 434 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; 448 }; 449 450 }; // namespace android 451 452 #endif // ANDROID_MEDIAPROFILES_H 453