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