OMXCodec.cpp revision f5ee327780ea2b538b8affafa8063f0ce0390fe0
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 minUndequeuedBufs++; 1784 1785 // Use conservative allocation while also trying to reduce starvation 1786 // 1787 // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 1788 // minimum needed for the consumer to be able to work 1789 // 2. try to allocate two (2) additional buffers to reduce starvation from 1790 // the consumer 1791 CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d", 1792 def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); 1793 1794 for (OMX_U32 extraBuffers = 2; /* condition inside loop */; extraBuffers--) { 1795 OMX_U32 newBufferCount = 1796 def.nBufferCountMin + minUndequeuedBufs + extraBuffers; 1797 def.nBufferCountActual = newBufferCount; 1798 err = mOMX->setParameter( 1799 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1800 1801 if (err == OK) { 1802 minUndequeuedBufs += extraBuffers; 1803 break; 1804 } 1805 1806 CODEC_LOGW("setting nBufferCountActual to %lu failed: %d", 1807 newBufferCount, err); 1808 /* exit condition */ 1809 if (extraBuffers == 0) { 1810 return err; 1811 } 1812 } 1813 CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d", 1814 def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); 1815 1816 err = native_window_set_buffer_count( 1817 mNativeWindow.get(), def.nBufferCountActual); 1818 if (err != 0) { 1819 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1820 -err); 1821 return err; 1822 } 1823 1824 CODEC_LOGV("allocating %lu buffers from a native window of size %lu on " 1825 "output port", def.nBufferCountActual, def.nBufferSize); 1826 1827 // Dequeue buffers and send them to OMX 1828 for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { 1829 ANativeWindowBuffer* buf; 1830 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 1831 if (err != 0) { 1832 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1833 break; 1834 } 1835 1836 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1837 BufferInfo info; 1838 info.mData = NULL; 1839 info.mSize = def.nBufferSize; 1840 info.mStatus = OWNED_BY_US; 1841 info.mMem = NULL; 1842 info.mMediaBuffer = new MediaBuffer(graphicBuffer); 1843 info.mMediaBuffer->setObserver(this); 1844 mPortBuffers[kPortIndexOutput].push(info); 1845 1846 IOMX::buffer_id bufferId; 1847 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 1848 &bufferId); 1849 if (err != 0) { 1850 CODEC_LOGE("registering GraphicBuffer with OMX IL component " 1851 "failed: %d", err); 1852 break; 1853 } 1854 1855 mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId; 1856 1857 CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)", 1858 bufferId, graphicBuffer.get()); 1859 } 1860 1861 OMX_U32 cancelStart; 1862 OMX_U32 cancelEnd; 1863 if (err != 0) { 1864 // If an error occurred while dequeuing we need to cancel any buffers 1865 // that were dequeued. 1866 cancelStart = 0; 1867 cancelEnd = mPortBuffers[kPortIndexOutput].size(); 1868 } else { 1869 // Return the last two buffers to the native window. 1870 cancelStart = def.nBufferCountActual - minUndequeuedBufs; 1871 cancelEnd = def.nBufferCountActual; 1872 } 1873 1874 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1875 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i); 1876 cancelBufferToNativeWindow(info); 1877 } 1878 1879 return err; 1880} 1881 1882status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) { 1883 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 1884 CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer); 1885 int err = mNativeWindow->cancelBuffer( 1886 mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1); 1887 if (err != 0) { 1888 CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err); 1889 1890 setState(ERROR); 1891 return err; 1892 } 1893 info->mStatus = OWNED_BY_NATIVE_WINDOW; 1894 return OK; 1895} 1896 1897OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() { 1898 // Dequeue the next buffer from the native window. 1899 ANativeWindowBuffer* buf; 1900 int fenceFd = -1; 1901 int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 1902 if (err != 0) { 1903 CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err); 1904 1905 setState(ERROR); 1906 return 0; 1907 } 1908 1909 // Determine which buffer we just dequeued. 1910 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1911 BufferInfo *bufInfo = 0; 1912 for (size_t i = 0; i < buffers->size(); i++) { 1913 sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i). 1914 mMediaBuffer->graphicBuffer(); 1915 if (graphicBuffer->handle == buf->handle) { 1916 bufInfo = &buffers->editItemAt(i); 1917 break; 1918 } 1919 } 1920 1921 if (bufInfo == 0) { 1922 CODEC_LOGE("dequeued unrecognized buffer: %p", buf); 1923 1924 setState(ERROR); 1925 return 0; 1926 } 1927 1928 // The native window no longer owns the buffer. 1929 CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW); 1930 bufInfo->mStatus = OWNED_BY_US; 1931 1932 return bufInfo; 1933} 1934 1935status_t OMXCodec::pushBlankBuffersToNativeWindow() { 1936 status_t err = NO_ERROR; 1937 ANativeWindowBuffer* anb = NULL; 1938 int numBufs = 0; 1939 int minUndequeuedBufs = 0; 1940 1941 // We need to reconnect to the ANativeWindow as a CPU client to ensure that 1942 // no frames get dropped by SurfaceFlinger assuming that these are video 1943 // frames. 1944 err = native_window_api_disconnect(mNativeWindow.get(), 1945 NATIVE_WINDOW_API_MEDIA); 1946 if (err != NO_ERROR) { 1947 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 1948 strerror(-err), -err); 1949 return err; 1950 } 1951 1952 err = native_window_api_connect(mNativeWindow.get(), 1953 NATIVE_WINDOW_API_CPU); 1954 if (err != NO_ERROR) { 1955 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 1956 strerror(-err), -err); 1957 return err; 1958 } 1959 1960 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1, 1961 HAL_PIXEL_FORMAT_RGBX_8888); 1962 if (err != NO_ERROR) { 1963 ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)", 1964 strerror(-err), -err); 1965 goto error; 1966 } 1967 1968 err = native_window_set_usage(mNativeWindow.get(), 1969 GRALLOC_USAGE_SW_WRITE_OFTEN); 1970 if (err != NO_ERROR) { 1971 ALOGE("error pushing blank frames: set_usage failed: %s (%d)", 1972 strerror(-err), -err); 1973 goto error; 1974 } 1975 1976 err = native_window_set_scaling_mode(mNativeWindow.get(), 1977 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 1978 if (err != OK) { 1979 ALOGE("error pushing blank frames: set_scaling_mode failed: %s (%d)", 1980 strerror(-err), -err); 1981 goto error; 1982 } 1983 1984 err = mNativeWindow->query(mNativeWindow.get(), 1985 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 1986 if (err != NO_ERROR) { 1987 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 1988 "failed: %s (%d)", strerror(-err), -err); 1989 goto error; 1990 } 1991 1992 numBufs = minUndequeuedBufs + 1; 1993 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs); 1994 if (err != NO_ERROR) { 1995 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", 1996 strerror(-err), -err); 1997 goto error; 1998 } 1999 2000 // We push numBufs + 1 buffers to ensure that we've drawn into the same 2001 // buffer twice. This should guarantee that the buffer has been displayed 2002 // on the screen and then been replaced, so an previous video frames are 2003 // guaranteed NOT to be currently displayed. 2004 for (int i = 0; i < numBufs + 1; i++) { 2005 int fenceFd = -1; 2006 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb); 2007 if (err != NO_ERROR) { 2008 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 2009 strerror(-err), -err); 2010 goto error; 2011 } 2012 2013 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 2014 2015 // Fill the buffer with the a 1x1 checkerboard pattern ;) 2016 uint32_t* img = NULL; 2017 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 2018 if (err != NO_ERROR) { 2019 ALOGE("error pushing blank frames: lock failed: %s (%d)", 2020 strerror(-err), -err); 2021 goto error; 2022 } 2023 2024 *img = 0; 2025 2026 err = buf->unlock(); 2027 if (err != NO_ERROR) { 2028 ALOGE("error pushing blank frames: unlock failed: %s (%d)", 2029 strerror(-err), -err); 2030 goto error; 2031 } 2032 2033 err = mNativeWindow->queueBuffer(mNativeWindow.get(), 2034 buf->getNativeBuffer(), -1); 2035 if (err != NO_ERROR) { 2036 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", 2037 strerror(-err), -err); 2038 goto error; 2039 } 2040 2041 anb = NULL; 2042 } 2043 2044error: 2045 2046 if (err != NO_ERROR) { 2047 // Clean up after an error. 2048 if (anb != NULL) { 2049 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1); 2050 } 2051 2052 native_window_api_disconnect(mNativeWindow.get(), 2053 NATIVE_WINDOW_API_CPU); 2054 native_window_api_connect(mNativeWindow.get(), 2055 NATIVE_WINDOW_API_MEDIA); 2056 2057 return err; 2058 } else { 2059 // Clean up after success. 2060 err = native_window_api_disconnect(mNativeWindow.get(), 2061 NATIVE_WINDOW_API_CPU); 2062 if (err != NO_ERROR) { 2063 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2064 strerror(-err), -err); 2065 return err; 2066 } 2067 2068 err = native_window_api_connect(mNativeWindow.get(), 2069 NATIVE_WINDOW_API_MEDIA); 2070 if (err != NO_ERROR) { 2071 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 2072 strerror(-err), -err); 2073 return err; 2074 } 2075 2076 return NO_ERROR; 2077 } 2078} 2079 2080int64_t OMXCodec::getDecodingTimeUs() { 2081 CHECK(mIsEncoder && mIsVideo); 2082 2083 if (mDecodingTimeList.empty()) { 2084 CHECK(mSignalledEOS || mNoMoreOutputData); 2085 // No corresponding input frame available. 2086 // This could happen when EOS is reached. 2087 return 0; 2088 } 2089 2090 List<int64_t>::iterator it = mDecodingTimeList.begin(); 2091 int64_t timeUs = *it; 2092 mDecodingTimeList.erase(it); 2093 return timeUs; 2094} 2095 2096void OMXCodec::on_message(const omx_message &msg) { 2097 if (mState == ERROR) { 2098 /* 2099 * only drop EVENT messages, EBD and FBD are still 2100 * processed for bookkeeping purposes 2101 */ 2102 if (msg.type == omx_message::EVENT) { 2103 ALOGW("Dropping OMX EVENT message - we're in ERROR state."); 2104 return; 2105 } 2106 } 2107 2108 switch (msg.type) { 2109 case omx_message::EVENT: 2110 { 2111 onEvent( 2112 msg.u.event_data.event, msg.u.event_data.data1, 2113 msg.u.event_data.data2); 2114 2115 break; 2116 } 2117 2118 case omx_message::EMPTY_BUFFER_DONE: 2119 { 2120 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2121 2122 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 2123 2124 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2125 size_t i = 0; 2126 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2127 ++i; 2128 } 2129 2130 CHECK(i < buffers->size()); 2131 if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) { 2132 ALOGW("We already own input buffer %p, yet received " 2133 "an EMPTY_BUFFER_DONE.", buffer); 2134 } 2135 2136 BufferInfo* info = &buffers->editItemAt(i); 2137 info->mStatus = OWNED_BY_US; 2138 2139 // Buffer could not be released until empty buffer done is called. 2140 if (info->mMediaBuffer != NULL) { 2141 info->mMediaBuffer->release(); 2142 info->mMediaBuffer = NULL; 2143 } 2144 2145 if (mPortStatus[kPortIndexInput] == DISABLING) { 2146 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2147 2148 status_t err = freeBuffer(kPortIndexInput, i); 2149 CHECK_EQ(err, (status_t)OK); 2150 } else if (mState != ERROR 2151 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 2152 CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED); 2153 2154 if (mFlags & kUseSecureInputBuffers) { 2155 drainAnyInputBuffer(); 2156 } else { 2157 drainInputBuffer(&buffers->editItemAt(i)); 2158 } 2159 } 2160 break; 2161 } 2162 2163 case omx_message::FILL_BUFFER_DONE: 2164 { 2165 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2166 OMX_U32 flags = msg.u.extended_buffer_data.flags; 2167 2168 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 2169 buffer, 2170 msg.u.extended_buffer_data.range_length, 2171 flags, 2172 msg.u.extended_buffer_data.timestamp, 2173 msg.u.extended_buffer_data.timestamp / 1E6); 2174 2175 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2176 size_t i = 0; 2177 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2178 ++i; 2179 } 2180 2181 CHECK(i < buffers->size()); 2182 BufferInfo *info = &buffers->editItemAt(i); 2183 2184 if (info->mStatus != OWNED_BY_COMPONENT) { 2185 ALOGW("We already own output buffer %p, yet received " 2186 "a FILL_BUFFER_DONE.", buffer); 2187 } 2188 2189 info->mStatus = OWNED_BY_US; 2190 2191 if (mPortStatus[kPortIndexOutput] == DISABLING) { 2192 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2193 2194 status_t err = freeBuffer(kPortIndexOutput, i); 2195 CHECK_EQ(err, (status_t)OK); 2196 2197#if 0 2198 } else if (mPortStatus[kPortIndexOutput] == ENABLED 2199 && (flags & OMX_BUFFERFLAG_EOS)) { 2200 CODEC_LOGV("No more output data."); 2201 mNoMoreOutputData = true; 2202 mBufferFilled.signal(); 2203#endif 2204 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 2205 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 2206 2207 if (info->mMediaBuffer == NULL) { 2208 CHECK(mOMXLivesLocally); 2209 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 2210 CHECK(mQuirks & kDefersOutputBufferAllocation); 2211 2212 // The qcom video decoders on Nexus don't actually allocate 2213 // output buffer memory on a call to OMX_AllocateBuffer 2214 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 2215 // structure is only filled in later. 2216 2217 info->mMediaBuffer = new MediaBuffer( 2218 msg.u.extended_buffer_data.data_ptr, 2219 info->mSize); 2220 info->mMediaBuffer->setObserver(this); 2221 } 2222 2223 MediaBuffer *buffer = info->mMediaBuffer; 2224 bool isGraphicBuffer = buffer->graphicBuffer() != NULL; 2225 2226 if (!isGraphicBuffer 2227 && msg.u.extended_buffer_data.range_offset 2228 + msg.u.extended_buffer_data.range_length 2229 > buffer->size()) { 2230 CODEC_LOGE( 2231 "Codec lied about its buffer size requirements, " 2232 "sending a buffer larger than the originally " 2233 "advertised size in FILL_BUFFER_DONE!"); 2234 } 2235 buffer->set_range( 2236 msg.u.extended_buffer_data.range_offset, 2237 msg.u.extended_buffer_data.range_length); 2238 2239 buffer->meta_data()->clear(); 2240 2241 buffer->meta_data()->setInt64( 2242 kKeyTime, msg.u.extended_buffer_data.timestamp); 2243 2244 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 2245 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 2246 } 2247 bool isCodecSpecific = false; 2248 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 2249 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 2250 isCodecSpecific = true; 2251 } 2252 2253 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) { 2254 buffer->meta_data()->setInt32(kKeyIsUnreadable, true); 2255 } 2256 2257 buffer->meta_data()->setPointer( 2258 kKeyPlatformPrivate, 2259 msg.u.extended_buffer_data.platform_private); 2260 2261 buffer->meta_data()->setPointer( 2262 kKeyBufferID, 2263 msg.u.extended_buffer_data.buffer); 2264 2265 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 2266 CODEC_LOGV("No more output data."); 2267 mNoMoreOutputData = true; 2268 } 2269 2270 if (mIsEncoder && mIsVideo) { 2271 int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs(); 2272 buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 2273 } 2274 2275 if (mTargetTimeUs >= 0) { 2276 CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs); 2277 2278 if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) { 2279 CODEC_LOGV( 2280 "skipping output buffer at timestamp %lld us", 2281 msg.u.extended_buffer_data.timestamp); 2282 2283 fillOutputBuffer(info); 2284 break; 2285 } 2286 2287 CODEC_LOGV( 2288 "returning output buffer at target timestamp " 2289 "%lld us", 2290 msg.u.extended_buffer_data.timestamp); 2291 2292 mTargetTimeUs = -1; 2293 } 2294 2295 mFilledBuffers.push_back(i); 2296 mBufferFilled.signal(); 2297 if (mIsEncoder) { 2298 sched_yield(); 2299 } 2300 } 2301 2302 break; 2303 } 2304 2305 default: 2306 { 2307 CHECK(!"should not be here."); 2308 break; 2309 } 2310 } 2311} 2312 2313// Has the format changed in any way that the client would have to be aware of? 2314static bool formatHasNotablyChanged( 2315 const sp<MetaData> &from, const sp<MetaData> &to) { 2316 if (from.get() == NULL && to.get() == NULL) { 2317 return false; 2318 } 2319 2320 if ((from.get() == NULL && to.get() != NULL) 2321 || (from.get() != NULL && to.get() == NULL)) { 2322 return true; 2323 } 2324 2325 const char *mime_from, *mime_to; 2326 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 2327 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 2328 2329 if (strcasecmp(mime_from, mime_to)) { 2330 return true; 2331 } 2332 2333 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 2334 int32_t colorFormat_from, colorFormat_to; 2335 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 2336 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 2337 2338 if (colorFormat_from != colorFormat_to) { 2339 return true; 2340 } 2341 2342 int32_t width_from, width_to; 2343 CHECK(from->findInt32(kKeyWidth, &width_from)); 2344 CHECK(to->findInt32(kKeyWidth, &width_to)); 2345 2346 if (width_from != width_to) { 2347 return true; 2348 } 2349 2350 int32_t height_from, height_to; 2351 CHECK(from->findInt32(kKeyHeight, &height_from)); 2352 CHECK(to->findInt32(kKeyHeight, &height_to)); 2353 2354 if (height_from != height_to) { 2355 return true; 2356 } 2357 2358 int32_t left_from, top_from, right_from, bottom_from; 2359 CHECK(from->findRect( 2360 kKeyCropRect, 2361 &left_from, &top_from, &right_from, &bottom_from)); 2362 2363 int32_t left_to, top_to, right_to, bottom_to; 2364 CHECK(to->findRect( 2365 kKeyCropRect, 2366 &left_to, &top_to, &right_to, &bottom_to)); 2367 2368 if (left_to != left_from || top_to != top_from 2369 || right_to != right_from || bottom_to != bottom_from) { 2370 return true; 2371 } 2372 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 2373 int32_t numChannels_from, numChannels_to; 2374 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 2375 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 2376 2377 if (numChannels_from != numChannels_to) { 2378 return true; 2379 } 2380 2381 int32_t sampleRate_from, sampleRate_to; 2382 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 2383 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 2384 2385 if (sampleRate_from != sampleRate_to) { 2386 return true; 2387 } 2388 } 2389 2390 return false; 2391} 2392 2393void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2394 switch (event) { 2395 case OMX_EventCmdComplete: 2396 { 2397 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 2398 break; 2399 } 2400 2401 case OMX_EventError: 2402 { 2403 CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); 2404 2405 setState(ERROR); 2406 break; 2407 } 2408 2409 case OMX_EventPortSettingsChanged: 2410 { 2411 CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", 2412 data1, data2); 2413 2414 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 2415 // There is no need to check whether mFilledBuffers is empty or not 2416 // when the OMX_EventPortSettingsChanged is not meant for reallocating 2417 // the output buffers. 2418 if (data1 == kPortIndexOutput) { 2419 CHECK(mFilledBuffers.empty()); 2420 } 2421 onPortSettingsChanged(data1); 2422 } else if (data1 == kPortIndexOutput && 2423 (data2 == OMX_IndexConfigCommonOutputCrop || 2424 data2 == OMX_IndexConfigCommonScale)) { 2425 2426 sp<MetaData> oldOutputFormat = mOutputFormat; 2427 initOutputFormat(mSource->getFormat()); 2428 2429 if (data2 == OMX_IndexConfigCommonOutputCrop && 2430 formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) { 2431 mOutputPortSettingsHaveChanged = true; 2432 2433 } else if (data2 == OMX_IndexConfigCommonScale) { 2434 OMX_CONFIG_SCALEFACTORTYPE scale; 2435 InitOMXParams(&scale); 2436 scale.nPortIndex = kPortIndexOutput; 2437 2438 // Change display dimension only when necessary. 2439 if (OK == mOMX->getConfig( 2440 mNode, 2441 OMX_IndexConfigCommonScale, 2442 &scale, sizeof(scale))) { 2443 int32_t left, top, right, bottom; 2444 CHECK(mOutputFormat->findRect(kKeyCropRect, 2445 &left, &top, 2446 &right, &bottom)); 2447 2448 // The scale is in 16.16 format. 2449 // scale 1.0 = 0x010000. When there is no 2450 // need to change the display, skip it. 2451 ALOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx", 2452 scale.xWidth, scale.xHeight); 2453 2454 if (scale.xWidth != 0x010000) { 2455 mOutputFormat->setInt32(kKeyDisplayWidth, 2456 ((right - left + 1) * scale.xWidth) >> 16); 2457 mOutputPortSettingsHaveChanged = true; 2458 } 2459 2460 if (scale.xHeight != 0x010000) { 2461 mOutputFormat->setInt32(kKeyDisplayHeight, 2462 ((bottom - top + 1) * scale.xHeight) >> 16); 2463 mOutputPortSettingsHaveChanged = true; 2464 } 2465 } 2466 } 2467 } 2468 break; 2469 } 2470 2471#if 0 2472 case OMX_EventBufferFlag: 2473 { 2474 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 2475 2476 if (data1 == kPortIndexOutput) { 2477 mNoMoreOutputData = true; 2478 } 2479 break; 2480 } 2481#endif 2482 2483 default: 2484 { 2485 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 2486 break; 2487 } 2488 } 2489} 2490 2491void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 2492 switch (cmd) { 2493 case OMX_CommandStateSet: 2494 { 2495 onStateChange((OMX_STATETYPE)data); 2496 break; 2497 } 2498 2499 case OMX_CommandPortDisable: 2500 { 2501 OMX_U32 portIndex = data; 2502 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 2503 2504 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2505 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING); 2506 CHECK_EQ(mPortBuffers[portIndex].size(), 0u); 2507 2508 mPortStatus[portIndex] = DISABLED; 2509 2510 if (mState == RECONFIGURING) { 2511 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2512 2513 sp<MetaData> oldOutputFormat = mOutputFormat; 2514 initOutputFormat(mSource->getFormat()); 2515 2516 // Don't notify clients if the output port settings change 2517 // wasn't of importance to them, i.e. it may be that just the 2518 // number of buffers has changed and nothing else. 2519 bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 2520 if (!mOutputPortSettingsHaveChanged) { 2521 mOutputPortSettingsHaveChanged = formatChanged; 2522 } 2523 2524 status_t err = enablePortAsync(portIndex); 2525 if (err != OK) { 2526 CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err); 2527 setState(ERROR); 2528 } else { 2529 err = allocateBuffersOnPort(portIndex); 2530 if (err != OK) { 2531 CODEC_LOGE("allocateBuffersOnPort (%s) failed " 2532 "(err = %d)", 2533 portIndex == kPortIndexInput 2534 ? "input" : "output", 2535 err); 2536 2537 setState(ERROR); 2538 } 2539 } 2540 } 2541 break; 2542 } 2543 2544 case OMX_CommandPortEnable: 2545 { 2546 OMX_U32 portIndex = data; 2547 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 2548 2549 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2550 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING); 2551 2552 mPortStatus[portIndex] = ENABLED; 2553 2554 if (mState == RECONFIGURING) { 2555 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2556 2557 setState(EXECUTING); 2558 2559 fillOutputBuffers(); 2560 } 2561 break; 2562 } 2563 2564 case OMX_CommandFlush: 2565 { 2566 OMX_U32 portIndex = data; 2567 2568 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 2569 2570 CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN); 2571 mPortStatus[portIndex] = ENABLED; 2572 2573 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 2574 mPortBuffers[portIndex].size()); 2575 2576 if (mSkipCutBuffer != NULL && mPortStatus[kPortIndexOutput] == ENABLED) { 2577 mSkipCutBuffer->clear(); 2578 } 2579 2580 if (mState == RECONFIGURING) { 2581 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2582 2583 disablePortAsync(portIndex); 2584 } else if (mState == EXECUTING_TO_IDLE) { 2585 if (mPortStatus[kPortIndexInput] == ENABLED 2586 && mPortStatus[kPortIndexOutput] == ENABLED) { 2587 CODEC_LOGV("Finished flushing both ports, now completing " 2588 "transition from EXECUTING to IDLE."); 2589 2590 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2591 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2592 2593 status_t err = 2594 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2595 CHECK_EQ(err, (status_t)OK); 2596 } 2597 } else { 2598 // We're flushing both ports in preparation for seeking. 2599 2600 if (mPortStatus[kPortIndexInput] == ENABLED 2601 && mPortStatus[kPortIndexOutput] == ENABLED) { 2602 CODEC_LOGV("Finished flushing both ports, now continuing from" 2603 " seek-time."); 2604 2605 // We implicitly resume pulling on our upstream source. 2606 mPaused = false; 2607 2608 drainInputBuffers(); 2609 fillOutputBuffers(); 2610 } 2611 2612 if (mOutputPortSettingsChangedPending) { 2613 CODEC_LOGV( 2614 "Honoring deferred output port settings change."); 2615 2616 mOutputPortSettingsChangedPending = false; 2617 onPortSettingsChanged(kPortIndexOutput); 2618 } 2619 } 2620 2621 break; 2622 } 2623 2624 default: 2625 { 2626 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 2627 break; 2628 } 2629 } 2630} 2631 2632void OMXCodec::onStateChange(OMX_STATETYPE newState) { 2633 CODEC_LOGV("onStateChange %d", newState); 2634 2635 switch (newState) { 2636 case OMX_StateIdle: 2637 { 2638 CODEC_LOGV("Now Idle."); 2639 if (mState == LOADED_TO_IDLE) { 2640 status_t err = mOMX->sendCommand( 2641 mNode, OMX_CommandStateSet, OMX_StateExecuting); 2642 2643 CHECK_EQ(err, (status_t)OK); 2644 2645 setState(IDLE_TO_EXECUTING); 2646 } else { 2647 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE); 2648 2649 if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) != 2650 mPortBuffers[kPortIndexInput].size()) { 2651 ALOGE("Codec did not return all input buffers " 2652 "(received %d / %d)", 2653 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 2654 mPortBuffers[kPortIndexInput].size()); 2655 TRESPASS(); 2656 } 2657 2658 if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) != 2659 mPortBuffers[kPortIndexOutput].size()) { 2660 ALOGE("Codec did not return all output buffers " 2661 "(received %d / %d)", 2662 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 2663 mPortBuffers[kPortIndexOutput].size()); 2664 TRESPASS(); 2665 } 2666 2667 status_t err = mOMX->sendCommand( 2668 mNode, OMX_CommandStateSet, OMX_StateLoaded); 2669 2670 CHECK_EQ(err, (status_t)OK); 2671 2672 err = freeBuffersOnPort(kPortIndexInput); 2673 CHECK_EQ(err, (status_t)OK); 2674 2675 err = freeBuffersOnPort(kPortIndexOutput); 2676 CHECK_EQ(err, (status_t)OK); 2677 2678 mPortStatus[kPortIndexInput] = ENABLED; 2679 mPortStatus[kPortIndexOutput] = ENABLED; 2680 2681 if ((mFlags & kEnableGrallocUsageProtected) && 2682 mNativeWindow != NULL) { 2683 // We push enough 1x1 blank buffers to ensure that one of 2684 // them has made it to the display. This allows the OMX 2685 // component teardown to zero out any protected buffers 2686 // without the risk of scanning out one of those buffers. 2687 pushBlankBuffersToNativeWindow(); 2688 } 2689 2690 setState(IDLE_TO_LOADED); 2691 } 2692 break; 2693 } 2694 2695 case OMX_StateExecuting: 2696 { 2697 CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING); 2698 2699 CODEC_LOGV("Now Executing."); 2700 2701 mOutputPortSettingsChangedPending = false; 2702 2703 setState(EXECUTING); 2704 2705 // Buffers will be submitted to the component in the first 2706 // call to OMXCodec::read as mInitialBufferSubmit is true at 2707 // this point. This ensures that this on_message call returns, 2708 // releases the lock and ::init can notice the state change and 2709 // itself return. 2710 break; 2711 } 2712 2713 case OMX_StateLoaded: 2714 { 2715 CHECK_EQ((int)mState, (int)IDLE_TO_LOADED); 2716 2717 CODEC_LOGV("Now Loaded."); 2718 2719 setState(LOADED); 2720 break; 2721 } 2722 2723 case OMX_StateInvalid: 2724 { 2725 setState(ERROR); 2726 break; 2727 } 2728 2729 default: 2730 { 2731 CHECK(!"should not be here."); 2732 break; 2733 } 2734 } 2735} 2736 2737// static 2738size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 2739 size_t n = 0; 2740 for (size_t i = 0; i < buffers.size(); ++i) { 2741 if (buffers[i].mStatus != OWNED_BY_COMPONENT) { 2742 ++n; 2743 } 2744 } 2745 2746 return n; 2747} 2748 2749status_t OMXCodec::freeBuffersOnPort( 2750 OMX_U32 portIndex, bool onlyThoseWeOwn) { 2751 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2752 2753 status_t stickyErr = OK; 2754 2755 for (size_t i = buffers->size(); i-- > 0;) { 2756 BufferInfo *info = &buffers->editItemAt(i); 2757 2758 if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) { 2759 continue; 2760 } 2761 2762 CHECK(info->mStatus == OWNED_BY_US 2763 || info->mStatus == OWNED_BY_NATIVE_WINDOW); 2764 2765 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 2766 2767 status_t err = freeBuffer(portIndex, i); 2768 2769 if (err != OK) { 2770 stickyErr = err; 2771 } 2772 2773 } 2774 2775 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 2776 2777 return stickyErr; 2778} 2779 2780status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { 2781 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2782 2783 BufferInfo *info = &buffers->editItemAt(bufIndex); 2784 2785 status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 2786 2787 if (err == OK && info->mMediaBuffer != NULL) { 2788 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2789 info->mMediaBuffer->setObserver(NULL); 2790 2791 // Make sure nobody but us owns this buffer at this point. 2792 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 2793 2794 // Cancel the buffer if it belongs to an ANativeWindow. 2795 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer(); 2796 if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) { 2797 err = cancelBufferToNativeWindow(info); 2798 } 2799 2800 info->mMediaBuffer->release(); 2801 info->mMediaBuffer = NULL; 2802 } 2803 2804 if (err == OK) { 2805 buffers->removeAt(bufIndex); 2806 } 2807 2808 return err; 2809} 2810 2811void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 2812 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 2813 2814 CHECK_EQ((int)mState, (int)EXECUTING); 2815 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2816 CHECK(!mOutputPortSettingsChangedPending); 2817 2818 if (mPortStatus[kPortIndexOutput] != ENABLED) { 2819 CODEC_LOGV("Deferring output port settings change."); 2820 mOutputPortSettingsChangedPending = true; 2821 return; 2822 } 2823 2824 setState(RECONFIGURING); 2825 2826 if (mQuirks & kNeedsFlushBeforeDisable) { 2827 if (!flushPortAsync(portIndex)) { 2828 onCmdComplete(OMX_CommandFlush, portIndex); 2829 } 2830 } else { 2831 disablePortAsync(portIndex); 2832 } 2833} 2834 2835bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 2836 CHECK(mState == EXECUTING || mState == RECONFIGURING 2837 || mState == EXECUTING_TO_IDLE); 2838 2839 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 2840 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 2841 mPortBuffers[portIndex].size()); 2842 2843 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2844 mPortStatus[portIndex] = SHUTTING_DOWN; 2845 2846 if ((mQuirks & kRequiresFlushCompleteEmulation) 2847 && countBuffersWeOwn(mPortBuffers[portIndex]) 2848 == mPortBuffers[portIndex].size()) { 2849 // No flush is necessary and this component fails to send a 2850 // flush-complete event in this case. 2851 2852 return false; 2853 } 2854 2855 status_t err = 2856 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 2857 CHECK_EQ(err, (status_t)OK); 2858 2859 return true; 2860} 2861 2862void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 2863 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2864 2865 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2866 mPortStatus[portIndex] = DISABLING; 2867 2868 CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex); 2869 status_t err = 2870 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 2871 CHECK_EQ(err, (status_t)OK); 2872 2873 freeBuffersOnPort(portIndex, true); 2874} 2875 2876status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) { 2877 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2878 2879 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED); 2880 mPortStatus[portIndex] = ENABLING; 2881 2882 CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex); 2883 return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 2884} 2885 2886void OMXCodec::fillOutputBuffers() { 2887 CHECK_EQ((int)mState, (int)EXECUTING); 2888 2889 // This is a workaround for some decoders not properly reporting 2890 // end-of-output-stream. If we own all input buffers and also own 2891 // all output buffers and we already signalled end-of-input-stream, 2892 // the end-of-output-stream is implied. 2893 if (mSignalledEOS 2894 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 2895 == mPortBuffers[kPortIndexInput].size() 2896 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 2897 == mPortBuffers[kPortIndexOutput].size()) { 2898 mNoMoreOutputData = true; 2899 mBufferFilled.signal(); 2900 2901 return; 2902 } 2903 2904 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2905 for (size_t i = 0; i < buffers->size(); ++i) { 2906 BufferInfo *info = &buffers->editItemAt(i); 2907 if (info->mStatus == OWNED_BY_US) { 2908 fillOutputBuffer(&buffers->editItemAt(i)); 2909 } 2910 } 2911} 2912 2913void OMXCodec::drainInputBuffers() { 2914 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2915 2916 if (mFlags & kUseSecureInputBuffers) { 2917 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2918 for (size_t i = 0; i < buffers->size(); ++i) { 2919 if (!drainAnyInputBuffer() 2920 || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) { 2921 break; 2922 } 2923 } 2924 } else { 2925 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2926 for (size_t i = 0; i < buffers->size(); ++i) { 2927 BufferInfo *info = &buffers->editItemAt(i); 2928 2929 if (info->mStatus != OWNED_BY_US) { 2930 continue; 2931 } 2932 2933 if (!drainInputBuffer(info)) { 2934 break; 2935 } 2936 2937 if (mFlags & kOnlySubmitOneInputBufferAtOneTime) { 2938 break; 2939 } 2940 } 2941 } 2942} 2943 2944bool OMXCodec::drainAnyInputBuffer() { 2945 return drainInputBuffer((BufferInfo *)NULL); 2946} 2947 2948OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) { 2949 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 2950 for (size_t i = 0; i < infos->size(); ++i) { 2951 BufferInfo *info = &infos->editItemAt(i); 2952 2953 if (info->mData == ptr) { 2954 CODEC_LOGV( 2955 "input buffer data ptr = %p, buffer_id = %p", 2956 ptr, 2957 info->mBuffer); 2958 2959 return info; 2960 } 2961 } 2962 2963 TRESPASS(); 2964} 2965 2966OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() { 2967 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 2968 for (size_t i = 0; i < infos->size(); ++i) { 2969 BufferInfo *info = &infos->editItemAt(i); 2970 2971 if (info->mStatus == OWNED_BY_US) { 2972 return info; 2973 } 2974 } 2975 2976 TRESPASS(); 2977} 2978 2979bool OMXCodec::drainInputBuffer(BufferInfo *info) { 2980 if (info != NULL) { 2981 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 2982 } 2983 2984 if (mSignalledEOS) { 2985 return false; 2986 } 2987 2988 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 2989 CHECK(!(mFlags & kUseSecureInputBuffers)); 2990 2991 const CodecSpecificData *specific = 2992 mCodecSpecificData[mCodecSpecificDataIndex]; 2993 2994 size_t size = specific->mSize; 2995 2996 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 2997 && !(mQuirks & kWantsNALFragments)) { 2998 static const uint8_t kNALStartCode[4] = 2999 { 0x00, 0x00, 0x00, 0x01 }; 3000 3001 CHECK(info->mSize >= specific->mSize + 4); 3002 3003 size += 4; 3004 3005 memcpy(info->mData, kNALStartCode, 4); 3006 memcpy((uint8_t *)info->mData + 4, 3007 specific->mData, specific->mSize); 3008 } else { 3009 CHECK(info->mSize >= specific->mSize); 3010 memcpy(info->mData, specific->mData, specific->mSize); 3011 } 3012 3013 mNoMoreOutputData = false; 3014 3015 CODEC_LOGV("calling emptyBuffer with codec specific data"); 3016 3017 status_t err = mOMX->emptyBuffer( 3018 mNode, info->mBuffer, 0, size, 3019 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 3020 0); 3021 CHECK_EQ(err, (status_t)OK); 3022 3023 info->mStatus = OWNED_BY_COMPONENT; 3024 3025 ++mCodecSpecificDataIndex; 3026 return true; 3027 } 3028 3029 if (mPaused) { 3030 return false; 3031 } 3032 3033 status_t err; 3034 3035 bool signalEOS = false; 3036 int64_t timestampUs = 0; 3037 3038 size_t offset = 0; 3039 int32_t n = 0; 3040 3041 3042 for (;;) { 3043 MediaBuffer *srcBuffer; 3044 if (mSeekTimeUs >= 0) { 3045 if (mLeftOverBuffer) { 3046 mLeftOverBuffer->release(); 3047 mLeftOverBuffer = NULL; 3048 } 3049 3050 MediaSource::ReadOptions options; 3051 options.setSeekTo(mSeekTimeUs, mSeekMode); 3052 3053 mSeekTimeUs = -1; 3054 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3055 mBufferFilled.signal(); 3056 3057 err = mSource->read(&srcBuffer, &options); 3058 3059 if (err == OK) { 3060 int64_t targetTimeUs; 3061 if (srcBuffer->meta_data()->findInt64( 3062 kKeyTargetTime, &targetTimeUs) 3063 && targetTimeUs >= 0) { 3064 CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs); 3065 mTargetTimeUs = targetTimeUs; 3066 } else { 3067 mTargetTimeUs = -1; 3068 } 3069 } 3070 } else if (mLeftOverBuffer) { 3071 srcBuffer = mLeftOverBuffer; 3072 mLeftOverBuffer = NULL; 3073 3074 err = OK; 3075 } else { 3076 err = mSource->read(&srcBuffer); 3077 } 3078 3079 if (err != OK) { 3080 signalEOS = true; 3081 mFinalStatus = err; 3082 mSignalledEOS = true; 3083 mBufferFilled.signal(); 3084 break; 3085 } 3086 3087 if (mFlags & kUseSecureInputBuffers) { 3088 info = findInputBufferByDataPointer(srcBuffer->data()); 3089 CHECK(info != NULL); 3090 } 3091 3092 size_t remainingBytes = info->mSize - offset; 3093 3094 if (srcBuffer->range_length() > remainingBytes) { 3095 if (offset == 0) { 3096 CODEC_LOGE( 3097 "Codec's input buffers are too small to accomodate " 3098 "buffer read from source (info->mSize = %d, srcLength = %d)", 3099 info->mSize, srcBuffer->range_length()); 3100 3101 srcBuffer->release(); 3102 srcBuffer = NULL; 3103 3104 setState(ERROR); 3105 return false; 3106 } 3107 3108 mLeftOverBuffer = srcBuffer; 3109 break; 3110 } 3111 3112 bool releaseBuffer = true; 3113 if (mFlags & kStoreMetaDataInVideoBuffers) { 3114 releaseBuffer = false; 3115 info->mMediaBuffer = srcBuffer; 3116 } 3117 3118 if (mFlags & kUseSecureInputBuffers) { 3119 // Data in "info" is already provided at this time. 3120 3121 releaseBuffer = false; 3122 3123 CHECK(info->mMediaBuffer == NULL); 3124 info->mMediaBuffer = srcBuffer; 3125 } else { 3126 CHECK(srcBuffer->data() != NULL) ; 3127 memcpy((uint8_t *)info->mData + offset, 3128 (const uint8_t *)srcBuffer->data() 3129 + srcBuffer->range_offset(), 3130 srcBuffer->range_length()); 3131 } 3132 3133 int64_t lastBufferTimeUs; 3134 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); 3135 CHECK(lastBufferTimeUs >= 0); 3136 if (mIsEncoder && mIsVideo) { 3137 mDecodingTimeList.push_back(lastBufferTimeUs); 3138 } 3139 3140 if (offset == 0) { 3141 timestampUs = lastBufferTimeUs; 3142 } 3143 3144 offset += srcBuffer->range_length(); 3145 3146 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) { 3147 CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer)); 3148 CHECK_GE(info->mSize, offset + sizeof(int32_t)); 3149 3150 int32_t numPageSamples; 3151 if (!srcBuffer->meta_data()->findInt32( 3152 kKeyValidSamples, &numPageSamples)) { 3153 numPageSamples = -1; 3154 } 3155 3156 memcpy((uint8_t *)info->mData + offset, 3157 &numPageSamples, 3158 sizeof(numPageSamples)); 3159 3160 offset += sizeof(numPageSamples); 3161 } 3162 3163 if (releaseBuffer) { 3164 srcBuffer->release(); 3165 srcBuffer = NULL; 3166 } 3167 3168 ++n; 3169 3170 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) { 3171 break; 3172 } 3173 3174 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs; 3175 3176 if (coalescedDurationUs > 250000ll) { 3177 // Don't coalesce more than 250ms worth of encoded data at once. 3178 break; 3179 } 3180 } 3181 3182 if (n > 1) { 3183 ALOGV("coalesced %d frames into one input buffer", n); 3184 } 3185 3186 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 3187 3188 if (signalEOS) { 3189 flags |= OMX_BUFFERFLAG_EOS; 3190 } else { 3191 mNoMoreOutputData = false; 3192 } 3193 3194 if (info == NULL) { 3195 CHECK(mFlags & kUseSecureInputBuffers); 3196 CHECK(signalEOS); 3197 3198 // This is fishy, there's still a MediaBuffer corresponding to this 3199 // info available to the source at this point even though we're going 3200 // to use it to signal EOS to the codec. 3201 info = findEmptyInputBuffer(); 3202 } 3203 3204 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 3205 "timestamp %lld us (%.2f secs)", 3206 info->mBuffer, offset, 3207 timestampUs, timestampUs / 1E6); 3208 3209 err = mOMX->emptyBuffer( 3210 mNode, info->mBuffer, 0, offset, 3211 flags, timestampUs); 3212 3213 if (err != OK) { 3214 setState(ERROR); 3215 return false; 3216 } 3217 3218 info->mStatus = OWNED_BY_COMPONENT; 3219 3220 return true; 3221} 3222 3223void OMXCodec::fillOutputBuffer(BufferInfo *info) { 3224 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3225 3226 if (mNoMoreOutputData) { 3227 CODEC_LOGV("There is no more output data available, not " 3228 "calling fillOutputBuffer"); 3229 return; 3230 } 3231 3232 CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer); 3233 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 3234 3235 if (err != OK) { 3236 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err); 3237 3238 setState(ERROR); 3239 return; 3240 } 3241 3242 info->mStatus = OWNED_BY_COMPONENT; 3243} 3244 3245bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 3246 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 3247 for (size_t i = 0; i < buffers->size(); ++i) { 3248 if ((*buffers)[i].mBuffer == buffer) { 3249 return drainInputBuffer(&buffers->editItemAt(i)); 3250 } 3251 } 3252 3253 CHECK(!"should not be here."); 3254 3255 return false; 3256} 3257 3258void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 3259 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3260 for (size_t i = 0; i < buffers->size(); ++i) { 3261 if ((*buffers)[i].mBuffer == buffer) { 3262 fillOutputBuffer(&buffers->editItemAt(i)); 3263 return; 3264 } 3265 } 3266 3267 CHECK(!"should not be here."); 3268} 3269 3270void OMXCodec::setState(State newState) { 3271 mState = newState; 3272 mAsyncCompletion.signal(); 3273 3274 // This may cause some spurious wakeups but is necessary to 3275 // unblock the reader if we enter ERROR state. 3276 mBufferFilled.signal(); 3277} 3278 3279status_t OMXCodec::waitForBufferFilled_l() { 3280 3281 if (mIsEncoder) { 3282 // For timelapse video recording, the timelapse video recording may 3283 // not send an input frame for a _long_ time. Do not use timeout 3284 // for video encoding. 3285 return mBufferFilled.wait(mLock); 3286 } 3287 status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs); 3288 if (err != OK) { 3289 CODEC_LOGE("Timed out waiting for output buffers: %d/%d", 3290 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 3291 countBuffersWeOwn(mPortBuffers[kPortIndexOutput])); 3292 } 3293 return err; 3294} 3295 3296void OMXCodec::setRawAudioFormat( 3297 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 3298 3299 // port definition 3300 OMX_PARAM_PORTDEFINITIONTYPE def; 3301 InitOMXParams(&def); 3302 def.nPortIndex = portIndex; 3303 status_t err = mOMX->getParameter( 3304 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3305 CHECK_EQ(err, (status_t)OK); 3306 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 3307 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3308 &def, sizeof(def)), (status_t)OK); 3309 3310 // pcm param 3311 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 3312 InitOMXParams(&pcmParams); 3313 pcmParams.nPortIndex = portIndex; 3314 3315 err = mOMX->getParameter( 3316 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3317 3318 CHECK_EQ(err, (status_t)OK); 3319 3320 pcmParams.nChannels = numChannels; 3321 pcmParams.eNumData = OMX_NumericalDataSigned; 3322 pcmParams.bInterleaved = OMX_TRUE; 3323 pcmParams.nBitPerSample = 16; 3324 pcmParams.nSamplingRate = sampleRate; 3325 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 3326 3327 CHECK_EQ(getOMXChannelMapping( 3328 numChannels, pcmParams.eChannelMapping), (status_t)OK); 3329 3330 err = mOMX->setParameter( 3331 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3332 3333 CHECK_EQ(err, (status_t)OK); 3334} 3335 3336static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) { 3337 if (isAMRWB) { 3338 if (bps <= 6600) { 3339 return OMX_AUDIO_AMRBandModeWB0; 3340 } else if (bps <= 8850) { 3341 return OMX_AUDIO_AMRBandModeWB1; 3342 } else if (bps <= 12650) { 3343 return OMX_AUDIO_AMRBandModeWB2; 3344 } else if (bps <= 14250) { 3345 return OMX_AUDIO_AMRBandModeWB3; 3346 } else if (bps <= 15850) { 3347 return OMX_AUDIO_AMRBandModeWB4; 3348 } else if (bps <= 18250) { 3349 return OMX_AUDIO_AMRBandModeWB5; 3350 } else if (bps <= 19850) { 3351 return OMX_AUDIO_AMRBandModeWB6; 3352 } else if (bps <= 23050) { 3353 return OMX_AUDIO_AMRBandModeWB7; 3354 } 3355 3356 // 23850 bps 3357 return OMX_AUDIO_AMRBandModeWB8; 3358 } else { // AMRNB 3359 if (bps <= 4750) { 3360 return OMX_AUDIO_AMRBandModeNB0; 3361 } else if (bps <= 5150) { 3362 return OMX_AUDIO_AMRBandModeNB1; 3363 } else if (bps <= 5900) { 3364 return OMX_AUDIO_AMRBandModeNB2; 3365 } else if (bps <= 6700) { 3366 return OMX_AUDIO_AMRBandModeNB3; 3367 } else if (bps <= 7400) { 3368 return OMX_AUDIO_AMRBandModeNB4; 3369 } else if (bps <= 7950) { 3370 return OMX_AUDIO_AMRBandModeNB5; 3371 } else if (bps <= 10200) { 3372 return OMX_AUDIO_AMRBandModeNB6; 3373 } 3374 3375 // 12200 bps 3376 return OMX_AUDIO_AMRBandModeNB7; 3377 } 3378} 3379 3380void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) { 3381 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 3382 3383 OMX_AUDIO_PARAM_AMRTYPE def; 3384 InitOMXParams(&def); 3385 def.nPortIndex = portIndex; 3386 3387 status_t err = 3388 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3389 3390 CHECK_EQ(err, (status_t)OK); 3391 3392 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 3393 3394 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate); 3395 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3396 CHECK_EQ(err, (status_t)OK); 3397 3398 //////////////////////// 3399 3400 if (mIsEncoder) { 3401 sp<MetaData> format = mSource->getFormat(); 3402 int32_t sampleRate; 3403 int32_t numChannels; 3404 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 3405 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 3406 3407 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3408 } 3409} 3410 3411status_t OMXCodec::setAACFormat( 3412 int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS) { 3413 if (numChannels > 2) { 3414 ALOGW("Number of channels: (%d) \n", numChannels); 3415 } 3416 3417 if (mIsEncoder) { 3418 if (isADTS) { 3419 return -EINVAL; 3420 } 3421 3422 //////////////// input port //////////////////// 3423 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3424 3425 //////////////// output port //////////////////// 3426 // format 3427 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 3428 InitOMXParams(&format); 3429 format.nPortIndex = kPortIndexOutput; 3430 format.nIndex = 0; 3431 status_t err = OMX_ErrorNone; 3432 while (OMX_ErrorNone == err) { 3433 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, 3434 &format, sizeof(format)), (status_t)OK); 3435 if (format.eEncoding == OMX_AUDIO_CodingAAC) { 3436 break; 3437 } 3438 format.nIndex++; 3439 } 3440 CHECK_EQ((status_t)OK, err); 3441 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, 3442 &format, sizeof(format)), (status_t)OK); 3443 3444 // port definition 3445 OMX_PARAM_PORTDEFINITIONTYPE def; 3446 InitOMXParams(&def); 3447 def.nPortIndex = kPortIndexOutput; 3448 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, 3449 &def, sizeof(def)), (status_t)OK); 3450 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 3451 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 3452 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3453 &def, sizeof(def)), (status_t)OK); 3454 3455 // profile 3456 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3457 InitOMXParams(&profile); 3458 profile.nPortIndex = kPortIndexOutput; 3459 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, 3460 &profile, sizeof(profile)), (status_t)OK); 3461 profile.nChannels = numChannels; 3462 profile.eChannelMode = (numChannels == 1? 3463 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); 3464 profile.nSampleRate = sampleRate; 3465 profile.nBitRate = bitRate; 3466 profile.nAudioBandWidth = 0; 3467 profile.nFrameLength = 0; 3468 profile.nAACtools = OMX_AUDIO_AACToolAll; 3469 profile.nAACERtools = OMX_AUDIO_AACERNone; 3470 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 3471 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 3472 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, 3473 &profile, sizeof(profile)); 3474 3475 if (err != OK) { 3476 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed " 3477 "(err = %d)", 3478 err); 3479 return err; 3480 } 3481 } else { 3482 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3483 InitOMXParams(&profile); 3484 profile.nPortIndex = kPortIndexInput; 3485 3486 status_t err = mOMX->getParameter( 3487 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3488 CHECK_EQ(err, (status_t)OK); 3489 3490 profile.nChannels = numChannels; 3491 profile.nSampleRate = sampleRate; 3492 3493 profile.eAACStreamFormat = 3494 isADTS 3495 ? OMX_AUDIO_AACStreamFormatMP4ADTS 3496 : OMX_AUDIO_AACStreamFormatMP4FF; 3497 3498 err = mOMX->setParameter( 3499 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3500 3501 if (err != OK) { 3502 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed " 3503 "(err = %d)", 3504 err); 3505 return err; 3506 } 3507 } 3508 3509 return OK; 3510} 3511 3512void OMXCodec::setG711Format(int32_t numChannels) { 3513 CHECK(!mIsEncoder); 3514 setRawAudioFormat(kPortIndexInput, 8000, numChannels); 3515} 3516 3517void OMXCodec::setImageOutputFormat( 3518 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 3519 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 3520 3521#if 0 3522 OMX_INDEXTYPE index; 3523 status_t err = mOMX->get_extension_index( 3524 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 3525 CHECK_EQ(err, (status_t)OK); 3526 3527 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 3528 CHECK_EQ(err, (status_t)OK); 3529#endif 3530 3531 OMX_PARAM_PORTDEFINITIONTYPE def; 3532 InitOMXParams(&def); 3533 def.nPortIndex = kPortIndexOutput; 3534 3535 status_t err = mOMX->getParameter( 3536 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3537 CHECK_EQ(err, (status_t)OK); 3538 3539 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3540 3541 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3542 3543 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused); 3544 imageDef->eColorFormat = format; 3545 imageDef->nFrameWidth = width; 3546 imageDef->nFrameHeight = height; 3547 3548 switch (format) { 3549 case OMX_COLOR_FormatYUV420PackedPlanar: 3550 case OMX_COLOR_FormatYUV411Planar: 3551 { 3552 def.nBufferSize = (width * height * 3) / 2; 3553 break; 3554 } 3555 3556 case OMX_COLOR_FormatCbYCrY: 3557 { 3558 def.nBufferSize = width * height * 2; 3559 break; 3560 } 3561 3562 case OMX_COLOR_Format32bitARGB8888: 3563 { 3564 def.nBufferSize = width * height * 4; 3565 break; 3566 } 3567 3568 case OMX_COLOR_Format16bitARGB4444: 3569 case OMX_COLOR_Format16bitARGB1555: 3570 case OMX_COLOR_Format16bitRGB565: 3571 case OMX_COLOR_Format16bitBGR565: 3572 { 3573 def.nBufferSize = width * height * 2; 3574 break; 3575 } 3576 3577 default: 3578 CHECK(!"Should not be here. Unknown color format."); 3579 break; 3580 } 3581 3582 def.nBufferCountActual = def.nBufferCountMin; 3583 3584 err = mOMX->setParameter( 3585 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3586 CHECK_EQ(err, (status_t)OK); 3587} 3588 3589void OMXCodec::setJPEGInputFormat( 3590 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 3591 OMX_PARAM_PORTDEFINITIONTYPE def; 3592 InitOMXParams(&def); 3593 def.nPortIndex = kPortIndexInput; 3594 3595 status_t err = mOMX->getParameter( 3596 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3597 CHECK_EQ(err, (status_t)OK); 3598 3599 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3600 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3601 3602 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG); 3603 imageDef->nFrameWidth = width; 3604 imageDef->nFrameHeight = height; 3605 3606 def.nBufferSize = compressedSize; 3607 def.nBufferCountActual = def.nBufferCountMin; 3608 3609 err = mOMX->setParameter( 3610 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3611 CHECK_EQ(err, (status_t)OK); 3612} 3613 3614void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 3615 CodecSpecificData *specific = 3616 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 3617 3618 specific->mSize = size; 3619 memcpy(specific->mData, data, size); 3620 3621 mCodecSpecificData.push(specific); 3622} 3623 3624void OMXCodec::clearCodecSpecificData() { 3625 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 3626 free(mCodecSpecificData.editItemAt(i)); 3627 } 3628 mCodecSpecificData.clear(); 3629 mCodecSpecificDataIndex = 0; 3630} 3631 3632status_t OMXCodec::start(MetaData *meta) { 3633 Mutex::Autolock autoLock(mLock); 3634 3635 if (mState != LOADED) { 3636 CODEC_LOGE("called start in the unexpected state: %d", mState); 3637 return UNKNOWN_ERROR; 3638 } 3639 3640 sp<MetaData> params = new MetaData; 3641 if (mQuirks & kWantsNALFragments) { 3642 params->setInt32(kKeyWantsNALFragments, true); 3643 } 3644 if (meta) { 3645 int64_t startTimeUs = 0; 3646 int64_t timeUs; 3647 if (meta->findInt64(kKeyTime, &timeUs)) { 3648 startTimeUs = timeUs; 3649 } 3650 params->setInt64(kKeyTime, startTimeUs); 3651 } 3652 3653 mCodecSpecificDataIndex = 0; 3654 mInitialBufferSubmit = true; 3655 mSignalledEOS = false; 3656 mNoMoreOutputData = false; 3657 mOutputPortSettingsHaveChanged = false; 3658 mSeekTimeUs = -1; 3659 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3660 mTargetTimeUs = -1; 3661 mFilledBuffers.clear(); 3662 mPaused = false; 3663 3664 status_t err; 3665 if (mIsEncoder) { 3666 // Calling init() before starting its source so that we can configure, 3667 // if supported, the source to use exactly the same number of input 3668 // buffers as requested by the encoder. 3669 if ((err = init()) != OK) { 3670 CODEC_LOGE("init failed: %d", err); 3671 return err; 3672 } 3673 3674 params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size()); 3675 err = mSource->start(params.get()); 3676 if (err != OK) { 3677 CODEC_LOGE("source failed to start: %d", err); 3678 stopOmxComponent_l(); 3679 } 3680 return err; 3681 } 3682 3683 // Decoder case 3684 if ((err = mSource->start(params.get())) != OK) { 3685 CODEC_LOGE("source failed to start: %d", err); 3686 return err; 3687 } 3688 return init(); 3689} 3690 3691status_t OMXCodec::stop() { 3692 CODEC_LOGV("stop mState=%d", mState); 3693 Mutex::Autolock autoLock(mLock); 3694 status_t err = stopOmxComponent_l(); 3695 mSource->stop(); 3696 3697 CODEC_LOGV("stopped in state %d", mState); 3698 return err; 3699} 3700 3701status_t OMXCodec::stopOmxComponent_l() { 3702 CODEC_LOGV("stopOmxComponent_l mState=%d", mState); 3703 3704 while (isIntermediateState(mState)) { 3705 mAsyncCompletion.wait(mLock); 3706 } 3707 3708 bool isError = false; 3709 switch (mState) { 3710 case LOADED: 3711 break; 3712 3713 case ERROR: 3714 { 3715 if (mPortStatus[kPortIndexOutput] == ENABLING) { 3716 // Codec is in a wedged state (technical term) 3717 // We've seen an output port settings change from the codec, 3718 // We've disabled the output port, then freed the output 3719 // buffers, initiated re-enabling the output port but 3720 // failed to reallocate the output buffers. 3721 // There doesn't seem to be a way to orderly transition 3722 // from executing->idle and idle->loaded now that the 3723 // output port hasn't been reenabled yet... 3724 // Simply free as many resources as we can and pretend 3725 // that we're in LOADED state so that the destructor 3726 // will free the component instance without asserting. 3727 freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */); 3728 freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */); 3729 setState(LOADED); 3730 break; 3731 } else { 3732 OMX_STATETYPE state = OMX_StateInvalid; 3733 status_t err = mOMX->getState(mNode, &state); 3734 CHECK_EQ(err, (status_t)OK); 3735 3736 if (state != OMX_StateExecuting) { 3737 break; 3738 } 3739 // else fall through to the idling code 3740 } 3741 3742 isError = true; 3743 } 3744 3745 case EXECUTING: 3746 { 3747 setState(EXECUTING_TO_IDLE); 3748 3749 if (mQuirks & kRequiresFlushBeforeShutdown) { 3750 CODEC_LOGV("This component requires a flush before transitioning " 3751 "from EXECUTING to IDLE..."); 3752 3753 bool emulateInputFlushCompletion = 3754 !flushPortAsync(kPortIndexInput); 3755 3756 bool emulateOutputFlushCompletion = 3757 !flushPortAsync(kPortIndexOutput); 3758 3759 if (emulateInputFlushCompletion) { 3760 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3761 } 3762 3763 if (emulateOutputFlushCompletion) { 3764 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3765 } 3766 } else { 3767 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 3768 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 3769 3770 status_t err = 3771 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 3772 CHECK_EQ(err, (status_t)OK); 3773 } 3774 3775 while (mState != LOADED && mState != ERROR) { 3776 mAsyncCompletion.wait(mLock); 3777 } 3778 3779 if (isError) { 3780 // We were in the ERROR state coming in, so restore that now 3781 // that we've idled the OMX component. 3782 setState(ERROR); 3783 } 3784 3785 break; 3786 } 3787 3788 default: 3789 { 3790 CHECK(!"should not be here."); 3791 break; 3792 } 3793 } 3794 3795 if (mLeftOverBuffer) { 3796 mLeftOverBuffer->release(); 3797 mLeftOverBuffer = NULL; 3798 } 3799 3800 return OK; 3801} 3802 3803sp<MetaData> OMXCodec::getFormat() { 3804 Mutex::Autolock autoLock(mLock); 3805 3806 return mOutputFormat; 3807} 3808 3809status_t OMXCodec::read( 3810 MediaBuffer **buffer, const ReadOptions *options) { 3811 status_t err = OK; 3812 *buffer = NULL; 3813 3814 Mutex::Autolock autoLock(mLock); 3815 3816 if (mState != EXECUTING && mState != RECONFIGURING) { 3817 return UNKNOWN_ERROR; 3818 } 3819 3820 bool seeking = false; 3821 int64_t seekTimeUs; 3822 ReadOptions::SeekMode seekMode; 3823 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 3824 seeking = true; 3825 } 3826 3827 if (mInitialBufferSubmit) { 3828 mInitialBufferSubmit = false; 3829 3830 if (seeking) { 3831 CHECK(seekTimeUs >= 0); 3832 mSeekTimeUs = seekTimeUs; 3833 mSeekMode = seekMode; 3834 3835 // There's no reason to trigger the code below, there's 3836 // nothing to flush yet. 3837 seeking = false; 3838 mPaused = false; 3839 } 3840 3841 drainInputBuffers(); 3842 3843 if (mState == EXECUTING) { 3844 // Otherwise mState == RECONFIGURING and this code will trigger 3845 // after the output port is reenabled. 3846 fillOutputBuffers(); 3847 } 3848 } 3849 3850 if (seeking) { 3851 while (mState == RECONFIGURING) { 3852 if ((err = waitForBufferFilled_l()) != OK) { 3853 return err; 3854 } 3855 } 3856 3857 if (mState != EXECUTING) { 3858 return UNKNOWN_ERROR; 3859 } 3860 3861 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 3862 3863 mSignalledEOS = false; 3864 3865 CHECK(seekTimeUs >= 0); 3866 mSeekTimeUs = seekTimeUs; 3867 mSeekMode = seekMode; 3868 3869 mFilledBuffers.clear(); 3870 3871 CHECK_EQ((int)mState, (int)EXECUTING); 3872 3873 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 3874 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 3875 3876 if (emulateInputFlushCompletion) { 3877 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3878 } 3879 3880 if (emulateOutputFlushCompletion) { 3881 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3882 } 3883 3884 while (mSeekTimeUs >= 0) { 3885 if ((err = waitForBufferFilled_l()) != OK) { 3886 return err; 3887 } 3888 } 3889 } 3890 3891 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 3892 if ((err = waitForBufferFilled_l()) != OK) { 3893 return err; 3894 } 3895 } 3896 3897 if (mState == ERROR) { 3898 return UNKNOWN_ERROR; 3899 } 3900 3901 if (mFilledBuffers.empty()) { 3902 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 3903 } 3904 3905 if (mOutputPortSettingsHaveChanged) { 3906 mOutputPortSettingsHaveChanged = false; 3907 3908 return INFO_FORMAT_CHANGED; 3909 } 3910 3911 size_t index = *mFilledBuffers.begin(); 3912 mFilledBuffers.erase(mFilledBuffers.begin()); 3913 3914 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 3915 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3916 info->mStatus = OWNED_BY_CLIENT; 3917 3918 info->mMediaBuffer->add_ref(); 3919 if (mSkipCutBuffer != NULL) { 3920 mSkipCutBuffer->submit(info->mMediaBuffer); 3921 } 3922 *buffer = info->mMediaBuffer; 3923 3924 return OK; 3925} 3926 3927void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 3928 Mutex::Autolock autoLock(mLock); 3929 3930 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3931 for (size_t i = 0; i < buffers->size(); ++i) { 3932 BufferInfo *info = &buffers->editItemAt(i); 3933 3934 if (info->mMediaBuffer == buffer) { 3935 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 3936 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT); 3937 3938 info->mStatus = OWNED_BY_US; 3939 3940 if (buffer->graphicBuffer() == 0) { 3941 fillOutputBuffer(info); 3942 } else { 3943 sp<MetaData> metaData = info->mMediaBuffer->meta_data(); 3944 int32_t rendered = 0; 3945 if (!metaData->findInt32(kKeyRendered, &rendered)) { 3946 rendered = 0; 3947 } 3948 if (!rendered) { 3949 status_t err = cancelBufferToNativeWindow(info); 3950 if (err < 0) { 3951 return; 3952 } 3953 } 3954 3955 info->mStatus = OWNED_BY_NATIVE_WINDOW; 3956 3957 // Dequeue the next buffer from the native window. 3958 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow(); 3959 if (nextBufInfo == 0) { 3960 return; 3961 } 3962 3963 // Give the buffer to the OMX node to fill. 3964 fillOutputBuffer(nextBufInfo); 3965 } 3966 return; 3967 } 3968 } 3969 3970 CHECK(!"should not be here."); 3971} 3972 3973static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 3974 static const char *kNames[] = { 3975 "OMX_IMAGE_CodingUnused", 3976 "OMX_IMAGE_CodingAutoDetect", 3977 "OMX_IMAGE_CodingJPEG", 3978 "OMX_IMAGE_CodingJPEG2K", 3979 "OMX_IMAGE_CodingEXIF", 3980 "OMX_IMAGE_CodingTIFF", 3981 "OMX_IMAGE_CodingGIF", 3982 "OMX_IMAGE_CodingPNG", 3983 "OMX_IMAGE_CodingLZW", 3984 "OMX_IMAGE_CodingBMP", 3985 }; 3986 3987 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 3988 3989 if (type < 0 || (size_t)type >= numNames) { 3990 return "UNKNOWN"; 3991 } else { 3992 return kNames[type]; 3993 } 3994} 3995 3996static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 3997 static const char *kNames[] = { 3998 "OMX_COLOR_FormatUnused", 3999 "OMX_COLOR_FormatMonochrome", 4000 "OMX_COLOR_Format8bitRGB332", 4001 "OMX_COLOR_Format12bitRGB444", 4002 "OMX_COLOR_Format16bitARGB4444", 4003 "OMX_COLOR_Format16bitARGB1555", 4004 "OMX_COLOR_Format16bitRGB565", 4005 "OMX_COLOR_Format16bitBGR565", 4006 "OMX_COLOR_Format18bitRGB666", 4007 "OMX_COLOR_Format18bitARGB1665", 4008 "OMX_COLOR_Format19bitARGB1666", 4009 "OMX_COLOR_Format24bitRGB888", 4010 "OMX_COLOR_Format24bitBGR888", 4011 "OMX_COLOR_Format24bitARGB1887", 4012 "OMX_COLOR_Format25bitARGB1888", 4013 "OMX_COLOR_Format32bitBGRA8888", 4014 "OMX_COLOR_Format32bitARGB8888", 4015 "OMX_COLOR_FormatYUV411Planar", 4016 "OMX_COLOR_FormatYUV411PackedPlanar", 4017 "OMX_COLOR_FormatYUV420Planar", 4018 "OMX_COLOR_FormatYUV420PackedPlanar", 4019 "OMX_COLOR_FormatYUV420SemiPlanar", 4020 "OMX_COLOR_FormatYUV422Planar", 4021 "OMX_COLOR_FormatYUV422PackedPlanar", 4022 "OMX_COLOR_FormatYUV422SemiPlanar", 4023 "OMX_COLOR_FormatYCbYCr", 4024 "OMX_COLOR_FormatYCrYCb", 4025 "OMX_COLOR_FormatCbYCrY", 4026 "OMX_COLOR_FormatCrYCbY", 4027 "OMX_COLOR_FormatYUV444Interleaved", 4028 "OMX_COLOR_FormatRawBayer8bit", 4029 "OMX_COLOR_FormatRawBayer10bit", 4030 "OMX_COLOR_FormatRawBayer8bitcompressed", 4031 "OMX_COLOR_FormatL2", 4032 "OMX_COLOR_FormatL4", 4033 "OMX_COLOR_FormatL8", 4034 "OMX_COLOR_FormatL16", 4035 "OMX_COLOR_FormatL24", 4036 "OMX_COLOR_FormatL32", 4037 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 4038 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 4039 "OMX_COLOR_Format18BitBGR666", 4040 "OMX_COLOR_Format24BitARGB6666", 4041 "OMX_COLOR_Format24BitABGR6666", 4042 }; 4043 4044 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4045 4046 if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 4047 return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; 4048 } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 4049 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 4050 } else if (type < 0 || (size_t)type >= numNames) { 4051 return "UNKNOWN"; 4052 } else { 4053 return kNames[type]; 4054 } 4055} 4056 4057static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 4058 static const char *kNames[] = { 4059 "OMX_VIDEO_CodingUnused", 4060 "OMX_VIDEO_CodingAutoDetect", 4061 "OMX_VIDEO_CodingMPEG2", 4062 "OMX_VIDEO_CodingH263", 4063 "OMX_VIDEO_CodingMPEG4", 4064 "OMX_VIDEO_CodingWMV", 4065 "OMX_VIDEO_CodingRV", 4066 "OMX_VIDEO_CodingAVC", 4067 "OMX_VIDEO_CodingMJPEG", 4068 }; 4069 4070 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4071 4072 if (type < 0 || (size_t)type >= numNames) { 4073 return "UNKNOWN"; 4074 } else { 4075 return kNames[type]; 4076 } 4077} 4078 4079static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 4080 static const char *kNames[] = { 4081 "OMX_AUDIO_CodingUnused", 4082 "OMX_AUDIO_CodingAutoDetect", 4083 "OMX_AUDIO_CodingPCM", 4084 "OMX_AUDIO_CodingADPCM", 4085 "OMX_AUDIO_CodingAMR", 4086 "OMX_AUDIO_CodingGSMFR", 4087 "OMX_AUDIO_CodingGSMEFR", 4088 "OMX_AUDIO_CodingGSMHR", 4089 "OMX_AUDIO_CodingPDCFR", 4090 "OMX_AUDIO_CodingPDCEFR", 4091 "OMX_AUDIO_CodingPDCHR", 4092 "OMX_AUDIO_CodingTDMAFR", 4093 "OMX_AUDIO_CodingTDMAEFR", 4094 "OMX_AUDIO_CodingQCELP8", 4095 "OMX_AUDIO_CodingQCELP13", 4096 "OMX_AUDIO_CodingEVRC", 4097 "OMX_AUDIO_CodingSMV", 4098 "OMX_AUDIO_CodingG711", 4099 "OMX_AUDIO_CodingG723", 4100 "OMX_AUDIO_CodingG726", 4101 "OMX_AUDIO_CodingG729", 4102 "OMX_AUDIO_CodingAAC", 4103 "OMX_AUDIO_CodingMP3", 4104 "OMX_AUDIO_CodingSBC", 4105 "OMX_AUDIO_CodingVORBIS", 4106 "OMX_AUDIO_CodingWMA", 4107 "OMX_AUDIO_CodingRA", 4108 "OMX_AUDIO_CodingMIDI", 4109 }; 4110 4111 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4112 4113 if (type < 0 || (size_t)type >= numNames) { 4114 return "UNKNOWN"; 4115 } else { 4116 return kNames[type]; 4117 } 4118} 4119 4120static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 4121 static const char *kNames[] = { 4122 "OMX_AUDIO_PCMModeLinear", 4123 "OMX_AUDIO_PCMModeALaw", 4124 "OMX_AUDIO_PCMModeMULaw", 4125 }; 4126 4127 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4128 4129 if (type < 0 || (size_t)type >= numNames) { 4130 return "UNKNOWN"; 4131 } else { 4132 return kNames[type]; 4133 } 4134} 4135 4136static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 4137 static const char *kNames[] = { 4138 "OMX_AUDIO_AMRBandModeUnused", 4139 "OMX_AUDIO_AMRBandModeNB0", 4140 "OMX_AUDIO_AMRBandModeNB1", 4141 "OMX_AUDIO_AMRBandModeNB2", 4142 "OMX_AUDIO_AMRBandModeNB3", 4143 "OMX_AUDIO_AMRBandModeNB4", 4144 "OMX_AUDIO_AMRBandModeNB5", 4145 "OMX_AUDIO_AMRBandModeNB6", 4146 "OMX_AUDIO_AMRBandModeNB7", 4147 "OMX_AUDIO_AMRBandModeWB0", 4148 "OMX_AUDIO_AMRBandModeWB1", 4149 "OMX_AUDIO_AMRBandModeWB2", 4150 "OMX_AUDIO_AMRBandModeWB3", 4151 "OMX_AUDIO_AMRBandModeWB4", 4152 "OMX_AUDIO_AMRBandModeWB5", 4153 "OMX_AUDIO_AMRBandModeWB6", 4154 "OMX_AUDIO_AMRBandModeWB7", 4155 "OMX_AUDIO_AMRBandModeWB8", 4156 }; 4157 4158 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4159 4160 if (type < 0 || (size_t)type >= numNames) { 4161 return "UNKNOWN"; 4162 } else { 4163 return kNames[type]; 4164 } 4165} 4166 4167static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 4168 static const char *kNames[] = { 4169 "OMX_AUDIO_AMRFrameFormatConformance", 4170 "OMX_AUDIO_AMRFrameFormatIF1", 4171 "OMX_AUDIO_AMRFrameFormatIF2", 4172 "OMX_AUDIO_AMRFrameFormatFSF", 4173 "OMX_AUDIO_AMRFrameFormatRTPPayload", 4174 "OMX_AUDIO_AMRFrameFormatITU", 4175 }; 4176 4177 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4178 4179 if (type < 0 || (size_t)type >= numNames) { 4180 return "UNKNOWN"; 4181 } else { 4182 return kNames[type]; 4183 } 4184} 4185 4186void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 4187 OMX_PARAM_PORTDEFINITIONTYPE def; 4188 InitOMXParams(&def); 4189 def.nPortIndex = portIndex; 4190 4191 status_t err = mOMX->getParameter( 4192 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4193 CHECK_EQ(err, (status_t)OK); 4194 4195 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 4196 4197 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 4198 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 4199 4200 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 4201 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 4202 printf(" nBufferSize = %ld\n", def.nBufferSize); 4203 4204 switch (def.eDomain) { 4205 case OMX_PortDomainImage: 4206 { 4207 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4208 4209 printf("\n"); 4210 printf(" // Image\n"); 4211 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 4212 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 4213 printf(" nStride = %ld\n", imageDef->nStride); 4214 4215 printf(" eCompressionFormat = %s\n", 4216 imageCompressionFormatString(imageDef->eCompressionFormat)); 4217 4218 printf(" eColorFormat = %s\n", 4219 colorFormatString(imageDef->eColorFormat)); 4220 4221 break; 4222 } 4223 4224 case OMX_PortDomainVideo: 4225 { 4226 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4227 4228 printf("\n"); 4229 printf(" // Video\n"); 4230 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 4231 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 4232 printf(" nStride = %ld\n", videoDef->nStride); 4233 4234 printf(" eCompressionFormat = %s\n", 4235 videoCompressionFormatString(videoDef->eCompressionFormat)); 4236 4237 printf(" eColorFormat = %s\n", 4238 colorFormatString(videoDef->eColorFormat)); 4239 4240 break; 4241 } 4242 4243 case OMX_PortDomainAudio: 4244 { 4245 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4246 4247 printf("\n"); 4248 printf(" // Audio\n"); 4249 printf(" eEncoding = %s\n", 4250 audioCodingTypeString(audioDef->eEncoding)); 4251 4252 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 4253 OMX_AUDIO_PARAM_PCMMODETYPE params; 4254 InitOMXParams(¶ms); 4255 params.nPortIndex = portIndex; 4256 4257 err = mOMX->getParameter( 4258 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4259 CHECK_EQ(err, (status_t)OK); 4260 4261 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 4262 printf(" nChannels = %ld\n", params.nChannels); 4263 printf(" bInterleaved = %d\n", params.bInterleaved); 4264 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 4265 4266 printf(" eNumData = %s\n", 4267 params.eNumData == OMX_NumericalDataSigned 4268 ? "signed" : "unsigned"); 4269 4270 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 4271 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 4272 OMX_AUDIO_PARAM_AMRTYPE amr; 4273 InitOMXParams(&amr); 4274 amr.nPortIndex = portIndex; 4275 4276 err = mOMX->getParameter( 4277 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4278 CHECK_EQ(err, (status_t)OK); 4279 4280 printf(" nChannels = %ld\n", amr.nChannels); 4281 printf(" eAMRBandMode = %s\n", 4282 amrBandModeString(amr.eAMRBandMode)); 4283 printf(" eAMRFrameFormat = %s\n", 4284 amrFrameFormatString(amr.eAMRFrameFormat)); 4285 } 4286 4287 break; 4288 } 4289 4290 default: 4291 { 4292 printf(" // Unknown\n"); 4293 break; 4294 } 4295 } 4296 4297 printf("}\n"); 4298} 4299 4300status_t OMXCodec::initNativeWindow() { 4301 // Enable use of a GraphicBuffer as the output for this node. This must 4302 // happen before getting the IndexParamPortDefinition parameter because it 4303 // will affect the pixel format that the node reports. 4304 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 4305 if (err != 0) { 4306 return err; 4307 } 4308 4309 return OK; 4310} 4311 4312void OMXCodec::initNativeWindowCrop() { 4313 int32_t left, top, right, bottom; 4314 4315 CHECK(mOutputFormat->findRect( 4316 kKeyCropRect, 4317 &left, &top, &right, &bottom)); 4318 4319 android_native_rect_t crop; 4320 crop.left = left; 4321 crop.top = top; 4322 crop.right = right + 1; 4323 crop.bottom = bottom + 1; 4324 4325 // We'll ignore any errors here, if the surface is 4326 // already invalid, we'll know soon enough. 4327 native_window_set_crop(mNativeWindow.get(), &crop); 4328} 4329 4330void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 4331 mOutputFormat = new MetaData; 4332 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 4333 if (mIsEncoder) { 4334 int32_t timeScale; 4335 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) { 4336 mOutputFormat->setInt32(kKeyTimeScale, timeScale); 4337 } 4338 } 4339 4340 OMX_PARAM_PORTDEFINITIONTYPE def; 4341 InitOMXParams(&def); 4342 def.nPortIndex = kPortIndexOutput; 4343 4344 status_t err = mOMX->getParameter( 4345 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4346 CHECK_EQ(err, (status_t)OK); 4347 4348 switch (def.eDomain) { 4349 case OMX_PortDomainImage: 4350 { 4351 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4352 CHECK_EQ((int)imageDef->eCompressionFormat, 4353 (int)OMX_IMAGE_CodingUnused); 4354 4355 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4356 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 4357 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 4358 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 4359 break; 4360 } 4361 4362 case OMX_PortDomainAudio: 4363 { 4364 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 4365 4366 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 4367 OMX_AUDIO_PARAM_PCMMODETYPE params; 4368 InitOMXParams(¶ms); 4369 params.nPortIndex = kPortIndexOutput; 4370 4371 err = mOMX->getParameter( 4372 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4373 CHECK_EQ(err, (status_t)OK); 4374 4375 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 4376 CHECK_EQ(params.nBitPerSample, 16u); 4377 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 4378 4379 int32_t numChannels, sampleRate; 4380 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4381 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4382 4383 if ((OMX_U32)numChannels != params.nChannels) { 4384 ALOGV("Codec outputs a different number of channels than " 4385 "the input stream contains (contains %d channels, " 4386 "codec outputs %ld channels).", 4387 numChannels, params.nChannels); 4388 } 4389 4390 if (sampleRate != (int32_t)params.nSamplingRate) { 4391 ALOGV("Codec outputs at different sampling rate than " 4392 "what the input stream contains (contains data at " 4393 "%d Hz, codec outputs %lu Hz)", 4394 sampleRate, params.nSamplingRate); 4395 } 4396 4397 mOutputFormat->setCString( 4398 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 4399 4400 // Use the codec-advertised number of channels, as some 4401 // codecs appear to output stereo even if the input data is 4402 // mono. If we know the codec lies about this information, 4403 // use the actual number of channels instead. 4404 mOutputFormat->setInt32( 4405 kKeyChannelCount, 4406 (mQuirks & kDecoderLiesAboutNumberOfChannels) 4407 ? numChannels : params.nChannels); 4408 4409 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate); 4410 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 4411 OMX_AUDIO_PARAM_AMRTYPE amr; 4412 InitOMXParams(&amr); 4413 amr.nPortIndex = kPortIndexOutput; 4414 4415 err = mOMX->getParameter( 4416 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4417 CHECK_EQ(err, (status_t)OK); 4418 4419 CHECK_EQ(amr.nChannels, 1u); 4420 mOutputFormat->setInt32(kKeyChannelCount, 1); 4421 4422 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 4423 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 4424 mOutputFormat->setCString( 4425 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 4426 mOutputFormat->setInt32(kKeySampleRate, 8000); 4427 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 4428 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 4429 mOutputFormat->setCString( 4430 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 4431 mOutputFormat->setInt32(kKeySampleRate, 16000); 4432 } else { 4433 CHECK(!"Unknown AMR band mode."); 4434 } 4435 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 4436 mOutputFormat->setCString( 4437 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 4438 int32_t numChannels, sampleRate, bitRate; 4439 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4440 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4441 inputFormat->findInt32(kKeyBitRate, &bitRate); 4442 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 4443 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 4444 mOutputFormat->setInt32(kKeyBitRate, bitRate); 4445 } else { 4446 CHECK(!"Should not be here. Unknown audio encoding."); 4447 } 4448 break; 4449 } 4450 4451 case OMX_PortDomainVideo: 4452 { 4453 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4454 4455 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 4456 mOutputFormat->setCString( 4457 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4458 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4459 mOutputFormat->setCString( 4460 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 4461 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 4462 mOutputFormat->setCString( 4463 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 4464 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 4465 mOutputFormat->setCString( 4466 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 4467 } else { 4468 CHECK(!"Unknown compression format."); 4469 } 4470 4471 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 4472 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 4473 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 4474 4475 if (!mIsEncoder) { 4476 OMX_CONFIG_RECTTYPE rect; 4477 InitOMXParams(&rect); 4478 rect.nPortIndex = kPortIndexOutput; 4479 status_t err = 4480 mOMX->getConfig( 4481 mNode, OMX_IndexConfigCommonOutputCrop, 4482 &rect, sizeof(rect)); 4483 4484 CODEC_LOGI( 4485 "video dimensions are %ld x %ld", 4486 video_def->nFrameWidth, video_def->nFrameHeight); 4487 4488 if (err == OK) { 4489 CHECK_GE(rect.nLeft, 0); 4490 CHECK_GE(rect.nTop, 0); 4491 CHECK_GE(rect.nWidth, 0u); 4492 CHECK_GE(rect.nHeight, 0u); 4493 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth); 4494 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight); 4495 4496 mOutputFormat->setRect( 4497 kKeyCropRect, 4498 rect.nLeft, 4499 rect.nTop, 4500 rect.nLeft + rect.nWidth - 1, 4501 rect.nTop + rect.nHeight - 1); 4502 4503 CODEC_LOGI( 4504 "Crop rect is %ld x %ld @ (%ld, %ld)", 4505 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop); 4506 } else { 4507 mOutputFormat->setRect( 4508 kKeyCropRect, 4509 0, 0, 4510 video_def->nFrameWidth - 1, 4511 video_def->nFrameHeight - 1); 4512 } 4513 4514 if (mNativeWindow != NULL) { 4515 initNativeWindowCrop(); 4516 } 4517 } 4518 break; 4519 } 4520 4521 default: 4522 { 4523 CHECK(!"should not be here, neither audio nor video."); 4524 break; 4525 } 4526 } 4527 4528 // If the input format contains rotation information, flag the output 4529 // format accordingly. 4530 4531 int32_t rotationDegrees; 4532 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) { 4533 mOutputFormat->setInt32(kKeyRotation, rotationDegrees); 4534 } 4535} 4536 4537status_t OMXCodec::pause() { 4538 Mutex::Autolock autoLock(mLock); 4539 4540 mPaused = true; 4541 4542 return OK; 4543} 4544 4545//////////////////////////////////////////////////////////////////////////////// 4546 4547status_t QueryCodecs( 4548 const sp<IOMX> &omx, 4549 const char *mime, bool queryDecoders, bool hwCodecOnly, 4550 Vector<CodecCapabilities> *results) { 4551 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 4552 results->clear(); 4553 4554 OMXCodec::findMatchingCodecs(mime, 4555 !queryDecoders /*createEncoder*/, 4556 NULL /*matchComponentName*/, 4557 hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/, 4558 &matchingCodecs); 4559 4560 for (size_t c = 0; c < matchingCodecs.size(); c++) { 4561 const char *componentName = matchingCodecs.itemAt(c).mName.string(); 4562 4563 results->push(); 4564 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4565 4566 status_t err = 4567 QueryCodec(omx, componentName, mime, !queryDecoders, caps); 4568 4569 if (err != OK) { 4570 results->removeAt(results->size() - 1); 4571 } 4572 } 4573 4574 return OK; 4575} 4576 4577status_t QueryCodec( 4578 const sp<IOMX> &omx, 4579 const char *componentName, const char *mime, 4580 bool isEncoder, 4581 CodecCapabilities *caps) { 4582 if (strncmp(componentName, "OMX.", 4)) { 4583 // Not an OpenMax component but a software codec. 4584 caps->mFlags = 0; 4585 caps->mComponentName = componentName; 4586 return OK; 4587 } 4588 4589 sp<OMXCodecObserver> observer = new OMXCodecObserver; 4590 IOMX::node_id node; 4591 status_t err = omx->allocateNode(componentName, observer, &node); 4592 4593 if (err != OK) { 4594 return err; 4595 } 4596 4597 OMXCodec::setComponentRole(omx, node, isEncoder, mime); 4598 4599 caps->mFlags = 0; 4600 caps->mComponentName = componentName; 4601 4602 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 4603 InitOMXParams(¶m); 4604 4605 param.nPortIndex = !isEncoder ? 0 : 1; 4606 4607 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 4608 err = omx->getParameter( 4609 node, OMX_IndexParamVideoProfileLevelQuerySupported, 4610 ¶m, sizeof(param)); 4611 4612 if (err != OK) { 4613 break; 4614 } 4615 4616 CodecProfileLevel profileLevel; 4617 profileLevel.mProfile = param.eProfile; 4618 profileLevel.mLevel = param.eLevel; 4619 4620 caps->mProfileLevels.push(profileLevel); 4621 } 4622 4623 // Color format query 4624 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 4625 InitOMXParams(&portFormat); 4626 portFormat.nPortIndex = !isEncoder ? 1 : 0; 4627 for (portFormat.nIndex = 0;; ++portFormat.nIndex) { 4628 err = omx->getParameter( 4629 node, OMX_IndexParamVideoPortFormat, 4630 &portFormat, sizeof(portFormat)); 4631 if (err != OK) { 4632 break; 4633 } 4634 caps->mColorFormats.push(portFormat.eColorFormat); 4635 } 4636 4637 if (!isEncoder && !strncmp(mime, "video/", 6)) { 4638 if (omx->storeMetaDataInBuffers( 4639 node, 1 /* port index */, OMX_TRUE) == OK || 4640 omx->prepareForAdaptivePlayback( 4641 node, 1 /* port index */, OMX_TRUE, 4642 1280 /* width */, 720 /* height */) == OK) { 4643 caps->mFlags |= CodecCapabilities::kFlagSupportsAdaptivePlayback; 4644 } 4645 } 4646 4647 CHECK_EQ(omx->freeNode(node), (status_t)OK); 4648 4649 return OK; 4650} 4651 4652status_t QueryCodecs( 4653 const sp<IOMX> &omx, 4654 const char *mimeType, bool queryDecoders, 4655 Vector<CodecCapabilities> *results) { 4656 return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results); 4657} 4658 4659// These are supposed be equivalent to the logic in 4660// "audio_channel_out_mask_from_count". 4661status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 4662 switch (numChannels) { 4663 case 1: 4664 map[0] = OMX_AUDIO_ChannelCF; 4665 break; 4666 case 2: 4667 map[0] = OMX_AUDIO_ChannelLF; 4668 map[1] = OMX_AUDIO_ChannelRF; 4669 break; 4670 case 3: 4671 map[0] = OMX_AUDIO_ChannelLF; 4672 map[1] = OMX_AUDIO_ChannelRF; 4673 map[2] = OMX_AUDIO_ChannelCF; 4674 break; 4675 case 4: 4676 map[0] = OMX_AUDIO_ChannelLF; 4677 map[1] = OMX_AUDIO_ChannelRF; 4678 map[2] = OMX_AUDIO_ChannelLR; 4679 map[3] = OMX_AUDIO_ChannelRR; 4680 break; 4681 case 5: 4682 map[0] = OMX_AUDIO_ChannelLF; 4683 map[1] = OMX_AUDIO_ChannelRF; 4684 map[2] = OMX_AUDIO_ChannelCF; 4685 map[3] = OMX_AUDIO_ChannelLR; 4686 map[4] = OMX_AUDIO_ChannelRR; 4687 break; 4688 case 6: 4689 map[0] = OMX_AUDIO_ChannelLF; 4690 map[1] = OMX_AUDIO_ChannelRF; 4691 map[2] = OMX_AUDIO_ChannelCF; 4692 map[3] = OMX_AUDIO_ChannelLFE; 4693 map[4] = OMX_AUDIO_ChannelLR; 4694 map[5] = OMX_AUDIO_ChannelRR; 4695 break; 4696 case 7: 4697 map[0] = OMX_AUDIO_ChannelLF; 4698 map[1] = OMX_AUDIO_ChannelRF; 4699 map[2] = OMX_AUDIO_ChannelCF; 4700 map[3] = OMX_AUDIO_ChannelLFE; 4701 map[4] = OMX_AUDIO_ChannelLR; 4702 map[5] = OMX_AUDIO_ChannelRR; 4703 map[6] = OMX_AUDIO_ChannelCS; 4704 break; 4705 case 8: 4706 map[0] = OMX_AUDIO_ChannelLF; 4707 map[1] = OMX_AUDIO_ChannelRF; 4708 map[2] = OMX_AUDIO_ChannelCF; 4709 map[3] = OMX_AUDIO_ChannelLFE; 4710 map[4] = OMX_AUDIO_ChannelLR; 4711 map[5] = OMX_AUDIO_ChannelRR; 4712 map[6] = OMX_AUDIO_ChannelLS; 4713 map[7] = OMX_AUDIO_ChannelRS; 4714 break; 4715 default: 4716 return -EINVAL; 4717 } 4718 4719 return OK; 4720} 4721 4722} // namespace android 4723