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 /** 62 * Set CIF as default maximum import and export resolution of video editor. 63 * The maximum import and export resolutions are platform specific, 64 * which should be defined in media_profiles.xml. 65 * Set default maximum prefetch YUV frames to 6, which means video editor can 66 * queue up to 6 YUV frames in the video encoder source. 67 * This value is used to limit the amount of memory used by video editor 68 * engine when the encoder consumes YUV frames at a lower speed 69 * than video editor engine produces. 70 */ 71 enum videoeditor_capability { 72 VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352, 73 VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288, 74 VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352, 75 VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288, 76 VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES = 6 77 }; 78 79 enum video_decoder { 80 VIDEO_DECODER_WMV, 81 }; 82 83 enum audio_decoder { 84 AUDIO_DECODER_WMA, 85 }; 86 87 88 class MediaProfiles 89 { 90 public: 91 92 /** 93 * Returns the singleton instance for subsequence queries. 94 * or NULL if error. 95 */ 96 static MediaProfiles* getInstance(); 97 98 /** 99 * Returns the value for the given param name for the given camera at 100 * the given quality level, or -1 if error. 101 * 102 * Supported param name are: 103 * duration - the recording duration. 104 * file.format - output file format. see mediarecorder.h for details 105 * vid.codec - video encoder. see mediarecorder.h for details. 106 * aud.codec - audio encoder. see mediarecorder.h for details. 107 * vid.width - video frame width 108 * vid.height - video frame height 109 * vid.fps - video frame rate 110 * vid.bps - video bit rate 111 * aud.bps - audio bit rate 112 * aud.hz - audio sample rate 113 * aud.ch - number of audio channels 114 */ 115 int getCamcorderProfileParamByName(const char *name, int cameraId, 116 camcorder_quality quality) const; 117 118 /** 119 * Returns true if a profile for the given camera at the given quality exists, 120 * or false if not. 121 */ 122 bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const; 123 124 /** 125 * Returns the output file formats supported. 126 */ 127 Vector<output_format> getOutputFileFormats() const; 128 129 /** 130 * Returns the video encoders supported. 131 */ 132 Vector<video_encoder> getVideoEncoders() const; 133 134 /** 135 * Returns the value for the given param name for the given video encoder 136 * returned from getVideoEncoderByIndex or -1 if error. 137 * 138 * Supported param name are: 139 * enc.vid.width.min - min video frame width 140 * enc.vid.width.max - max video frame width 141 * enc.vid.height.min - min video frame height 142 * enc.vid.height.max - max video frame height 143 * enc.vid.bps.min - min bit rate in bits per second 144 * enc.vid.bps.max - max bit rate in bits per second 145 * enc.vid.fps.min - min frame rate in frames per second 146 * enc.vid.fps.max - max frame rate in frames per second 147 */ 148 int getVideoEncoderParamByName(const char *name, video_encoder codec) const; 149 150 /** 151 * Returns the value for the given param name for the video editor cap 152 * param or -1 if error. 153 * Supported param name are: 154 * videoeditor.input.width.max - max input video frame width 155 * videoeditor.input.height.max - max input video frame height 156 * videoeditor.output.width.max - max output video frame width 157 * videoeditor.output.height.max - max output video frame height 158 * maxPrefetchYUVFrames - max prefetch YUV frames in video editor engine. This value is used 159 * to limit the memory consumption. 160 */ 161 int getVideoEditorCapParamByName(const char *name) const; 162 163 /** 164 * Returns the value for the given param name for the video editor export codec format 165 * param or -1 if error. 166 * Supported param name are: 167 * videoeditor.export.profile - export video profile 168 * videoeditor.export.level - export video level 169 * Supported param codec are: 170 * 1 for h263 171 * 2 for h264 172 * 3 for mpeg4 173 */ 174 int getVideoEditorExportParamByName(const char *name, int codec) const; 175 176 /** 177 * Returns the audio encoders supported. 178 */ 179 Vector<audio_encoder> getAudioEncoders() const; 180 181 /** 182 * Returns the value for the given param name for the given audio encoder 183 * returned from getAudioEncoderByIndex or -1 if error. 184 * 185 * Supported param name are: 186 * enc.aud.ch.min - min number of channels 187 * enc.aud.ch.max - max number of channels 188 * enc.aud.bps.min - min bit rate in bits per second 189 * enc.aud.bps.max - max bit rate in bits per second 190 * enc.aud.hz.min - min sample rate in samples per second 191 * enc.aud.hz.max - max sample rate in samples per second 192 */ 193 int getAudioEncoderParamByName(const char *name, audio_encoder codec) const; 194 195 /** 196 * Returns the video decoders supported. 197 */ 198 Vector<video_decoder> getVideoDecoders() const; 199 200 /** 201 * Returns the audio decoders supported. 202 */ 203 Vector<audio_decoder> getAudioDecoders() const; 204 205 /** 206 * Returns the number of image encoding quality levels supported. 207 */ 208 Vector<int> getImageEncodingQualityLevels(int cameraId) const; 209 210 /** 211 * Returns the start time offset (in ms) for the given camera Id. 212 * If the given camera Id does not exist, -1 will be returned. 213 */ 214 int getStartTimeOffsetMs(int cameraId) const; 215 216 private: 217 enum { 218 // Camcorder profiles (high/low) and timelapse profiles (high/low) 219 kNumRequiredProfiles = 4, 220 }; 221 222 MediaProfiles& operator=(const MediaProfiles&); // Don't call me 223 MediaProfiles(const MediaProfiles&); // Don't call me MediaProfiles()224 MediaProfiles() { mVideoEditorCap = NULL; } // Dummy default constructor 225 ~MediaProfiles(); // Don't delete me 226 227 struct VideoCodec { VideoCodecVideoCodec228 VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate) 229 : mCodec(codec), 230 mBitRate(bitRate), 231 mFrameWidth(frameWidth), 232 mFrameHeight(frameHeight), 233 mFrameRate(frameRate) {} 234 VideoCodecVideoCodec235 VideoCodec(const VideoCodec& copy) { 236 mCodec = copy.mCodec; 237 mBitRate = copy.mBitRate; 238 mFrameWidth = copy.mFrameWidth; 239 mFrameHeight = copy.mFrameHeight; 240 mFrameRate = copy.mFrameRate; 241 } 242 ~VideoCodecVideoCodec243 ~VideoCodec() {} 244 245 video_encoder mCodec; 246 int mBitRate; 247 int mFrameWidth; 248 int mFrameHeight; 249 int mFrameRate; 250 }; 251 252 struct AudioCodec { AudioCodecAudioCodec253 AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels) 254 : mCodec(codec), 255 mBitRate(bitRate), 256 mSampleRate(sampleRate), 257 mChannels(channels) {} 258 AudioCodecAudioCodec259 AudioCodec(const AudioCodec& copy) { 260 mCodec = copy.mCodec; 261 mBitRate = copy.mBitRate; 262 mSampleRate = copy.mSampleRate; 263 mChannels = copy.mChannels; 264 } 265 ~AudioCodecAudioCodec266 ~AudioCodec() {} 267 268 audio_encoder mCodec; 269 int mBitRate; 270 int mSampleRate; 271 int mChannels; 272 }; 273 274 struct CamcorderProfile { CamcorderProfileCamcorderProfile275 CamcorderProfile() 276 : mCameraId(0), 277 mFileFormat(OUTPUT_FORMAT_THREE_GPP), 278 mQuality(CAMCORDER_QUALITY_HIGH), 279 mDuration(0), 280 mVideoCodec(0), 281 mAudioCodec(0) {} 282 CamcorderProfileCamcorderProfile283 CamcorderProfile(const CamcorderProfile& copy) { 284 mCameraId = copy.mCameraId; 285 mFileFormat = copy.mFileFormat; 286 mQuality = copy.mQuality; 287 mDuration = copy.mDuration; 288 mVideoCodec = new VideoCodec(*copy.mVideoCodec); 289 mAudioCodec = new AudioCodec(*copy.mAudioCodec); 290 } 291 ~CamcorderProfileCamcorderProfile292 ~CamcorderProfile() { 293 delete mVideoCodec; 294 delete mAudioCodec; 295 } 296 297 int mCameraId; 298 output_format mFileFormat; 299 camcorder_quality mQuality; 300 int mDuration; 301 VideoCodec *mVideoCodec; 302 AudioCodec *mAudioCodec; 303 }; 304 305 struct VideoEncoderCap { 306 // Ugly constructor VideoEncoderCapVideoEncoderCap307 VideoEncoderCap(video_encoder codec, 308 int minBitRate, int maxBitRate, 309 int minFrameWidth, int maxFrameWidth, 310 int minFrameHeight, int maxFrameHeight, 311 int minFrameRate, int maxFrameRate) 312 : mCodec(codec), 313 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate), 314 mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth), 315 mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight), 316 mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {} 317 ~VideoEncoderCapVideoEncoderCap318 ~VideoEncoderCap() {} 319 320 video_encoder mCodec; 321 int mMinBitRate, mMaxBitRate; 322 int mMinFrameWidth, mMaxFrameWidth; 323 int mMinFrameHeight, mMaxFrameHeight; 324 int mMinFrameRate, mMaxFrameRate; 325 }; 326 327 struct AudioEncoderCap { 328 // Ugly constructor AudioEncoderCapAudioEncoderCap329 AudioEncoderCap(audio_encoder codec, 330 int minBitRate, int maxBitRate, 331 int minSampleRate, int maxSampleRate, 332 int minChannels, int maxChannels) 333 : mCodec(codec), 334 mMinBitRate(minBitRate), mMaxBitRate(maxBitRate), 335 mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate), 336 mMinChannels(minChannels), mMaxChannels(maxChannels) {} 337 ~AudioEncoderCapAudioEncoderCap338 ~AudioEncoderCap() {} 339 340 audio_encoder mCodec; 341 int mMinBitRate, mMaxBitRate; 342 int mMinSampleRate, mMaxSampleRate; 343 int mMinChannels, mMaxChannels; 344 }; 345 346 struct VideoDecoderCap { VideoDecoderCapVideoDecoderCap347 VideoDecoderCap(video_decoder codec): mCodec(codec) {} ~VideoDecoderCapVideoDecoderCap348 ~VideoDecoderCap() {} 349 350 video_decoder mCodec; 351 }; 352 353 struct AudioDecoderCap { AudioDecoderCapAudioDecoderCap354 AudioDecoderCap(audio_decoder codec): mCodec(codec) {} ~AudioDecoderCapAudioDecoderCap355 ~AudioDecoderCap() {} 356 357 audio_decoder mCodec; 358 }; 359 360 struct NameToTagMap { 361 const char* name; 362 int tag; 363 }; 364 365 struct ImageEncodingQualityLevels { 366 int mCameraId; 367 Vector<int> mLevels; 368 }; 369 struct ExportVideoProfile { ExportVideoProfileExportVideoProfile370 ExportVideoProfile(int codec, int profile, int level) 371 :mCodec(codec),mProfile(profile),mLevel(level) {} ~ExportVideoProfileExportVideoProfile372 ~ExportVideoProfile() {} 373 int mCodec; 374 int mProfile; 375 int mLevel; 376 }; 377 struct VideoEditorCap { VideoEditorCapVideoEditorCap378 VideoEditorCap(int inFrameWidth, int inFrameHeight, 379 int outFrameWidth, int outFrameHeight, int frames) 380 : mMaxInputFrameWidth(inFrameWidth), 381 mMaxInputFrameHeight(inFrameHeight), 382 mMaxOutputFrameWidth(outFrameWidth), 383 mMaxOutputFrameHeight(outFrameHeight), 384 mMaxPrefetchYUVFrames(frames) {} 385 ~VideoEditorCapVideoEditorCap386 ~VideoEditorCap() {} 387 388 int mMaxInputFrameWidth; 389 int mMaxInputFrameHeight; 390 int mMaxOutputFrameWidth; 391 int mMaxOutputFrameHeight; 392 int mMaxPrefetchYUVFrames; 393 }; 394 395 int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const; 396 void initRequiredProfileRefs(const Vector<int>& cameraIds); 397 int getRequiredProfileRefIndex(int cameraId); 398 399 // Debug 400 static void logVideoCodec(const VideoCodec& codec); 401 static void logAudioCodec(const AudioCodec& codec); 402 static void logVideoEncoderCap(const VideoEncoderCap& cap); 403 static void logAudioEncoderCap(const AudioEncoderCap& cap); 404 static void logVideoDecoderCap(const VideoDecoderCap& cap); 405 static void logAudioDecoderCap(const AudioDecoderCap& cap); 406 static void logVideoEditorCap(const VideoEditorCap& cap); 407 408 // If the xml configuration file does exist, use the settings 409 // from the xml 410 static MediaProfiles* createInstanceFromXmlFile(const char *xml); 411 static output_format createEncoderOutputFileFormat(const char **atts); 412 static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles); 413 static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles); 414 static AudioDecoderCap* createAudioDecoderCap(const char **atts); 415 static VideoDecoderCap* createVideoDecoderCap(const char **atts); 416 static VideoEncoderCap* createVideoEncoderCap(const char **atts); 417 static AudioEncoderCap* createAudioEncoderCap(const char **atts); 418 static VideoEditorCap* createVideoEditorCap( 419 const char **atts, MediaProfiles *profiles); 420 static ExportVideoProfile* createExportVideoProfile(const char **atts); 421 422 static CamcorderProfile* createCamcorderProfile( 423 int cameraId, const char **atts, Vector<int>& cameraIds); 424 425 static int getCameraId(const char **atts); 426 427 void addStartTimeOffset(int cameraId, const char **atts); 428 429 ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const; 430 void addImageEncodingQualityLevel(int cameraId, const char** atts); 431 432 // Customized element tag handler for parsing the xml configuration file. 433 static void startElementHandler(void *userData, const char *name, const char **atts); 434 435 // If the xml configuration file does not exist, use hard-coded values 436 static MediaProfiles* createDefaultInstance(); 437 438 static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality); 439 static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality); 440 static void createDefaultCamcorderLowProfiles( 441 MediaProfiles::CamcorderProfile **lowProfile, 442 MediaProfiles::CamcorderProfile **lowSpecificProfile); 443 static void createDefaultCamcorderHighProfiles( 444 MediaProfiles::CamcorderProfile **highProfile, 445 MediaProfiles::CamcorderProfile **highSpecificProfile); 446 447 static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality); 448 static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality); 449 static void createDefaultCamcorderTimeLapseLowProfiles( 450 MediaProfiles::CamcorderProfile **lowTimeLapseProfile, 451 MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile); 452 static void createDefaultCamcorderTimeLapseHighProfiles( 453 MediaProfiles::CamcorderProfile **highTimeLapseProfile, 454 MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile); 455 456 static void createDefaultCamcorderProfiles(MediaProfiles *profiles); 457 static void createDefaultVideoEncoders(MediaProfiles *profiles); 458 static void createDefaultAudioEncoders(MediaProfiles *profiles); 459 static void createDefaultVideoDecoders(MediaProfiles *profiles); 460 static void createDefaultAudioDecoders(MediaProfiles *profiles); 461 static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles); 462 static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles); 463 static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles); 464 static void createDefaultVideoEditorCap(MediaProfiles *profiles); 465 static void createDefaultExportVideoProfiles(MediaProfiles *profiles); 466 467 static VideoEncoderCap* createDefaultH263VideoEncoderCap(); 468 static VideoEncoderCap* createDefaultM4vVideoEncoderCap(); 469 static AudioEncoderCap* createDefaultAmrNBEncoderCap(); 470 471 static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name); 472 473 /** 474 * Check on existing profiles with the following criteria: 475 * 1. Low quality profile must have the lowest video 476 * resolution product (width x height) 477 * 2. High quality profile must have the highest video 478 * resolution product (width x height) 479 * 480 * and add required low/high quality camcorder/timelapse 481 * profiles if they are not found. This allows to remove 482 * duplicate profile definitions in the media_profiles.xml 483 * file. 484 */ 485 void checkAndAddRequiredProfilesIfNecessary(); 486 487 488 // Mappings from name (for instance, codec name) to enum value 489 static const NameToTagMap sVideoEncoderNameMap[]; 490 static const NameToTagMap sAudioEncoderNameMap[]; 491 static const NameToTagMap sFileFormatMap[]; 492 static const NameToTagMap sVideoDecoderNameMap[]; 493 static const NameToTagMap sAudioDecoderNameMap[]; 494 static const NameToTagMap sCamcorderQualityNameMap[]; 495 496 static bool sIsInitialized; 497 static MediaProfiles *sInstance; 498 static Mutex sLock; 499 int mCurrentCameraId; 500 501 Vector<CamcorderProfile*> mCamcorderProfiles; 502 Vector<AudioEncoderCap*> mAudioEncoders; 503 Vector<VideoEncoderCap*> mVideoEncoders; 504 Vector<AudioDecoderCap*> mAudioDecoders; 505 Vector<VideoDecoderCap*> mVideoDecoders; 506 Vector<output_format> mEncoderOutputFileFormats; 507 Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels; 508 KeyedVector<int, int> mStartTimeOffsets; 509 510 typedef struct { 511 bool mHasRefProfile; // Refers to an existing profile 512 int mRefProfileIndex; // Reference profile index 513 int mResolutionProduct; // width x height 514 } RequiredProfileRefInfo; // Required low and high profiles 515 516 typedef struct { 517 RequiredProfileRefInfo mRefs[kNumRequiredProfiles]; 518 int mCameraId; 519 } RequiredProfiles; 520 521 RequiredProfiles *mRequiredProfileRefs; 522 Vector<int> mCameraIds; 523 VideoEditorCap* mVideoEditorCap; 524 Vector<ExportVideoProfile*> mVideoEditorExportProfiles; 525 }; 526 527 }; // namespace android 528 529 #endif // ANDROID_MEDIAPROFILES_H 530