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