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