MediaProfiles.cpp revision aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5b
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 19//#define LOG_NDEBUG 0 20#define LOG_TAG "MediaProfiles" 21 22#include <stdlib.h> 23#include <utils/Log.h> 24#include <utils/Vector.h> 25#include <cutils/properties.h> 26#include <expat.h> 27#include <media/MediaProfiles.h> 28#include <media/stagefright/foundation/ADebug.h> 29#include <OMX_Video.h> 30 31namespace android { 32 33Mutex MediaProfiles::sLock; 34bool MediaProfiles::sIsInitialized = false; 35MediaProfiles *MediaProfiles::sInstance = NULL; 36 37const MediaProfiles::NameToTagMap MediaProfiles::sVideoEncoderNameMap[] = { 38 {"h263", VIDEO_ENCODER_H263}, 39 {"h264", VIDEO_ENCODER_H264}, 40 {"m4v", VIDEO_ENCODER_MPEG_4_SP} 41}; 42 43const MediaProfiles::NameToTagMap MediaProfiles::sAudioEncoderNameMap[] = { 44 {"amrnb", AUDIO_ENCODER_AMR_NB}, 45 {"amrwb", AUDIO_ENCODER_AMR_WB}, 46 {"aac", AUDIO_ENCODER_AAC}, 47 {"aaceld", AUDIO_ENCODER_AAC_ELD}, 48}; 49 50const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = { 51 {"3gp", OUTPUT_FORMAT_THREE_GPP}, 52 {"mp4", OUTPUT_FORMAT_MPEG_4} 53}; 54 55const MediaProfiles::NameToTagMap MediaProfiles::sVideoDecoderNameMap[] = { 56 {"wmv", VIDEO_DECODER_WMV} 57}; 58 59const MediaProfiles::NameToTagMap MediaProfiles::sAudioDecoderNameMap[] = { 60 {"wma", AUDIO_DECODER_WMA} 61}; 62 63const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = { 64 {"low", CAMCORDER_QUALITY_LOW}, 65 {"high", CAMCORDER_QUALITY_HIGH}, 66 {"qcif", CAMCORDER_QUALITY_QCIF}, 67 {"cif", CAMCORDER_QUALITY_CIF}, 68 {"480p", CAMCORDER_QUALITY_480P}, 69 {"720p", CAMCORDER_QUALITY_720P}, 70 {"1080p", CAMCORDER_QUALITY_1080P}, 71 {"qvga", CAMCORDER_QUALITY_QVGA}, 72 73 {"timelapselow", CAMCORDER_QUALITY_TIME_LAPSE_LOW}, 74 {"timelapsehigh", CAMCORDER_QUALITY_TIME_LAPSE_HIGH}, 75 {"timelapseqcif", CAMCORDER_QUALITY_TIME_LAPSE_QCIF}, 76 {"timelapsecif", CAMCORDER_QUALITY_TIME_LAPSE_CIF}, 77 {"timelapse480p", CAMCORDER_QUALITY_TIME_LAPSE_480P}, 78 {"timelapse720p", CAMCORDER_QUALITY_TIME_LAPSE_720P}, 79 {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P}, 80 {"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA}, 81}; 82 83/*static*/ void 84MediaProfiles::logVideoCodec(const MediaProfiles::VideoCodec& codec) 85{ 86 ALOGV("video codec:"); 87 ALOGV("codec = %d", codec.mCodec); 88 ALOGV("bit rate: %d", codec.mBitRate); 89 ALOGV("frame width: %d", codec.mFrameWidth); 90 ALOGV("frame height: %d", codec.mFrameHeight); 91 ALOGV("frame rate: %d", codec.mFrameRate); 92} 93 94/*static*/ void 95MediaProfiles::logAudioCodec(const MediaProfiles::AudioCodec& codec) 96{ 97 ALOGV("audio codec:"); 98 ALOGV("codec = %d", codec.mCodec); 99 ALOGV("bit rate: %d", codec.mBitRate); 100 ALOGV("sample rate: %d", codec.mSampleRate); 101 ALOGV("number of channels: %d", codec.mChannels); 102} 103 104/*static*/ void 105MediaProfiles::logVideoEncoderCap(const MediaProfiles::VideoEncoderCap& cap) 106{ 107 ALOGV("video encoder cap:"); 108 ALOGV("codec = %d", cap.mCodec); 109 ALOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate); 110 ALOGV("frame width: min = %d and max = %d", cap.mMinFrameWidth, cap.mMaxFrameWidth); 111 ALOGV("frame height: min = %d and max = %d", cap.mMinFrameHeight, cap.mMaxFrameHeight); 112 ALOGV("frame rate: min = %d and max = %d", cap.mMinFrameRate, cap.mMaxFrameRate); 113} 114 115/*static*/ void 116MediaProfiles::logAudioEncoderCap(const MediaProfiles::AudioEncoderCap& cap) 117{ 118 ALOGV("audio encoder cap:"); 119 ALOGV("codec = %d", cap.mCodec); 120 ALOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate); 121 ALOGV("sample rate: min = %d and max = %d", cap.mMinSampleRate, cap.mMaxSampleRate); 122 ALOGV("number of channels: min = %d and max = %d", cap.mMinChannels, cap.mMaxChannels); 123} 124 125/*static*/ void 126MediaProfiles::logVideoDecoderCap(const MediaProfiles::VideoDecoderCap& cap) 127{ 128 ALOGV("video decoder cap:"); 129 ALOGV("codec = %d", cap.mCodec); 130} 131 132/*static*/ void 133MediaProfiles::logAudioDecoderCap(const MediaProfiles::AudioDecoderCap& cap) 134{ 135 ALOGV("audio codec cap:"); 136 ALOGV("codec = %d", cap.mCodec); 137} 138 139/*static*/ void 140MediaProfiles::logVideoEditorCap(const MediaProfiles::VideoEditorCap& cap) 141{ 142 ALOGV("videoeditor cap:"); 143 ALOGV("mMaxInputFrameWidth = %d", cap.mMaxInputFrameWidth); 144 ALOGV("mMaxInputFrameHeight = %d", cap.mMaxInputFrameHeight); 145 ALOGV("mMaxOutputFrameWidth = %d", cap.mMaxOutputFrameWidth); 146 ALOGV("mMaxOutputFrameHeight = %d", cap.mMaxOutputFrameHeight); 147} 148 149/*static*/ int 150MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings, const char *name) 151{ 152 int tag = -1; 153 for (size_t i = 0; i < nMappings; ++i) { 154 if (!strcmp(map[i].name, name)) { 155 tag = map[i].tag; 156 break; 157 } 158 } 159 return tag; 160} 161 162/*static*/ MediaProfiles::VideoCodec* 163MediaProfiles::createVideoCodec(const char **atts, MediaProfiles *profiles) 164{ 165 CHECK(!strcmp("codec", atts[0]) && 166 !strcmp("bitRate", atts[2]) && 167 !strcmp("width", atts[4]) && 168 !strcmp("height", atts[6]) && 169 !strcmp("frameRate", atts[8])); 170 171 const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]); 172 const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]); 173 CHECK(codec != -1); 174 175 MediaProfiles::VideoCodec *videoCodec = 176 new MediaProfiles::VideoCodec(static_cast<video_encoder>(codec), 177 atoi(atts[3]), atoi(atts[5]), atoi(atts[7]), atoi(atts[9])); 178 logVideoCodec(*videoCodec); 179 180 size_t nCamcorderProfiles; 181 CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1); 182 profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mVideoCodec = videoCodec; 183 return videoCodec; 184} 185 186/*static*/ MediaProfiles::AudioCodec* 187MediaProfiles::createAudioCodec(const char **atts, MediaProfiles *profiles) 188{ 189 CHECK(!strcmp("codec", atts[0]) && 190 !strcmp("bitRate", atts[2]) && 191 !strcmp("sampleRate", atts[4]) && 192 !strcmp("channels", atts[6])); 193 const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]); 194 const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]); 195 CHECK(codec != -1); 196 197 MediaProfiles::AudioCodec *audioCodec = 198 new MediaProfiles::AudioCodec(static_cast<audio_encoder>(codec), 199 atoi(atts[3]), atoi(atts[5]), atoi(atts[7])); 200 logAudioCodec(*audioCodec); 201 202 size_t nCamcorderProfiles; 203 CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1); 204 profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mAudioCodec = audioCodec; 205 return audioCodec; 206} 207/*static*/ MediaProfiles::AudioDecoderCap* 208MediaProfiles::createAudioDecoderCap(const char **atts) 209{ 210 CHECK(!strcmp("name", atts[0]) && 211 !strcmp("enabled", atts[2])); 212 213 const size_t nMappings = sizeof(sAudioDecoderNameMap)/sizeof(sAudioDecoderNameMap[0]); 214 const int codec = findTagForName(sAudioDecoderNameMap, nMappings, atts[1]); 215 CHECK(codec != -1); 216 217 MediaProfiles::AudioDecoderCap *cap = 218 new MediaProfiles::AudioDecoderCap(static_cast<audio_decoder>(codec)); 219 logAudioDecoderCap(*cap); 220 return cap; 221} 222 223/*static*/ MediaProfiles::VideoDecoderCap* 224MediaProfiles::createVideoDecoderCap(const char **atts) 225{ 226 CHECK(!strcmp("name", atts[0]) && 227 !strcmp("enabled", atts[2])); 228 229 const size_t nMappings = sizeof(sVideoDecoderNameMap)/sizeof(sVideoDecoderNameMap[0]); 230 const int codec = findTagForName(sVideoDecoderNameMap, nMappings, atts[1]); 231 CHECK(codec != -1); 232 233 MediaProfiles::VideoDecoderCap *cap = 234 new MediaProfiles::VideoDecoderCap(static_cast<video_decoder>(codec)); 235 logVideoDecoderCap(*cap); 236 return cap; 237} 238 239/*static*/ MediaProfiles::VideoEncoderCap* 240MediaProfiles::createVideoEncoderCap(const char **atts) 241{ 242 CHECK(!strcmp("name", atts[0]) && 243 !strcmp("enabled", atts[2]) && 244 !strcmp("minBitRate", atts[4]) && 245 !strcmp("maxBitRate", atts[6]) && 246 !strcmp("minFrameWidth", atts[8]) && 247 !strcmp("maxFrameWidth", atts[10]) && 248 !strcmp("minFrameHeight", atts[12]) && 249 !strcmp("maxFrameHeight", atts[14]) && 250 !strcmp("minFrameRate", atts[16]) && 251 !strcmp("maxFrameRate", atts[18])); 252 253 const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]); 254 const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]); 255 CHECK(codec != -1); 256 257 MediaProfiles::VideoEncoderCap *cap = 258 new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec), 259 atoi(atts[5]), atoi(atts[7]), atoi(atts[9]), atoi(atts[11]), atoi(atts[13]), 260 atoi(atts[15]), atoi(atts[17]), atoi(atts[19])); 261 logVideoEncoderCap(*cap); 262 return cap; 263} 264 265/*static*/ MediaProfiles::AudioEncoderCap* 266MediaProfiles::createAudioEncoderCap(const char **atts) 267{ 268 CHECK(!strcmp("name", atts[0]) && 269 !strcmp("enabled", atts[2]) && 270 !strcmp("minBitRate", atts[4]) && 271 !strcmp("maxBitRate", atts[6]) && 272 !strcmp("minSampleRate", atts[8]) && 273 !strcmp("maxSampleRate", atts[10]) && 274 !strcmp("minChannels", atts[12]) && 275 !strcmp("maxChannels", atts[14])); 276 277 const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]); 278 const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]); 279 CHECK(codec != -1); 280 281 MediaProfiles::AudioEncoderCap *cap = 282 new MediaProfiles::AudioEncoderCap(static_cast<audio_encoder>(codec), atoi(atts[5]), atoi(atts[7]), 283 atoi(atts[9]), atoi(atts[11]), atoi(atts[13]), 284 atoi(atts[15])); 285 logAudioEncoderCap(*cap); 286 return cap; 287} 288 289/*static*/ output_format 290MediaProfiles::createEncoderOutputFileFormat(const char **atts) 291{ 292 CHECK(!strcmp("name", atts[0])); 293 294 const size_t nMappings =sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]); 295 const int format = findTagForName(sFileFormatMap, nMappings, atts[1]); 296 CHECK(format != -1); 297 298 return static_cast<output_format>(format); 299} 300 301static bool isCameraIdFound(int cameraId, const Vector<int>& cameraIds) { 302 for (int i = 0, n = cameraIds.size(); i < n; ++i) { 303 if (cameraId == cameraIds[i]) { 304 return true; 305 } 306 } 307 return false; 308} 309 310/*static*/ MediaProfiles::CamcorderProfile* 311MediaProfiles::createCamcorderProfile(int cameraId, const char **atts, Vector<int>& cameraIds) 312{ 313 CHECK(!strcmp("quality", atts[0]) && 314 !strcmp("fileFormat", atts[2]) && 315 !strcmp("duration", atts[4])); 316 317 const size_t nProfileMappings = sizeof(sCamcorderQualityNameMap)/sizeof(sCamcorderQualityNameMap[0]); 318 const int quality = findTagForName(sCamcorderQualityNameMap, nProfileMappings, atts[1]); 319 CHECK(quality != -1); 320 321 const size_t nFormatMappings = sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]); 322 const int fileFormat = findTagForName(sFileFormatMap, nFormatMappings, atts[3]); 323 CHECK(fileFormat != -1); 324 325 MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; 326 profile->mCameraId = cameraId; 327 if (!isCameraIdFound(cameraId, cameraIds)) { 328 cameraIds.add(cameraId); 329 } 330 profile->mFileFormat = static_cast<output_format>(fileFormat); 331 profile->mQuality = static_cast<camcorder_quality>(quality); 332 profile->mDuration = atoi(atts[5]); 333 return profile; 334} 335 336MediaProfiles::ImageEncodingQualityLevels* 337MediaProfiles::findImageEncodingQualityLevels(int cameraId) const 338{ 339 int n = mImageEncodingQualityLevels.size(); 340 for (int i = 0; i < n; i++) { 341 ImageEncodingQualityLevels *levels = mImageEncodingQualityLevels[i]; 342 if (levels->mCameraId == cameraId) { 343 return levels; 344 } 345 } 346 return NULL; 347} 348 349void MediaProfiles::addImageEncodingQualityLevel(int cameraId, const char** atts) 350{ 351 CHECK(!strcmp("quality", atts[0])); 352 int quality = atoi(atts[1]); 353 ALOGV("%s: cameraId=%d, quality=%d", __func__, cameraId, quality); 354 ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId); 355 356 if (levels == NULL) { 357 levels = new ImageEncodingQualityLevels(); 358 levels->mCameraId = cameraId; 359 mImageEncodingQualityLevels.add(levels); 360 } 361 362 levels->mLevels.add(quality); 363} 364 365/*static*/ int 366MediaProfiles::getCameraId(const char** atts) 367{ 368 if (!atts[0]) return 0; // default cameraId = 0 369 CHECK(!strcmp("cameraId", atts[0])); 370 return atoi(atts[1]); 371} 372 373void MediaProfiles::addStartTimeOffset(int cameraId, const char** atts) 374{ 375 int offsetTimeMs = 700; 376 if (atts[2]) { 377 CHECK(!strcmp("startOffsetMs", atts[2])); 378 offsetTimeMs = atoi(atts[3]); 379 } 380 381 ALOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs); 382 mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs); 383} 384/*static*/ MediaProfiles::ExportVideoProfile* 385MediaProfiles::createExportVideoProfile(const char **atts) 386{ 387 CHECK(!strcmp("name", atts[0]) && 388 !strcmp("profile", atts[2]) && 389 !strcmp("level", atts[4])); 390 391 const size_t nMappings = 392 sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]); 393 const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]); 394 CHECK(codec != -1); 395 396 MediaProfiles::ExportVideoProfile *profile = 397 new MediaProfiles::ExportVideoProfile( 398 codec, atoi(atts[3]), atoi(atts[5])); 399 400 return profile; 401} 402/*static*/ MediaProfiles::VideoEditorCap* 403MediaProfiles::createVideoEditorCap(const char **atts, MediaProfiles *profiles) 404{ 405 CHECK(!strcmp("maxInputFrameWidth", atts[0]) && 406 !strcmp("maxInputFrameHeight", atts[2]) && 407 !strcmp("maxOutputFrameWidth", atts[4]) && 408 !strcmp("maxOutputFrameHeight", atts[6]) && 409 !strcmp("maxPrefetchYUVFrames", atts[8])); 410 411 MediaProfiles::VideoEditorCap *pVideoEditorCap = 412 new MediaProfiles::VideoEditorCap(atoi(atts[1]), atoi(atts[3]), 413 atoi(atts[5]), atoi(atts[7]), atoi(atts[9])); 414 415 logVideoEditorCap(*pVideoEditorCap); 416 profiles->mVideoEditorCap = pVideoEditorCap; 417 418 return pVideoEditorCap; 419} 420 421/*static*/ void 422MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts) 423{ 424 MediaProfiles *profiles = (MediaProfiles *) userData; 425 if (strcmp("Video", name) == 0) { 426 createVideoCodec(atts, profiles); 427 } else if (strcmp("Audio", name) == 0) { 428 createAudioCodec(atts, profiles); 429 } else if (strcmp("VideoEncoderCap", name) == 0 && 430 strcmp("true", atts[3]) == 0) { 431 profiles->mVideoEncoders.add(createVideoEncoderCap(atts)); 432 } else if (strcmp("AudioEncoderCap", name) == 0 && 433 strcmp("true", atts[3]) == 0) { 434 profiles->mAudioEncoders.add(createAudioEncoderCap(atts)); 435 } else if (strcmp("VideoDecoderCap", name) == 0 && 436 strcmp("true", atts[3]) == 0) { 437 profiles->mVideoDecoders.add(createVideoDecoderCap(atts)); 438 } else if (strcmp("AudioDecoderCap", name) == 0 && 439 strcmp("true", atts[3]) == 0) { 440 profiles->mAudioDecoders.add(createAudioDecoderCap(atts)); 441 } else if (strcmp("EncoderOutputFileFormat", name) == 0) { 442 profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts)); 443 } else if (strcmp("CamcorderProfiles", name) == 0) { 444 profiles->mCurrentCameraId = getCameraId(atts); 445 profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts); 446 } else if (strcmp("EncoderProfile", name) == 0) { 447 profiles->mCamcorderProfiles.add( 448 createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds)); 449 } else if (strcmp("ImageEncoding", name) == 0) { 450 profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts); 451 } else if (strcmp("VideoEditorCap", name) == 0) { 452 createVideoEditorCap(atts, profiles); 453 } else if (strcmp("ExportVideoProfile", name) == 0) { 454 profiles->mVideoEditorExportProfiles.add(createExportVideoProfile(atts)); 455 } 456} 457 458static bool isCamcorderProfile(camcorder_quality quality) { 459 return quality >= CAMCORDER_QUALITY_LIST_START && 460 quality <= CAMCORDER_QUALITY_LIST_END; 461} 462 463static bool isTimelapseProfile(camcorder_quality quality) { 464 return quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START && 465 quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END; 466} 467 468void MediaProfiles::initRequiredProfileRefs(const Vector<int>& cameraIds) { 469 ALOGV("Number of camera ids: %d", cameraIds.size()); 470 CHECK(cameraIds.size() > 0); 471 mRequiredProfileRefs = new RequiredProfiles[cameraIds.size()]; 472 for (size_t i = 0, n = cameraIds.size(); i < n; ++i) { 473 mRequiredProfileRefs[i].mCameraId = cameraIds[i]; 474 for (size_t j = 0; j < kNumRequiredProfiles; ++j) { 475 mRequiredProfileRefs[i].mRefs[j].mHasRefProfile = false; 476 mRequiredProfileRefs[i].mRefs[j].mRefProfileIndex = -1; 477 if ((j & 1) == 0) { // low resolution 478 mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0x7FFFFFFF; 479 } else { // high resolution 480 mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0; 481 } 482 } 483 } 484} 485 486int MediaProfiles::getRequiredProfileRefIndex(int cameraId) { 487 for (size_t i = 0, n = mCameraIds.size(); i < n; ++i) { 488 if (mCameraIds[i] == cameraId) { 489 return i; 490 } 491 } 492 return -1; 493} 494 495void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() { 496 if (sIsInitialized) { 497 return; 498 } 499 500 initRequiredProfileRefs(mCameraIds); 501 502 for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) { 503 int product = mCamcorderProfiles[i]->mVideoCodec->mFrameWidth * 504 mCamcorderProfiles[i]->mVideoCodec->mFrameHeight; 505 506 camcorder_quality quality = mCamcorderProfiles[i]->mQuality; 507 int cameraId = mCamcorderProfiles[i]->mCameraId; 508 int index = -1; 509 int refIndex = getRequiredProfileRefIndex(cameraId); 510 CHECK(refIndex != -1); 511 RequiredProfileRefInfo *info; 512 camcorder_quality refQuality; 513 VideoCodec *codec = NULL; 514 515 // Check high and low from either camcorder profile or timelapse profile 516 // but not both. Default, check camcorder profile 517 size_t j = 0; 518 size_t n = 2; 519 if (isTimelapseProfile(quality)) { 520 // Check timelapse profile instead. 521 j = 2; 522 n = kNumRequiredProfiles; 523 } else { 524 // Must be camcorder profile. 525 CHECK(isCamcorderProfile(quality)); 526 } 527 for (; j < n; ++j) { 528 info = &(mRequiredProfileRefs[refIndex].mRefs[j]); 529 if ((j % 2 == 0 && product > info->mResolutionProduct) || // low 530 (j % 2 != 0 && product < info->mResolutionProduct)) { // high 531 continue; 532 } 533 switch (j) { 534 case 0: 535 refQuality = CAMCORDER_QUALITY_LOW; 536 break; 537 case 1: 538 refQuality = CAMCORDER_QUALITY_HIGH; 539 break; 540 case 2: 541 refQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW; 542 break; 543 case 3: 544 refQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH; 545 break; 546 default: 547 CHECK(!"Should never reach here"); 548 } 549 550 if (!info->mHasRefProfile) { 551 index = getCamcorderProfileIndex(cameraId, refQuality); 552 } 553 if (index == -1) { 554 // New high or low quality profile is found. 555 // Update its reference. 556 info->mHasRefProfile = true; 557 info->mRefProfileIndex = i; 558 info->mResolutionProduct = product; 559 } 560 } 561 } 562 563 for (size_t cameraId = 0; cameraId < mCameraIds.size(); ++cameraId) { 564 for (size_t j = 0; j < kNumRequiredProfiles; ++j) { 565 int refIndex = getRequiredProfileRefIndex(cameraId); 566 CHECK(refIndex != -1); 567 RequiredProfileRefInfo *info = 568 &mRequiredProfileRefs[refIndex].mRefs[j]; 569 570 if (info->mHasRefProfile) { 571 572 CamcorderProfile *profile = 573 new CamcorderProfile( 574 *mCamcorderProfiles[info->mRefProfileIndex]); 575 576 // Overwrite the quality 577 switch (j % kNumRequiredProfiles) { 578 case 0: 579 profile->mQuality = CAMCORDER_QUALITY_LOW; 580 break; 581 case 1: 582 profile->mQuality = CAMCORDER_QUALITY_HIGH; 583 break; 584 case 2: 585 profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW; 586 break; 587 case 3: 588 profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH; 589 break; 590 default: 591 CHECK(!"Should never come here"); 592 } 593 594 int index = getCamcorderProfileIndex(cameraId, profile->mQuality); 595 if (index != -1) { 596 ALOGV("Profile quality %d for camera %d already exists", 597 profile->mQuality, cameraId); 598 CHECK(index == refIndex); 599 continue; 600 } 601 602 // Insert the new profile 603 ALOGV("Add a profile: quality %d=>%d for camera %d", 604 mCamcorderProfiles[info->mRefProfileIndex]->mQuality, 605 profile->mQuality, cameraId); 606 607 mCamcorderProfiles.add(profile); 608 } 609 } 610 } 611} 612 613/*static*/ MediaProfiles* 614MediaProfiles::getInstance() 615{ 616 ALOGV("getInstance"); 617 Mutex::Autolock lock(sLock); 618 if (!sIsInitialized) { 619 char value[PROPERTY_VALUE_MAX]; 620 if (property_get("media.settings.xml", value, NULL) <= 0) { 621 const char *defaultXmlFile = "/etc/media_profiles.xml"; 622 FILE *fp = fopen(defaultXmlFile, "r"); 623 if (fp == NULL) { 624 ALOGW("could not find media config xml file"); 625 sInstance = createDefaultInstance(); 626 } else { 627 fclose(fp); // close the file first. 628 sInstance = createInstanceFromXmlFile(defaultXmlFile); 629 } 630 } else { 631 sInstance = createInstanceFromXmlFile(value); 632 } 633 CHECK(sInstance != NULL); 634 sInstance->checkAndAddRequiredProfilesIfNecessary(); 635 sIsInitialized = true; 636 } 637 638 return sInstance; 639} 640 641/*static*/ MediaProfiles::VideoEncoderCap* 642MediaProfiles::createDefaultH263VideoEncoderCap() 643{ 644 return new MediaProfiles::VideoEncoderCap( 645 VIDEO_ENCODER_H263, 192000, 420000, 176, 352, 144, 288, 1, 20); 646} 647 648/*static*/ MediaProfiles::VideoEncoderCap* 649MediaProfiles::createDefaultM4vVideoEncoderCap() 650{ 651 return new MediaProfiles::VideoEncoderCap( 652 VIDEO_ENCODER_MPEG_4_SP, 192000, 420000, 176, 352, 144, 288, 1, 20); 653} 654 655 656/*static*/ void 657MediaProfiles::createDefaultVideoEncoders(MediaProfiles *profiles) 658{ 659 profiles->mVideoEncoders.add(createDefaultH263VideoEncoderCap()); 660 profiles->mVideoEncoders.add(createDefaultM4vVideoEncoderCap()); 661} 662 663/*static*/ MediaProfiles::CamcorderProfile* 664MediaProfiles::createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality) 665{ 666 MediaProfiles::VideoCodec *videoCodec = 667 new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 1000000, 176, 144, 20); 668 669 AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); 670 CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; 671 profile->mCameraId = 0; 672 profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; 673 profile->mQuality = quality; 674 profile->mDuration = 60; 675 profile->mVideoCodec = videoCodec; 676 profile->mAudioCodec = audioCodec; 677 return profile; 678} 679 680/*static*/ MediaProfiles::CamcorderProfile* 681MediaProfiles::createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality) 682{ 683 MediaProfiles::VideoCodec *videoCodec = 684 new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 20000000, 720, 480, 20); 685 686 AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); 687 CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; 688 profile->mCameraId = 0; 689 profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; 690 profile->mQuality = quality; 691 profile->mDuration = 60; 692 profile->mVideoCodec = videoCodec; 693 profile->mAudioCodec = audioCodec; 694 return profile; 695} 696 697/*static*/ void 698MediaProfiles::createDefaultCamcorderTimeLapseLowProfiles( 699 MediaProfiles::CamcorderProfile **lowTimeLapseProfile, 700 MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile) { 701 *lowTimeLapseProfile = createDefaultCamcorderTimeLapseQcifProfile(CAMCORDER_QUALITY_TIME_LAPSE_LOW); 702 *lowSpecificTimeLapseProfile = createDefaultCamcorderTimeLapseQcifProfile(CAMCORDER_QUALITY_TIME_LAPSE_QCIF); 703} 704 705/*static*/ void 706MediaProfiles::createDefaultCamcorderTimeLapseHighProfiles( 707 MediaProfiles::CamcorderProfile **highTimeLapseProfile, 708 MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile) { 709 *highTimeLapseProfile = createDefaultCamcorderTimeLapse480pProfile(CAMCORDER_QUALITY_TIME_LAPSE_HIGH); 710 *highSpecificTimeLapseProfile = createDefaultCamcorderTimeLapse480pProfile(CAMCORDER_QUALITY_TIME_LAPSE_480P); 711} 712 713/*static*/ MediaProfiles::CamcorderProfile* 714MediaProfiles::createDefaultCamcorderQcifProfile(camcorder_quality quality) 715{ 716 MediaProfiles::VideoCodec *videoCodec = 717 new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 192000, 176, 144, 20); 718 719 MediaProfiles::AudioCodec *audioCodec = 720 new MediaProfiles::AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); 721 722 MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; 723 profile->mCameraId = 0; 724 profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; 725 profile->mQuality = quality; 726 profile->mDuration = 30; 727 profile->mVideoCodec = videoCodec; 728 profile->mAudioCodec = audioCodec; 729 return profile; 730} 731 732/*static*/ MediaProfiles::CamcorderProfile* 733MediaProfiles::createDefaultCamcorderCifProfile(camcorder_quality quality) 734{ 735 MediaProfiles::VideoCodec *videoCodec = 736 new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 360000, 352, 288, 20); 737 738 AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); 739 CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; 740 profile->mCameraId = 0; 741 profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; 742 profile->mQuality = quality; 743 profile->mDuration = 60; 744 profile->mVideoCodec = videoCodec; 745 profile->mAudioCodec = audioCodec; 746 return profile; 747} 748 749/*static*/ void 750MediaProfiles::createDefaultCamcorderLowProfiles( 751 MediaProfiles::CamcorderProfile **lowProfile, 752 MediaProfiles::CamcorderProfile **lowSpecificProfile) { 753 *lowProfile = createDefaultCamcorderQcifProfile(CAMCORDER_QUALITY_LOW); 754 *lowSpecificProfile = createDefaultCamcorderQcifProfile(CAMCORDER_QUALITY_QCIF); 755} 756 757/*static*/ void 758MediaProfiles::createDefaultCamcorderHighProfiles( 759 MediaProfiles::CamcorderProfile **highProfile, 760 MediaProfiles::CamcorderProfile **highSpecificProfile) { 761 *highProfile = createDefaultCamcorderCifProfile(CAMCORDER_QUALITY_HIGH); 762 *highSpecificProfile = createDefaultCamcorderCifProfile(CAMCORDER_QUALITY_CIF); 763} 764 765/*static*/ void 766MediaProfiles::createDefaultCamcorderProfiles(MediaProfiles *profiles) 767{ 768 // low camcorder profiles. 769 MediaProfiles::CamcorderProfile *lowProfile, *lowSpecificProfile; 770 createDefaultCamcorderLowProfiles(&lowProfile, &lowSpecificProfile); 771 profiles->mCamcorderProfiles.add(lowProfile); 772 profiles->mCamcorderProfiles.add(lowSpecificProfile); 773 774 // high camcorder profiles. 775 MediaProfiles::CamcorderProfile* highProfile, *highSpecificProfile; 776 createDefaultCamcorderHighProfiles(&highProfile, &highSpecificProfile); 777 profiles->mCamcorderProfiles.add(highProfile); 778 profiles->mCamcorderProfiles.add(highSpecificProfile); 779 780 // low camcorder time lapse profiles. 781 MediaProfiles::CamcorderProfile *lowTimeLapseProfile, *lowSpecificTimeLapseProfile; 782 createDefaultCamcorderTimeLapseLowProfiles(&lowTimeLapseProfile, &lowSpecificTimeLapseProfile); 783 profiles->mCamcorderProfiles.add(lowTimeLapseProfile); 784 profiles->mCamcorderProfiles.add(lowSpecificTimeLapseProfile); 785 786 // high camcorder time lapse profiles. 787 MediaProfiles::CamcorderProfile *highTimeLapseProfile, *highSpecificTimeLapseProfile; 788 createDefaultCamcorderTimeLapseHighProfiles(&highTimeLapseProfile, &highSpecificTimeLapseProfile); 789 profiles->mCamcorderProfiles.add(highTimeLapseProfile); 790 profiles->mCamcorderProfiles.add(highSpecificTimeLapseProfile); 791 792 // For emulator and other legacy devices which does not have a 793 // media_profiles.xml file, We assume that the default camera id 794 // is 0 and that is the only camera available. 795 profiles->mCameraIds.push(0); 796} 797 798/*static*/ void 799MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles) 800{ 801 profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap()); 802} 803 804/*static*/ void 805MediaProfiles::createDefaultVideoDecoders(MediaProfiles *profiles) 806{ 807 MediaProfiles::VideoDecoderCap *cap = 808 new MediaProfiles::VideoDecoderCap(VIDEO_DECODER_WMV); 809 810 profiles->mVideoDecoders.add(cap); 811} 812 813/*static*/ void 814MediaProfiles::createDefaultAudioDecoders(MediaProfiles *profiles) 815{ 816 MediaProfiles::AudioDecoderCap *cap = 817 new MediaProfiles::AudioDecoderCap(AUDIO_DECODER_WMA); 818 819 profiles->mAudioDecoders.add(cap); 820} 821 822/*static*/ void 823MediaProfiles::createDefaultEncoderOutputFileFormats(MediaProfiles *profiles) 824{ 825 profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_THREE_GPP); 826 profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_MPEG_4); 827} 828 829/*static*/ MediaProfiles::AudioEncoderCap* 830MediaProfiles::createDefaultAmrNBEncoderCap() 831{ 832 return new MediaProfiles::AudioEncoderCap( 833 AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1); 834} 835 836/*static*/ void 837MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles) 838{ 839 ImageEncodingQualityLevels *levels = new ImageEncodingQualityLevels(); 840 levels->mCameraId = 0; 841 levels->mLevels.add(70); 842 levels->mLevels.add(80); 843 levels->mLevels.add(90); 844 profiles->mImageEncodingQualityLevels.add(levels); 845} 846 847/*static*/ void 848MediaProfiles::createDefaultVideoEditorCap(MediaProfiles *profiles) 849{ 850 profiles->mVideoEditorCap = 851 new MediaProfiles::VideoEditorCap( 852 VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH, 853 VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT, 854 VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH, 855 VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT, 856 VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES); 857} 858/*static*/ void 859MediaProfiles::createDefaultExportVideoProfiles(MediaProfiles *profiles) 860{ 861 // Create default video export profiles 862 profiles->mVideoEditorExportProfiles.add( 863 new ExportVideoProfile(VIDEO_ENCODER_H263, 864 OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10)); 865 profiles->mVideoEditorExportProfiles.add( 866 new ExportVideoProfile(VIDEO_ENCODER_MPEG_4_SP, 867 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1)); 868 profiles->mVideoEditorExportProfiles.add( 869 new ExportVideoProfile(VIDEO_ENCODER_H264, 870 OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13)); 871} 872 873/*static*/ MediaProfiles* 874MediaProfiles::createDefaultInstance() 875{ 876 MediaProfiles *profiles = new MediaProfiles; 877 createDefaultCamcorderProfiles(profiles); 878 createDefaultVideoEncoders(profiles); 879 createDefaultAudioEncoders(profiles); 880 createDefaultVideoDecoders(profiles); 881 createDefaultAudioDecoders(profiles); 882 createDefaultEncoderOutputFileFormats(profiles); 883 createDefaultImageEncodingQualityLevels(profiles); 884 createDefaultVideoEditorCap(profiles); 885 createDefaultExportVideoProfiles(profiles); 886 return profiles; 887} 888 889/*static*/ MediaProfiles* 890MediaProfiles::createInstanceFromXmlFile(const char *xml) 891{ 892 FILE *fp = NULL; 893 CHECK((fp = fopen(xml, "r"))); 894 895 XML_Parser parser = ::XML_ParserCreate(NULL); 896 CHECK(parser != NULL); 897 898 MediaProfiles *profiles = new MediaProfiles(); 899 ::XML_SetUserData(parser, profiles); 900 ::XML_SetElementHandler(parser, startElementHandler, NULL); 901 902 /* 903 FIXME: 904 expat is not compiled with -DXML_DTD. We don't have DTD parsing support. 905 906 if (!::XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)) { 907 ALOGE("failed to enable DTD support in the xml file"); 908 return UNKNOWN_ERROR; 909 } 910 911 */ 912 913 const int BUFF_SIZE = 512; 914 for (;;) { 915 void *buff = ::XML_GetBuffer(parser, BUFF_SIZE); 916 if (buff == NULL) { 917 ALOGE("failed to in call to XML_GetBuffer()"); 918 delete profiles; 919 profiles = NULL; 920 goto exit; 921 } 922 923 int bytes_read = ::fread(buff, 1, BUFF_SIZE, fp); 924 if (bytes_read < 0) { 925 ALOGE("failed in call to read"); 926 delete profiles; 927 profiles = NULL; 928 goto exit; 929 } 930 931 CHECK(::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)); 932 933 if (bytes_read == 0) break; // done parsing the xml file 934 } 935 936exit: 937 ::XML_ParserFree(parser); 938 ::fclose(fp); 939 return profiles; 940} 941 942Vector<output_format> MediaProfiles::getOutputFileFormats() const 943{ 944 return mEncoderOutputFileFormats; // copy out 945} 946 947Vector<video_encoder> MediaProfiles::getVideoEncoders() const 948{ 949 Vector<video_encoder> encoders; 950 for (size_t i = 0; i < mVideoEncoders.size(); ++i) { 951 encoders.add(mVideoEncoders[i]->mCodec); 952 } 953 return encoders; // copy out 954} 955 956int MediaProfiles::getVideoEncoderParamByName(const char *name, video_encoder codec) const 957{ 958 ALOGV("getVideoEncoderParamByName: %s for codec %d", name, codec); 959 int index = -1; 960 for (size_t i = 0, n = mVideoEncoders.size(); i < n; ++i) { 961 if (mVideoEncoders[i]->mCodec == codec) { 962 index = i; 963 break; 964 } 965 } 966 if (index == -1) { 967 ALOGE("The given video encoder %d is not found", codec); 968 return -1; 969 } 970 971 if (!strcmp("enc.vid.width.min", name)) return mVideoEncoders[index]->mMinFrameWidth; 972 if (!strcmp("enc.vid.width.max", name)) return mVideoEncoders[index]->mMaxFrameWidth; 973 if (!strcmp("enc.vid.height.min", name)) return mVideoEncoders[index]->mMinFrameHeight; 974 if (!strcmp("enc.vid.height.max", name)) return mVideoEncoders[index]->mMaxFrameHeight; 975 if (!strcmp("enc.vid.bps.min", name)) return mVideoEncoders[index]->mMinBitRate; 976 if (!strcmp("enc.vid.bps.max", name)) return mVideoEncoders[index]->mMaxBitRate; 977 if (!strcmp("enc.vid.fps.min", name)) return mVideoEncoders[index]->mMinFrameRate; 978 if (!strcmp("enc.vid.fps.max", name)) return mVideoEncoders[index]->mMaxFrameRate; 979 980 ALOGE("The given video encoder param name %s is not found", name); 981 return -1; 982} 983int MediaProfiles::getVideoEditorExportParamByName( 984 const char *name, int codec) const 985{ 986 ALOGV("getVideoEditorExportParamByName: name %s codec %d", name, codec); 987 ExportVideoProfile *exportProfile = NULL; 988 int index = -1; 989 for (size_t i =0; i < mVideoEditorExportProfiles.size(); i++) { 990 exportProfile = mVideoEditorExportProfiles[i]; 991 if (exportProfile->mCodec == codec) { 992 index = i; 993 break; 994 } 995 } 996 if (index == -1) { 997 ALOGE("The given video decoder %d is not found", codec); 998 return -1; 999 } 1000 if (!strcmp("videoeditor.export.profile", name)) 1001 return exportProfile->mProfile; 1002 if (!strcmp("videoeditor.export.level", name)) 1003 return exportProfile->mLevel; 1004 1005 ALOGE("The given video editor export param name %s is not found", name); 1006 return -1; 1007} 1008int MediaProfiles::getVideoEditorCapParamByName(const char *name) const 1009{ 1010 ALOGV("getVideoEditorCapParamByName: %s", name); 1011 1012 if (mVideoEditorCap == NULL) { 1013 ALOGE("The mVideoEditorCap is not created, then create default cap."); 1014 createDefaultVideoEditorCap(sInstance); 1015 } 1016 1017 if (!strcmp("videoeditor.input.width.max", name)) 1018 return mVideoEditorCap->mMaxInputFrameWidth; 1019 if (!strcmp("videoeditor.input.height.max", name)) 1020 return mVideoEditorCap->mMaxInputFrameHeight; 1021 if (!strcmp("videoeditor.output.width.max", name)) 1022 return mVideoEditorCap->mMaxOutputFrameWidth; 1023 if (!strcmp("videoeditor.output.height.max", name)) 1024 return mVideoEditorCap->mMaxOutputFrameHeight; 1025 if (!strcmp("maxPrefetchYUVFrames", name)) 1026 return mVideoEditorCap->mMaxPrefetchYUVFrames; 1027 1028 ALOGE("The given video editor param name %s is not found", name); 1029 return -1; 1030} 1031 1032Vector<audio_encoder> MediaProfiles::getAudioEncoders() const 1033{ 1034 Vector<audio_encoder> encoders; 1035 for (size_t i = 0; i < mAudioEncoders.size(); ++i) { 1036 encoders.add(mAudioEncoders[i]->mCodec); 1037 } 1038 return encoders; // copy out 1039} 1040 1041int MediaProfiles::getAudioEncoderParamByName(const char *name, audio_encoder codec) const 1042{ 1043 ALOGV("getAudioEncoderParamByName: %s for codec %d", name, codec); 1044 int index = -1; 1045 for (size_t i = 0, n = mAudioEncoders.size(); i < n; ++i) { 1046 if (mAudioEncoders[i]->mCodec == codec) { 1047 index = i; 1048 break; 1049 } 1050 } 1051 if (index == -1) { 1052 ALOGE("The given audio encoder %d is not found", codec); 1053 return -1; 1054 } 1055 1056 if (!strcmp("enc.aud.ch.min", name)) return mAudioEncoders[index]->mMinChannels; 1057 if (!strcmp("enc.aud.ch.max", name)) return mAudioEncoders[index]->mMaxChannels; 1058 if (!strcmp("enc.aud.bps.min", name)) return mAudioEncoders[index]->mMinBitRate; 1059 if (!strcmp("enc.aud.bps.max", name)) return mAudioEncoders[index]->mMaxBitRate; 1060 if (!strcmp("enc.aud.hz.min", name)) return mAudioEncoders[index]->mMinSampleRate; 1061 if (!strcmp("enc.aud.hz.max", name)) return mAudioEncoders[index]->mMaxSampleRate; 1062 1063 ALOGE("The given audio encoder param name %s is not found", name); 1064 return -1; 1065} 1066 1067Vector<video_decoder> MediaProfiles::getVideoDecoders() const 1068{ 1069 Vector<video_decoder> decoders; 1070 for (size_t i = 0; i < mVideoDecoders.size(); ++i) { 1071 decoders.add(mVideoDecoders[i]->mCodec); 1072 } 1073 return decoders; // copy out 1074} 1075 1076Vector<audio_decoder> MediaProfiles::getAudioDecoders() const 1077{ 1078 Vector<audio_decoder> decoders; 1079 for (size_t i = 0; i < mAudioDecoders.size(); ++i) { 1080 decoders.add(mAudioDecoders[i]->mCodec); 1081 } 1082 return decoders; // copy out 1083} 1084 1085int MediaProfiles::getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const 1086{ 1087 int index = -1; 1088 for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) { 1089 if (mCamcorderProfiles[i]->mCameraId == cameraId && 1090 mCamcorderProfiles[i]->mQuality == quality) { 1091 index = i; 1092 break; 1093 } 1094 } 1095 return index; 1096} 1097 1098int MediaProfiles::getCamcorderProfileParamByName(const char *name, 1099 int cameraId, 1100 camcorder_quality quality) const 1101{ 1102 ALOGV("getCamcorderProfileParamByName: %s for camera %d, quality %d", 1103 name, cameraId, quality); 1104 1105 int index = getCamcorderProfileIndex(cameraId, quality); 1106 if (index == -1) { 1107 ALOGE("The given camcorder profile camera %d quality %d is not found", 1108 cameraId, quality); 1109 return -1; 1110 } 1111 1112 if (!strcmp("duration", name)) return mCamcorderProfiles[index]->mDuration; 1113 if (!strcmp("file.format", name)) return mCamcorderProfiles[index]->mFileFormat; 1114 if (!strcmp("vid.codec", name)) return mCamcorderProfiles[index]->mVideoCodec->mCodec; 1115 if (!strcmp("vid.width", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameWidth; 1116 if (!strcmp("vid.height", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameHeight; 1117 if (!strcmp("vid.bps", name)) return mCamcorderProfiles[index]->mVideoCodec->mBitRate; 1118 if (!strcmp("vid.fps", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameRate; 1119 if (!strcmp("aud.codec", name)) return mCamcorderProfiles[index]->mAudioCodec->mCodec; 1120 if (!strcmp("aud.bps", name)) return mCamcorderProfiles[index]->mAudioCodec->mBitRate; 1121 if (!strcmp("aud.ch", name)) return mCamcorderProfiles[index]->mAudioCodec->mChannels; 1122 if (!strcmp("aud.hz", name)) return mCamcorderProfiles[index]->mAudioCodec->mSampleRate; 1123 1124 ALOGE("The given camcorder profile param id %d name %s is not found", cameraId, name); 1125 return -1; 1126} 1127 1128bool MediaProfiles::hasCamcorderProfile(int cameraId, camcorder_quality quality) const 1129{ 1130 return (getCamcorderProfileIndex(cameraId, quality) != -1); 1131} 1132 1133Vector<int> MediaProfiles::getImageEncodingQualityLevels(int cameraId) const 1134{ 1135 Vector<int> result; 1136 ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId); 1137 if (levels != NULL) { 1138 result = levels->mLevels; // copy out 1139 } 1140 return result; 1141} 1142 1143int MediaProfiles::getStartTimeOffsetMs(int cameraId) const { 1144 int offsetTimeMs = -1; 1145 ssize_t index = mStartTimeOffsets.indexOfKey(cameraId); 1146 if (index >= 0) { 1147 offsetTimeMs = mStartTimeOffsets.valueFor(cameraId); 1148 } 1149 ALOGV("offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId); 1150 return offsetTimeMs; 1151} 1152 1153MediaProfiles::~MediaProfiles() 1154{ 1155 CHECK("destructor should never be called" == 0); 1156#if 0 1157 for (size_t i = 0; i < mAudioEncoders.size(); ++i) { 1158 delete mAudioEncoders[i]; 1159 } 1160 mAudioEncoders.clear(); 1161 1162 for (size_t i = 0; i < mVideoEncoders.size(); ++i) { 1163 delete mVideoEncoders[i]; 1164 } 1165 mVideoEncoders.clear(); 1166 1167 for (size_t i = 0; i < mVideoDecoders.size(); ++i) { 1168 delete mVideoDecoders[i]; 1169 } 1170 mVideoDecoders.clear(); 1171 1172 for (size_t i = 0; i < mAudioDecoders.size(); ++i) { 1173 delete mAudioDecoders[i]; 1174 } 1175 mAudioDecoders.clear(); 1176 1177 for (size_t i = 0; i < mCamcorderProfiles.size(); ++i) { 1178 delete mCamcorderProfiles[i]; 1179 } 1180 mCamcorderProfiles.clear(); 1181#endif 1182} 1183} // namespace android 1184