1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "OMXCodec" 19 #include <utils/Log.h> 20 21 #include "include/AACEncoder.h" 22 23 #include "include/ESDS.h" 24 25 #include <binder/IServiceManager.h> 26 #include <binder/MemoryDealer.h> 27 #include <binder/ProcessState.h> 28 #include <HardwareAPI.h> 29 #include <media/stagefright/foundation/ADebug.h> 30 #include <media/IMediaPlayerService.h> 31 #include <media/stagefright/MediaBuffer.h> 32 #include <media/stagefright/MediaBufferGroup.h> 33 #include <media/stagefright/MediaDefs.h> 34 #include <media/stagefright/MediaCodecList.h> 35 #include <media/stagefright/MediaExtractor.h> 36 #include <media/stagefright/MetaData.h> 37 #include <media/stagefright/OMXCodec.h> 38 #include <media/stagefright/Utils.h> 39 #include <media/stagefright/SkipCutBuffer.h> 40 #include <utils/Vector.h> 41 42 #include <OMX_Audio.h> 43 #include <OMX_Component.h> 44 45 #include "include/avc_utils.h" 46 47 namespace android { 48 49 // Treat time out as an error if we have not received any output 50 // buffers after 3 seconds. 51 const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL; 52 53 // OMX Spec defines less than 50 color formats. If the query for 54 // color format is executed for more than kMaxColorFormatSupported, 55 // the query will fail to avoid looping forever. 56 // 1000 is more than enough for us to tell whether the omx 57 // component in question is buggy or not. 58 const static uint32_t kMaxColorFormatSupported = 1000; 59 60 #define FACTORY_CREATE_ENCODER(name) \ 61 static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \ 62 return new name(source, meta); \ 63 } 64 65 #define FACTORY_REF(name) { #name, Make##name }, 66 67 FACTORY_CREATE_ENCODER(AACEncoder) 68 69 static sp<MediaSource> InstantiateSoftwareEncoder( 70 const char *name, const sp<MediaSource> &source, 71 const sp<MetaData> &meta) { 72 struct FactoryInfo { 73 const char *name; 74 sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &); 75 }; 76 77 static const FactoryInfo kFactoryInfo[] = { 78 FACTORY_REF(AACEncoder) 79 }; 80 for (size_t i = 0; 81 i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 82 if (!strcmp(name, kFactoryInfo[i].name)) { 83 return (*kFactoryInfo[i].CreateFunc)(source, meta); 84 } 85 } 86 87 return NULL; 88 } 89 90 #undef FACTORY_CREATE_ENCODER 91 #undef FACTORY_REF 92 93 #define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 94 #define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 95 #define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__) 96 97 struct OMXCodecObserver : public BnOMXObserver { 98 OMXCodecObserver() { 99 } 100 101 void setCodec(const sp<OMXCodec> &target) { 102 mTarget = target; 103 } 104 105 // from IOMXObserver 106 virtual void onMessage(const omx_message &msg) { 107 sp<OMXCodec> codec = mTarget.promote(); 108 109 if (codec.get() != NULL) { 110 Mutex::Autolock autoLock(codec->mLock); 111 codec->on_message(msg); 112 codec.clear(); 113 } 114 } 115 116 protected: 117 virtual ~OMXCodecObserver() {} 118 119 private: 120 wp<OMXCodec> mTarget; 121 122 OMXCodecObserver(const OMXCodecObserver &); 123 OMXCodecObserver &operator=(const OMXCodecObserver &); 124 }; 125 126 template<class T> 127 static void InitOMXParams(T *params) { 128 params->nSize = sizeof(T); 129 params->nVersion.s.nVersionMajor = 1; 130 params->nVersion.s.nVersionMinor = 0; 131 params->nVersion.s.nRevision = 0; 132 params->nVersion.s.nStep = 0; 133 } 134 135 static bool IsSoftwareCodec(const char *componentName) { 136 if (!strncmp("OMX.google.", componentName, 11)) { 137 return true; 138 } 139 140 if (!strncmp("OMX.", componentName, 4)) { 141 return false; 142 } 143 144 return true; 145 } 146 147 // A sort order in which OMX software codecs are first, followed 148 // by other (non-OMX) software codecs, followed by everything else. 149 static int CompareSoftwareCodecsFirst( 150 const OMXCodec::CodecNameAndQuirks *elem1, 151 const OMXCodec::CodecNameAndQuirks *elem2) { 152 bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4); 153 bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4); 154 155 bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string()); 156 bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string()); 157 158 if (isSoftwareCodec1) { 159 if (!isSoftwareCodec2) { return -1; } 160 161 if (isOMX1) { 162 if (isOMX2) { return 0; } 163 164 return -1; 165 } else { 166 if (isOMX2) { return 0; } 167 168 return 1; 169 } 170 171 return -1; 172 } 173 174 if (isSoftwareCodec2) { 175 return 1; 176 } 177 178 return 0; 179 } 180 181 // static 182 void OMXCodec::findMatchingCodecs( 183 const char *mime, 184 bool createEncoder, const char *matchComponentName, 185 uint32_t flags, 186 Vector<CodecNameAndQuirks> *matchingCodecs) { 187 matchingCodecs->clear(); 188 189 const MediaCodecList *list = MediaCodecList::getInstance(); 190 if (list == NULL) { 191 return; 192 } 193 194 size_t index = 0; 195 for (;;) { 196 ssize_t matchIndex = 197 list->findCodecByType(mime, createEncoder, index); 198 199 if (matchIndex < 0) { 200 break; 201 } 202 203 index = matchIndex + 1; 204 205 const char *componentName = list->getCodecName(matchIndex); 206 207 // If a specific codec is requested, skip the non-matching ones. 208 if (matchComponentName && strcmp(componentName, matchComponentName)) { 209 continue; 210 } 211 212 // When requesting software-only codecs, only push software codecs 213 // When requesting hardware-only codecs, only push hardware codecs 214 // When there is request neither for software-only nor for 215 // hardware-only codecs, push all codecs 216 if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) || 217 ((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) || 218 (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) { 219 220 ssize_t index = matchingCodecs->add(); 221 CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index); 222 entry->mName = String8(componentName); 223 entry->mQuirks = getComponentQuirks(list, matchIndex); 224 225 ALOGV("matching '%s' quirks 0x%08x", 226 entry->mName.string(), entry->mQuirks); 227 } 228 } 229 230 if (flags & kPreferSoftwareCodecs) { 231 matchingCodecs->sort(CompareSoftwareCodecsFirst); 232 } 233 } 234 235 // static 236 uint32_t OMXCodec::getComponentQuirks( 237 const MediaCodecList *list, size_t index) { 238 uint32_t quirks = 0; 239 if (list->codecHasQuirk( 240 index, "requires-allocate-on-input-ports")) { 241 quirks |= kRequiresAllocateBufferOnInputPorts; 242 } 243 if (list->codecHasQuirk( 244 index, "requires-allocate-on-output-ports")) { 245 quirks |= kRequiresAllocateBufferOnOutputPorts; 246 } 247 if (list->codecHasQuirk( 248 index, "output-buffers-are-unreadable")) { 249 quirks |= kOutputBuffersAreUnreadable; 250 } 251 252 return quirks; 253 } 254 255 // static 256 bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) { 257 const MediaCodecList *list = MediaCodecList::getInstance(); 258 259 if (list == NULL) { 260 return false; 261 } 262 263 ssize_t index = list->findCodecByName(componentName); 264 265 if (index < 0) { 266 return false; 267 } 268 269 *quirks = getComponentQuirks(list, index); 270 271 return true; 272 } 273 274 // static 275 sp<MediaSource> OMXCodec::Create( 276 const sp<IOMX> &omx, 277 const sp<MetaData> &meta, bool createEncoder, 278 const sp<MediaSource> &source, 279 const char *matchComponentName, 280 uint32_t flags, 281 const sp<ANativeWindow> &nativeWindow) { 282 int32_t requiresSecureBuffers; 283 if (source->getFormat()->findInt32( 284 kKeyRequiresSecureBuffers, 285 &requiresSecureBuffers) 286 && requiresSecureBuffers) { 287 flags |= kIgnoreCodecSpecificData; 288 flags |= kUseSecureInputBuffers; 289 } 290 291 const char *mime; 292 bool success = meta->findCString(kKeyMIMEType, &mime); 293 CHECK(success); 294 295 Vector<CodecNameAndQuirks> matchingCodecs; 296 findMatchingCodecs( 297 mime, createEncoder, matchComponentName, flags, &matchingCodecs); 298 299 if (matchingCodecs.isEmpty()) { 300 ALOGV("No matching codecs! (mime: %s, createEncoder: %s, " 301 "matchComponentName: %s, flags: 0x%x)", 302 mime, createEncoder ? "true" : "false", matchComponentName, flags); 303 return NULL; 304 } 305 306 sp<OMXCodecObserver> observer = new OMXCodecObserver; 307 IOMX::node_id node = 0; 308 309 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 310 const char *componentNameBase = matchingCodecs[i].mName.string(); 311 uint32_t quirks = matchingCodecs[i].mQuirks; 312 const char *componentName = componentNameBase; 313 314 AString tmp; 315 if (flags & kUseSecureInputBuffers) { 316 tmp = componentNameBase; 317 tmp.append(".secure"); 318 319 componentName = tmp.c_str(); 320 } 321 322 if (createEncoder) { 323 sp<MediaSource> softwareCodec = 324 InstantiateSoftwareEncoder(componentName, source, meta); 325 326 if (softwareCodec != NULL) { 327 ALOGV("Successfully allocated software codec '%s'", componentName); 328 329 return softwareCodec; 330 } 331 } 332 333 ALOGV("Attempting to allocate OMX node '%s'", componentName); 334 335 if (!createEncoder 336 && (quirks & kOutputBuffersAreUnreadable) 337 && (flags & kClientNeedsFramebuffer)) { 338 if (strncmp(componentName, "OMX.SEC.", 8)) { 339 // For OMX.SEC.* decoders we can enable a special mode that 340 // gives the client access to the framebuffer contents. 341 342 ALOGW("Component '%s' does not give the client access to " 343 "the framebuffer contents. Skipping.", 344 componentName); 345 346 continue; 347 } 348 } 349 350 status_t err = omx->allocateNode(componentName, observer, &node); 351 if (err == OK) { 352 ALOGV("Successfully allocated OMX node '%s'", componentName); 353 354 sp<OMXCodec> codec = new OMXCodec( 355 omx, node, quirks, flags, 356 createEncoder, mime, componentName, 357 source, nativeWindow); 358 359 observer->setCodec(codec); 360 361 err = codec->configureCodec(meta); 362 363 if (err == OK) { 364 if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) { 365 codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime; 366 } 367 368 return codec; 369 } 370 371 ALOGV("Failed to configure codec '%s'", componentName); 372 } 373 } 374 375 return NULL; 376 } 377 378 status_t OMXCodec::parseAVCCodecSpecificData( 379 const void *data, size_t size, 380 unsigned *profile, unsigned *level) { 381 const uint8_t *ptr = (const uint8_t *)data; 382 383 // verify minimum size and configurationVersion == 1. 384 if (size < 7 || ptr[0] != 1) { 385 return ERROR_MALFORMED; 386 } 387 388 *profile = ptr[1]; 389 *level = ptr[3]; 390 391 // There is decodable content out there that fails the following 392 // assertion, let's be lenient for now... 393 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 394 395 size_t lengthSize = 1 + (ptr[4] & 3); 396 397 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 398 // violates it... 399 // CHECK((ptr[5] >> 5) == 7); // reserved 400 401 size_t numSeqParameterSets = ptr[5] & 31; 402 403 ptr += 6; 404 size -= 6; 405 406 for (size_t i = 0; i < numSeqParameterSets; ++i) { 407 if (size < 2) { 408 return ERROR_MALFORMED; 409 } 410 411 size_t length = U16_AT(ptr); 412 413 ptr += 2; 414 size -= 2; 415 416 if (size < length) { 417 return ERROR_MALFORMED; 418 } 419 420 addCodecSpecificData(ptr, length); 421 422 ptr += length; 423 size -= length; 424 } 425 426 if (size < 1) { 427 return ERROR_MALFORMED; 428 } 429 430 size_t numPictureParameterSets = *ptr; 431 ++ptr; 432 --size; 433 434 for (size_t i = 0; i < numPictureParameterSets; ++i) { 435 if (size < 2) { 436 return ERROR_MALFORMED; 437 } 438 439 size_t length = U16_AT(ptr); 440 441 ptr += 2; 442 size -= 2; 443 444 if (size < length) { 445 return ERROR_MALFORMED; 446 } 447 448 addCodecSpecificData(ptr, length); 449 450 ptr += length; 451 size -= length; 452 } 453 454 return OK; 455 } 456 457 status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { 458 ALOGV("configureCodec protected=%d", 459 (mFlags & kEnableGrallocUsageProtected) ? 1 : 0); 460 461 if (!(mFlags & kIgnoreCodecSpecificData)) { 462 uint32_t type; 463 const void *data; 464 size_t size; 465 if (meta->findData(kKeyESDS, &type, &data, &size)) { 466 ESDS esds((const char *)data, size); 467 CHECK_EQ(esds.InitCheck(), (status_t)OK); 468 469 const void *codec_specific_data; 470 size_t codec_specific_data_size; 471 esds.getCodecSpecificInfo( 472 &codec_specific_data, &codec_specific_data_size); 473 474 addCodecSpecificData( 475 codec_specific_data, codec_specific_data_size); 476 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 477 // Parse the AVCDecoderConfigurationRecord 478 479 unsigned profile, level; 480 status_t err; 481 if ((err = parseAVCCodecSpecificData( 482 data, size, &profile, &level)) != OK) { 483 ALOGE("Malformed AVC codec specific data."); 484 return err; 485 } 486 487 CODEC_LOGI( 488 "AVC profile = %u (%s), level = %u", 489 profile, AVCProfileToString(profile), level); 490 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 491 addCodecSpecificData(data, size); 492 493 CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 494 addCodecSpecificData(data, size); 495 } 496 } 497 498 int32_t bitRate = 0; 499 if (mIsEncoder) { 500 CHECK(meta->findInt32(kKeyBitRate, &bitRate)); 501 } 502 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) { 503 setAMRFormat(false /* isWAMR */, bitRate); 504 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) { 505 setAMRFormat(true /* isWAMR */, bitRate); 506 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) { 507 int32_t numChannels, sampleRate, aacProfile; 508 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 509 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 510 511 if (!meta->findInt32(kKeyAACProfile, &aacProfile)) { 512 aacProfile = OMX_AUDIO_AACObjectNull; 513 } 514 515 int32_t isADTS; 516 if (!meta->findInt32(kKeyIsADTS, &isADTS)) { 517 isADTS = false; 518 } 519 520 status_t err = setAACFormat(numChannels, sampleRate, bitRate, aacProfile, isADTS); 521 if (err != OK) { 522 CODEC_LOGE("setAACFormat() failed (err = %d)", err); 523 return err; 524 } 525 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, mMIME)) { 526 int32_t numChannels, sampleRate; 527 if (meta->findInt32(kKeyChannelCount, &numChannels) 528 && meta->findInt32(kKeySampleRate, &sampleRate)) { 529 // Since we did not always check for these, leave them optional 530 // and have the decoder figure it all out. 531 setRawAudioFormat( 532 mIsEncoder ? kPortIndexInput : kPortIndexOutput, 533 sampleRate, 534 numChannels); 535 } 536 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME) 537 || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) { 538 // These are PCM-like formats with a fixed sample rate but 539 // a variable number of channels. 540 541 int32_t numChannels; 542 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 543 544 setG711Format(numChannels); 545 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mMIME)) { 546 CHECK(!mIsEncoder); 547 548 int32_t numChannels, sampleRate; 549 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 550 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 551 552 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 553 } 554 555 if (!strncasecmp(mMIME, "video/", 6)) { 556 557 if (mIsEncoder) { 558 setVideoInputFormat(mMIME, meta); 559 } else { 560 status_t err = setVideoOutputFormat( 561 mMIME, meta); 562 563 if (err != OK) { 564 return err; 565 } 566 } 567 } 568 569 int32_t maxInputSize; 570 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 571 setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize); 572 } 573 574 initOutputFormat(meta); 575 576 if ((mFlags & kClientNeedsFramebuffer) 577 && !strncmp(mComponentName, "OMX.SEC.", 8)) { 578 // This appears to no longer be needed??? 579 580 OMX_INDEXTYPE index; 581 582 status_t err = 583 mOMX->getExtensionIndex( 584 mNode, 585 "OMX.SEC.index.ThumbnailMode", 586 &index); 587 588 if (err != OK) { 589 return err; 590 } 591 592 OMX_BOOL enable = OMX_TRUE; 593 err = mOMX->setConfig(mNode, index, &enable, sizeof(enable)); 594 595 if (err != OK) { 596 CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') " 597 "returned error 0x%08x", err); 598 599 return err; 600 } 601 602 mQuirks &= ~kOutputBuffersAreUnreadable; 603 } 604 605 if (mNativeWindow != NULL 606 && !mIsEncoder 607 && !strncasecmp(mMIME, "video/", 6) 608 && !strncmp(mComponentName, "OMX.", 4)) { 609 status_t err = initNativeWindow(); 610 if (err != OK) { 611 return err; 612 } 613 } 614 615 return OK; 616 } 617 618 void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { 619 OMX_PARAM_PORTDEFINITIONTYPE def; 620 InitOMXParams(&def); 621 def.nPortIndex = portIndex; 622 623 status_t err = mOMX->getParameter( 624 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 625 CHECK_EQ(err, (status_t)OK); 626 627 if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus)) 628 || (def.nBufferSize < size)) { 629 def.nBufferSize = size; 630 } 631 632 err = mOMX->setParameter( 633 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 634 CHECK_EQ(err, (status_t)OK); 635 636 err = mOMX->getParameter( 637 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 638 CHECK_EQ(err, (status_t)OK); 639 640 // Make sure the setting actually stuck. 641 if (portIndex == kPortIndexInput 642 && (mQuirks & kInputBufferSizesAreBogus)) { 643 CHECK_EQ(def.nBufferSize, size); 644 } else { 645 CHECK(def.nBufferSize >= size); 646 } 647 } 648 649 status_t OMXCodec::setVideoPortFormatType( 650 OMX_U32 portIndex, 651 OMX_VIDEO_CODINGTYPE compressionFormat, 652 OMX_COLOR_FORMATTYPE colorFormat) { 653 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 654 InitOMXParams(&format); 655 format.nPortIndex = portIndex; 656 format.nIndex = 0; 657 bool found = false; 658 659 OMX_U32 index = 0; 660 for (;;) { 661 format.nIndex = index; 662 status_t err = mOMX->getParameter( 663 mNode, OMX_IndexParamVideoPortFormat, 664 &format, sizeof(format)); 665 666 if (err != OK) { 667 return err; 668 } 669 670 // The following assertion is violated by TI's video decoder. 671 // CHECK_EQ(format.nIndex, index); 672 673 #if 1 674 CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", 675 portIndex, 676 index, format.eCompressionFormat, format.eColorFormat); 677 #endif 678 679 if (format.eCompressionFormat == compressionFormat 680 && format.eColorFormat == colorFormat) { 681 found = true; 682 break; 683 } 684 685 ++index; 686 if (index >= kMaxColorFormatSupported) { 687 CODEC_LOGE("color format %d or compression format %d is not supported", 688 colorFormat, compressionFormat); 689 return UNKNOWN_ERROR; 690 } 691 } 692 693 if (!found) { 694 return UNKNOWN_ERROR; 695 } 696 697 CODEC_LOGV("found a match."); 698 status_t err = mOMX->setParameter( 699 mNode, OMX_IndexParamVideoPortFormat, 700 &format, sizeof(format)); 701 702 return err; 703 } 704 705 static size_t getFrameSize( 706 OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) { 707 switch (colorFormat) { 708 case OMX_COLOR_FormatYCbYCr: 709 case OMX_COLOR_FormatCbYCrY: 710 return width * height * 2; 711 712 case OMX_COLOR_FormatYUV420Planar: 713 case OMX_COLOR_FormatYUV420SemiPlanar: 714 case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: 715 /* 716 * FIXME: For the Opaque color format, the frame size does not 717 * need to be (w*h*3)/2. It just needs to 718 * be larger than certain minimum buffer size. However, 719 * currently, this opaque foramt has been tested only on 720 * YUV420 formats. If that is changed, then we need to revisit 721 * this part in the future 722 */ 723 case OMX_COLOR_FormatAndroidOpaque: 724 return (width * height * 3) / 2; 725 726 default: 727 CHECK(!"Should not be here. Unsupported color format."); 728 break; 729 } 730 } 731 732 status_t OMXCodec::findTargetColorFormat( 733 const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) { 734 ALOGV("findTargetColorFormat"); 735 CHECK(mIsEncoder); 736 737 *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 738 int32_t targetColorFormat; 739 if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) { 740 *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat; 741 } 742 743 // Check whether the target color format is supported. 744 return isColorFormatSupported(*colorFormat, kPortIndexInput); 745 } 746 747 status_t OMXCodec::isColorFormatSupported( 748 OMX_COLOR_FORMATTYPE colorFormat, int portIndex) { 749 ALOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat)); 750 751 // Enumerate all the color formats supported by 752 // the omx component to see whether the given 753 // color format is supported. 754 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 755 InitOMXParams(&portFormat); 756 portFormat.nPortIndex = portIndex; 757 OMX_U32 index = 0; 758 portFormat.nIndex = index; 759 while (true) { 760 if (OMX_ErrorNone != mOMX->getParameter( 761 mNode, OMX_IndexParamVideoPortFormat, 762 &portFormat, sizeof(portFormat))) { 763 break; 764 } 765 // Make sure that omx component does not overwrite 766 // the incremented index (bug 2897413). 767 CHECK_EQ(index, portFormat.nIndex); 768 if (portFormat.eColorFormat == colorFormat) { 769 CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat); 770 return OK; // colorFormat is supported! 771 } 772 ++index; 773 portFormat.nIndex = index; 774 775 if (index >= kMaxColorFormatSupported) { 776 CODEC_LOGE("More than %ld color formats are supported???", index); 777 break; 778 } 779 } 780 781 CODEC_LOGE("color format %d is not supported", colorFormat); 782 return UNKNOWN_ERROR; 783 } 784 785 void OMXCodec::setVideoInputFormat( 786 const char *mime, const sp<MetaData>& meta) { 787 788 int32_t width, height, frameRate, bitRate, stride, sliceHeight; 789 bool success = meta->findInt32(kKeyWidth, &width); 790 success = success && meta->findInt32(kKeyHeight, &height); 791 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 792 success = success && meta->findInt32(kKeyBitRate, &bitRate); 793 success = success && meta->findInt32(kKeyStride, &stride); 794 success = success && meta->findInt32(kKeySliceHeight, &sliceHeight); 795 CHECK(success); 796 CHECK(stride != 0); 797 798 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 799 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 800 compressionFormat = OMX_VIDEO_CodingAVC; 801 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 802 compressionFormat = OMX_VIDEO_CodingMPEG4; 803 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 804 compressionFormat = OMX_VIDEO_CodingH263; 805 } else { 806 ALOGE("Not a supported video mime type: %s", mime); 807 CHECK(!"Should not be here. Not a supported video mime type."); 808 } 809 810 OMX_COLOR_FORMATTYPE colorFormat; 811 CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat)); 812 813 status_t err; 814 OMX_PARAM_PORTDEFINITIONTYPE def; 815 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 816 817 //////////////////////// Input port ///////////////////////// 818 CHECK_EQ(setVideoPortFormatType( 819 kPortIndexInput, OMX_VIDEO_CodingUnused, 820 colorFormat), (status_t)OK); 821 822 InitOMXParams(&def); 823 def.nPortIndex = kPortIndexInput; 824 825 err = mOMX->getParameter( 826 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 827 CHECK_EQ(err, (status_t)OK); 828 829 def.nBufferSize = getFrameSize(colorFormat, 830 stride > 0? stride: -stride, sliceHeight); 831 832 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 833 834 video_def->nFrameWidth = width; 835 video_def->nFrameHeight = height; 836 video_def->nStride = stride; 837 video_def->nSliceHeight = sliceHeight; 838 video_def->xFramerate = (frameRate << 16); // Q16 format 839 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 840 video_def->eColorFormat = colorFormat; 841 842 err = mOMX->setParameter( 843 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 844 CHECK_EQ(err, (status_t)OK); 845 846 //////////////////////// Output port ///////////////////////// 847 CHECK_EQ(setVideoPortFormatType( 848 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused), 849 (status_t)OK); 850 InitOMXParams(&def); 851 def.nPortIndex = kPortIndexOutput; 852 853 err = mOMX->getParameter( 854 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 855 856 CHECK_EQ(err, (status_t)OK); 857 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 858 859 video_def->nFrameWidth = width; 860 video_def->nFrameHeight = height; 861 video_def->xFramerate = 0; // No need for output port 862 video_def->nBitrate = bitRate; // Q16 format 863 video_def->eCompressionFormat = compressionFormat; 864 video_def->eColorFormat = OMX_COLOR_FormatUnused; 865 if (mQuirks & kRequiresLargerEncoderOutputBuffer) { 866 // Increases the output buffer size 867 def.nBufferSize = ((def.nBufferSize * 3) >> 1); 868 } 869 870 err = mOMX->setParameter( 871 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 872 CHECK_EQ(err, (status_t)OK); 873 874 /////////////////// Codec-specific //////////////////////// 875 switch (compressionFormat) { 876 case OMX_VIDEO_CodingMPEG4: 877 { 878 CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK); 879 break; 880 } 881 882 case OMX_VIDEO_CodingH263: 883 CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK); 884 break; 885 886 case OMX_VIDEO_CodingAVC: 887 { 888 CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK); 889 break; 890 } 891 892 default: 893 CHECK(!"Support for this compressionFormat to be implemented."); 894 break; 895 } 896 } 897 898 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 899 if (iFramesInterval < 0) { 900 return 0xFFFFFFFF; 901 } else if (iFramesInterval == 0) { 902 return 0; 903 } 904 OMX_U32 ret = frameRate * iFramesInterval - 1; 905 CHECK(ret > 1); 906 return ret; 907 } 908 909 status_t OMXCodec::setupErrorCorrectionParameters() { 910 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 911 InitOMXParams(&errorCorrectionType); 912 errorCorrectionType.nPortIndex = kPortIndexOutput; 913 914 status_t err = mOMX->getParameter( 915 mNode, OMX_IndexParamVideoErrorCorrection, 916 &errorCorrectionType, sizeof(errorCorrectionType)); 917 if (err != OK) { 918 ALOGW("Error correction param query is not supported"); 919 return OK; // Optional feature. Ignore this failure 920 } 921 922 errorCorrectionType.bEnableHEC = OMX_FALSE; 923 errorCorrectionType.bEnableResync = OMX_TRUE; 924 errorCorrectionType.nResynchMarkerSpacing = 256; 925 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 926 errorCorrectionType.bEnableRVLC = OMX_FALSE; 927 928 err = mOMX->setParameter( 929 mNode, OMX_IndexParamVideoErrorCorrection, 930 &errorCorrectionType, sizeof(errorCorrectionType)); 931 if (err != OK) { 932 ALOGW("Error correction param configuration is not supported"); 933 } 934 935 // Optional feature. Ignore the failure. 936 return OK; 937 } 938 939 status_t OMXCodec::setupBitRate(int32_t bitRate) { 940 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 941 InitOMXParams(&bitrateType); 942 bitrateType.nPortIndex = kPortIndexOutput; 943 944 status_t err = mOMX->getParameter( 945 mNode, OMX_IndexParamVideoBitrate, 946 &bitrateType, sizeof(bitrateType)); 947 CHECK_EQ(err, (status_t)OK); 948 949 bitrateType.eControlRate = OMX_Video_ControlRateVariable; 950 bitrateType.nTargetBitrate = bitRate; 951 952 err = mOMX->setParameter( 953 mNode, OMX_IndexParamVideoBitrate, 954 &bitrateType, sizeof(bitrateType)); 955 CHECK_EQ(err, (status_t)OK); 956 return OK; 957 } 958 959 status_t OMXCodec::getVideoProfileLevel( 960 const sp<MetaData>& meta, 961 const CodecProfileLevel& defaultProfileLevel, 962 CodecProfileLevel &profileLevel) { 963 CODEC_LOGV("Default profile: %ld, level %ld", 964 defaultProfileLevel.mProfile, defaultProfileLevel.mLevel); 965 966 // Are the default profile and level overwriten? 967 int32_t profile, level; 968 if (!meta->findInt32(kKeyVideoProfile, &profile)) { 969 profile = defaultProfileLevel.mProfile; 970 } 971 if (!meta->findInt32(kKeyVideoLevel, &level)) { 972 level = defaultProfileLevel.mLevel; 973 } 974 CODEC_LOGV("Target profile: %d, level: %d", profile, level); 975 976 // Are the target profile and level supported by the encoder? 977 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 978 InitOMXParams(¶m); 979 param.nPortIndex = kPortIndexOutput; 980 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 981 status_t err = mOMX->getParameter( 982 mNode, OMX_IndexParamVideoProfileLevelQuerySupported, 983 ¶m, sizeof(param)); 984 985 if (err != OK) break; 986 987 int32_t supportedProfile = static_cast<int32_t>(param.eProfile); 988 int32_t supportedLevel = static_cast<int32_t>(param.eLevel); 989 CODEC_LOGV("Supported profile: %d, level %d", 990 supportedProfile, supportedLevel); 991 992 if (profile == supportedProfile && 993 level <= supportedLevel) { 994 // We can further check whether the level is a valid 995 // value; but we will leave that to the omx encoder component 996 // via OMX_SetParameter call. 997 profileLevel.mProfile = profile; 998 profileLevel.mLevel = level; 999 return OK; 1000 } 1001 } 1002 1003 CODEC_LOGE("Target profile (%d) and level (%d) is not supported", 1004 profile, level); 1005 return BAD_VALUE; 1006 } 1007 1008 status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) { 1009 int32_t iFramesInterval, frameRate, bitRate; 1010 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1011 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1012 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1013 CHECK(success); 1014 OMX_VIDEO_PARAM_H263TYPE h263type; 1015 InitOMXParams(&h263type); 1016 h263type.nPortIndex = kPortIndexOutput; 1017 1018 status_t err = mOMX->getParameter( 1019 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1020 CHECK_EQ(err, (status_t)OK); 1021 1022 h263type.nAllowedPictureTypes = 1023 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1024 1025 h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1026 if (h263type.nPFrames == 0) { 1027 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1028 } 1029 h263type.nBFrames = 0; 1030 1031 // Check profile and level parameters 1032 CodecProfileLevel defaultProfileLevel, profileLevel; 1033 defaultProfileLevel.mProfile = h263type.eProfile; 1034 defaultProfileLevel.mLevel = h263type.eLevel; 1035 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1036 if (err != OK) return err; 1037 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile); 1038 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel); 1039 1040 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 1041 h263type.bForceRoundingTypeToZero = OMX_FALSE; 1042 h263type.nPictureHeaderRepetition = 0; 1043 h263type.nGOBHeaderInterval = 0; 1044 1045 err = mOMX->setParameter( 1046 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1047 CHECK_EQ(err, (status_t)OK); 1048 1049 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1050 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1051 1052 return OK; 1053 } 1054 1055 status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { 1056 int32_t iFramesInterval, frameRate, bitRate; 1057 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1058 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1059 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1060 CHECK(success); 1061 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 1062 InitOMXParams(&mpeg4type); 1063 mpeg4type.nPortIndex = kPortIndexOutput; 1064 1065 status_t err = mOMX->getParameter( 1066 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1067 CHECK_EQ(err, (status_t)OK); 1068 1069 mpeg4type.nSliceHeaderSpacing = 0; 1070 mpeg4type.bSVH = OMX_FALSE; 1071 mpeg4type.bGov = OMX_FALSE; 1072 1073 mpeg4type.nAllowedPictureTypes = 1074 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1075 1076 mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1077 if (mpeg4type.nPFrames == 0) { 1078 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1079 } 1080 mpeg4type.nBFrames = 0; 1081 mpeg4type.nIDCVLCThreshold = 0; 1082 mpeg4type.bACPred = OMX_TRUE; 1083 mpeg4type.nMaxPacketSize = 256; 1084 mpeg4type.nTimeIncRes = 1000; 1085 mpeg4type.nHeaderExtension = 0; 1086 mpeg4type.bReversibleVLC = OMX_FALSE; 1087 1088 // Check profile and level parameters 1089 CodecProfileLevel defaultProfileLevel, profileLevel; 1090 defaultProfileLevel.mProfile = mpeg4type.eProfile; 1091 defaultProfileLevel.mLevel = mpeg4type.eLevel; 1092 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1093 if (err != OK) return err; 1094 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile); 1095 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel); 1096 1097 err = mOMX->setParameter( 1098 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1099 CHECK_EQ(err, (status_t)OK); 1100 1101 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1102 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1103 1104 return OK; 1105 } 1106 1107 status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) { 1108 int32_t iFramesInterval, frameRate, bitRate; 1109 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1110 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1111 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1112 CHECK(success); 1113 1114 OMX_VIDEO_PARAM_AVCTYPE h264type; 1115 InitOMXParams(&h264type); 1116 h264type.nPortIndex = kPortIndexOutput; 1117 1118 status_t err = mOMX->getParameter( 1119 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1120 CHECK_EQ(err, (status_t)OK); 1121 1122 h264type.nAllowedPictureTypes = 1123 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1124 1125 // Check profile and level parameters 1126 CodecProfileLevel defaultProfileLevel, profileLevel; 1127 defaultProfileLevel.mProfile = h264type.eProfile; 1128 defaultProfileLevel.mLevel = h264type.eLevel; 1129 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1130 if (err != OK) return err; 1131 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile); 1132 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel); 1133 1134 // XXX 1135 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 1136 ALOGW("Use baseline profile instead of %d for AVC recording", 1137 h264type.eProfile); 1138 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 1139 } 1140 1141 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 1142 h264type.nSliceHeaderSpacing = 0; 1143 h264type.bUseHadamard = OMX_TRUE; 1144 h264type.nRefFrames = 1; 1145 h264type.nBFrames = 0; 1146 h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1147 if (h264type.nPFrames == 0) { 1148 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1149 } 1150 h264type.nRefIdx10ActiveMinus1 = 0; 1151 h264type.nRefIdx11ActiveMinus1 = 0; 1152 h264type.bEntropyCodingCABAC = OMX_FALSE; 1153 h264type.bWeightedPPrediction = OMX_FALSE; 1154 h264type.bconstIpred = OMX_FALSE; 1155 h264type.bDirect8x8Inference = OMX_FALSE; 1156 h264type.bDirectSpatialTemporal = OMX_FALSE; 1157 h264type.nCabacInitIdc = 0; 1158 } 1159 1160 if (h264type.nBFrames != 0) { 1161 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 1162 } 1163 1164 h264type.bEnableUEP = OMX_FALSE; 1165 h264type.bEnableFMO = OMX_FALSE; 1166 h264type.bEnableASO = OMX_FALSE; 1167 h264type.bEnableRS = OMX_FALSE; 1168 h264type.bFrameMBsOnly = OMX_TRUE; 1169 h264type.bMBAFF = OMX_FALSE; 1170 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 1171 1172 err = mOMX->setParameter( 1173 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1174 CHECK_EQ(err, (status_t)OK); 1175 1176 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1177 1178 return OK; 1179 } 1180 1181 status_t OMXCodec::setVideoOutputFormat( 1182 const char *mime, const sp<MetaData>& meta) { 1183 1184 int32_t width, height; 1185 bool success = meta->findInt32(kKeyWidth, &width); 1186 success = success && meta->findInt32(kKeyHeight, &height); 1187 CHECK(success); 1188 1189 CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); 1190 1191 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 1192 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1193 compressionFormat = OMX_VIDEO_CodingAVC; 1194 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1195 compressionFormat = OMX_VIDEO_CodingMPEG4; 1196 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1197 compressionFormat = OMX_VIDEO_CodingH263; 1198 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) { 1199 compressionFormat = OMX_VIDEO_CodingVPX; 1200 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) { 1201 compressionFormat = OMX_VIDEO_CodingMPEG2; 1202 } else { 1203 ALOGE("Not a supported video mime type: %s", mime); 1204 CHECK(!"Should not be here. Not a supported video mime type."); 1205 } 1206 1207 status_t err = setVideoPortFormatType( 1208 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 1209 1210 if (err != OK) { 1211 return err; 1212 } 1213 1214 #if 1 1215 { 1216 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1217 InitOMXParams(&format); 1218 format.nPortIndex = kPortIndexOutput; 1219 format.nIndex = 0; 1220 1221 status_t err = mOMX->getParameter( 1222 mNode, OMX_IndexParamVideoPortFormat, 1223 &format, sizeof(format)); 1224 CHECK_EQ(err, (status_t)OK); 1225 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 1226 1227 int32_t colorFormat; 1228 if (meta->findInt32(kKeyColorFormat, &colorFormat) 1229 && colorFormat != OMX_COLOR_FormatUnused 1230 && colorFormat != format.eColorFormat) { 1231 1232 while (OMX_ErrorNoMore != err) { 1233 format.nIndex++; 1234 err = mOMX->getParameter( 1235 mNode, OMX_IndexParamVideoPortFormat, 1236 &format, sizeof(format)); 1237 if (format.eColorFormat == colorFormat) { 1238 break; 1239 } 1240 } 1241 if (format.eColorFormat != colorFormat) { 1242 CODEC_LOGE("Color format %d is not supported", colorFormat); 1243 return ERROR_UNSUPPORTED; 1244 } 1245 } 1246 1247 err = mOMX->setParameter( 1248 mNode, OMX_IndexParamVideoPortFormat, 1249 &format, sizeof(format)); 1250 1251 if (err != OK) { 1252 return err; 1253 } 1254 } 1255 #endif 1256 1257 OMX_PARAM_PORTDEFINITIONTYPE def; 1258 InitOMXParams(&def); 1259 def.nPortIndex = kPortIndexInput; 1260 1261 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1262 1263 err = mOMX->getParameter( 1264 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1265 1266 CHECK_EQ(err, (status_t)OK); 1267 1268 #if 1 1269 // XXX Need a (much) better heuristic to compute input buffer sizes. 1270 const size_t X = 64 * 1024; 1271 if (def.nBufferSize < X) { 1272 def.nBufferSize = X; 1273 } 1274 #endif 1275 1276 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1277 1278 video_def->nFrameWidth = width; 1279 video_def->nFrameHeight = height; 1280 1281 video_def->eCompressionFormat = compressionFormat; 1282 video_def->eColorFormat = OMX_COLOR_FormatUnused; 1283 1284 err = mOMX->setParameter( 1285 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1286 1287 if (err != OK) { 1288 return err; 1289 } 1290 1291 //////////////////////////////////////////////////////////////////////////// 1292 1293 InitOMXParams(&def); 1294 def.nPortIndex = kPortIndexOutput; 1295 1296 err = mOMX->getParameter( 1297 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1298 CHECK_EQ(err, (status_t)OK); 1299 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1300 1301 #if 0 1302 def.nBufferSize = 1303 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 1304 #endif 1305 1306 video_def->nFrameWidth = width; 1307 video_def->nFrameHeight = height; 1308 1309 err = mOMX->setParameter( 1310 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1311 1312 return err; 1313 } 1314 1315 OMXCodec::OMXCodec( 1316 const sp<IOMX> &omx, IOMX::node_id node, 1317 uint32_t quirks, uint32_t flags, 1318 bool isEncoder, 1319 const char *mime, 1320 const char *componentName, 1321 const sp<MediaSource> &source, 1322 const sp<ANativeWindow> &nativeWindow) 1323 : mOMX(omx), 1324 mOMXLivesLocally(omx->livesLocally(node, getpid())), 1325 mNode(node), 1326 mQuirks(quirks), 1327 mFlags(flags), 1328 mIsEncoder(isEncoder), 1329 mIsVideo(!strncasecmp("video/", mime, 6)), 1330 mMIME(strdup(mime)), 1331 mComponentName(strdup(componentName)), 1332 mSource(source), 1333 mCodecSpecificDataIndex(0), 1334 mState(LOADED), 1335 mInitialBufferSubmit(true), 1336 mSignalledEOS(false), 1337 mNoMoreOutputData(false), 1338 mOutputPortSettingsHaveChanged(false), 1339 mSeekTimeUs(-1), 1340 mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC), 1341 mTargetTimeUs(-1), 1342 mOutputPortSettingsChangedPending(false), 1343 mSkipCutBuffer(NULL), 1344 mLeftOverBuffer(NULL), 1345 mPaused(false), 1346 mNativeWindow( 1347 (!strncmp(componentName, "OMX.google.", 11) 1348 || !strcmp(componentName, "OMX.Nvidia.mpeg2v.decode")) 1349 ? NULL : nativeWindow) { 1350 mPortStatus[kPortIndexInput] = ENABLED; 1351 mPortStatus[kPortIndexOutput] = ENABLED; 1352 1353 setComponentRole(); 1354 } 1355 1356 // static 1357 void OMXCodec::setComponentRole( 1358 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, 1359 const char *mime) { 1360 struct MimeToRole { 1361 const char *mime; 1362 const char *decoderRole; 1363 const char *encoderRole; 1364 }; 1365 1366 static const MimeToRole kMimeToRole[] = { 1367 { MEDIA_MIMETYPE_AUDIO_MPEG, 1368 "audio_decoder.mp3", "audio_encoder.mp3" }, 1369 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 1370 "audio_decoder.mp1", "audio_encoder.mp1" }, 1371 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 1372 "audio_decoder.mp2", "audio_encoder.mp2" }, 1373 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1374 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1375 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1376 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1377 { MEDIA_MIMETYPE_AUDIO_AAC, 1378 "audio_decoder.aac", "audio_encoder.aac" }, 1379 { MEDIA_MIMETYPE_AUDIO_VORBIS, 1380 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 1381 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 1382 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 1383 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 1384 "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 1385 { MEDIA_MIMETYPE_VIDEO_AVC, 1386 "video_decoder.avc", "video_encoder.avc" }, 1387 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1388 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1389 { MEDIA_MIMETYPE_VIDEO_H263, 1390 "video_decoder.h263", "video_encoder.h263" }, 1391 { MEDIA_MIMETYPE_VIDEO_VPX, 1392 "video_decoder.vpx", "video_encoder.vpx" }, 1393 { MEDIA_MIMETYPE_AUDIO_RAW, 1394 "audio_decoder.raw", "audio_encoder.raw" }, 1395 { MEDIA_MIMETYPE_AUDIO_FLAC, 1396 "audio_decoder.flac", "audio_encoder.flac" }, 1397 { MEDIA_MIMETYPE_AUDIO_MSGSM, 1398 "audio_decoder.gsm", "audio_encoder.gsm" }, 1399 }; 1400 1401 static const size_t kNumMimeToRole = 1402 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1403 1404 size_t i; 1405 for (i = 0; i < kNumMimeToRole; ++i) { 1406 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1407 break; 1408 } 1409 } 1410 1411 if (i == kNumMimeToRole) { 1412 return; 1413 } 1414 1415 const char *role = 1416 isEncoder ? kMimeToRole[i].encoderRole 1417 : kMimeToRole[i].decoderRole; 1418 1419 if (role != NULL) { 1420 OMX_PARAM_COMPONENTROLETYPE roleParams; 1421 InitOMXParams(&roleParams); 1422 1423 strncpy((char *)roleParams.cRole, 1424 role, OMX_MAX_STRINGNAME_SIZE - 1); 1425 1426 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1427 1428 status_t err = omx->setParameter( 1429 node, OMX_IndexParamStandardComponentRole, 1430 &roleParams, sizeof(roleParams)); 1431 1432 if (err != OK) { 1433 ALOGW("Failed to set standard component role '%s'.", role); 1434 } 1435 } 1436 } 1437 1438 void OMXCodec::setComponentRole() { 1439 setComponentRole(mOMX, mNode, mIsEncoder, mMIME); 1440 } 1441 1442 OMXCodec::~OMXCodec() { 1443 mSource.clear(); 1444 1445 CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE); 1446 1447 status_t err = mOMX->freeNode(mNode); 1448 CHECK_EQ(err, (status_t)OK); 1449 1450 mNode = NULL; 1451 setState(DEAD); 1452 1453 clearCodecSpecificData(); 1454 1455 free(mComponentName); 1456 mComponentName = NULL; 1457 1458 free(mMIME); 1459 mMIME = NULL; 1460 } 1461 1462 status_t OMXCodec::init() { 1463 // mLock is held. 1464 1465 CHECK_EQ((int)mState, (int)LOADED); 1466 1467 status_t err; 1468 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 1469 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1470 CHECK_EQ(err, (status_t)OK); 1471 setState(LOADED_TO_IDLE); 1472 } 1473 1474 err = allocateBuffers(); 1475 if (err != (status_t)OK) { 1476 return err; 1477 } 1478 1479 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 1480 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1481 CHECK_EQ(err, (status_t)OK); 1482 1483 setState(LOADED_TO_IDLE); 1484 } 1485 1486 while (mState != EXECUTING && mState != ERROR) { 1487 mAsyncCompletion.wait(mLock); 1488 } 1489 1490 return mState == ERROR ? UNKNOWN_ERROR : OK; 1491 } 1492 1493 // static 1494 bool OMXCodec::isIntermediateState(State state) { 1495 return state == LOADED_TO_IDLE 1496 || state == IDLE_TO_EXECUTING 1497 || state == EXECUTING_TO_IDLE 1498 || state == IDLE_TO_LOADED 1499 || state == RECONFIGURING; 1500 } 1501 1502 status_t OMXCodec::allocateBuffers() { 1503 status_t err = allocateBuffersOnPort(kPortIndexInput); 1504 1505 if (err != OK) { 1506 return err; 1507 } 1508 1509 return allocateBuffersOnPort(kPortIndexOutput); 1510 } 1511 1512 status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 1513 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 1514 return allocateOutputBuffersFromNativeWindow(); 1515 } 1516 1517 if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) { 1518 ALOGE("protected output buffers must be stent to an ANativeWindow"); 1519 return PERMISSION_DENIED; 1520 } 1521 1522 status_t err = OK; 1523 if ((mFlags & kStoreMetaDataInVideoBuffers) 1524 && portIndex == kPortIndexInput) { 1525 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 1526 if (err != OK) { 1527 ALOGE("Storing meta data in video buffers is not supported"); 1528 return err; 1529 } 1530 } 1531 1532 OMX_PARAM_PORTDEFINITIONTYPE def; 1533 InitOMXParams(&def); 1534 def.nPortIndex = portIndex; 1535 1536 err = mOMX->getParameter( 1537 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1538 1539 if (err != OK) { 1540 return err; 1541 } 1542 1543 CODEC_LOGV("allocating %lu buffers of size %lu on %s port", 1544 def.nBufferCountActual, def.nBufferSize, 1545 portIndex == kPortIndexInput ? "input" : "output"); 1546 1547 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 1548 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 1549 1550 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 1551 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 1552 CHECK(mem.get() != NULL); 1553 1554 BufferInfo info; 1555 info.mData = NULL; 1556 info.mSize = def.nBufferSize; 1557 1558 IOMX::buffer_id buffer; 1559 if (portIndex == kPortIndexInput 1560 && ((mQuirks & kRequiresAllocateBufferOnInputPorts) 1561 || (mFlags & kUseSecureInputBuffers))) { 1562 if (mOMXLivesLocally) { 1563 mem.clear(); 1564 1565 err = mOMX->allocateBuffer( 1566 mNode, portIndex, def.nBufferSize, &buffer, 1567 &info.mData); 1568 } else { 1569 err = mOMX->allocateBufferWithBackup( 1570 mNode, portIndex, mem, &buffer); 1571 } 1572 } else if (portIndex == kPortIndexOutput 1573 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 1574 if (mOMXLivesLocally) { 1575 mem.clear(); 1576 1577 err = mOMX->allocateBuffer( 1578 mNode, portIndex, def.nBufferSize, &buffer, 1579 &info.mData); 1580 } else { 1581 err = mOMX->allocateBufferWithBackup( 1582 mNode, portIndex, mem, &buffer); 1583 } 1584 } else { 1585 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 1586 } 1587 1588 if (err != OK) { 1589 ALOGE("allocate_buffer_with_backup failed"); 1590 return err; 1591 } 1592 1593 if (mem != NULL) { 1594 info.mData = mem->pointer(); 1595 } 1596 1597 info.mBuffer = buffer; 1598 info.mStatus = OWNED_BY_US; 1599 info.mMem = mem; 1600 info.mMediaBuffer = NULL; 1601 1602 if (portIndex == kPortIndexOutput) { 1603 if (!(mOMXLivesLocally 1604 && (mQuirks & kRequiresAllocateBufferOnOutputPorts) 1605 && (mQuirks & kDefersOutputBufferAllocation))) { 1606 // If the node does not fill in the buffer ptr at this time, 1607 // we will defer creating the MediaBuffer until receiving 1608 // the first FILL_BUFFER_DONE notification instead. 1609 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); 1610 info.mMediaBuffer->setObserver(this); 1611 } 1612 } 1613 1614 mPortBuffers[portIndex].push(info); 1615 1616 CODEC_LOGV("allocated buffer %p on %s port", buffer, 1617 portIndex == kPortIndexInput ? "input" : "output"); 1618 } 1619 1620 if (portIndex == kPortIndexOutput) { 1621 1622 sp<MetaData> meta = mSource->getFormat(); 1623 int32_t delay = 0; 1624 if (!meta->findInt32(kKeyEncoderDelay, &delay)) { 1625 delay = 0; 1626 } 1627 int32_t padding = 0; 1628 if (!meta->findInt32(kKeyEncoderPadding, &padding)) { 1629 padding = 0; 1630 } 1631 int32_t numchannels = 0; 1632 if (delay + padding) { 1633 if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) { 1634 size_t frameSize = numchannels * sizeof(int16_t); 1635 if (mSkipCutBuffer != NULL) { 1636 size_t prevbuffersize = mSkipCutBuffer->size(); 1637 if (prevbuffersize != 0) { 1638 ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize); 1639 } 1640 } 1641 mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize); 1642 } 1643 } 1644 } 1645 1646 // dumpPortStatus(portIndex); 1647 1648 if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) { 1649 Vector<MediaBuffer *> buffers; 1650 for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1651 const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i); 1652 1653 MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize); 1654 buffers.push(mbuf); 1655 } 1656 1657 status_t err = mSource->setBuffers(buffers); 1658 1659 if (err != OK) { 1660 for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1661 buffers.editItemAt(i)->release(); 1662 } 1663 buffers.clear(); 1664 1665 CODEC_LOGE( 1666 "Codec requested to use secure input buffers but " 1667 "upstream source didn't support that."); 1668 1669 return err; 1670 } 1671 } 1672 1673 return OK; 1674 } 1675 1676 status_t OMXCodec::applyRotation() { 1677 sp<MetaData> meta = mSource->getFormat(); 1678 1679 int32_t rotationDegrees; 1680 if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { 1681 rotationDegrees = 0; 1682 } 1683 1684 uint32_t transform; 1685 switch (rotationDegrees) { 1686 case 0: transform = 0; break; 1687 case 90: transform = HAL_TRANSFORM_ROT_90; break; 1688 case 180: transform = HAL_TRANSFORM_ROT_180; break; 1689 case 270: transform = HAL_TRANSFORM_ROT_270; break; 1690 default: transform = 0; break; 1691 } 1692 1693 status_t err = OK; 1694 1695 if (transform) { 1696 err = native_window_set_buffers_transform( 1697 mNativeWindow.get(), transform); 1698 ALOGE("native_window_set_buffers_transform failed: %s (%d)", 1699 strerror(-err), -err); 1700 } 1701 1702 return err; 1703 } 1704 1705 status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { 1706 // Get the number of buffers needed. 1707 OMX_PARAM_PORTDEFINITIONTYPE def; 1708 InitOMXParams(&def); 1709 def.nPortIndex = kPortIndexOutput; 1710 1711 status_t err = mOMX->getParameter( 1712 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1713 if (err != OK) { 1714 CODEC_LOGE("getParameter failed: %d", err); 1715 return err; 1716 } 1717 1718 err = native_window_set_buffers_geometry( 1719 mNativeWindow.get(), 1720 def.format.video.nFrameWidth, 1721 def.format.video.nFrameHeight, 1722 def.format.video.eColorFormat); 1723 1724 if (err != 0) { 1725 ALOGE("native_window_set_buffers_geometry failed: %s (%d)", 1726 strerror(-err), -err); 1727 return err; 1728 } 1729 1730 err = applyRotation(); 1731 if (err != OK) { 1732 return err; 1733 } 1734 1735 // Set up the native window. 1736 OMX_U32 usage = 0; 1737 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 1738 if (err != 0) { 1739 ALOGW("querying usage flags from OMX IL component failed: %d", err); 1740 // XXX: Currently this error is logged, but not fatal. 1741 usage = 0; 1742 } 1743 if (mFlags & kEnableGrallocUsageProtected) { 1744 usage |= GRALLOC_USAGE_PROTECTED; 1745 } 1746 1747 // Make sure to check whether either Stagefright or the video decoder 1748 // requested protected buffers. 1749 if (usage & GRALLOC_USAGE_PROTECTED) { 1750 // Verify that the ANativeWindow sends images directly to 1751 // SurfaceFlinger. 1752 int queuesToNativeWindow = 0; 1753 err = mNativeWindow->query( 1754 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 1755 &queuesToNativeWindow); 1756 if (err != 0) { 1757 ALOGE("error authenticating native window: %d", err); 1758 return err; 1759 } 1760 if (queuesToNativeWindow != 1) { 1761 ALOGE("native window could not be authenticated"); 1762 return PERMISSION_DENIED; 1763 } 1764 } 1765 1766 ALOGV("native_window_set_usage usage=0x%lx", usage); 1767 err = native_window_set_usage( 1768 mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 1769 if (err != 0) { 1770 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 1771 return err; 1772 } 1773 1774 int minUndequeuedBufs = 0; 1775 err = mNativeWindow->query(mNativeWindow.get(), 1776 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 1777 if (err != 0) { 1778 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 1779 strerror(-err), -err); 1780 return err; 1781 } 1782 1783 // XXX: Is this the right logic to use? It's not clear to me what the OMX 1784 // buffer counts refer to - how do they account for the renderer holding on 1785 // to buffers? 1786 if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { 1787 OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; 1788 def.nBufferCountActual = newBufferCount; 1789 err = mOMX->setParameter( 1790 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1791 if (err != OK) { 1792 CODEC_LOGE("setting nBufferCountActual to %lu failed: %d", 1793 newBufferCount, err); 1794 return err; 1795 } 1796 } 1797 1798 err = native_window_set_buffer_count( 1799 mNativeWindow.get(), def.nBufferCountActual); 1800 if (err != 0) { 1801 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1802 -err); 1803 return err; 1804 } 1805 1806 CODEC_LOGV("allocating %lu buffers from a native window of size %lu on " 1807 "output port", def.nBufferCountActual, def.nBufferSize); 1808 1809 // Dequeue buffers and send them to OMX 1810 for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { 1811 ANativeWindowBuffer* buf; 1812 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 1813 if (err != 0) { 1814 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1815 break; 1816 } 1817 1818 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1819 BufferInfo info; 1820 info.mData = NULL; 1821 info.mSize = def.nBufferSize; 1822 info.mStatus = OWNED_BY_US; 1823 info.mMem = NULL; 1824 info.mMediaBuffer = new MediaBuffer(graphicBuffer); 1825 info.mMediaBuffer->setObserver(this); 1826 mPortBuffers[kPortIndexOutput].push(info); 1827 1828 IOMX::buffer_id bufferId; 1829 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 1830 &bufferId); 1831 if (err != 0) { 1832 CODEC_LOGE("registering GraphicBuffer with OMX IL component " 1833 "failed: %d", err); 1834 break; 1835 } 1836 1837 mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId; 1838 1839 CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)", 1840 bufferId, graphicBuffer.get()); 1841 } 1842 1843 OMX_U32 cancelStart; 1844 OMX_U32 cancelEnd; 1845 if (err != 0) { 1846 // If an error occurred while dequeuing we need to cancel any buffers 1847 // that were dequeued. 1848 cancelStart = 0; 1849 cancelEnd = mPortBuffers[kPortIndexOutput].size(); 1850 } else { 1851 // Return the last two buffers to the native window. 1852 cancelStart = def.nBufferCountActual - minUndequeuedBufs; 1853 cancelEnd = def.nBufferCountActual; 1854 } 1855 1856 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1857 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i); 1858 cancelBufferToNativeWindow(info); 1859 } 1860 1861 return err; 1862 } 1863 1864 status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) { 1865 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 1866 CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer); 1867 int err = mNativeWindow->cancelBuffer( 1868 mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1); 1869 if (err != 0) { 1870 CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err); 1871 1872 setState(ERROR); 1873 return err; 1874 } 1875 info->mStatus = OWNED_BY_NATIVE_WINDOW; 1876 return OK; 1877 } 1878 1879 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() { 1880 // Dequeue the next buffer from the native window. 1881 ANativeWindowBuffer* buf; 1882 int fenceFd = -1; 1883 int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 1884 if (err != 0) { 1885 CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err); 1886 1887 setState(ERROR); 1888 return 0; 1889 } 1890 1891 // Determine which buffer we just dequeued. 1892 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1893 BufferInfo *bufInfo = 0; 1894 for (size_t i = 0; i < buffers->size(); i++) { 1895 sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i). 1896 mMediaBuffer->graphicBuffer(); 1897 if (graphicBuffer->handle == buf->handle) { 1898 bufInfo = &buffers->editItemAt(i); 1899 break; 1900 } 1901 } 1902 1903 if (bufInfo == 0) { 1904 CODEC_LOGE("dequeued unrecognized buffer: %p", buf); 1905 1906 setState(ERROR); 1907 return 0; 1908 } 1909 1910 // The native window no longer owns the buffer. 1911 CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW); 1912 bufInfo->mStatus = OWNED_BY_US; 1913 1914 return bufInfo; 1915 } 1916 1917 status_t OMXCodec::pushBlankBuffersToNativeWindow() { 1918 status_t err = NO_ERROR; 1919 ANativeWindowBuffer* anb = NULL; 1920 int numBufs = 0; 1921 int minUndequeuedBufs = 0; 1922 1923 // We need to reconnect to the ANativeWindow as a CPU client to ensure that 1924 // no frames get dropped by SurfaceFlinger assuming that these are video 1925 // frames. 1926 err = native_window_api_disconnect(mNativeWindow.get(), 1927 NATIVE_WINDOW_API_MEDIA); 1928 if (err != NO_ERROR) { 1929 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 1930 strerror(-err), -err); 1931 return err; 1932 } 1933 1934 err = native_window_api_connect(mNativeWindow.get(), 1935 NATIVE_WINDOW_API_CPU); 1936 if (err != NO_ERROR) { 1937 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 1938 strerror(-err), -err); 1939 return err; 1940 } 1941 1942 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1, 1943 HAL_PIXEL_FORMAT_RGBX_8888); 1944 if (err != NO_ERROR) { 1945 ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)", 1946 strerror(-err), -err); 1947 goto error; 1948 } 1949 1950 err = native_window_set_usage(mNativeWindow.get(), 1951 GRALLOC_USAGE_SW_WRITE_OFTEN); 1952 if (err != NO_ERROR) { 1953 ALOGE("error pushing blank frames: set_usage failed: %s (%d)", 1954 strerror(-err), -err); 1955 goto error; 1956 } 1957 1958 err = native_window_set_scaling_mode(mNativeWindow.get(), 1959 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 1960 if (err != OK) { 1961 ALOGE("error pushing blank frames: set_scaling_mode failed: %s (%d)", 1962 strerror(-err), -err); 1963 goto error; 1964 } 1965 1966 err = mNativeWindow->query(mNativeWindow.get(), 1967 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 1968 if (err != NO_ERROR) { 1969 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 1970 "failed: %s (%d)", strerror(-err), -err); 1971 goto error; 1972 } 1973 1974 numBufs = minUndequeuedBufs + 1; 1975 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs); 1976 if (err != NO_ERROR) { 1977 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", 1978 strerror(-err), -err); 1979 goto error; 1980 } 1981 1982 // We push numBufs + 1 buffers to ensure that we've drawn into the same 1983 // buffer twice. This should guarantee that the buffer has been displayed 1984 // on the screen and then been replaced, so an previous video frames are 1985 // guaranteed NOT to be currently displayed. 1986 for (int i = 0; i < numBufs + 1; i++) { 1987 int fenceFd = -1; 1988 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb); 1989 if (err != NO_ERROR) { 1990 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 1991 strerror(-err), -err); 1992 goto error; 1993 } 1994 1995 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 1996 1997 // Fill the buffer with the a 1x1 checkerboard pattern ;) 1998 uint32_t* img = NULL; 1999 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 2000 if (err != NO_ERROR) { 2001 ALOGE("error pushing blank frames: lock failed: %s (%d)", 2002 strerror(-err), -err); 2003 goto error; 2004 } 2005 2006 *img = 0; 2007 2008 err = buf->unlock(); 2009 if (err != NO_ERROR) { 2010 ALOGE("error pushing blank frames: unlock failed: %s (%d)", 2011 strerror(-err), -err); 2012 goto error; 2013 } 2014 2015 err = mNativeWindow->queueBuffer(mNativeWindow.get(), 2016 buf->getNativeBuffer(), -1); 2017 if (err != NO_ERROR) { 2018 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", 2019 strerror(-err), -err); 2020 goto error; 2021 } 2022 2023 anb = NULL; 2024 } 2025 2026 error: 2027 2028 if (err != NO_ERROR) { 2029 // Clean up after an error. 2030 if (anb != NULL) { 2031 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1); 2032 } 2033 2034 native_window_api_disconnect(mNativeWindow.get(), 2035 NATIVE_WINDOW_API_CPU); 2036 native_window_api_connect(mNativeWindow.get(), 2037 NATIVE_WINDOW_API_MEDIA); 2038 2039 return err; 2040 } else { 2041 // Clean up after success. 2042 err = native_window_api_disconnect(mNativeWindow.get(), 2043 NATIVE_WINDOW_API_CPU); 2044 if (err != NO_ERROR) { 2045 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2046 strerror(-err), -err); 2047 return err; 2048 } 2049 2050 err = native_window_api_connect(mNativeWindow.get(), 2051 NATIVE_WINDOW_API_MEDIA); 2052 if (err != NO_ERROR) { 2053 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 2054 strerror(-err), -err); 2055 return err; 2056 } 2057 2058 return NO_ERROR; 2059 } 2060 } 2061 2062 int64_t OMXCodec::getDecodingTimeUs() { 2063 CHECK(mIsEncoder && mIsVideo); 2064 2065 if (mDecodingTimeList.empty()) { 2066 CHECK(mSignalledEOS || mNoMoreOutputData); 2067 // No corresponding input frame available. 2068 // This could happen when EOS is reached. 2069 return 0; 2070 } 2071 2072 List<int64_t>::iterator it = mDecodingTimeList.begin(); 2073 int64_t timeUs = *it; 2074 mDecodingTimeList.erase(it); 2075 return timeUs; 2076 } 2077 2078 void OMXCodec::on_message(const omx_message &msg) { 2079 if (mState == ERROR) { 2080 /* 2081 * only drop EVENT messages, EBD and FBD are still 2082 * processed for bookkeeping purposes 2083 */ 2084 if (msg.type == omx_message::EVENT) { 2085 ALOGW("Dropping OMX EVENT message - we're in ERROR state."); 2086 return; 2087 } 2088 } 2089 2090 switch (msg.type) { 2091 case omx_message::EVENT: 2092 { 2093 onEvent( 2094 msg.u.event_data.event, msg.u.event_data.data1, 2095 msg.u.event_data.data2); 2096 2097 break; 2098 } 2099 2100 case omx_message::EMPTY_BUFFER_DONE: 2101 { 2102 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2103 2104 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 2105 2106 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2107 size_t i = 0; 2108 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2109 ++i; 2110 } 2111 2112 CHECK(i < buffers->size()); 2113 if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) { 2114 ALOGW("We already own input buffer %p, yet received " 2115 "an EMPTY_BUFFER_DONE.", buffer); 2116 } 2117 2118 BufferInfo* info = &buffers->editItemAt(i); 2119 info->mStatus = OWNED_BY_US; 2120 2121 // Buffer could not be released until empty buffer done is called. 2122 if (info->mMediaBuffer != NULL) { 2123 info->mMediaBuffer->release(); 2124 info->mMediaBuffer = NULL; 2125 } 2126 2127 if (mPortStatus[kPortIndexInput] == DISABLING) { 2128 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2129 2130 status_t err = freeBuffer(kPortIndexInput, i); 2131 CHECK_EQ(err, (status_t)OK); 2132 } else if (mState != ERROR 2133 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 2134 CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED); 2135 2136 if (mFlags & kUseSecureInputBuffers) { 2137 drainAnyInputBuffer(); 2138 } else { 2139 drainInputBuffer(&buffers->editItemAt(i)); 2140 } 2141 } 2142 break; 2143 } 2144 2145 case omx_message::FILL_BUFFER_DONE: 2146 { 2147 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2148 OMX_U32 flags = msg.u.extended_buffer_data.flags; 2149 2150 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 2151 buffer, 2152 msg.u.extended_buffer_data.range_length, 2153 flags, 2154 msg.u.extended_buffer_data.timestamp, 2155 msg.u.extended_buffer_data.timestamp / 1E6); 2156 2157 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2158 size_t i = 0; 2159 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2160 ++i; 2161 } 2162 2163 CHECK(i < buffers->size()); 2164 BufferInfo *info = &buffers->editItemAt(i); 2165 2166 if (info->mStatus != OWNED_BY_COMPONENT) { 2167 ALOGW("We already own output buffer %p, yet received " 2168 "a FILL_BUFFER_DONE.", buffer); 2169 } 2170 2171 info->mStatus = OWNED_BY_US; 2172 2173 if (mPortStatus[kPortIndexOutput] == DISABLING) { 2174 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2175 2176 status_t err = freeBuffer(kPortIndexOutput, i); 2177 CHECK_EQ(err, (status_t)OK); 2178 2179 #if 0 2180 } else if (mPortStatus[kPortIndexOutput] == ENABLED 2181 && (flags & OMX_BUFFERFLAG_EOS)) { 2182 CODEC_LOGV("No more output data."); 2183 mNoMoreOutputData = true; 2184 mBufferFilled.signal(); 2185 #endif 2186 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 2187 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 2188 2189 if (info->mMediaBuffer == NULL) { 2190 CHECK(mOMXLivesLocally); 2191 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 2192 CHECK(mQuirks & kDefersOutputBufferAllocation); 2193 2194 // The qcom video decoders on Nexus don't actually allocate 2195 // output buffer memory on a call to OMX_AllocateBuffer 2196 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 2197 // structure is only filled in later. 2198 2199 info->mMediaBuffer = new MediaBuffer( 2200 msg.u.extended_buffer_data.data_ptr, 2201 info->mSize); 2202 info->mMediaBuffer->setObserver(this); 2203 } 2204 2205 MediaBuffer *buffer = info->mMediaBuffer; 2206 bool isGraphicBuffer = buffer->graphicBuffer() != NULL; 2207 2208 if (!isGraphicBuffer 2209 && msg.u.extended_buffer_data.range_offset 2210 + msg.u.extended_buffer_data.range_length 2211 > buffer->size()) { 2212 CODEC_LOGE( 2213 "Codec lied about its buffer size requirements, " 2214 "sending a buffer larger than the originally " 2215 "advertised size in FILL_BUFFER_DONE!"); 2216 } 2217 buffer->set_range( 2218 msg.u.extended_buffer_data.range_offset, 2219 msg.u.extended_buffer_data.range_length); 2220 2221 buffer->meta_data()->clear(); 2222 2223 buffer->meta_data()->setInt64( 2224 kKeyTime, msg.u.extended_buffer_data.timestamp); 2225 2226 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 2227 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 2228 } 2229 bool isCodecSpecific = false; 2230 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 2231 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 2232 isCodecSpecific = true; 2233 } 2234 2235 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) { 2236 buffer->meta_data()->setInt32(kKeyIsUnreadable, true); 2237 } 2238 2239 buffer->meta_data()->setPointer( 2240 kKeyPlatformPrivate, 2241 msg.u.extended_buffer_data.platform_private); 2242 2243 buffer->meta_data()->setPointer( 2244 kKeyBufferID, 2245 msg.u.extended_buffer_data.buffer); 2246 2247 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 2248 CODEC_LOGV("No more output data."); 2249 mNoMoreOutputData = true; 2250 } 2251 2252 if (mIsEncoder && mIsVideo) { 2253 int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs(); 2254 buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 2255 } 2256 2257 if (mTargetTimeUs >= 0) { 2258 CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs); 2259 2260 if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) { 2261 CODEC_LOGV( 2262 "skipping output buffer at timestamp %lld us", 2263 msg.u.extended_buffer_data.timestamp); 2264 2265 fillOutputBuffer(info); 2266 break; 2267 } 2268 2269 CODEC_LOGV( 2270 "returning output buffer at target timestamp " 2271 "%lld us", 2272 msg.u.extended_buffer_data.timestamp); 2273 2274 mTargetTimeUs = -1; 2275 } 2276 2277 mFilledBuffers.push_back(i); 2278 mBufferFilled.signal(); 2279 if (mIsEncoder) { 2280 sched_yield(); 2281 } 2282 } 2283 2284 break; 2285 } 2286 2287 default: 2288 { 2289 CHECK(!"should not be here."); 2290 break; 2291 } 2292 } 2293 } 2294 2295 // Has the format changed in any way that the client would have to be aware of? 2296 static bool formatHasNotablyChanged( 2297 const sp<MetaData> &from, const sp<MetaData> &to) { 2298 if (from.get() == NULL && to.get() == NULL) { 2299 return false; 2300 } 2301 2302 if ((from.get() == NULL && to.get() != NULL) 2303 || (from.get() != NULL && to.get() == NULL)) { 2304 return true; 2305 } 2306 2307 const char *mime_from, *mime_to; 2308 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 2309 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 2310 2311 if (strcasecmp(mime_from, mime_to)) { 2312 return true; 2313 } 2314 2315 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 2316 int32_t colorFormat_from, colorFormat_to; 2317 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 2318 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 2319 2320 if (colorFormat_from != colorFormat_to) { 2321 return true; 2322 } 2323 2324 int32_t width_from, width_to; 2325 CHECK(from->findInt32(kKeyWidth, &width_from)); 2326 CHECK(to->findInt32(kKeyWidth, &width_to)); 2327 2328 if (width_from != width_to) { 2329 return true; 2330 } 2331 2332 int32_t height_from, height_to; 2333 CHECK(from->findInt32(kKeyHeight, &height_from)); 2334 CHECK(to->findInt32(kKeyHeight, &height_to)); 2335 2336 if (height_from != height_to) { 2337 return true; 2338 } 2339 2340 int32_t left_from, top_from, right_from, bottom_from; 2341 CHECK(from->findRect( 2342 kKeyCropRect, 2343 &left_from, &top_from, &right_from, &bottom_from)); 2344 2345 int32_t left_to, top_to, right_to, bottom_to; 2346 CHECK(to->findRect( 2347 kKeyCropRect, 2348 &left_to, &top_to, &right_to, &bottom_to)); 2349 2350 if (left_to != left_from || top_to != top_from 2351 || right_to != right_from || bottom_to != bottom_from) { 2352 return true; 2353 } 2354 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 2355 int32_t numChannels_from, numChannels_to; 2356 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 2357 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 2358 2359 if (numChannels_from != numChannels_to) { 2360 return true; 2361 } 2362 2363 int32_t sampleRate_from, sampleRate_to; 2364 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 2365 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 2366 2367 if (sampleRate_from != sampleRate_to) { 2368 return true; 2369 } 2370 } 2371 2372 return false; 2373 } 2374 2375 void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2376 switch (event) { 2377 case OMX_EventCmdComplete: 2378 { 2379 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 2380 break; 2381 } 2382 2383 case OMX_EventError: 2384 { 2385 CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); 2386 2387 setState(ERROR); 2388 break; 2389 } 2390 2391 case OMX_EventPortSettingsChanged: 2392 { 2393 CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", 2394 data1, data2); 2395 2396 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 2397 // There is no need to check whether mFilledBuffers is empty or not 2398 // when the OMX_EventPortSettingsChanged is not meant for reallocating 2399 // the output buffers. 2400 if (data1 == kPortIndexOutput) { 2401 CHECK(mFilledBuffers.empty()); 2402 } 2403 onPortSettingsChanged(data1); 2404 } else if (data1 == kPortIndexOutput && 2405 (data2 == OMX_IndexConfigCommonOutputCrop || 2406 data2 == OMX_IndexConfigCommonScale)) { 2407 2408 sp<MetaData> oldOutputFormat = mOutputFormat; 2409 initOutputFormat(mSource->getFormat()); 2410 2411 if (data2 == OMX_IndexConfigCommonOutputCrop && 2412 formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) { 2413 mOutputPortSettingsHaveChanged = true; 2414 2415 } else if (data2 == OMX_IndexConfigCommonScale) { 2416 OMX_CONFIG_SCALEFACTORTYPE scale; 2417 InitOMXParams(&scale); 2418 scale.nPortIndex = kPortIndexOutput; 2419 2420 // Change display dimension only when necessary. 2421 if (OK == mOMX->getConfig( 2422 mNode, 2423 OMX_IndexConfigCommonScale, 2424 &scale, sizeof(scale))) { 2425 int32_t left, top, right, bottom; 2426 CHECK(mOutputFormat->findRect(kKeyCropRect, 2427 &left, &top, 2428 &right, &bottom)); 2429 2430 // The scale is in 16.16 format. 2431 // scale 1.0 = 0x010000. When there is no 2432 // need to change the display, skip it. 2433 ALOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx", 2434 scale.xWidth, scale.xHeight); 2435 2436 if (scale.xWidth != 0x010000) { 2437 mOutputFormat->setInt32(kKeyDisplayWidth, 2438 ((right - left + 1) * scale.xWidth) >> 16); 2439 mOutputPortSettingsHaveChanged = true; 2440 } 2441 2442 if (scale.xHeight != 0x010000) { 2443 mOutputFormat->setInt32(kKeyDisplayHeight, 2444 ((bottom - top + 1) * scale.xHeight) >> 16); 2445 mOutputPortSettingsHaveChanged = true; 2446 } 2447 } 2448 } 2449 } 2450 break; 2451 } 2452 2453 #if 0 2454 case OMX_EventBufferFlag: 2455 { 2456 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 2457 2458 if (data1 == kPortIndexOutput) { 2459 mNoMoreOutputData = true; 2460 } 2461 break; 2462 } 2463 #endif 2464 2465 default: 2466 { 2467 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 2468 break; 2469 } 2470 } 2471 } 2472 2473 void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 2474 switch (cmd) { 2475 case OMX_CommandStateSet: 2476 { 2477 onStateChange((OMX_STATETYPE)data); 2478 break; 2479 } 2480 2481 case OMX_CommandPortDisable: 2482 { 2483 OMX_U32 portIndex = data; 2484 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 2485 2486 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2487 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING); 2488 CHECK_EQ(mPortBuffers[portIndex].size(), 0u); 2489 2490 mPortStatus[portIndex] = DISABLED; 2491 2492 if (mState == RECONFIGURING) { 2493 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2494 2495 sp<MetaData> oldOutputFormat = mOutputFormat; 2496 initOutputFormat(mSource->getFormat()); 2497 2498 // Don't notify clients if the output port settings change 2499 // wasn't of importance to them, i.e. it may be that just the 2500 // number of buffers has changed and nothing else. 2501 bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 2502 if (!mOutputPortSettingsHaveChanged) { 2503 mOutputPortSettingsHaveChanged = formatChanged; 2504 } 2505 2506 status_t err = enablePortAsync(portIndex); 2507 if (err != OK) { 2508 CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err); 2509 setState(ERROR); 2510 } else { 2511 err = allocateBuffersOnPort(portIndex); 2512 if (err != OK) { 2513 CODEC_LOGE("allocateBuffersOnPort (%s) failed " 2514 "(err = %d)", 2515 portIndex == kPortIndexInput 2516 ? "input" : "output", 2517 err); 2518 2519 setState(ERROR); 2520 } 2521 } 2522 } 2523 break; 2524 } 2525 2526 case OMX_CommandPortEnable: 2527 { 2528 OMX_U32 portIndex = data; 2529 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 2530 2531 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2532 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING); 2533 2534 mPortStatus[portIndex] = ENABLED; 2535 2536 if (mState == RECONFIGURING) { 2537 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2538 2539 setState(EXECUTING); 2540 2541 fillOutputBuffers(); 2542 } 2543 break; 2544 } 2545 2546 case OMX_CommandFlush: 2547 { 2548 OMX_U32 portIndex = data; 2549 2550 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 2551 2552 CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN); 2553 mPortStatus[portIndex] = ENABLED; 2554 2555 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 2556 mPortBuffers[portIndex].size()); 2557 2558 if (mSkipCutBuffer != NULL && mPortStatus[kPortIndexOutput] == ENABLED) { 2559 mSkipCutBuffer->clear(); 2560 } 2561 2562 if (mState == RECONFIGURING) { 2563 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2564 2565 disablePortAsync(portIndex); 2566 } else if (mState == EXECUTING_TO_IDLE) { 2567 if (mPortStatus[kPortIndexInput] == ENABLED 2568 && mPortStatus[kPortIndexOutput] == ENABLED) { 2569 CODEC_LOGV("Finished flushing both ports, now completing " 2570 "transition from EXECUTING to IDLE."); 2571 2572 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2573 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2574 2575 status_t err = 2576 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2577 CHECK_EQ(err, (status_t)OK); 2578 } 2579 } else { 2580 // We're flushing both ports in preparation for seeking. 2581 2582 if (mPortStatus[kPortIndexInput] == ENABLED 2583 && mPortStatus[kPortIndexOutput] == ENABLED) { 2584 CODEC_LOGV("Finished flushing both ports, now continuing from" 2585 " seek-time."); 2586 2587 // We implicitly resume pulling on our upstream source. 2588 mPaused = false; 2589 2590 drainInputBuffers(); 2591 fillOutputBuffers(); 2592 } 2593 2594 if (mOutputPortSettingsChangedPending) { 2595 CODEC_LOGV( 2596 "Honoring deferred output port settings change."); 2597 2598 mOutputPortSettingsChangedPending = false; 2599 onPortSettingsChanged(kPortIndexOutput); 2600 } 2601 } 2602 2603 break; 2604 } 2605 2606 default: 2607 { 2608 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 2609 break; 2610 } 2611 } 2612 } 2613 2614 void OMXCodec::onStateChange(OMX_STATETYPE newState) { 2615 CODEC_LOGV("onStateChange %d", newState); 2616 2617 switch (newState) { 2618 case OMX_StateIdle: 2619 { 2620 CODEC_LOGV("Now Idle."); 2621 if (mState == LOADED_TO_IDLE) { 2622 status_t err = mOMX->sendCommand( 2623 mNode, OMX_CommandStateSet, OMX_StateExecuting); 2624 2625 CHECK_EQ(err, (status_t)OK); 2626 2627 setState(IDLE_TO_EXECUTING); 2628 } else { 2629 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE); 2630 2631 if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) != 2632 mPortBuffers[kPortIndexInput].size()) { 2633 ALOGE("Codec did not return all input buffers " 2634 "(received %d / %d)", 2635 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 2636 mPortBuffers[kPortIndexInput].size()); 2637 TRESPASS(); 2638 } 2639 2640 if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) != 2641 mPortBuffers[kPortIndexOutput].size()) { 2642 ALOGE("Codec did not return all output buffers " 2643 "(received %d / %d)", 2644 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 2645 mPortBuffers[kPortIndexOutput].size()); 2646 TRESPASS(); 2647 } 2648 2649 status_t err = mOMX->sendCommand( 2650 mNode, OMX_CommandStateSet, OMX_StateLoaded); 2651 2652 CHECK_EQ(err, (status_t)OK); 2653 2654 err = freeBuffersOnPort(kPortIndexInput); 2655 CHECK_EQ(err, (status_t)OK); 2656 2657 err = freeBuffersOnPort(kPortIndexOutput); 2658 CHECK_EQ(err, (status_t)OK); 2659 2660 mPortStatus[kPortIndexInput] = ENABLED; 2661 mPortStatus[kPortIndexOutput] = ENABLED; 2662 2663 if ((mFlags & kEnableGrallocUsageProtected) && 2664 mNativeWindow != NULL) { 2665 // We push enough 1x1 blank buffers to ensure that one of 2666 // them has made it to the display. This allows the OMX 2667 // component teardown to zero out any protected buffers 2668 // without the risk of scanning out one of those buffers. 2669 pushBlankBuffersToNativeWindow(); 2670 } 2671 2672 setState(IDLE_TO_LOADED); 2673 } 2674 break; 2675 } 2676 2677 case OMX_StateExecuting: 2678 { 2679 CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING); 2680 2681 CODEC_LOGV("Now Executing."); 2682 2683 mOutputPortSettingsChangedPending = false; 2684 2685 setState(EXECUTING); 2686 2687 // Buffers will be submitted to the component in the first 2688 // call to OMXCodec::read as mInitialBufferSubmit is true at 2689 // this point. This ensures that this on_message call returns, 2690 // releases the lock and ::init can notice the state change and 2691 // itself return. 2692 break; 2693 } 2694 2695 case OMX_StateLoaded: 2696 { 2697 CHECK_EQ((int)mState, (int)IDLE_TO_LOADED); 2698 2699 CODEC_LOGV("Now Loaded."); 2700 2701 setState(LOADED); 2702 break; 2703 } 2704 2705 case OMX_StateInvalid: 2706 { 2707 setState(ERROR); 2708 break; 2709 } 2710 2711 default: 2712 { 2713 CHECK(!"should not be here."); 2714 break; 2715 } 2716 } 2717 } 2718 2719 // static 2720 size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 2721 size_t n = 0; 2722 for (size_t i = 0; i < buffers.size(); ++i) { 2723 if (buffers[i].mStatus != OWNED_BY_COMPONENT) { 2724 ++n; 2725 } 2726 } 2727 2728 return n; 2729 } 2730 2731 status_t OMXCodec::freeBuffersOnPort( 2732 OMX_U32 portIndex, bool onlyThoseWeOwn) { 2733 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2734 2735 status_t stickyErr = OK; 2736 2737 for (size_t i = buffers->size(); i-- > 0;) { 2738 BufferInfo *info = &buffers->editItemAt(i); 2739 2740 if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) { 2741 continue; 2742 } 2743 2744 CHECK(info->mStatus == OWNED_BY_US 2745 || info->mStatus == OWNED_BY_NATIVE_WINDOW); 2746 2747 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 2748 2749 status_t err = freeBuffer(portIndex, i); 2750 2751 if (err != OK) { 2752 stickyErr = err; 2753 } 2754 2755 } 2756 2757 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 2758 2759 return stickyErr; 2760 } 2761 2762 status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { 2763 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2764 2765 BufferInfo *info = &buffers->editItemAt(bufIndex); 2766 2767 status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 2768 2769 if (err == OK && info->mMediaBuffer != NULL) { 2770 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2771 info->mMediaBuffer->setObserver(NULL); 2772 2773 // Make sure nobody but us owns this buffer at this point. 2774 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 2775 2776 // Cancel the buffer if it belongs to an ANativeWindow. 2777 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer(); 2778 if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) { 2779 err = cancelBufferToNativeWindow(info); 2780 } 2781 2782 info->mMediaBuffer->release(); 2783 info->mMediaBuffer = NULL; 2784 } 2785 2786 if (err == OK) { 2787 buffers->removeAt(bufIndex); 2788 } 2789 2790 return err; 2791 } 2792 2793 void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 2794 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 2795 2796 CHECK_EQ((int)mState, (int)EXECUTING); 2797 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2798 CHECK(!mOutputPortSettingsChangedPending); 2799 2800 if (mPortStatus[kPortIndexOutput] != ENABLED) { 2801 CODEC_LOGV("Deferring output port settings change."); 2802 mOutputPortSettingsChangedPending = true; 2803 return; 2804 } 2805 2806 setState(RECONFIGURING); 2807 2808 if (mQuirks & kNeedsFlushBeforeDisable) { 2809 if (!flushPortAsync(portIndex)) { 2810 onCmdComplete(OMX_CommandFlush, portIndex); 2811 } 2812 } else { 2813 disablePortAsync(portIndex); 2814 } 2815 } 2816 2817 bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 2818 CHECK(mState == EXECUTING || mState == RECONFIGURING 2819 || mState == EXECUTING_TO_IDLE); 2820 2821 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 2822 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 2823 mPortBuffers[portIndex].size()); 2824 2825 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2826 mPortStatus[portIndex] = SHUTTING_DOWN; 2827 2828 if ((mQuirks & kRequiresFlushCompleteEmulation) 2829 && countBuffersWeOwn(mPortBuffers[portIndex]) 2830 == mPortBuffers[portIndex].size()) { 2831 // No flush is necessary and this component fails to send a 2832 // flush-complete event in this case. 2833 2834 return false; 2835 } 2836 2837 status_t err = 2838 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 2839 CHECK_EQ(err, (status_t)OK); 2840 2841 return true; 2842 } 2843 2844 void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 2845 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2846 2847 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2848 mPortStatus[portIndex] = DISABLING; 2849 2850 CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex); 2851 status_t err = 2852 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 2853 CHECK_EQ(err, (status_t)OK); 2854 2855 freeBuffersOnPort(portIndex, true); 2856 } 2857 2858 status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) { 2859 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2860 2861 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED); 2862 mPortStatus[portIndex] = ENABLING; 2863 2864 CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex); 2865 return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 2866 } 2867 2868 void OMXCodec::fillOutputBuffers() { 2869 CHECK_EQ((int)mState, (int)EXECUTING); 2870 2871 // This is a workaround for some decoders not properly reporting 2872 // end-of-output-stream. If we own all input buffers and also own 2873 // all output buffers and we already signalled end-of-input-stream, 2874 // the end-of-output-stream is implied. 2875 if (mSignalledEOS 2876 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 2877 == mPortBuffers[kPortIndexInput].size() 2878 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 2879 == mPortBuffers[kPortIndexOutput].size()) { 2880 mNoMoreOutputData = true; 2881 mBufferFilled.signal(); 2882 2883 return; 2884 } 2885 2886 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2887 for (size_t i = 0; i < buffers->size(); ++i) { 2888 BufferInfo *info = &buffers->editItemAt(i); 2889 if (info->mStatus == OWNED_BY_US) { 2890 fillOutputBuffer(&buffers->editItemAt(i)); 2891 } 2892 } 2893 } 2894 2895 void OMXCodec::drainInputBuffers() { 2896 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2897 2898 if (mFlags & kUseSecureInputBuffers) { 2899 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2900 for (size_t i = 0; i < buffers->size(); ++i) { 2901 if (!drainAnyInputBuffer() 2902 || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) { 2903 break; 2904 } 2905 } 2906 } else { 2907 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2908 for (size_t i = 0; i < buffers->size(); ++i) { 2909 BufferInfo *info = &buffers->editItemAt(i); 2910 2911 if (info->mStatus != OWNED_BY_US) { 2912 continue; 2913 } 2914 2915 if (!drainInputBuffer(info)) { 2916 break; 2917 } 2918 2919 if (mFlags & kOnlySubmitOneInputBufferAtOneTime) { 2920 break; 2921 } 2922 } 2923 } 2924 } 2925 2926 bool OMXCodec::drainAnyInputBuffer() { 2927 return drainInputBuffer((BufferInfo *)NULL); 2928 } 2929 2930 OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) { 2931 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 2932 for (size_t i = 0; i < infos->size(); ++i) { 2933 BufferInfo *info = &infos->editItemAt(i); 2934 2935 if (info->mData == ptr) { 2936 CODEC_LOGV( 2937 "input buffer data ptr = %p, buffer_id = %p", 2938 ptr, 2939 info->mBuffer); 2940 2941 return info; 2942 } 2943 } 2944 2945 TRESPASS(); 2946 } 2947 2948 OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() { 2949 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 2950 for (size_t i = 0; i < infos->size(); ++i) { 2951 BufferInfo *info = &infos->editItemAt(i); 2952 2953 if (info->mStatus == OWNED_BY_US) { 2954 return info; 2955 } 2956 } 2957 2958 TRESPASS(); 2959 } 2960 2961 bool OMXCodec::drainInputBuffer(BufferInfo *info) { 2962 if (info != NULL) { 2963 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 2964 } 2965 2966 if (mSignalledEOS) { 2967 return false; 2968 } 2969 2970 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 2971 CHECK(!(mFlags & kUseSecureInputBuffers)); 2972 2973 const CodecSpecificData *specific = 2974 mCodecSpecificData[mCodecSpecificDataIndex]; 2975 2976 size_t size = specific->mSize; 2977 2978 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 2979 && !(mQuirks & kWantsNALFragments)) { 2980 static const uint8_t kNALStartCode[4] = 2981 { 0x00, 0x00, 0x00, 0x01 }; 2982 2983 CHECK(info->mSize >= specific->mSize + 4); 2984 2985 size += 4; 2986 2987 memcpy(info->mData, kNALStartCode, 4); 2988 memcpy((uint8_t *)info->mData + 4, 2989 specific->mData, specific->mSize); 2990 } else { 2991 CHECK(info->mSize >= specific->mSize); 2992 memcpy(info->mData, specific->mData, specific->mSize); 2993 } 2994 2995 mNoMoreOutputData = false; 2996 2997 CODEC_LOGV("calling emptyBuffer with codec specific data"); 2998 2999 status_t err = mOMX->emptyBuffer( 3000 mNode, info->mBuffer, 0, size, 3001 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 3002 0); 3003 CHECK_EQ(err, (status_t)OK); 3004 3005 info->mStatus = OWNED_BY_COMPONENT; 3006 3007 ++mCodecSpecificDataIndex; 3008 return true; 3009 } 3010 3011 if (mPaused) { 3012 return false; 3013 } 3014 3015 status_t err; 3016 3017 bool signalEOS = false; 3018 int64_t timestampUs = 0; 3019 3020 size_t offset = 0; 3021 int32_t n = 0; 3022 3023 3024 for (;;) { 3025 MediaBuffer *srcBuffer; 3026 if (mSeekTimeUs >= 0) { 3027 if (mLeftOverBuffer) { 3028 mLeftOverBuffer->release(); 3029 mLeftOverBuffer = NULL; 3030 } 3031 3032 MediaSource::ReadOptions options; 3033 options.setSeekTo(mSeekTimeUs, mSeekMode); 3034 3035 mSeekTimeUs = -1; 3036 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3037 mBufferFilled.signal(); 3038 3039 err = mSource->read(&srcBuffer, &options); 3040 3041 if (err == OK) { 3042 int64_t targetTimeUs; 3043 if (srcBuffer->meta_data()->findInt64( 3044 kKeyTargetTime, &targetTimeUs) 3045 && targetTimeUs >= 0) { 3046 CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs); 3047 mTargetTimeUs = targetTimeUs; 3048 } else { 3049 mTargetTimeUs = -1; 3050 } 3051 } 3052 } else if (mLeftOverBuffer) { 3053 srcBuffer = mLeftOverBuffer; 3054 mLeftOverBuffer = NULL; 3055 3056 err = OK; 3057 } else { 3058 err = mSource->read(&srcBuffer); 3059 } 3060 3061 if (err != OK) { 3062 signalEOS = true; 3063 mFinalStatus = err; 3064 mSignalledEOS = true; 3065 mBufferFilled.signal(); 3066 break; 3067 } 3068 3069 if (mFlags & kUseSecureInputBuffers) { 3070 info = findInputBufferByDataPointer(srcBuffer->data()); 3071 CHECK(info != NULL); 3072 } 3073 3074 size_t remainingBytes = info->mSize - offset; 3075 3076 if (srcBuffer->range_length() > remainingBytes) { 3077 if (offset == 0) { 3078 CODEC_LOGE( 3079 "Codec's input buffers are too small to accomodate " 3080 "buffer read from source (info->mSize = %d, srcLength = %d)", 3081 info->mSize, srcBuffer->range_length()); 3082 3083 srcBuffer->release(); 3084 srcBuffer = NULL; 3085 3086 setState(ERROR); 3087 return false; 3088 } 3089 3090 mLeftOverBuffer = srcBuffer; 3091 break; 3092 } 3093 3094 bool releaseBuffer = true; 3095 if (mFlags & kStoreMetaDataInVideoBuffers) { 3096 releaseBuffer = false; 3097 info->mMediaBuffer = srcBuffer; 3098 } 3099 3100 if (mFlags & kUseSecureInputBuffers) { 3101 // Data in "info" is already provided at this time. 3102 3103 releaseBuffer = false; 3104 3105 CHECK(info->mMediaBuffer == NULL); 3106 info->mMediaBuffer = srcBuffer; 3107 } else { 3108 CHECK(srcBuffer->data() != NULL) ; 3109 memcpy((uint8_t *)info->mData + offset, 3110 (const uint8_t *)srcBuffer->data() 3111 + srcBuffer->range_offset(), 3112 srcBuffer->range_length()); 3113 } 3114 3115 int64_t lastBufferTimeUs; 3116 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); 3117 CHECK(lastBufferTimeUs >= 0); 3118 if (mIsEncoder && mIsVideo) { 3119 mDecodingTimeList.push_back(lastBufferTimeUs); 3120 } 3121 3122 if (offset == 0) { 3123 timestampUs = lastBufferTimeUs; 3124 } 3125 3126 offset += srcBuffer->range_length(); 3127 3128 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) { 3129 CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer)); 3130 CHECK_GE(info->mSize, offset + sizeof(int32_t)); 3131 3132 int32_t numPageSamples; 3133 if (!srcBuffer->meta_data()->findInt32( 3134 kKeyValidSamples, &numPageSamples)) { 3135 numPageSamples = -1; 3136 } 3137 3138 memcpy((uint8_t *)info->mData + offset, 3139 &numPageSamples, 3140 sizeof(numPageSamples)); 3141 3142 offset += sizeof(numPageSamples); 3143 } 3144 3145 if (releaseBuffer) { 3146 srcBuffer->release(); 3147 srcBuffer = NULL; 3148 } 3149 3150 ++n; 3151 3152 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) { 3153 break; 3154 } 3155 3156 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs; 3157 3158 if (coalescedDurationUs > 250000ll) { 3159 // Don't coalesce more than 250ms worth of encoded data at once. 3160 break; 3161 } 3162 } 3163 3164 if (n > 1) { 3165 ALOGV("coalesced %d frames into one input buffer", n); 3166 } 3167 3168 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 3169 3170 if (signalEOS) { 3171 flags |= OMX_BUFFERFLAG_EOS; 3172 } else { 3173 mNoMoreOutputData = false; 3174 } 3175 3176 if (info == NULL) { 3177 CHECK(mFlags & kUseSecureInputBuffers); 3178 CHECK(signalEOS); 3179 3180 // This is fishy, there's still a MediaBuffer corresponding to this 3181 // info available to the source at this point even though we're going 3182 // to use it to signal EOS to the codec. 3183 info = findEmptyInputBuffer(); 3184 } 3185 3186 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 3187 "timestamp %lld us (%.2f secs)", 3188 info->mBuffer, offset, 3189 timestampUs, timestampUs / 1E6); 3190 3191 err = mOMX->emptyBuffer( 3192 mNode, info->mBuffer, 0, offset, 3193 flags, timestampUs); 3194 3195 if (err != OK) { 3196 setState(ERROR); 3197 return false; 3198 } 3199 3200 info->mStatus = OWNED_BY_COMPONENT; 3201 3202 return true; 3203 } 3204 3205 void OMXCodec::fillOutputBuffer(BufferInfo *info) { 3206 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3207 3208 if (mNoMoreOutputData) { 3209 CODEC_LOGV("There is no more output data available, not " 3210 "calling fillOutputBuffer"); 3211 return; 3212 } 3213 3214 CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer); 3215 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 3216 3217 if (err != OK) { 3218 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err); 3219 3220 setState(ERROR); 3221 return; 3222 } 3223 3224 info->mStatus = OWNED_BY_COMPONENT; 3225 } 3226 3227 bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 3228 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 3229 for (size_t i = 0; i < buffers->size(); ++i) { 3230 if ((*buffers)[i].mBuffer == buffer) { 3231 return drainInputBuffer(&buffers->editItemAt(i)); 3232 } 3233 } 3234 3235 CHECK(!"should not be here."); 3236 3237 return false; 3238 } 3239 3240 void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 3241 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3242 for (size_t i = 0; i < buffers->size(); ++i) { 3243 if ((*buffers)[i].mBuffer == buffer) { 3244 fillOutputBuffer(&buffers->editItemAt(i)); 3245 return; 3246 } 3247 } 3248 3249 CHECK(!"should not be here."); 3250 } 3251 3252 void OMXCodec::setState(State newState) { 3253 mState = newState; 3254 mAsyncCompletion.signal(); 3255 3256 // This may cause some spurious wakeups but is necessary to 3257 // unblock the reader if we enter ERROR state. 3258 mBufferFilled.signal(); 3259 } 3260 3261 status_t OMXCodec::waitForBufferFilled_l() { 3262 3263 if (mIsEncoder) { 3264 // For timelapse video recording, the timelapse video recording may 3265 // not send an input frame for a _long_ time. Do not use timeout 3266 // for video encoding. 3267 return mBufferFilled.wait(mLock); 3268 } 3269 status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs); 3270 if (err != OK) { 3271 CODEC_LOGE("Timed out waiting for output buffers: %d/%d", 3272 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 3273 countBuffersWeOwn(mPortBuffers[kPortIndexOutput])); 3274 } 3275 return err; 3276 } 3277 3278 void OMXCodec::setRawAudioFormat( 3279 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 3280 3281 // port definition 3282 OMX_PARAM_PORTDEFINITIONTYPE def; 3283 InitOMXParams(&def); 3284 def.nPortIndex = portIndex; 3285 status_t err = mOMX->getParameter( 3286 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3287 CHECK_EQ(err, (status_t)OK); 3288 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 3289 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3290 &def, sizeof(def)), (status_t)OK); 3291 3292 // pcm param 3293 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 3294 InitOMXParams(&pcmParams); 3295 pcmParams.nPortIndex = portIndex; 3296 3297 err = mOMX->getParameter( 3298 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3299 3300 CHECK_EQ(err, (status_t)OK); 3301 3302 pcmParams.nChannels = numChannels; 3303 pcmParams.eNumData = OMX_NumericalDataSigned; 3304 pcmParams.bInterleaved = OMX_TRUE; 3305 pcmParams.nBitPerSample = 16; 3306 pcmParams.nSamplingRate = sampleRate; 3307 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 3308 3309 CHECK_EQ(getOMXChannelMapping( 3310 numChannels, pcmParams.eChannelMapping), (status_t)OK); 3311 3312 err = mOMX->setParameter( 3313 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3314 3315 CHECK_EQ(err, (status_t)OK); 3316 } 3317 3318 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) { 3319 if (isAMRWB) { 3320 if (bps <= 6600) { 3321 return OMX_AUDIO_AMRBandModeWB0; 3322 } else if (bps <= 8850) { 3323 return OMX_AUDIO_AMRBandModeWB1; 3324 } else if (bps <= 12650) { 3325 return OMX_AUDIO_AMRBandModeWB2; 3326 } else if (bps <= 14250) { 3327 return OMX_AUDIO_AMRBandModeWB3; 3328 } else if (bps <= 15850) { 3329 return OMX_AUDIO_AMRBandModeWB4; 3330 } else if (bps <= 18250) { 3331 return OMX_AUDIO_AMRBandModeWB5; 3332 } else if (bps <= 19850) { 3333 return OMX_AUDIO_AMRBandModeWB6; 3334 } else if (bps <= 23050) { 3335 return OMX_AUDIO_AMRBandModeWB7; 3336 } 3337 3338 // 23850 bps 3339 return OMX_AUDIO_AMRBandModeWB8; 3340 } else { // AMRNB 3341 if (bps <= 4750) { 3342 return OMX_AUDIO_AMRBandModeNB0; 3343 } else if (bps <= 5150) { 3344 return OMX_AUDIO_AMRBandModeNB1; 3345 } else if (bps <= 5900) { 3346 return OMX_AUDIO_AMRBandModeNB2; 3347 } else if (bps <= 6700) { 3348 return OMX_AUDIO_AMRBandModeNB3; 3349 } else if (bps <= 7400) { 3350 return OMX_AUDIO_AMRBandModeNB4; 3351 } else if (bps <= 7950) { 3352 return OMX_AUDIO_AMRBandModeNB5; 3353 } else if (bps <= 10200) { 3354 return OMX_AUDIO_AMRBandModeNB6; 3355 } 3356 3357 // 12200 bps 3358 return OMX_AUDIO_AMRBandModeNB7; 3359 } 3360 } 3361 3362 void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) { 3363 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 3364 3365 OMX_AUDIO_PARAM_AMRTYPE def; 3366 InitOMXParams(&def); 3367 def.nPortIndex = portIndex; 3368 3369 status_t err = 3370 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3371 3372 CHECK_EQ(err, (status_t)OK); 3373 3374 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 3375 3376 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate); 3377 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3378 CHECK_EQ(err, (status_t)OK); 3379 3380 //////////////////////// 3381 3382 if (mIsEncoder) { 3383 sp<MetaData> format = mSource->getFormat(); 3384 int32_t sampleRate; 3385 int32_t numChannels; 3386 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 3387 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 3388 3389 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3390 } 3391 } 3392 3393 status_t OMXCodec::setAACFormat( 3394 int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS) { 3395 if (numChannels > 2) { 3396 ALOGW("Number of channels: (%d) \n", numChannels); 3397 } 3398 3399 if (mIsEncoder) { 3400 if (isADTS) { 3401 return -EINVAL; 3402 } 3403 3404 //////////////// input port //////////////////// 3405 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3406 3407 //////////////// output port //////////////////// 3408 // format 3409 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 3410 InitOMXParams(&format); 3411 format.nPortIndex = kPortIndexOutput; 3412 format.nIndex = 0; 3413 status_t err = OMX_ErrorNone; 3414 while (OMX_ErrorNone == err) { 3415 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, 3416 &format, sizeof(format)), (status_t)OK); 3417 if (format.eEncoding == OMX_AUDIO_CodingAAC) { 3418 break; 3419 } 3420 format.nIndex++; 3421 } 3422 CHECK_EQ((status_t)OK, err); 3423 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, 3424 &format, sizeof(format)), (status_t)OK); 3425 3426 // port definition 3427 OMX_PARAM_PORTDEFINITIONTYPE def; 3428 InitOMXParams(&def); 3429 def.nPortIndex = kPortIndexOutput; 3430 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, 3431 &def, sizeof(def)), (status_t)OK); 3432 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 3433 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 3434 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3435 &def, sizeof(def)), (status_t)OK); 3436 3437 // profile 3438 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3439 InitOMXParams(&profile); 3440 profile.nPortIndex = kPortIndexOutput; 3441 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, 3442 &profile, sizeof(profile)), (status_t)OK); 3443 profile.nChannels = numChannels; 3444 profile.eChannelMode = (numChannels == 1? 3445 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); 3446 profile.nSampleRate = sampleRate; 3447 profile.nBitRate = bitRate; 3448 profile.nAudioBandWidth = 0; 3449 profile.nFrameLength = 0; 3450 profile.nAACtools = OMX_AUDIO_AACToolAll; 3451 profile.nAACERtools = OMX_AUDIO_AACERNone; 3452 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 3453 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 3454 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, 3455 &profile, sizeof(profile)); 3456 3457 if (err != OK) { 3458 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed " 3459 "(err = %d)", 3460 err); 3461 return err; 3462 } 3463 } else { 3464 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3465 InitOMXParams(&profile); 3466 profile.nPortIndex = kPortIndexInput; 3467 3468 status_t err = mOMX->getParameter( 3469 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3470 CHECK_EQ(err, (status_t)OK); 3471 3472 profile.nChannels = numChannels; 3473 profile.nSampleRate = sampleRate; 3474 3475 profile.eAACStreamFormat = 3476 isADTS 3477 ? OMX_AUDIO_AACStreamFormatMP4ADTS 3478 : OMX_AUDIO_AACStreamFormatMP4FF; 3479 3480 err = mOMX->setParameter( 3481 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3482 3483 if (err != OK) { 3484 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed " 3485 "(err = %d)", 3486 err); 3487 return err; 3488 } 3489 } 3490 3491 return OK; 3492 } 3493 3494 void OMXCodec::setG711Format(int32_t numChannels) { 3495 CHECK(!mIsEncoder); 3496 setRawAudioFormat(kPortIndexInput, 8000, numChannels); 3497 } 3498 3499 void OMXCodec::setImageOutputFormat( 3500 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 3501 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 3502 3503 #if 0 3504 OMX_INDEXTYPE index; 3505 status_t err = mOMX->get_extension_index( 3506 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 3507 CHECK_EQ(err, (status_t)OK); 3508 3509 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 3510 CHECK_EQ(err, (status_t)OK); 3511 #endif 3512 3513 OMX_PARAM_PORTDEFINITIONTYPE def; 3514 InitOMXParams(&def); 3515 def.nPortIndex = kPortIndexOutput; 3516 3517 status_t err = mOMX->getParameter( 3518 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3519 CHECK_EQ(err, (status_t)OK); 3520 3521 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3522 3523 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3524 3525 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused); 3526 imageDef->eColorFormat = format; 3527 imageDef->nFrameWidth = width; 3528 imageDef->nFrameHeight = height; 3529 3530 switch (format) { 3531 case OMX_COLOR_FormatYUV420PackedPlanar: 3532 case OMX_COLOR_FormatYUV411Planar: 3533 { 3534 def.nBufferSize = (width * height * 3) / 2; 3535 break; 3536 } 3537 3538 case OMX_COLOR_FormatCbYCrY: 3539 { 3540 def.nBufferSize = width * height * 2; 3541 break; 3542 } 3543 3544 case OMX_COLOR_Format32bitARGB8888: 3545 { 3546 def.nBufferSize = width * height * 4; 3547 break; 3548 } 3549 3550 case OMX_COLOR_Format16bitARGB4444: 3551 case OMX_COLOR_Format16bitARGB1555: 3552 case OMX_COLOR_Format16bitRGB565: 3553 case OMX_COLOR_Format16bitBGR565: 3554 { 3555 def.nBufferSize = width * height * 2; 3556 break; 3557 } 3558 3559 default: 3560 CHECK(!"Should not be here. Unknown color format."); 3561 break; 3562 } 3563 3564 def.nBufferCountActual = def.nBufferCountMin; 3565 3566 err = mOMX->setParameter( 3567 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3568 CHECK_EQ(err, (status_t)OK); 3569 } 3570 3571 void OMXCodec::setJPEGInputFormat( 3572 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 3573 OMX_PARAM_PORTDEFINITIONTYPE def; 3574 InitOMXParams(&def); 3575 def.nPortIndex = kPortIndexInput; 3576 3577 status_t err = mOMX->getParameter( 3578 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3579 CHECK_EQ(err, (status_t)OK); 3580 3581 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3582 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3583 3584 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG); 3585 imageDef->nFrameWidth = width; 3586 imageDef->nFrameHeight = height; 3587 3588 def.nBufferSize = compressedSize; 3589 def.nBufferCountActual = def.nBufferCountMin; 3590 3591 err = mOMX->setParameter( 3592 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3593 CHECK_EQ(err, (status_t)OK); 3594 } 3595 3596 void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 3597 CodecSpecificData *specific = 3598 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 3599 3600 specific->mSize = size; 3601 memcpy(specific->mData, data, size); 3602 3603 mCodecSpecificData.push(specific); 3604 } 3605 3606 void OMXCodec::clearCodecSpecificData() { 3607 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 3608 free(mCodecSpecificData.editItemAt(i)); 3609 } 3610 mCodecSpecificData.clear(); 3611 mCodecSpecificDataIndex = 0; 3612 } 3613 3614 status_t OMXCodec::start(MetaData *meta) { 3615 Mutex::Autolock autoLock(mLock); 3616 3617 if (mState != LOADED) { 3618 CODEC_LOGE("called start in the unexpected state: %d", mState); 3619 return UNKNOWN_ERROR; 3620 } 3621 3622 sp<MetaData> params = new MetaData; 3623 if (mQuirks & kWantsNALFragments) { 3624 params->setInt32(kKeyWantsNALFragments, true); 3625 } 3626 if (meta) { 3627 int64_t startTimeUs = 0; 3628 int64_t timeUs; 3629 if (meta->findInt64(kKeyTime, &timeUs)) { 3630 startTimeUs = timeUs; 3631 } 3632 params->setInt64(kKeyTime, startTimeUs); 3633 } 3634 3635 mCodecSpecificDataIndex = 0; 3636 mInitialBufferSubmit = true; 3637 mSignalledEOS = false; 3638 mNoMoreOutputData = false; 3639 mOutputPortSettingsHaveChanged = false; 3640 mSeekTimeUs = -1; 3641 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3642 mTargetTimeUs = -1; 3643 mFilledBuffers.clear(); 3644 mPaused = false; 3645 3646 status_t err; 3647 if (mIsEncoder) { 3648 // Calling init() before starting its source so that we can configure, 3649 // if supported, the source to use exactly the same number of input 3650 // buffers as requested by the encoder. 3651 if ((err = init()) != OK) { 3652 CODEC_LOGE("init failed: %d", err); 3653 return err; 3654 } 3655 3656 params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size()); 3657 err = mSource->start(params.get()); 3658 if (err != OK) { 3659 CODEC_LOGE("source failed to start: %d", err); 3660 stopOmxComponent_l(); 3661 } 3662 return err; 3663 } 3664 3665 // Decoder case 3666 if ((err = mSource->start(params.get())) != OK) { 3667 CODEC_LOGE("source failed to start: %d", err); 3668 return err; 3669 } 3670 return init(); 3671 } 3672 3673 status_t OMXCodec::stop() { 3674 CODEC_LOGV("stop mState=%d", mState); 3675 Mutex::Autolock autoLock(mLock); 3676 status_t err = stopOmxComponent_l(); 3677 mSource->stop(); 3678 3679 CODEC_LOGV("stopped in state %d", mState); 3680 return err; 3681 } 3682 3683 status_t OMXCodec::stopOmxComponent_l() { 3684 CODEC_LOGV("stopOmxComponent_l mState=%d", mState); 3685 3686 while (isIntermediateState(mState)) { 3687 mAsyncCompletion.wait(mLock); 3688 } 3689 3690 bool isError = false; 3691 switch (mState) { 3692 case LOADED: 3693 break; 3694 3695 case ERROR: 3696 { 3697 if (mPortStatus[kPortIndexOutput] == ENABLING) { 3698 // Codec is in a wedged state (technical term) 3699 // We've seen an output port settings change from the codec, 3700 // We've disabled the output port, then freed the output 3701 // buffers, initiated re-enabling the output port but 3702 // failed to reallocate the output buffers. 3703 // There doesn't seem to be a way to orderly transition 3704 // from executing->idle and idle->loaded now that the 3705 // output port hasn't been reenabled yet... 3706 // Simply free as many resources as we can and pretend 3707 // that we're in LOADED state so that the destructor 3708 // will free the component instance without asserting. 3709 freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */); 3710 freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */); 3711 setState(LOADED); 3712 break; 3713 } else { 3714 OMX_STATETYPE state = OMX_StateInvalid; 3715 status_t err = mOMX->getState(mNode, &state); 3716 CHECK_EQ(err, (status_t)OK); 3717 3718 if (state != OMX_StateExecuting) { 3719 break; 3720 } 3721 // else fall through to the idling code 3722 } 3723 3724 isError = true; 3725 } 3726 3727 case EXECUTING: 3728 { 3729 setState(EXECUTING_TO_IDLE); 3730 3731 if (mQuirks & kRequiresFlushBeforeShutdown) { 3732 CODEC_LOGV("This component requires a flush before transitioning " 3733 "from EXECUTING to IDLE..."); 3734 3735 bool emulateInputFlushCompletion = 3736 !flushPortAsync(kPortIndexInput); 3737 3738 bool emulateOutputFlushCompletion = 3739 !flushPortAsync(kPortIndexOutput); 3740 3741 if (emulateInputFlushCompletion) { 3742 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3743 } 3744 3745 if (emulateOutputFlushCompletion) { 3746 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3747 } 3748 } else { 3749 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 3750 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 3751 3752 status_t err = 3753 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 3754 CHECK_EQ(err, (status_t)OK); 3755 } 3756 3757 while (mState != LOADED && mState != ERROR) { 3758 mAsyncCompletion.wait(mLock); 3759 } 3760 3761 if (isError) { 3762 // We were in the ERROR state coming in, so restore that now 3763 // that we've idled the OMX component. 3764 setState(ERROR); 3765 } 3766 3767 break; 3768 } 3769 3770 default: 3771 { 3772 CHECK(!"should not be here."); 3773 break; 3774 } 3775 } 3776 3777 if (mLeftOverBuffer) { 3778 mLeftOverBuffer->release(); 3779 mLeftOverBuffer = NULL; 3780 } 3781 3782 return OK; 3783 } 3784 3785 sp<MetaData> OMXCodec::getFormat() { 3786 Mutex::Autolock autoLock(mLock); 3787 3788 return mOutputFormat; 3789 } 3790 3791 status_t OMXCodec::read( 3792 MediaBuffer **buffer, const ReadOptions *options) { 3793 status_t err = OK; 3794 *buffer = NULL; 3795 3796 Mutex::Autolock autoLock(mLock); 3797 3798 if (mState != EXECUTING && mState != RECONFIGURING) { 3799 return UNKNOWN_ERROR; 3800 } 3801 3802 bool seeking = false; 3803 int64_t seekTimeUs; 3804 ReadOptions::SeekMode seekMode; 3805 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 3806 seeking = true; 3807 } 3808 3809 if (mInitialBufferSubmit) { 3810 mInitialBufferSubmit = false; 3811 3812 if (seeking) { 3813 CHECK(seekTimeUs >= 0); 3814 mSeekTimeUs = seekTimeUs; 3815 mSeekMode = seekMode; 3816 3817 // There's no reason to trigger the code below, there's 3818 // nothing to flush yet. 3819 seeking = false; 3820 mPaused = false; 3821 } 3822 3823 drainInputBuffers(); 3824 3825 if (mState == EXECUTING) { 3826 // Otherwise mState == RECONFIGURING and this code will trigger 3827 // after the output port is reenabled. 3828 fillOutputBuffers(); 3829 } 3830 } 3831 3832 if (seeking) { 3833 while (mState == RECONFIGURING) { 3834 if ((err = waitForBufferFilled_l()) != OK) { 3835 return err; 3836 } 3837 } 3838 3839 if (mState != EXECUTING) { 3840 return UNKNOWN_ERROR; 3841 } 3842 3843 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 3844 3845 mSignalledEOS = false; 3846 3847 CHECK(seekTimeUs >= 0); 3848 mSeekTimeUs = seekTimeUs; 3849 mSeekMode = seekMode; 3850 3851 mFilledBuffers.clear(); 3852 3853 CHECK_EQ((int)mState, (int)EXECUTING); 3854 3855 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 3856 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 3857 3858 if (emulateInputFlushCompletion) { 3859 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3860 } 3861 3862 if (emulateOutputFlushCompletion) { 3863 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3864 } 3865 3866 while (mSeekTimeUs >= 0) { 3867 if ((err = waitForBufferFilled_l()) != OK) { 3868 return err; 3869 } 3870 } 3871 } 3872 3873 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 3874 if ((err = waitForBufferFilled_l()) != OK) { 3875 return err; 3876 } 3877 } 3878 3879 if (mState == ERROR) { 3880 return UNKNOWN_ERROR; 3881 } 3882 3883 if (mFilledBuffers.empty()) { 3884 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 3885 } 3886 3887 if (mOutputPortSettingsHaveChanged) { 3888 mOutputPortSettingsHaveChanged = false; 3889 3890 return INFO_FORMAT_CHANGED; 3891 } 3892 3893 size_t index = *mFilledBuffers.begin(); 3894 mFilledBuffers.erase(mFilledBuffers.begin()); 3895 3896 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 3897 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3898 info->mStatus = OWNED_BY_CLIENT; 3899 3900 info->mMediaBuffer->add_ref(); 3901 if (mSkipCutBuffer != NULL) { 3902 mSkipCutBuffer->submit(info->mMediaBuffer); 3903 } 3904 *buffer = info->mMediaBuffer; 3905 3906 return OK; 3907 } 3908 3909 void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 3910 Mutex::Autolock autoLock(mLock); 3911 3912 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3913 for (size_t i = 0; i < buffers->size(); ++i) { 3914 BufferInfo *info = &buffers->editItemAt(i); 3915 3916 if (info->mMediaBuffer == buffer) { 3917 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 3918 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT); 3919 3920 info->mStatus = OWNED_BY_US; 3921 3922 if (buffer->graphicBuffer() == 0) { 3923 fillOutputBuffer(info); 3924 } else { 3925 sp<MetaData> metaData = info->mMediaBuffer->meta_data(); 3926 int32_t rendered = 0; 3927 if (!metaData->findInt32(kKeyRendered, &rendered)) { 3928 rendered = 0; 3929 } 3930 if (!rendered) { 3931 status_t err = cancelBufferToNativeWindow(info); 3932 if (err < 0) { 3933 return; 3934 } 3935 } 3936 3937 info->mStatus = OWNED_BY_NATIVE_WINDOW; 3938 3939 // Dequeue the next buffer from the native window. 3940 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow(); 3941 if (nextBufInfo == 0) { 3942 return; 3943 } 3944 3945 // Give the buffer to the OMX node to fill. 3946 fillOutputBuffer(nextBufInfo); 3947 } 3948 return; 3949 } 3950 } 3951 3952 CHECK(!"should not be here."); 3953 } 3954 3955 static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 3956 static const char *kNames[] = { 3957 "OMX_IMAGE_CodingUnused", 3958 "OMX_IMAGE_CodingAutoDetect", 3959 "OMX_IMAGE_CodingJPEG", 3960 "OMX_IMAGE_CodingJPEG2K", 3961 "OMX_IMAGE_CodingEXIF", 3962 "OMX_IMAGE_CodingTIFF", 3963 "OMX_IMAGE_CodingGIF", 3964 "OMX_IMAGE_CodingPNG", 3965 "OMX_IMAGE_CodingLZW", 3966 "OMX_IMAGE_CodingBMP", 3967 }; 3968 3969 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 3970 3971 if (type < 0 || (size_t)type >= numNames) { 3972 return "UNKNOWN"; 3973 } else { 3974 return kNames[type]; 3975 } 3976 } 3977 3978 static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 3979 static const char *kNames[] = { 3980 "OMX_COLOR_FormatUnused", 3981 "OMX_COLOR_FormatMonochrome", 3982 "OMX_COLOR_Format8bitRGB332", 3983 "OMX_COLOR_Format12bitRGB444", 3984 "OMX_COLOR_Format16bitARGB4444", 3985 "OMX_COLOR_Format16bitARGB1555", 3986 "OMX_COLOR_Format16bitRGB565", 3987 "OMX_COLOR_Format16bitBGR565", 3988 "OMX_COLOR_Format18bitRGB666", 3989 "OMX_COLOR_Format18bitARGB1665", 3990 "OMX_COLOR_Format19bitARGB1666", 3991 "OMX_COLOR_Format24bitRGB888", 3992 "OMX_COLOR_Format24bitBGR888", 3993 "OMX_COLOR_Format24bitARGB1887", 3994 "OMX_COLOR_Format25bitARGB1888", 3995 "OMX_COLOR_Format32bitBGRA8888", 3996 "OMX_COLOR_Format32bitARGB8888", 3997 "OMX_COLOR_FormatYUV411Planar", 3998 "OMX_COLOR_FormatYUV411PackedPlanar", 3999 "OMX_COLOR_FormatYUV420Planar", 4000 "OMX_COLOR_FormatYUV420PackedPlanar", 4001 "OMX_COLOR_FormatYUV420SemiPlanar", 4002 "OMX_COLOR_FormatYUV422Planar", 4003 "OMX_COLOR_FormatYUV422PackedPlanar", 4004 "OMX_COLOR_FormatYUV422SemiPlanar", 4005 "OMX_COLOR_FormatYCbYCr", 4006 "OMX_COLOR_FormatYCrYCb", 4007 "OMX_COLOR_FormatCbYCrY", 4008 "OMX_COLOR_FormatCrYCbY", 4009 "OMX_COLOR_FormatYUV444Interleaved", 4010 "OMX_COLOR_FormatRawBayer8bit", 4011 "OMX_COLOR_FormatRawBayer10bit", 4012 "OMX_COLOR_FormatRawBayer8bitcompressed", 4013 "OMX_COLOR_FormatL2", 4014 "OMX_COLOR_FormatL4", 4015 "OMX_COLOR_FormatL8", 4016 "OMX_COLOR_FormatL16", 4017 "OMX_COLOR_FormatL24", 4018 "OMX_COLOR_FormatL32", 4019 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 4020 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 4021 "OMX_COLOR_Format18BitBGR666", 4022 "OMX_COLOR_Format24BitARGB6666", 4023 "OMX_COLOR_Format24BitABGR6666", 4024 }; 4025 4026 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4027 4028 if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 4029 return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; 4030 } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 4031 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 4032 } else if (type < 0 || (size_t)type >= numNames) { 4033 return "UNKNOWN"; 4034 } else { 4035 return kNames[type]; 4036 } 4037 } 4038 4039 static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 4040 static const char *kNames[] = { 4041 "OMX_VIDEO_CodingUnused", 4042 "OMX_VIDEO_CodingAutoDetect", 4043 "OMX_VIDEO_CodingMPEG2", 4044 "OMX_VIDEO_CodingH263", 4045 "OMX_VIDEO_CodingMPEG4", 4046 "OMX_VIDEO_CodingWMV", 4047 "OMX_VIDEO_CodingRV", 4048 "OMX_VIDEO_CodingAVC", 4049 "OMX_VIDEO_CodingMJPEG", 4050 }; 4051 4052 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4053 4054 if (type < 0 || (size_t)type >= numNames) { 4055 return "UNKNOWN"; 4056 } else { 4057 return kNames[type]; 4058 } 4059 } 4060 4061 static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 4062 static const char *kNames[] = { 4063 "OMX_AUDIO_CodingUnused", 4064 "OMX_AUDIO_CodingAutoDetect", 4065 "OMX_AUDIO_CodingPCM", 4066 "OMX_AUDIO_CodingADPCM", 4067 "OMX_AUDIO_CodingAMR", 4068 "OMX_AUDIO_CodingGSMFR", 4069 "OMX_AUDIO_CodingGSMEFR", 4070 "OMX_AUDIO_CodingGSMHR", 4071 "OMX_AUDIO_CodingPDCFR", 4072 "OMX_AUDIO_CodingPDCEFR", 4073 "OMX_AUDIO_CodingPDCHR", 4074 "OMX_AUDIO_CodingTDMAFR", 4075 "OMX_AUDIO_CodingTDMAEFR", 4076 "OMX_AUDIO_CodingQCELP8", 4077 "OMX_AUDIO_CodingQCELP13", 4078 "OMX_AUDIO_CodingEVRC", 4079 "OMX_AUDIO_CodingSMV", 4080 "OMX_AUDIO_CodingG711", 4081 "OMX_AUDIO_CodingG723", 4082 "OMX_AUDIO_CodingG726", 4083 "OMX_AUDIO_CodingG729", 4084 "OMX_AUDIO_CodingAAC", 4085 "OMX_AUDIO_CodingMP3", 4086 "OMX_AUDIO_CodingSBC", 4087 "OMX_AUDIO_CodingVORBIS", 4088 "OMX_AUDIO_CodingWMA", 4089 "OMX_AUDIO_CodingRA", 4090 "OMX_AUDIO_CodingMIDI", 4091 }; 4092 4093 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4094 4095 if (type < 0 || (size_t)type >= numNames) { 4096 return "UNKNOWN"; 4097 } else { 4098 return kNames[type]; 4099 } 4100 } 4101 4102 static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 4103 static const char *kNames[] = { 4104 "OMX_AUDIO_PCMModeLinear", 4105 "OMX_AUDIO_PCMModeALaw", 4106 "OMX_AUDIO_PCMModeMULaw", 4107 }; 4108 4109 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4110 4111 if (type < 0 || (size_t)type >= numNames) { 4112 return "UNKNOWN"; 4113 } else { 4114 return kNames[type]; 4115 } 4116 } 4117 4118 static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 4119 static const char *kNames[] = { 4120 "OMX_AUDIO_AMRBandModeUnused", 4121 "OMX_AUDIO_AMRBandModeNB0", 4122 "OMX_AUDIO_AMRBandModeNB1", 4123 "OMX_AUDIO_AMRBandModeNB2", 4124 "OMX_AUDIO_AMRBandModeNB3", 4125 "OMX_AUDIO_AMRBandModeNB4", 4126 "OMX_AUDIO_AMRBandModeNB5", 4127 "OMX_AUDIO_AMRBandModeNB6", 4128 "OMX_AUDIO_AMRBandModeNB7", 4129 "OMX_AUDIO_AMRBandModeWB0", 4130 "OMX_AUDIO_AMRBandModeWB1", 4131 "OMX_AUDIO_AMRBandModeWB2", 4132 "OMX_AUDIO_AMRBandModeWB3", 4133 "OMX_AUDIO_AMRBandModeWB4", 4134 "OMX_AUDIO_AMRBandModeWB5", 4135 "OMX_AUDIO_AMRBandModeWB6", 4136 "OMX_AUDIO_AMRBandModeWB7", 4137 "OMX_AUDIO_AMRBandModeWB8", 4138 }; 4139 4140 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4141 4142 if (type < 0 || (size_t)type >= numNames) { 4143 return "UNKNOWN"; 4144 } else { 4145 return kNames[type]; 4146 } 4147 } 4148 4149 static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 4150 static const char *kNames[] = { 4151 "OMX_AUDIO_AMRFrameFormatConformance", 4152 "OMX_AUDIO_AMRFrameFormatIF1", 4153 "OMX_AUDIO_AMRFrameFormatIF2", 4154 "OMX_AUDIO_AMRFrameFormatFSF", 4155 "OMX_AUDIO_AMRFrameFormatRTPPayload", 4156 "OMX_AUDIO_AMRFrameFormatITU", 4157 }; 4158 4159 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4160 4161 if (type < 0 || (size_t)type >= numNames) { 4162 return "UNKNOWN"; 4163 } else { 4164 return kNames[type]; 4165 } 4166 } 4167 4168 void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 4169 OMX_PARAM_PORTDEFINITIONTYPE def; 4170 InitOMXParams(&def); 4171 def.nPortIndex = portIndex; 4172 4173 status_t err = mOMX->getParameter( 4174 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4175 CHECK_EQ(err, (status_t)OK); 4176 4177 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 4178 4179 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 4180 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 4181 4182 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 4183 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 4184 printf(" nBufferSize = %ld\n", def.nBufferSize); 4185 4186 switch (def.eDomain) { 4187 case OMX_PortDomainImage: 4188 { 4189 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4190 4191 printf("\n"); 4192 printf(" // Image\n"); 4193 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 4194 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 4195 printf(" nStride = %ld\n", imageDef->nStride); 4196 4197 printf(" eCompressionFormat = %s\n", 4198 imageCompressionFormatString(imageDef->eCompressionFormat)); 4199 4200 printf(" eColorFormat = %s\n", 4201 colorFormatString(imageDef->eColorFormat)); 4202 4203 break; 4204 } 4205 4206 case OMX_PortDomainVideo: 4207 { 4208 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4209 4210 printf("\n"); 4211 printf(" // Video\n"); 4212 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 4213 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 4214 printf(" nStride = %ld\n", videoDef->nStride); 4215 4216 printf(" eCompressionFormat = %s\n", 4217 videoCompressionFormatString(videoDef->eCompressionFormat)); 4218 4219 printf(" eColorFormat = %s\n", 4220 colorFormatString(videoDef->eColorFormat)); 4221 4222 break; 4223 } 4224 4225 case OMX_PortDomainAudio: 4226 { 4227 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4228 4229 printf("\n"); 4230 printf(" // Audio\n"); 4231 printf(" eEncoding = %s\n", 4232 audioCodingTypeString(audioDef->eEncoding)); 4233 4234 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 4235 OMX_AUDIO_PARAM_PCMMODETYPE params; 4236 InitOMXParams(¶ms); 4237 params.nPortIndex = portIndex; 4238 4239 err = mOMX->getParameter( 4240 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4241 CHECK_EQ(err, (status_t)OK); 4242 4243 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 4244 printf(" nChannels = %ld\n", params.nChannels); 4245 printf(" bInterleaved = %d\n", params.bInterleaved); 4246 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 4247 4248 printf(" eNumData = %s\n", 4249 params.eNumData == OMX_NumericalDataSigned 4250 ? "signed" : "unsigned"); 4251 4252 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 4253 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 4254 OMX_AUDIO_PARAM_AMRTYPE amr; 4255 InitOMXParams(&amr); 4256 amr.nPortIndex = portIndex; 4257 4258 err = mOMX->getParameter( 4259 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4260 CHECK_EQ(err, (status_t)OK); 4261 4262 printf(" nChannels = %ld\n", amr.nChannels); 4263 printf(" eAMRBandMode = %s\n", 4264 amrBandModeString(amr.eAMRBandMode)); 4265 printf(" eAMRFrameFormat = %s\n", 4266 amrFrameFormatString(amr.eAMRFrameFormat)); 4267 } 4268 4269 break; 4270 } 4271 4272 default: 4273 { 4274 printf(" // Unknown\n"); 4275 break; 4276 } 4277 } 4278 4279 printf("}\n"); 4280 } 4281 4282 status_t OMXCodec::initNativeWindow() { 4283 // Enable use of a GraphicBuffer as the output for this node. This must 4284 // happen before getting the IndexParamPortDefinition parameter because it 4285 // will affect the pixel format that the node reports. 4286 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 4287 if (err != 0) { 4288 return err; 4289 } 4290 4291 return OK; 4292 } 4293 4294 void OMXCodec::initNativeWindowCrop() { 4295 int32_t left, top, right, bottom; 4296 4297 CHECK(mOutputFormat->findRect( 4298 kKeyCropRect, 4299 &left, &top, &right, &bottom)); 4300 4301 android_native_rect_t crop; 4302 crop.left = left; 4303 crop.top = top; 4304 crop.right = right + 1; 4305 crop.bottom = bottom + 1; 4306 4307 // We'll ignore any errors here, if the surface is 4308 // already invalid, we'll know soon enough. 4309 native_window_set_crop(mNativeWindow.get(), &crop); 4310 } 4311 4312 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 4313 mOutputFormat = new MetaData; 4314 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 4315 if (mIsEncoder) { 4316 int32_t timeScale; 4317 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) { 4318 mOutputFormat->setInt32(kKeyTimeScale, timeScale); 4319 } 4320 } 4321 4322 OMX_PARAM_PORTDEFINITIONTYPE def; 4323 InitOMXParams(&def); 4324 def.nPortIndex = kPortIndexOutput; 4325 4326 status_t err = mOMX->getParameter( 4327 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4328 CHECK_EQ(err, (status_t)OK); 4329 4330 switch (def.eDomain) { 4331 case OMX_PortDomainImage: 4332 { 4333 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4334 CHECK_EQ((int)imageDef->eCompressionFormat, 4335 (int)OMX_IMAGE_CodingUnused); 4336 4337 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4338 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 4339 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 4340 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 4341 break; 4342 } 4343 4344 case OMX_PortDomainAudio: 4345 { 4346 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 4347 4348 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 4349 OMX_AUDIO_PARAM_PCMMODETYPE params; 4350 InitOMXParams(¶ms); 4351 params.nPortIndex = kPortIndexOutput; 4352 4353 err = mOMX->getParameter( 4354 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4355 CHECK_EQ(err, (status_t)OK); 4356 4357 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 4358 CHECK_EQ(params.nBitPerSample, 16u); 4359 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 4360 4361 int32_t numChannels, sampleRate; 4362 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4363 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4364 4365 if ((OMX_U32)numChannels != params.nChannels) { 4366 ALOGV("Codec outputs a different number of channels than " 4367 "the input stream contains (contains %d channels, " 4368 "codec outputs %ld channels).", 4369 numChannels, params.nChannels); 4370 } 4371 4372 if (sampleRate != (int32_t)params.nSamplingRate) { 4373 ALOGV("Codec outputs at different sampling rate than " 4374 "what the input stream contains (contains data at " 4375 "%d Hz, codec outputs %lu Hz)", 4376 sampleRate, params.nSamplingRate); 4377 } 4378 4379 mOutputFormat->setCString( 4380 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 4381 4382 // Use the codec-advertised number of channels, as some 4383 // codecs appear to output stereo even if the input data is 4384 // mono. If we know the codec lies about this information, 4385 // use the actual number of channels instead. 4386 mOutputFormat->setInt32( 4387 kKeyChannelCount, 4388 (mQuirks & kDecoderLiesAboutNumberOfChannels) 4389 ? numChannels : params.nChannels); 4390 4391 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate); 4392 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 4393 OMX_AUDIO_PARAM_AMRTYPE amr; 4394 InitOMXParams(&amr); 4395 amr.nPortIndex = kPortIndexOutput; 4396 4397 err = mOMX->getParameter( 4398 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4399 CHECK_EQ(err, (status_t)OK); 4400 4401 CHECK_EQ(amr.nChannels, 1u); 4402 mOutputFormat->setInt32(kKeyChannelCount, 1); 4403 4404 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 4405 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 4406 mOutputFormat->setCString( 4407 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 4408 mOutputFormat->setInt32(kKeySampleRate, 8000); 4409 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 4410 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 4411 mOutputFormat->setCString( 4412 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 4413 mOutputFormat->setInt32(kKeySampleRate, 16000); 4414 } else { 4415 CHECK(!"Unknown AMR band mode."); 4416 } 4417 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 4418 mOutputFormat->setCString( 4419 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 4420 int32_t numChannels, sampleRate, bitRate; 4421 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4422 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4423 inputFormat->findInt32(kKeyBitRate, &bitRate); 4424 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 4425 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 4426 mOutputFormat->setInt32(kKeyBitRate, bitRate); 4427 } else { 4428 CHECK(!"Should not be here. Unknown audio encoding."); 4429 } 4430 break; 4431 } 4432 4433 case OMX_PortDomainVideo: 4434 { 4435 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4436 4437 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 4438 mOutputFormat->setCString( 4439 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4440 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4441 mOutputFormat->setCString( 4442 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 4443 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 4444 mOutputFormat->setCString( 4445 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 4446 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 4447 mOutputFormat->setCString( 4448 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 4449 } else { 4450 CHECK(!"Unknown compression format."); 4451 } 4452 4453 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 4454 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 4455 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 4456 4457 if (!mIsEncoder) { 4458 OMX_CONFIG_RECTTYPE rect; 4459 InitOMXParams(&rect); 4460 rect.nPortIndex = kPortIndexOutput; 4461 status_t err = 4462 mOMX->getConfig( 4463 mNode, OMX_IndexConfigCommonOutputCrop, 4464 &rect, sizeof(rect)); 4465 4466 CODEC_LOGI( 4467 "video dimensions are %ld x %ld", 4468 video_def->nFrameWidth, video_def->nFrameHeight); 4469 4470 if (err == OK) { 4471 CHECK_GE(rect.nLeft, 0); 4472 CHECK_GE(rect.nTop, 0); 4473 CHECK_GE(rect.nWidth, 0u); 4474 CHECK_GE(rect.nHeight, 0u); 4475 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth); 4476 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight); 4477 4478 mOutputFormat->setRect( 4479 kKeyCropRect, 4480 rect.nLeft, 4481 rect.nTop, 4482 rect.nLeft + rect.nWidth - 1, 4483 rect.nTop + rect.nHeight - 1); 4484 4485 CODEC_LOGI( 4486 "Crop rect is %ld x %ld @ (%ld, %ld)", 4487 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop); 4488 } else { 4489 mOutputFormat->setRect( 4490 kKeyCropRect, 4491 0, 0, 4492 video_def->nFrameWidth - 1, 4493 video_def->nFrameHeight - 1); 4494 } 4495 4496 if (mNativeWindow != NULL) { 4497 initNativeWindowCrop(); 4498 } 4499 } 4500 break; 4501 } 4502 4503 default: 4504 { 4505 CHECK(!"should not be here, neither audio nor video."); 4506 break; 4507 } 4508 } 4509 4510 // If the input format contains rotation information, flag the output 4511 // format accordingly. 4512 4513 int32_t rotationDegrees; 4514 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) { 4515 mOutputFormat->setInt32(kKeyRotation, rotationDegrees); 4516 } 4517 } 4518 4519 status_t OMXCodec::pause() { 4520 Mutex::Autolock autoLock(mLock); 4521 4522 mPaused = true; 4523 4524 return OK; 4525 } 4526 4527 //////////////////////////////////////////////////////////////////////////////// 4528 4529 status_t QueryCodecs( 4530 const sp<IOMX> &omx, 4531 const char *mime, bool queryDecoders, bool hwCodecOnly, 4532 Vector<CodecCapabilities> *results) { 4533 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 4534 results->clear(); 4535 4536 OMXCodec::findMatchingCodecs(mime, 4537 !queryDecoders /*createEncoder*/, 4538 NULL /*matchComponentName*/, 4539 hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/, 4540 &matchingCodecs); 4541 4542 for (size_t c = 0; c < matchingCodecs.size(); c++) { 4543 const char *componentName = matchingCodecs.itemAt(c).mName.string(); 4544 4545 results->push(); 4546 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4547 4548 status_t err = 4549 QueryCodec(omx, componentName, mime, !queryDecoders, caps); 4550 4551 if (err != OK) { 4552 results->removeAt(results->size() - 1); 4553 } 4554 } 4555 4556 return OK; 4557 } 4558 4559 status_t QueryCodec( 4560 const sp<IOMX> &omx, 4561 const char *componentName, const char *mime, 4562 bool isEncoder, 4563 CodecCapabilities *caps) { 4564 if (strncmp(componentName, "OMX.", 4)) { 4565 // Not an OpenMax component but a software codec. 4566 4567 caps->mComponentName = componentName; 4568 return OK; 4569 } 4570 4571 sp<OMXCodecObserver> observer = new OMXCodecObserver; 4572 IOMX::node_id node; 4573 status_t err = omx->allocateNode(componentName, observer, &node); 4574 4575 if (err != OK) { 4576 return err; 4577 } 4578 4579 OMXCodec::setComponentRole(omx, node, isEncoder, mime); 4580 4581 caps->mComponentName = componentName; 4582 4583 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 4584 InitOMXParams(¶m); 4585 4586 param.nPortIndex = !isEncoder ? 0 : 1; 4587 4588 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 4589 err = omx->getParameter( 4590 node, OMX_IndexParamVideoProfileLevelQuerySupported, 4591 ¶m, sizeof(param)); 4592 4593 if (err != OK) { 4594 break; 4595 } 4596 4597 CodecProfileLevel profileLevel; 4598 profileLevel.mProfile = param.eProfile; 4599 profileLevel.mLevel = param.eLevel; 4600 4601 caps->mProfileLevels.push(profileLevel); 4602 } 4603 4604 // Color format query 4605 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 4606 InitOMXParams(&portFormat); 4607 portFormat.nPortIndex = !isEncoder ? 1 : 0; 4608 for (portFormat.nIndex = 0;; ++portFormat.nIndex) { 4609 err = omx->getParameter( 4610 node, OMX_IndexParamVideoPortFormat, 4611 &portFormat, sizeof(portFormat)); 4612 if (err != OK) { 4613 break; 4614 } 4615 caps->mColorFormats.push(portFormat.eColorFormat); 4616 } 4617 4618 CHECK_EQ(omx->freeNode(node), (status_t)OK); 4619 4620 return OK; 4621 } 4622 4623 status_t QueryCodecs( 4624 const sp<IOMX> &omx, 4625 const char *mimeType, bool queryDecoders, 4626 Vector<CodecCapabilities> *results) { 4627 return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results); 4628 } 4629 4630 // These are supposed be equivalent to the logic in 4631 // "audio_channel_out_mask_from_count". 4632 status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 4633 switch (numChannels) { 4634 case 1: 4635 map[0] = OMX_AUDIO_ChannelCF; 4636 break; 4637 case 2: 4638 map[0] = OMX_AUDIO_ChannelLF; 4639 map[1] = OMX_AUDIO_ChannelRF; 4640 break; 4641 case 3: 4642 map[0] = OMX_AUDIO_ChannelLF; 4643 map[1] = OMX_AUDIO_ChannelRF; 4644 map[2] = OMX_AUDIO_ChannelCF; 4645 break; 4646 case 4: 4647 map[0] = OMX_AUDIO_ChannelLF; 4648 map[1] = OMX_AUDIO_ChannelRF; 4649 map[2] = OMX_AUDIO_ChannelLR; 4650 map[3] = OMX_AUDIO_ChannelRR; 4651 break; 4652 case 5: 4653 map[0] = OMX_AUDIO_ChannelLF; 4654 map[1] = OMX_AUDIO_ChannelRF; 4655 map[2] = OMX_AUDIO_ChannelCF; 4656 map[3] = OMX_AUDIO_ChannelLR; 4657 map[4] = OMX_AUDIO_ChannelRR; 4658 break; 4659 case 6: 4660 map[0] = OMX_AUDIO_ChannelLF; 4661 map[1] = OMX_AUDIO_ChannelRF; 4662 map[2] = OMX_AUDIO_ChannelCF; 4663 map[3] = OMX_AUDIO_ChannelLFE; 4664 map[4] = OMX_AUDIO_ChannelLR; 4665 map[5] = OMX_AUDIO_ChannelRR; 4666 break; 4667 case 7: 4668 map[0] = OMX_AUDIO_ChannelLF; 4669 map[1] = OMX_AUDIO_ChannelRF; 4670 map[2] = OMX_AUDIO_ChannelCF; 4671 map[3] = OMX_AUDIO_ChannelLFE; 4672 map[4] = OMX_AUDIO_ChannelLR; 4673 map[5] = OMX_AUDIO_ChannelRR; 4674 map[6] = OMX_AUDIO_ChannelCS; 4675 break; 4676 case 8: 4677 map[0] = OMX_AUDIO_ChannelLF; 4678 map[1] = OMX_AUDIO_ChannelRF; 4679 map[2] = OMX_AUDIO_ChannelCF; 4680 map[3] = OMX_AUDIO_ChannelLFE; 4681 map[4] = OMX_AUDIO_ChannelLR; 4682 map[5] = OMX_AUDIO_ChannelRR; 4683 map[6] = OMX_AUDIO_ChannelLS; 4684 map[7] = OMX_AUDIO_ChannelRS; 4685 break; 4686 default: 4687 return -EINVAL; 4688 } 4689 4690 return OK; 4691 } 4692 4693 } // namespace android 4694