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