OMXCodec.cpp revision aae3f86c7c9a3bce5aab0d283343455d58b133b8
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <inttypes.h> 18 19//#define LOG_NDEBUG 0 20#define LOG_TAG "OMXCodec" 21#include <utils/Log.h> 22 23#include "include/AACEncoder.h" 24 25#include "include/ESDS.h" 26 27#include <binder/IServiceManager.h> 28#include <binder/MemoryDealer.h> 29#include <binder/ProcessState.h> 30#include <HardwareAPI.h> 31#include <media/stagefright/foundation/ADebug.h> 32#include <media/IMediaPlayerService.h> 33#include <media/stagefright/MediaBuffer.h> 34#include <media/stagefright/MediaBufferGroup.h> 35#include <media/stagefright/MediaDefs.h> 36#include <media/stagefright/MediaCodecList.h> 37#include <media/stagefright/MediaExtractor.h> 38#include <media/stagefright/MetaData.h> 39#include <media/stagefright/OMXCodec.h> 40#include <media/stagefright/Utils.h> 41#include <media/stagefright/SkipCutBuffer.h> 42#include <utils/Vector.h> 43 44#include <OMX_Audio.h> 45#include <OMX_AudioExt.h> 46#include <OMX_Component.h> 47#include <OMX_IndexExt.h> 48 49#include "include/avc_utils.h" 50 51namespace android { 52 53// Treat time out as an error if we have not received any output 54// buffers after 3 seconds. 55const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL; 56 57// OMX Spec defines less than 50 color formats. If the query for 58// color format is executed for more than kMaxColorFormatSupported, 59// the query will fail to avoid looping forever. 60// 1000 is more than enough for us to tell whether the omx 61// component in question is buggy or not. 62const static uint32_t kMaxColorFormatSupported = 1000; 63 64#define FACTORY_CREATE_ENCODER(name) \ 65static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \ 66 return new name(source, meta); \ 67} 68 69#define FACTORY_REF(name) { #name, Make##name }, 70 71FACTORY_CREATE_ENCODER(AACEncoder) 72 73static sp<MediaSource> InstantiateSoftwareEncoder( 74 const char *name, const sp<MediaSource> &source, 75 const sp<MetaData> &meta) { 76 struct FactoryInfo { 77 const char *name; 78 sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &); 79 }; 80 81 static const FactoryInfo kFactoryInfo[] = { 82 FACTORY_REF(AACEncoder) 83 }; 84 for (size_t i = 0; 85 i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 86 if (!strcmp(name, kFactoryInfo[i].name)) { 87 return (*kFactoryInfo[i].CreateFunc)(source, meta); 88 } 89 } 90 91 return NULL; 92} 93 94#undef FACTORY_CREATE_ENCODER 95#undef FACTORY_REF 96 97#define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 98#define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 99#define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__) 100 101struct OMXCodecObserver : public BnOMXObserver { 102 OMXCodecObserver() { 103 } 104 105 void setCodec(const sp<OMXCodec> &target) { 106 mTarget = target; 107 } 108 109 // from IOMXObserver 110 virtual void onMessage(const omx_message &msg) { 111 sp<OMXCodec> codec = mTarget.promote(); 112 113 if (codec.get() != NULL) { 114 Mutex::Autolock autoLock(codec->mLock); 115 codec->on_message(msg); 116 codec.clear(); 117 } 118 } 119 120protected: 121 virtual ~OMXCodecObserver() {} 122 123private: 124 wp<OMXCodec> mTarget; 125 126 OMXCodecObserver(const OMXCodecObserver &); 127 OMXCodecObserver &operator=(const OMXCodecObserver &); 128}; 129 130template<class T> 131static void InitOMXParams(T *params) { 132 params->nSize = sizeof(T); 133 params->nVersion.s.nVersionMajor = 1; 134 params->nVersion.s.nVersionMinor = 0; 135 params->nVersion.s.nRevision = 0; 136 params->nVersion.s.nStep = 0; 137} 138 139static bool IsSoftwareCodec(const char *componentName) { 140 if (!strncmp("OMX.google.", componentName, 11)) { 141 return true; 142 } 143 144 if (!strncmp("OMX.", componentName, 4)) { 145 return false; 146 } 147 148 return true; 149} 150 151// A sort order in which OMX software codecs are first, followed 152// by other (non-OMX) software codecs, followed by everything else. 153static int CompareSoftwareCodecsFirst( 154 const OMXCodec::CodecNameAndQuirks *elem1, 155 const OMXCodec::CodecNameAndQuirks *elem2) { 156 bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4); 157 bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4); 158 159 bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string()); 160 bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string()); 161 162 if (isSoftwareCodec1) { 163 if (!isSoftwareCodec2) { return -1; } 164 165 if (isOMX1) { 166 if (isOMX2) { return 0; } 167 168 return -1; 169 } else { 170 if (isOMX2) { return 0; } 171 172 return 1; 173 } 174 175 return -1; 176 } 177 178 if (isSoftwareCodec2) { 179 return 1; 180 } 181 182 return 0; 183} 184 185// static 186void OMXCodec::findMatchingCodecs( 187 const char *mime, 188 bool createEncoder, const char *matchComponentName, 189 uint32_t flags, 190 Vector<CodecNameAndQuirks> *matchingCodecs) { 191 matchingCodecs->clear(); 192 193 const MediaCodecList *list = MediaCodecList::getInstance(); 194 if (list == NULL) { 195 return; 196 } 197 198 size_t index = 0; 199 for (;;) { 200 ssize_t matchIndex = 201 list->findCodecByType(mime, createEncoder, index); 202 203 if (matchIndex < 0) { 204 break; 205 } 206 207 index = matchIndex + 1; 208 209 const char *componentName = list->getCodecName(matchIndex); 210 211 // If a specific codec is requested, skip the non-matching ones. 212 if (matchComponentName && strcmp(componentName, matchComponentName)) { 213 continue; 214 } 215 216 // When requesting software-only codecs, only push software codecs 217 // When requesting hardware-only codecs, only push hardware codecs 218 // When there is request neither for software-only nor for 219 // hardware-only codecs, push all codecs 220 if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) || 221 ((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) || 222 (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) { 223 224 ssize_t index = matchingCodecs->add(); 225 CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index); 226 entry->mName = String8(componentName); 227 entry->mQuirks = getComponentQuirks(list, matchIndex); 228 229 ALOGV("matching '%s' quirks 0x%08x", 230 entry->mName.string(), entry->mQuirks); 231 } 232 } 233 234 if (flags & kPreferSoftwareCodecs) { 235 matchingCodecs->sort(CompareSoftwareCodecsFirst); 236 } 237} 238 239// static 240uint32_t OMXCodec::getComponentQuirks( 241 const MediaCodecList *list, size_t index) { 242 uint32_t quirks = 0; 243 if (list->codecHasQuirk( 244 index, "requires-allocate-on-input-ports")) { 245 quirks |= kRequiresAllocateBufferOnInputPorts; 246 } 247 if (list->codecHasQuirk( 248 index, "requires-allocate-on-output-ports")) { 249 quirks |= kRequiresAllocateBufferOnOutputPorts; 250 } 251 if (list->codecHasQuirk( 252 index, "output-buffers-are-unreadable")) { 253 quirks |= kOutputBuffersAreUnreadable; 254 } 255 256 return quirks; 257} 258 259// static 260bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) { 261 const MediaCodecList *list = MediaCodecList::getInstance(); 262 263 if (list == NULL) { 264 return false; 265 } 266 267 ssize_t index = list->findCodecByName(componentName); 268 269 if (index < 0) { 270 return false; 271 } 272 273 *quirks = getComponentQuirks(list, index); 274 275 return true; 276} 277 278// static 279sp<MediaSource> OMXCodec::Create( 280 const sp<IOMX> &omx, 281 const sp<MetaData> &meta, bool createEncoder, 282 const sp<MediaSource> &source, 283 const char *matchComponentName, 284 uint32_t flags, 285 const sp<ANativeWindow> &nativeWindow) { 286 int32_t requiresSecureBuffers; 287 if (source->getFormat()->findInt32( 288 kKeyRequiresSecureBuffers, 289 &requiresSecureBuffers) 290 && requiresSecureBuffers) { 291 flags |= kIgnoreCodecSpecificData; 292 flags |= kUseSecureInputBuffers; 293 } 294 295 const char *mime; 296 bool success = meta->findCString(kKeyMIMEType, &mime); 297 CHECK(success); 298 299 Vector<CodecNameAndQuirks> matchingCodecs; 300 findMatchingCodecs( 301 mime, createEncoder, matchComponentName, flags, &matchingCodecs); 302 303 if (matchingCodecs.isEmpty()) { 304 ALOGV("No matching codecs! (mime: %s, createEncoder: %s, " 305 "matchComponentName: %s, flags: 0x%x)", 306 mime, createEncoder ? "true" : "false", matchComponentName, flags); 307 return NULL; 308 } 309 310 sp<OMXCodecObserver> observer = new OMXCodecObserver; 311 IOMX::node_id node = 0; 312 313 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 314 const char *componentNameBase = matchingCodecs[i].mName.string(); 315 uint32_t quirks = matchingCodecs[i].mQuirks; 316 const char *componentName = componentNameBase; 317 318 AString tmp; 319 if (flags & kUseSecureInputBuffers) { 320 tmp = componentNameBase; 321 tmp.append(".secure"); 322 323 componentName = tmp.c_str(); 324 } 325 326 if (createEncoder) { 327 sp<MediaSource> softwareCodec = 328 InstantiateSoftwareEncoder(componentName, source, meta); 329 330 if (softwareCodec != NULL) { 331 ALOGV("Successfully allocated software codec '%s'", componentName); 332 333 return softwareCodec; 334 } 335 } 336 337 ALOGV("Attempting to allocate OMX node '%s'", componentName); 338 339 if (!createEncoder 340 && (quirks & kOutputBuffersAreUnreadable) 341 && (flags & kClientNeedsFramebuffer)) { 342 if (strncmp(componentName, "OMX.SEC.", 8)) { 343 // For OMX.SEC.* decoders we can enable a special mode that 344 // gives the client access to the framebuffer contents. 345 346 ALOGW("Component '%s' does not give the client access to " 347 "the framebuffer contents. Skipping.", 348 componentName); 349 350 continue; 351 } 352 } 353 354 status_t err = omx->allocateNode(componentName, observer, &node); 355 if (err == OK) { 356 ALOGV("Successfully allocated OMX node '%s'", componentName); 357 358 sp<OMXCodec> codec = new OMXCodec( 359 omx, node, quirks, flags, 360 createEncoder, mime, componentName, 361 source, nativeWindow); 362 363 observer->setCodec(codec); 364 365 err = codec->configureCodec(meta); 366 if (err == OK) { 367 return codec; 368 } 369 370 ALOGV("Failed to configure codec '%s'", componentName); 371 } 372 } 373 374 return NULL; 375} 376 377status_t OMXCodec::parseAVCCodecSpecificData( 378 const void *data, size_t size, 379 unsigned *profile, unsigned *level) { 380 const uint8_t *ptr = (const uint8_t *)data; 381 382 // verify minimum size and configurationVersion == 1. 383 if (size < 7 || ptr[0] != 1) { 384 return ERROR_MALFORMED; 385 } 386 387 *profile = ptr[1]; 388 *level = ptr[3]; 389 390 // There is decodable content out there that fails the following 391 // assertion, let's be lenient for now... 392 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 393 394 size_t lengthSize = 1 + (ptr[4] & 3); 395 396 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 397 // violates it... 398 // CHECK((ptr[5] >> 5) == 7); // reserved 399 400 size_t numSeqParameterSets = ptr[5] & 31; 401 402 ptr += 6; 403 size -= 6; 404 405 for (size_t i = 0; i < numSeqParameterSets; ++i) { 406 if (size < 2) { 407 return ERROR_MALFORMED; 408 } 409 410 size_t length = U16_AT(ptr); 411 412 ptr += 2; 413 size -= 2; 414 415 if (size < length) { 416 return ERROR_MALFORMED; 417 } 418 419 addCodecSpecificData(ptr, length); 420 421 ptr += length; 422 size -= length; 423 } 424 425 if (size < 1) { 426 return ERROR_MALFORMED; 427 } 428 429 size_t numPictureParameterSets = *ptr; 430 ++ptr; 431 --size; 432 433 for (size_t i = 0; i < numPictureParameterSets; ++i) { 434 if (size < 2) { 435 return ERROR_MALFORMED; 436 } 437 438 size_t length = U16_AT(ptr); 439 440 ptr += 2; 441 size -= 2; 442 443 if (size < length) { 444 return ERROR_MALFORMED; 445 } 446 447 addCodecSpecificData(ptr, length); 448 449 ptr += length; 450 size -= length; 451 } 452 453 return OK; 454} 455 456status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { 457 ALOGV("configureCodec protected=%d", 458 (mFlags & kEnableGrallocUsageProtected) ? 1 : 0); 459 460 if (!(mFlags & kIgnoreCodecSpecificData)) { 461 uint32_t type; 462 const void *data; 463 size_t size; 464 if (meta->findData(kKeyESDS, &type, &data, &size)) { 465 ESDS esds((const char *)data, size); 466 CHECK_EQ(esds.InitCheck(), (status_t)OK); 467 468 const void *codec_specific_data; 469 size_t codec_specific_data_size; 470 esds.getCodecSpecificInfo( 471 &codec_specific_data, &codec_specific_data_size); 472 473 addCodecSpecificData( 474 codec_specific_data, codec_specific_data_size); 475 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 476 // Parse the AVCDecoderConfigurationRecord 477 478 unsigned profile, level; 479 status_t err; 480 if ((err = parseAVCCodecSpecificData( 481 data, size, &profile, &level)) != OK) { 482 ALOGE("Malformed AVC codec specific data."); 483 return err; 484 } 485 486 CODEC_LOGI( 487 "AVC profile = %u (%s), level = %u", 488 profile, AVCProfileToString(profile), level); 489 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 490 addCodecSpecificData(data, size); 491 492 CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 493 addCodecSpecificData(data, size); 494 } 495 } 496 497 int32_t bitRate = 0; 498 if (mIsEncoder) { 499 CHECK(meta->findInt32(kKeyBitRate, &bitRate)); 500 } 501 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) { 502 setAMRFormat(false /* isWAMR */, bitRate); 503 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) { 504 setAMRFormat(true /* isWAMR */, bitRate); 505 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) { 506 int32_t numChannels, sampleRate, aacProfile; 507 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 508 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 509 510 if (!meta->findInt32(kKeyAACProfile, &aacProfile)) { 511 aacProfile = OMX_AUDIO_AACObjectNull; 512 } 513 514 int32_t isADTS; 515 if (!meta->findInt32(kKeyIsADTS, &isADTS)) { 516 isADTS = false; 517 } 518 519 status_t err = setAACFormat(numChannels, sampleRate, bitRate, aacProfile, isADTS); 520 if (err != OK) { 521 CODEC_LOGE("setAACFormat() failed (err = %d)", err); 522 return err; 523 } 524 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, mMIME)) { 525 int32_t numChannels, sampleRate; 526 if (meta->findInt32(kKeyChannelCount, &numChannels) 527 && meta->findInt32(kKeySampleRate, &sampleRate)) { 528 // Since we did not always check for these, leave them optional 529 // and have the decoder figure it all out. 530 setRawAudioFormat( 531 mIsEncoder ? kPortIndexInput : kPortIndexOutput, 532 sampleRate, 533 numChannels); 534 } 535 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AC3, mMIME)) { 536 int32_t numChannels; 537 int32_t sampleRate; 538 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 539 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 540 541 status_t err = setAC3Format(numChannels, sampleRate); 542 if (err != OK) { 543 CODEC_LOGE("setAC3Format() failed (err = %d)", err); 544 return err; 545 } 546 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME) 547 || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) { 548 // These are PCM-like formats with a fixed sample rate but 549 // a variable number of channels. 550 551 int32_t numChannels; 552 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 553 554 setG711Format(numChannels); 555 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mMIME)) { 556 CHECK(!mIsEncoder); 557 558 int32_t numChannels, sampleRate; 559 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 560 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 561 562 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 563 } 564 565 if (!strncasecmp(mMIME, "video/", 6)) { 566 567 if (mIsEncoder) { 568 setVideoInputFormat(mMIME, meta); 569 } else { 570 status_t err = setVideoOutputFormat( 571 mMIME, meta); 572 573 if (err != OK) { 574 return err; 575 } 576 } 577 } 578 579 int32_t maxInputSize; 580 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 581 setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize); 582 } 583 584 initOutputFormat(meta); 585 586 if ((mFlags & kClientNeedsFramebuffer) 587 && !strncmp(mComponentName, "OMX.SEC.", 8)) { 588 // This appears to no longer be needed??? 589 590 OMX_INDEXTYPE index; 591 592 status_t err = 593 mOMX->getExtensionIndex( 594 mNode, 595 "OMX.SEC.index.ThumbnailMode", 596 &index); 597 598 if (err != OK) { 599 return err; 600 } 601 602 OMX_BOOL enable = OMX_TRUE; 603 err = mOMX->setConfig(mNode, index, &enable, sizeof(enable)); 604 605 if (err != OK) { 606 CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') " 607 "returned error 0x%08x", err); 608 609 return err; 610 } 611 612 mQuirks &= ~kOutputBuffersAreUnreadable; 613 } 614 615 if (mNativeWindow != NULL 616 && !mIsEncoder 617 && !strncasecmp(mMIME, "video/", 6) 618 && !strncmp(mComponentName, "OMX.", 4)) { 619 status_t err = initNativeWindow(); 620 if (err != OK) { 621 return err; 622 } 623 } 624 625 return OK; 626} 627 628void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { 629 OMX_PARAM_PORTDEFINITIONTYPE def; 630 InitOMXParams(&def); 631 def.nPortIndex = portIndex; 632 633 status_t err = mOMX->getParameter( 634 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 635 CHECK_EQ(err, (status_t)OK); 636 637 if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus)) 638 || (def.nBufferSize < size)) { 639 def.nBufferSize = size; 640 } 641 642 err = mOMX->setParameter( 643 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 644 CHECK_EQ(err, (status_t)OK); 645 646 err = mOMX->getParameter( 647 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 648 CHECK_EQ(err, (status_t)OK); 649 650 // Make sure the setting actually stuck. 651 if (portIndex == kPortIndexInput 652 && (mQuirks & kInputBufferSizesAreBogus)) { 653 CHECK_EQ(def.nBufferSize, size); 654 } else { 655 CHECK(def.nBufferSize >= size); 656 } 657} 658 659status_t OMXCodec::setVideoPortFormatType( 660 OMX_U32 portIndex, 661 OMX_VIDEO_CODINGTYPE compressionFormat, 662 OMX_COLOR_FORMATTYPE colorFormat) { 663 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 664 InitOMXParams(&format); 665 format.nPortIndex = portIndex; 666 format.nIndex = 0; 667 bool found = false; 668 669 OMX_U32 index = 0; 670 for (;;) { 671 format.nIndex = index; 672 status_t err = mOMX->getParameter( 673 mNode, OMX_IndexParamVideoPortFormat, 674 &format, sizeof(format)); 675 676 if (err != OK) { 677 return err; 678 } 679 680 // The following assertion is violated by TI's video decoder. 681 // CHECK_EQ(format.nIndex, index); 682 683#if 1 684 CODEC_LOGV("portIndex: %u, index: %u, eCompressionFormat=%d eColorFormat=%d", 685 portIndex, 686 index, format.eCompressionFormat, format.eColorFormat); 687#endif 688 689 if (format.eCompressionFormat == compressionFormat 690 && format.eColorFormat == colorFormat) { 691 found = true; 692 break; 693 } 694 695 ++index; 696 if (index >= kMaxColorFormatSupported) { 697 CODEC_LOGE("color format %d or compression format %d is not supported", 698 colorFormat, compressionFormat); 699 return UNKNOWN_ERROR; 700 } 701 } 702 703 if (!found) { 704 return UNKNOWN_ERROR; 705 } 706 707 CODEC_LOGV("found a match."); 708 status_t err = mOMX->setParameter( 709 mNode, OMX_IndexParamVideoPortFormat, 710 &format, sizeof(format)); 711 712 return err; 713} 714 715static size_t getFrameSize( 716 OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) { 717 switch (colorFormat) { 718 case OMX_COLOR_FormatYCbYCr: 719 case OMX_COLOR_FormatCbYCrY: 720 return width * height * 2; 721 722 case OMX_COLOR_FormatYUV420Planar: 723 case OMX_COLOR_FormatYUV420SemiPlanar: 724 case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: 725 /* 726 * FIXME: For the Opaque color format, the frame size does not 727 * need to be (w*h*3)/2. It just needs to 728 * be larger than certain minimum buffer size. However, 729 * currently, this opaque foramt has been tested only on 730 * YUV420 formats. If that is changed, then we need to revisit 731 * this part in the future 732 */ 733 case OMX_COLOR_FormatAndroidOpaque: 734 return (width * height * 3) / 2; 735 736 default: 737 CHECK(!"Should not be here. Unsupported color format."); 738 break; 739 } 740} 741 742status_t OMXCodec::findTargetColorFormat( 743 const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) { 744 ALOGV("findTargetColorFormat"); 745 CHECK(mIsEncoder); 746 747 *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 748 int32_t targetColorFormat; 749 if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) { 750 *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat; 751 } 752 753 // Check whether the target color format is supported. 754 return isColorFormatSupported(*colorFormat, kPortIndexInput); 755} 756 757status_t OMXCodec::isColorFormatSupported( 758 OMX_COLOR_FORMATTYPE colorFormat, int portIndex) { 759 ALOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat)); 760 761 // Enumerate all the color formats supported by 762 // the omx component to see whether the given 763 // color format is supported. 764 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 765 InitOMXParams(&portFormat); 766 portFormat.nPortIndex = portIndex; 767 OMX_U32 index = 0; 768 portFormat.nIndex = index; 769 while (true) { 770 if (OMX_ErrorNone != mOMX->getParameter( 771 mNode, OMX_IndexParamVideoPortFormat, 772 &portFormat, sizeof(portFormat))) { 773 break; 774 } 775 // Make sure that omx component does not overwrite 776 // the incremented index (bug 2897413). 777 CHECK_EQ(index, portFormat.nIndex); 778 if (portFormat.eColorFormat == colorFormat) { 779 CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat); 780 return OK; // colorFormat is supported! 781 } 782 ++index; 783 portFormat.nIndex = index; 784 785 if (index >= kMaxColorFormatSupported) { 786 CODEC_LOGE("More than %u color formats are supported???", index); 787 break; 788 } 789 } 790 791 CODEC_LOGE("color format %d is not supported", colorFormat); 792 return UNKNOWN_ERROR; 793} 794 795void OMXCodec::setVideoInputFormat( 796 const char *mime, const sp<MetaData>& meta) { 797 798 int32_t width, height, frameRate, bitRate, stride, sliceHeight; 799 bool success = meta->findInt32(kKeyWidth, &width); 800 success = success && meta->findInt32(kKeyHeight, &height); 801 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 802 success = success && meta->findInt32(kKeyBitRate, &bitRate); 803 success = success && meta->findInt32(kKeyStride, &stride); 804 success = success && meta->findInt32(kKeySliceHeight, &sliceHeight); 805 CHECK(success); 806 CHECK(stride != 0); 807 808 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 809 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 810 compressionFormat = OMX_VIDEO_CodingAVC; 811 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 812 compressionFormat = OMX_VIDEO_CodingMPEG4; 813 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 814 compressionFormat = OMX_VIDEO_CodingH263; 815 } else { 816 ALOGE("Not a supported video mime type: %s", mime); 817 CHECK(!"Should not be here. Not a supported video mime type."); 818 } 819 820 OMX_COLOR_FORMATTYPE colorFormat; 821 CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat)); 822 823 status_t err; 824 OMX_PARAM_PORTDEFINITIONTYPE def; 825 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 826 827 //////////////////////// Input port ///////////////////////// 828 CHECK_EQ(setVideoPortFormatType( 829 kPortIndexInput, OMX_VIDEO_CodingUnused, 830 colorFormat), (status_t)OK); 831 832 InitOMXParams(&def); 833 def.nPortIndex = kPortIndexInput; 834 835 err = mOMX->getParameter( 836 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 837 CHECK_EQ(err, (status_t)OK); 838 839 def.nBufferSize = getFrameSize(colorFormat, 840 stride > 0? stride: -stride, sliceHeight); 841 842 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 843 844 video_def->nFrameWidth = width; 845 video_def->nFrameHeight = height; 846 video_def->nStride = stride; 847 video_def->nSliceHeight = sliceHeight; 848 video_def->xFramerate = (frameRate << 16); // Q16 format 849 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 850 video_def->eColorFormat = colorFormat; 851 852 err = mOMX->setParameter( 853 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 854 CHECK_EQ(err, (status_t)OK); 855 856 //////////////////////// Output port ///////////////////////// 857 CHECK_EQ(setVideoPortFormatType( 858 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused), 859 (status_t)OK); 860 InitOMXParams(&def); 861 def.nPortIndex = kPortIndexOutput; 862 863 err = mOMX->getParameter( 864 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 865 866 CHECK_EQ(err, (status_t)OK); 867 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 868 869 video_def->nFrameWidth = width; 870 video_def->nFrameHeight = height; 871 video_def->xFramerate = 0; // No need for output port 872 video_def->nBitrate = bitRate; // Q16 format 873 video_def->eCompressionFormat = compressionFormat; 874 video_def->eColorFormat = OMX_COLOR_FormatUnused; 875 if (mQuirks & kRequiresLargerEncoderOutputBuffer) { 876 // Increases the output buffer size 877 def.nBufferSize = ((def.nBufferSize * 3) >> 1); 878 } 879 880 err = mOMX->setParameter( 881 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 882 CHECK_EQ(err, (status_t)OK); 883 884 /////////////////// Codec-specific //////////////////////// 885 switch (compressionFormat) { 886 case OMX_VIDEO_CodingMPEG4: 887 { 888 CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK); 889 break; 890 } 891 892 case OMX_VIDEO_CodingH263: 893 CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK); 894 break; 895 896 case OMX_VIDEO_CodingAVC: 897 { 898 CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK); 899 break; 900 } 901 902 default: 903 CHECK(!"Support for this compressionFormat to be implemented."); 904 break; 905 } 906} 907 908static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 909 if (iFramesInterval < 0) { 910 return 0xFFFFFFFF; 911 } else if (iFramesInterval == 0) { 912 return 0; 913 } 914 OMX_U32 ret = frameRate * iFramesInterval - 1; 915 CHECK(ret > 1); 916 return ret; 917} 918 919status_t OMXCodec::setupErrorCorrectionParameters() { 920 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 921 InitOMXParams(&errorCorrectionType); 922 errorCorrectionType.nPortIndex = kPortIndexOutput; 923 924 status_t err = mOMX->getParameter( 925 mNode, OMX_IndexParamVideoErrorCorrection, 926 &errorCorrectionType, sizeof(errorCorrectionType)); 927 if (err != OK) { 928 ALOGW("Error correction param query is not supported"); 929 return OK; // Optional feature. Ignore this failure 930 } 931 932 errorCorrectionType.bEnableHEC = OMX_FALSE; 933 errorCorrectionType.bEnableResync = OMX_TRUE; 934 errorCorrectionType.nResynchMarkerSpacing = 256; 935 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 936 errorCorrectionType.bEnableRVLC = OMX_FALSE; 937 938 err = mOMX->setParameter( 939 mNode, OMX_IndexParamVideoErrorCorrection, 940 &errorCorrectionType, sizeof(errorCorrectionType)); 941 if (err != OK) { 942 ALOGW("Error correction param configuration is not supported"); 943 } 944 945 // Optional feature. Ignore the failure. 946 return OK; 947} 948 949status_t OMXCodec::setupBitRate(int32_t bitRate) { 950 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 951 InitOMXParams(&bitrateType); 952 bitrateType.nPortIndex = kPortIndexOutput; 953 954 status_t err = mOMX->getParameter( 955 mNode, OMX_IndexParamVideoBitrate, 956 &bitrateType, sizeof(bitrateType)); 957 CHECK_EQ(err, (status_t)OK); 958 959 bitrateType.eControlRate = OMX_Video_ControlRateVariable; 960 bitrateType.nTargetBitrate = bitRate; 961 962 err = mOMX->setParameter( 963 mNode, OMX_IndexParamVideoBitrate, 964 &bitrateType, sizeof(bitrateType)); 965 CHECK_EQ(err, (status_t)OK); 966 return OK; 967} 968 969status_t OMXCodec::getVideoProfileLevel( 970 const sp<MetaData>& meta, 971 const CodecProfileLevel& defaultProfileLevel, 972 CodecProfileLevel &profileLevel) { 973 CODEC_LOGV("Default profile: %ld, level %ld", 974 defaultProfileLevel.mProfile, defaultProfileLevel.mLevel); 975 976 // Are the default profile and level overwriten? 977 int32_t profile, level; 978 if (!meta->findInt32(kKeyVideoProfile, &profile)) { 979 profile = defaultProfileLevel.mProfile; 980 } 981 if (!meta->findInt32(kKeyVideoLevel, &level)) { 982 level = defaultProfileLevel.mLevel; 983 } 984 CODEC_LOGV("Target profile: %d, level: %d", profile, level); 985 986 // Are the target profile and level supported by the encoder? 987 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 988 InitOMXParams(¶m); 989 param.nPortIndex = kPortIndexOutput; 990 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 991 status_t err = mOMX->getParameter( 992 mNode, OMX_IndexParamVideoProfileLevelQuerySupported, 993 ¶m, sizeof(param)); 994 995 if (err != OK) break; 996 997 int32_t supportedProfile = static_cast<int32_t>(param.eProfile); 998 int32_t supportedLevel = static_cast<int32_t>(param.eLevel); 999 CODEC_LOGV("Supported profile: %d, level %d", 1000 supportedProfile, supportedLevel); 1001 1002 if (profile == supportedProfile && 1003 level <= supportedLevel) { 1004 // We can further check whether the level is a valid 1005 // value; but we will leave that to the omx encoder component 1006 // via OMX_SetParameter call. 1007 profileLevel.mProfile = profile; 1008 profileLevel.mLevel = level; 1009 return OK; 1010 } 1011 } 1012 1013 CODEC_LOGE("Target profile (%d) and level (%d) is not supported", 1014 profile, level); 1015 return BAD_VALUE; 1016} 1017 1018status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) { 1019 int32_t iFramesInterval, frameRate, bitRate; 1020 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1021 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1022 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1023 CHECK(success); 1024 OMX_VIDEO_PARAM_H263TYPE h263type; 1025 InitOMXParams(&h263type); 1026 h263type.nPortIndex = kPortIndexOutput; 1027 1028 status_t err = mOMX->getParameter( 1029 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1030 CHECK_EQ(err, (status_t)OK); 1031 1032 h263type.nAllowedPictureTypes = 1033 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1034 1035 h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1036 if (h263type.nPFrames == 0) { 1037 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1038 } 1039 h263type.nBFrames = 0; 1040 1041 // Check profile and level parameters 1042 CodecProfileLevel defaultProfileLevel, profileLevel; 1043 defaultProfileLevel.mProfile = h263type.eProfile; 1044 defaultProfileLevel.mLevel = h263type.eLevel; 1045 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1046 if (err != OK) return err; 1047 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile); 1048 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel); 1049 1050 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 1051 h263type.bForceRoundingTypeToZero = OMX_FALSE; 1052 h263type.nPictureHeaderRepetition = 0; 1053 h263type.nGOBHeaderInterval = 0; 1054 1055 err = mOMX->setParameter( 1056 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1057 CHECK_EQ(err, (status_t)OK); 1058 1059 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1060 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1061 1062 return OK; 1063} 1064 1065status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { 1066 int32_t iFramesInterval, frameRate, bitRate; 1067 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1068 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1069 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1070 CHECK(success); 1071 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 1072 InitOMXParams(&mpeg4type); 1073 mpeg4type.nPortIndex = kPortIndexOutput; 1074 1075 status_t err = mOMX->getParameter( 1076 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1077 CHECK_EQ(err, (status_t)OK); 1078 1079 mpeg4type.nSliceHeaderSpacing = 0; 1080 mpeg4type.bSVH = OMX_FALSE; 1081 mpeg4type.bGov = OMX_FALSE; 1082 1083 mpeg4type.nAllowedPictureTypes = 1084 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1085 1086 mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1087 if (mpeg4type.nPFrames == 0) { 1088 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1089 } 1090 mpeg4type.nBFrames = 0; 1091 mpeg4type.nIDCVLCThreshold = 0; 1092 mpeg4type.bACPred = OMX_TRUE; 1093 mpeg4type.nMaxPacketSize = 256; 1094 mpeg4type.nTimeIncRes = 1000; 1095 mpeg4type.nHeaderExtension = 0; 1096 mpeg4type.bReversibleVLC = OMX_FALSE; 1097 1098 // Check profile and level parameters 1099 CodecProfileLevel defaultProfileLevel, profileLevel; 1100 defaultProfileLevel.mProfile = mpeg4type.eProfile; 1101 defaultProfileLevel.mLevel = mpeg4type.eLevel; 1102 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1103 if (err != OK) return err; 1104 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile); 1105 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel); 1106 1107 err = mOMX->setParameter( 1108 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1109 CHECK_EQ(err, (status_t)OK); 1110 1111 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1112 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1113 1114 return OK; 1115} 1116 1117status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) { 1118 int32_t iFramesInterval, frameRate, bitRate; 1119 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1120 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1121 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1122 CHECK(success); 1123 1124 OMX_VIDEO_PARAM_AVCTYPE h264type; 1125 InitOMXParams(&h264type); 1126 h264type.nPortIndex = kPortIndexOutput; 1127 1128 status_t err = mOMX->getParameter( 1129 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1130 CHECK_EQ(err, (status_t)OK); 1131 1132 h264type.nAllowedPictureTypes = 1133 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1134 1135 // Check profile and level parameters 1136 CodecProfileLevel defaultProfileLevel, profileLevel; 1137 defaultProfileLevel.mProfile = h264type.eProfile; 1138 defaultProfileLevel.mLevel = h264type.eLevel; 1139 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1140 if (err != OK) return err; 1141 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile); 1142 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel); 1143 1144 // XXX 1145 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 1146 ALOGW("Use baseline profile instead of %d for AVC recording", 1147 h264type.eProfile); 1148 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 1149 } 1150 1151 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 1152 h264type.nSliceHeaderSpacing = 0; 1153 h264type.bUseHadamard = OMX_TRUE; 1154 h264type.nRefFrames = 1; 1155 h264type.nBFrames = 0; 1156 h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1157 if (h264type.nPFrames == 0) { 1158 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1159 } 1160 h264type.nRefIdx10ActiveMinus1 = 0; 1161 h264type.nRefIdx11ActiveMinus1 = 0; 1162 h264type.bEntropyCodingCABAC = OMX_FALSE; 1163 h264type.bWeightedPPrediction = OMX_FALSE; 1164 h264type.bconstIpred = OMX_FALSE; 1165 h264type.bDirect8x8Inference = OMX_FALSE; 1166 h264type.bDirectSpatialTemporal = OMX_FALSE; 1167 h264type.nCabacInitIdc = 0; 1168 } 1169 1170 if (h264type.nBFrames != 0) { 1171 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 1172 } 1173 1174 h264type.bEnableUEP = OMX_FALSE; 1175 h264type.bEnableFMO = OMX_FALSE; 1176 h264type.bEnableASO = OMX_FALSE; 1177 h264type.bEnableRS = OMX_FALSE; 1178 h264type.bFrameMBsOnly = OMX_TRUE; 1179 h264type.bMBAFF = OMX_FALSE; 1180 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 1181 1182 err = mOMX->setParameter( 1183 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1184 CHECK_EQ(err, (status_t)OK); 1185 1186 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1187 1188 return OK; 1189} 1190 1191status_t OMXCodec::setVideoOutputFormat( 1192 const char *mime, const sp<MetaData>& meta) { 1193 1194 int32_t width, height; 1195 bool success = meta->findInt32(kKeyWidth, &width); 1196 success = success && meta->findInt32(kKeyHeight, &height); 1197 CHECK(success); 1198 1199 CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); 1200 1201 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 1202 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1203 compressionFormat = OMX_VIDEO_CodingAVC; 1204 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1205 compressionFormat = OMX_VIDEO_CodingMPEG4; 1206 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1207 compressionFormat = OMX_VIDEO_CodingH263; 1208 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) { 1209 compressionFormat = OMX_VIDEO_CodingVP8; 1210 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP9, mime)) { 1211 compressionFormat = OMX_VIDEO_CodingVP9; 1212 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) { 1213 compressionFormat = OMX_VIDEO_CodingMPEG2; 1214 } else { 1215 ALOGE("Not a supported video mime type: %s", mime); 1216 CHECK(!"Should not be here. Not a supported video mime type."); 1217 } 1218 1219 status_t err = setVideoPortFormatType( 1220 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 1221 1222 if (err != OK) { 1223 return err; 1224 } 1225 1226#if 1 1227 { 1228 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1229 InitOMXParams(&format); 1230 format.nPortIndex = kPortIndexOutput; 1231 format.nIndex = 0; 1232 1233 status_t err = mOMX->getParameter( 1234 mNode, OMX_IndexParamVideoPortFormat, 1235 &format, sizeof(format)); 1236 CHECK_EQ(err, (status_t)OK); 1237 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 1238 1239 int32_t colorFormat; 1240 if (meta->findInt32(kKeyColorFormat, &colorFormat) 1241 && colorFormat != OMX_COLOR_FormatUnused 1242 && colorFormat != format.eColorFormat) { 1243 1244 while (OMX_ErrorNoMore != err) { 1245 format.nIndex++; 1246 err = mOMX->getParameter( 1247 mNode, OMX_IndexParamVideoPortFormat, 1248 &format, sizeof(format)); 1249 if (format.eColorFormat == colorFormat) { 1250 break; 1251 } 1252 } 1253 if (format.eColorFormat != colorFormat) { 1254 CODEC_LOGE("Color format %d is not supported", colorFormat); 1255 return ERROR_UNSUPPORTED; 1256 } 1257 } 1258 1259 err = mOMX->setParameter( 1260 mNode, OMX_IndexParamVideoPortFormat, 1261 &format, sizeof(format)); 1262 1263 if (err != OK) { 1264 return err; 1265 } 1266 } 1267#endif 1268 1269 OMX_PARAM_PORTDEFINITIONTYPE def; 1270 InitOMXParams(&def); 1271 def.nPortIndex = kPortIndexInput; 1272 1273 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1274 1275 err = mOMX->getParameter( 1276 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1277 1278 CHECK_EQ(err, (status_t)OK); 1279 1280#if 1 1281 // XXX Need a (much) better heuristic to compute input buffer sizes. 1282 const size_t X = 64 * 1024; 1283 if (def.nBufferSize < X) { 1284 def.nBufferSize = X; 1285 } 1286#endif 1287 1288 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1289 1290 video_def->nFrameWidth = width; 1291 video_def->nFrameHeight = height; 1292 1293 video_def->eCompressionFormat = compressionFormat; 1294 video_def->eColorFormat = OMX_COLOR_FormatUnused; 1295 1296 err = mOMX->setParameter( 1297 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1298 1299 if (err != OK) { 1300 return err; 1301 } 1302 1303 //////////////////////////////////////////////////////////////////////////// 1304 1305 InitOMXParams(&def); 1306 def.nPortIndex = kPortIndexOutput; 1307 1308 err = mOMX->getParameter( 1309 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1310 CHECK_EQ(err, (status_t)OK); 1311 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1312 1313#if 0 1314 def.nBufferSize = 1315 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 1316#endif 1317 1318 video_def->nFrameWidth = width; 1319 video_def->nFrameHeight = height; 1320 1321 err = mOMX->setParameter( 1322 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1323 1324 return err; 1325} 1326 1327OMXCodec::OMXCodec( 1328 const sp<IOMX> &omx, IOMX::node_id node, 1329 uint32_t quirks, uint32_t flags, 1330 bool isEncoder, 1331 const char *mime, 1332 const char *componentName, 1333 const sp<MediaSource> &source, 1334 const sp<ANativeWindow> &nativeWindow) 1335 : mOMX(omx), 1336 mOMXLivesLocally(omx->livesLocally(node, getpid())), 1337 mNode(node), 1338 mQuirks(quirks), 1339 mFlags(flags), 1340 mIsEncoder(isEncoder), 1341 mIsVideo(!strncasecmp("video/", mime, 6)), 1342 mMIME(strdup(mime)), 1343 mComponentName(strdup(componentName)), 1344 mSource(source), 1345 mCodecSpecificDataIndex(0), 1346 mState(LOADED), 1347 mInitialBufferSubmit(true), 1348 mSignalledEOS(false), 1349 mNoMoreOutputData(false), 1350 mOutputPortSettingsHaveChanged(false), 1351 mSeekTimeUs(-1), 1352 mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC), 1353 mTargetTimeUs(-1), 1354 mOutputPortSettingsChangedPending(false), 1355 mSkipCutBuffer(NULL), 1356 mLeftOverBuffer(NULL), 1357 mPaused(false), 1358 mNativeWindow( 1359 (!strncmp(componentName, "OMX.google.", 11)) 1360 ? NULL : nativeWindow) { 1361 mPortStatus[kPortIndexInput] = ENABLED; 1362 mPortStatus[kPortIndexOutput] = ENABLED; 1363 1364 setComponentRole(); 1365} 1366 1367// static 1368void OMXCodec::setComponentRole( 1369 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, 1370 const char *mime) { 1371 struct MimeToRole { 1372 const char *mime; 1373 const char *decoderRole; 1374 const char *encoderRole; 1375 }; 1376 1377 static const MimeToRole kMimeToRole[] = { 1378 { MEDIA_MIMETYPE_AUDIO_MPEG, 1379 "audio_decoder.mp3", "audio_encoder.mp3" }, 1380 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 1381 "audio_decoder.mp1", "audio_encoder.mp1" }, 1382 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 1383 "audio_decoder.mp2", "audio_encoder.mp2" }, 1384 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1385 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1386 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1387 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1388 { MEDIA_MIMETYPE_AUDIO_AAC, 1389 "audio_decoder.aac", "audio_encoder.aac" }, 1390 { MEDIA_MIMETYPE_AUDIO_VORBIS, 1391 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 1392 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 1393 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 1394 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 1395 "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 1396 { MEDIA_MIMETYPE_VIDEO_AVC, 1397 "video_decoder.avc", "video_encoder.avc" }, 1398 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1399 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1400 { MEDIA_MIMETYPE_VIDEO_H263, 1401 "video_decoder.h263", "video_encoder.h263" }, 1402 { MEDIA_MIMETYPE_VIDEO_VP8, 1403 "video_decoder.vp8", "video_encoder.vp8" }, 1404 { MEDIA_MIMETYPE_VIDEO_VP9, 1405 "video_decoder.vp9", "video_encoder.vp9" }, 1406 { MEDIA_MIMETYPE_AUDIO_RAW, 1407 "audio_decoder.raw", "audio_encoder.raw" }, 1408 { MEDIA_MIMETYPE_AUDIO_FLAC, 1409 "audio_decoder.flac", "audio_encoder.flac" }, 1410 { MEDIA_MIMETYPE_AUDIO_MSGSM, 1411 "audio_decoder.gsm", "audio_encoder.gsm" }, 1412 { MEDIA_MIMETYPE_VIDEO_MPEG2, 1413 "video_decoder.mpeg2", "video_encoder.mpeg2" }, 1414 { MEDIA_MIMETYPE_AUDIO_AC3, 1415 "audio_decoder.ac3", "audio_encoder.ac3" }, 1416 }; 1417 1418 static const size_t kNumMimeToRole = 1419 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1420 1421 size_t i; 1422 for (i = 0; i < kNumMimeToRole; ++i) { 1423 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1424 break; 1425 } 1426 } 1427 1428 if (i == kNumMimeToRole) { 1429 return; 1430 } 1431 1432 const char *role = 1433 isEncoder ? kMimeToRole[i].encoderRole 1434 : kMimeToRole[i].decoderRole; 1435 1436 if (role != NULL) { 1437 OMX_PARAM_COMPONENTROLETYPE roleParams; 1438 InitOMXParams(&roleParams); 1439 1440 strncpy((char *)roleParams.cRole, 1441 role, OMX_MAX_STRINGNAME_SIZE - 1); 1442 1443 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1444 1445 status_t err = omx->setParameter( 1446 node, OMX_IndexParamStandardComponentRole, 1447 &roleParams, sizeof(roleParams)); 1448 1449 if (err != OK) { 1450 ALOGW("Failed to set standard component role '%s'.", role); 1451 } 1452 } 1453} 1454 1455void OMXCodec::setComponentRole() { 1456 setComponentRole(mOMX, mNode, mIsEncoder, mMIME); 1457} 1458 1459OMXCodec::~OMXCodec() { 1460 mSource.clear(); 1461 1462 CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE); 1463 1464 status_t err = mOMX->freeNode(mNode); 1465 CHECK_EQ(err, (status_t)OK); 1466 1467 mNode = NULL; 1468 setState(DEAD); 1469 1470 clearCodecSpecificData(); 1471 1472 free(mComponentName); 1473 mComponentName = NULL; 1474 1475 free(mMIME); 1476 mMIME = NULL; 1477} 1478 1479status_t OMXCodec::init() { 1480 // mLock is held. 1481 1482 CHECK_EQ((int)mState, (int)LOADED); 1483 1484 status_t err; 1485 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 1486 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1487 CHECK_EQ(err, (status_t)OK); 1488 setState(LOADED_TO_IDLE); 1489 } 1490 1491 err = allocateBuffers(); 1492 if (err != (status_t)OK) { 1493 return err; 1494 } 1495 1496 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 1497 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1498 CHECK_EQ(err, (status_t)OK); 1499 1500 setState(LOADED_TO_IDLE); 1501 } 1502 1503 while (mState != EXECUTING && mState != ERROR) { 1504 mAsyncCompletion.wait(mLock); 1505 } 1506 1507 return mState == ERROR ? UNKNOWN_ERROR : OK; 1508} 1509 1510// static 1511bool OMXCodec::isIntermediateState(State state) { 1512 return state == LOADED_TO_IDLE 1513 || state == IDLE_TO_EXECUTING 1514 || state == EXECUTING_TO_IDLE 1515 || state == IDLE_TO_LOADED 1516 || state == RECONFIGURING; 1517} 1518 1519status_t OMXCodec::allocateBuffers() { 1520 status_t err = allocateBuffersOnPort(kPortIndexInput); 1521 1522 if (err != OK) { 1523 return err; 1524 } 1525 1526 return allocateBuffersOnPort(kPortIndexOutput); 1527} 1528 1529status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 1530 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 1531 return allocateOutputBuffersFromNativeWindow(); 1532 } 1533 1534 if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) { 1535 ALOGE("protected output buffers must be stent to an ANativeWindow"); 1536 return PERMISSION_DENIED; 1537 } 1538 1539 status_t err = OK; 1540 if ((mFlags & kStoreMetaDataInVideoBuffers) 1541 && portIndex == kPortIndexInput) { 1542 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 1543 if (err != OK) { 1544 ALOGE("Storing meta data in video buffers is not supported"); 1545 return err; 1546 } 1547 } 1548 1549 OMX_PARAM_PORTDEFINITIONTYPE def; 1550 InitOMXParams(&def); 1551 def.nPortIndex = portIndex; 1552 1553 err = mOMX->getParameter( 1554 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1555 1556 if (err != OK) { 1557 return err; 1558 } 1559 1560 CODEC_LOGV("allocating %lu buffers of size %lu on %s port", 1561 def.nBufferCountActual, def.nBufferSize, 1562 portIndex == kPortIndexInput ? "input" : "output"); 1563 1564 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 1565 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 1566 1567 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 1568 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 1569 CHECK(mem.get() != NULL); 1570 1571 BufferInfo info; 1572 info.mData = NULL; 1573 info.mSize = def.nBufferSize; 1574 1575 IOMX::buffer_id buffer; 1576 if (portIndex == kPortIndexInput 1577 && ((mQuirks & kRequiresAllocateBufferOnInputPorts) 1578 || (mFlags & kUseSecureInputBuffers))) { 1579 if (mOMXLivesLocally) { 1580 mem.clear(); 1581 1582 err = mOMX->allocateBuffer( 1583 mNode, portIndex, def.nBufferSize, &buffer, 1584 &info.mData); 1585 } else { 1586 err = mOMX->allocateBufferWithBackup( 1587 mNode, portIndex, mem, &buffer); 1588 } 1589 } else if (portIndex == kPortIndexOutput 1590 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 1591 if (mOMXLivesLocally) { 1592 mem.clear(); 1593 1594 err = mOMX->allocateBuffer( 1595 mNode, portIndex, def.nBufferSize, &buffer, 1596 &info.mData); 1597 } else { 1598 err = mOMX->allocateBufferWithBackup( 1599 mNode, portIndex, mem, &buffer); 1600 } 1601 } else { 1602 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 1603 } 1604 1605 if (err != OK) { 1606 ALOGE("allocate_buffer_with_backup failed"); 1607 return err; 1608 } 1609 1610 if (mem != NULL) { 1611 info.mData = mem->pointer(); 1612 } 1613 1614 info.mBuffer = buffer; 1615 info.mStatus = OWNED_BY_US; 1616 info.mMem = mem; 1617 info.mMediaBuffer = NULL; 1618 1619 if (portIndex == kPortIndexOutput) { 1620 if (!(mOMXLivesLocally 1621 && (mQuirks & kRequiresAllocateBufferOnOutputPorts) 1622 && (mQuirks & kDefersOutputBufferAllocation))) { 1623 // If the node does not fill in the buffer ptr at this time, 1624 // we will defer creating the MediaBuffer until receiving 1625 // the first FILL_BUFFER_DONE notification instead. 1626 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); 1627 info.mMediaBuffer->setObserver(this); 1628 } 1629 } 1630 1631 mPortBuffers[portIndex].push(info); 1632 1633 CODEC_LOGV("allocated buffer %p on %s port", buffer, 1634 portIndex == kPortIndexInput ? "input" : "output"); 1635 } 1636 1637 if (portIndex == kPortIndexOutput) { 1638 1639 sp<MetaData> meta = mSource->getFormat(); 1640 int32_t delay = 0; 1641 if (!meta->findInt32(kKeyEncoderDelay, &delay)) { 1642 delay = 0; 1643 } 1644 int32_t padding = 0; 1645 if (!meta->findInt32(kKeyEncoderPadding, &padding)) { 1646 padding = 0; 1647 } 1648 int32_t numchannels = 0; 1649 if (delay + padding) { 1650 if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) { 1651 size_t frameSize = numchannels * sizeof(int16_t); 1652 if (mSkipCutBuffer != NULL) { 1653 size_t prevbuffersize = mSkipCutBuffer->size(); 1654 if (prevbuffersize != 0) { 1655 ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize); 1656 } 1657 } 1658 mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize); 1659 } 1660 } 1661 } 1662 1663 // dumpPortStatus(portIndex); 1664 1665 if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) { 1666 Vector<MediaBuffer *> buffers; 1667 for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1668 const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i); 1669 1670 MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize); 1671 buffers.push(mbuf); 1672 } 1673 1674 status_t err = mSource->setBuffers(buffers); 1675 1676 if (err != OK) { 1677 for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1678 buffers.editItemAt(i)->release(); 1679 } 1680 buffers.clear(); 1681 1682 CODEC_LOGE( 1683 "Codec requested to use secure input buffers but " 1684 "upstream source didn't support that."); 1685 1686 return err; 1687 } 1688 } 1689 1690 return OK; 1691} 1692 1693status_t OMXCodec::applyRotation() { 1694 sp<MetaData> meta = mSource->getFormat(); 1695 1696 int32_t rotationDegrees; 1697 if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { 1698 rotationDegrees = 0; 1699 } 1700 1701 uint32_t transform; 1702 switch (rotationDegrees) { 1703 case 0: transform = 0; break; 1704 case 90: transform = HAL_TRANSFORM_ROT_90; break; 1705 case 180: transform = HAL_TRANSFORM_ROT_180; break; 1706 case 270: transform = HAL_TRANSFORM_ROT_270; break; 1707 default: transform = 0; break; 1708 } 1709 1710 status_t err = OK; 1711 1712 if (transform) { 1713 err = native_window_set_buffers_transform( 1714 mNativeWindow.get(), transform); 1715 ALOGE("native_window_set_buffers_transform failed: %s (%d)", 1716 strerror(-err), -err); 1717 } 1718 1719 return err; 1720} 1721 1722status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { 1723 // Get the number of buffers needed. 1724 OMX_PARAM_PORTDEFINITIONTYPE def; 1725 InitOMXParams(&def); 1726 def.nPortIndex = kPortIndexOutput; 1727 1728 status_t err = mOMX->getParameter( 1729 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1730 if (err != OK) { 1731 CODEC_LOGE("getParameter failed: %d", err); 1732 return err; 1733 } 1734 1735 err = native_window_set_buffers_geometry( 1736 mNativeWindow.get(), 1737 def.format.video.nFrameWidth, 1738 def.format.video.nFrameHeight, 1739 def.format.video.eColorFormat); 1740 1741 if (err != 0) { 1742 ALOGE("native_window_set_buffers_geometry failed: %s (%d)", 1743 strerror(-err), -err); 1744 return err; 1745 } 1746 1747 err = applyRotation(); 1748 if (err != OK) { 1749 return err; 1750 } 1751 1752 // Set up the native window. 1753 OMX_U32 usage = 0; 1754 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 1755 if (err != 0) { 1756 ALOGW("querying usage flags from OMX IL component failed: %d", err); 1757 // XXX: Currently this error is logged, but not fatal. 1758 usage = 0; 1759 } 1760 if (mFlags & kEnableGrallocUsageProtected) { 1761 usage |= GRALLOC_USAGE_PROTECTED; 1762 } 1763 1764 // Make sure to check whether either Stagefright or the video decoder 1765 // requested protected buffers. 1766 if (usage & GRALLOC_USAGE_PROTECTED) { 1767 // Verify that the ANativeWindow sends images directly to 1768 // SurfaceFlinger. 1769 int queuesToNativeWindow = 0; 1770 err = mNativeWindow->query( 1771 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 1772 &queuesToNativeWindow); 1773 if (err != 0) { 1774 ALOGE("error authenticating native window: %d", err); 1775 return err; 1776 } 1777 if (queuesToNativeWindow != 1) { 1778 ALOGE("native window could not be authenticated"); 1779 return PERMISSION_DENIED; 1780 } 1781 } 1782 1783 ALOGV("native_window_set_usage usage=0x%lx", usage); 1784 err = native_window_set_usage( 1785 mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 1786 if (err != 0) { 1787 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 1788 return err; 1789 } 1790 1791 int minUndequeuedBufs = 0; 1792 err = mNativeWindow->query(mNativeWindow.get(), 1793 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 1794 if (err != 0) { 1795 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 1796 strerror(-err), -err); 1797 return err; 1798 } 1799 1800 // XXX: Is this the right logic to use? It's not clear to me what the OMX 1801 // buffer counts refer to - how do they account for the renderer holding on 1802 // to buffers? 1803 if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { 1804 OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; 1805 def.nBufferCountActual = newBufferCount; 1806 err = mOMX->setParameter( 1807 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1808 1809 if (err != OK) { 1810 ALOGE("setting nBufferCountActual to %u failed: %d", 1811 newBufferCount, err); 1812 return err; 1813 } 1814 } 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 %u buffers from a native window of size %u 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 %u (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 %u", 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: %u)", 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 %u, 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 %u", 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: %u, size: %u, flags: 0x%08x, 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 %u, 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 %u", 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()->setInt32( 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("OMX_EventError(0x%08x, %u)", data1, data2); 2404 2405 setState(ERROR); 2406 break; 2407 } 2408 2409 case OMX_EventPortSettingsChanged: 2410 { 2411 CODEC_LOGV("OMX_EventPortSettingsChanged(port=%u, data2=0x%08x)", 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%x/0x%x", 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, %u, %u)", 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(%u)", 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(%u) 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(%u)", 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(%u)", 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 3512status_t OMXCodec::setAC3Format(int32_t numChannels, int32_t sampleRate) { 3513 OMX_AUDIO_PARAM_ANDROID_AC3TYPE def; 3514 InitOMXParams(&def); 3515 def.nPortIndex = kPortIndexInput; 3516 3517 status_t err = mOMX->getParameter( 3518 mNode, 3519 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 3520 &def, 3521 sizeof(def)); 3522 3523 if (err != OK) { 3524 return err; 3525 } 3526 3527 def.nChannels = numChannels; 3528 def.nSampleRate = sampleRate; 3529 3530 return mOMX->setParameter( 3531 mNode, 3532 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 3533 &def, 3534 sizeof(def)); 3535} 3536 3537void OMXCodec::setG711Format(int32_t numChannels) { 3538 CHECK(!mIsEncoder); 3539 setRawAudioFormat(kPortIndexInput, 8000, numChannels); 3540} 3541 3542void OMXCodec::setImageOutputFormat( 3543 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 3544 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 3545 3546#if 0 3547 OMX_INDEXTYPE index; 3548 status_t err = mOMX->get_extension_index( 3549 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 3550 CHECK_EQ(err, (status_t)OK); 3551 3552 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 3553 CHECK_EQ(err, (status_t)OK); 3554#endif 3555 3556 OMX_PARAM_PORTDEFINITIONTYPE def; 3557 InitOMXParams(&def); 3558 def.nPortIndex = kPortIndexOutput; 3559 3560 status_t err = mOMX->getParameter( 3561 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3562 CHECK_EQ(err, (status_t)OK); 3563 3564 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3565 3566 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3567 3568 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused); 3569 imageDef->eColorFormat = format; 3570 imageDef->nFrameWidth = width; 3571 imageDef->nFrameHeight = height; 3572 3573 switch (format) { 3574 case OMX_COLOR_FormatYUV420PackedPlanar: 3575 case OMX_COLOR_FormatYUV411Planar: 3576 { 3577 def.nBufferSize = (width * height * 3) / 2; 3578 break; 3579 } 3580 3581 case OMX_COLOR_FormatCbYCrY: 3582 { 3583 def.nBufferSize = width * height * 2; 3584 break; 3585 } 3586 3587 case OMX_COLOR_Format32bitARGB8888: 3588 { 3589 def.nBufferSize = width * height * 4; 3590 break; 3591 } 3592 3593 case OMX_COLOR_Format16bitARGB4444: 3594 case OMX_COLOR_Format16bitARGB1555: 3595 case OMX_COLOR_Format16bitRGB565: 3596 case OMX_COLOR_Format16bitBGR565: 3597 { 3598 def.nBufferSize = width * height * 2; 3599 break; 3600 } 3601 3602 default: 3603 CHECK(!"Should not be here. Unknown color format."); 3604 break; 3605 } 3606 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::setJPEGInputFormat( 3615 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 3616 OMX_PARAM_PORTDEFINITIONTYPE def; 3617 InitOMXParams(&def); 3618 def.nPortIndex = kPortIndexInput; 3619 3620 status_t err = mOMX->getParameter( 3621 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3622 CHECK_EQ(err, (status_t)OK); 3623 3624 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3625 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3626 3627 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG); 3628 imageDef->nFrameWidth = width; 3629 imageDef->nFrameHeight = height; 3630 3631 def.nBufferSize = compressedSize; 3632 def.nBufferCountActual = def.nBufferCountMin; 3633 3634 err = mOMX->setParameter( 3635 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3636 CHECK_EQ(err, (status_t)OK); 3637} 3638 3639void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 3640 CodecSpecificData *specific = 3641 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 3642 3643 specific->mSize = size; 3644 memcpy(specific->mData, data, size); 3645 3646 mCodecSpecificData.push(specific); 3647} 3648 3649void OMXCodec::clearCodecSpecificData() { 3650 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 3651 free(mCodecSpecificData.editItemAt(i)); 3652 } 3653 mCodecSpecificData.clear(); 3654 mCodecSpecificDataIndex = 0; 3655} 3656 3657status_t OMXCodec::start(MetaData *meta) { 3658 Mutex::Autolock autoLock(mLock); 3659 3660 if (mState != LOADED) { 3661 CODEC_LOGE("called start in the unexpected state: %d", mState); 3662 return UNKNOWN_ERROR; 3663 } 3664 3665 sp<MetaData> params = new MetaData; 3666 if (mQuirks & kWantsNALFragments) { 3667 params->setInt32(kKeyWantsNALFragments, true); 3668 } 3669 if (meta) { 3670 int64_t startTimeUs = 0; 3671 int64_t timeUs; 3672 if (meta->findInt64(kKeyTime, &timeUs)) { 3673 startTimeUs = timeUs; 3674 } 3675 params->setInt64(kKeyTime, startTimeUs); 3676 } 3677 3678 mCodecSpecificDataIndex = 0; 3679 mInitialBufferSubmit = true; 3680 mSignalledEOS = false; 3681 mNoMoreOutputData = false; 3682 mOutputPortSettingsHaveChanged = false; 3683 mSeekTimeUs = -1; 3684 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3685 mTargetTimeUs = -1; 3686 mFilledBuffers.clear(); 3687 mPaused = false; 3688 3689 status_t err; 3690 if (mIsEncoder) { 3691 // Calling init() before starting its source so that we can configure, 3692 // if supported, the source to use exactly the same number of input 3693 // buffers as requested by the encoder. 3694 if ((err = init()) != OK) { 3695 CODEC_LOGE("init failed: %d", err); 3696 return err; 3697 } 3698 3699 params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size()); 3700 err = mSource->start(params.get()); 3701 if (err != OK) { 3702 CODEC_LOGE("source failed to start: %d", err); 3703 stopOmxComponent_l(); 3704 } 3705 return err; 3706 } 3707 3708 // Decoder case 3709 if ((err = mSource->start(params.get())) != OK) { 3710 CODEC_LOGE("source failed to start: %d", err); 3711 return err; 3712 } 3713 return init(); 3714} 3715 3716status_t OMXCodec::stop() { 3717 CODEC_LOGV("stop mState=%d", mState); 3718 Mutex::Autolock autoLock(mLock); 3719 status_t err = stopOmxComponent_l(); 3720 mSource->stop(); 3721 3722 CODEC_LOGV("stopped in state %d", mState); 3723 return err; 3724} 3725 3726status_t OMXCodec::stopOmxComponent_l() { 3727 CODEC_LOGV("stopOmxComponent_l mState=%d", mState); 3728 3729 while (isIntermediateState(mState)) { 3730 mAsyncCompletion.wait(mLock); 3731 } 3732 3733 bool isError = false; 3734 switch (mState) { 3735 case LOADED: 3736 break; 3737 3738 case ERROR: 3739 { 3740 if (mPortStatus[kPortIndexOutput] == ENABLING) { 3741 // Codec is in a wedged state (technical term) 3742 // We've seen an output port settings change from the codec, 3743 // We've disabled the output port, then freed the output 3744 // buffers, initiated re-enabling the output port but 3745 // failed to reallocate the output buffers. 3746 // There doesn't seem to be a way to orderly transition 3747 // from executing->idle and idle->loaded now that the 3748 // output port hasn't been reenabled yet... 3749 // Simply free as many resources as we can and pretend 3750 // that we're in LOADED state so that the destructor 3751 // will free the component instance without asserting. 3752 freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */); 3753 freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */); 3754 setState(LOADED); 3755 break; 3756 } else { 3757 OMX_STATETYPE state = OMX_StateInvalid; 3758 status_t err = mOMX->getState(mNode, &state); 3759 CHECK_EQ(err, (status_t)OK); 3760 3761 if (state != OMX_StateExecuting) { 3762 break; 3763 } 3764 // else fall through to the idling code 3765 } 3766 3767 isError = true; 3768 } 3769 3770 case EXECUTING: 3771 { 3772 setState(EXECUTING_TO_IDLE); 3773 3774 if (mQuirks & kRequiresFlushBeforeShutdown) { 3775 CODEC_LOGV("This component requires a flush before transitioning " 3776 "from EXECUTING to IDLE..."); 3777 3778 bool emulateInputFlushCompletion = 3779 !flushPortAsync(kPortIndexInput); 3780 3781 bool emulateOutputFlushCompletion = 3782 !flushPortAsync(kPortIndexOutput); 3783 3784 if (emulateInputFlushCompletion) { 3785 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3786 } 3787 3788 if (emulateOutputFlushCompletion) { 3789 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3790 } 3791 } else { 3792 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 3793 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 3794 3795 status_t err = 3796 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 3797 CHECK_EQ(err, (status_t)OK); 3798 } 3799 3800 while (mState != LOADED && mState != ERROR) { 3801 mAsyncCompletion.wait(mLock); 3802 } 3803 3804 if (isError) { 3805 // We were in the ERROR state coming in, so restore that now 3806 // that we've idled the OMX component. 3807 setState(ERROR); 3808 } 3809 3810 break; 3811 } 3812 3813 default: 3814 { 3815 CHECK(!"should not be here."); 3816 break; 3817 } 3818 } 3819 3820 if (mLeftOverBuffer) { 3821 mLeftOverBuffer->release(); 3822 mLeftOverBuffer = NULL; 3823 } 3824 3825 return OK; 3826} 3827 3828sp<MetaData> OMXCodec::getFormat() { 3829 Mutex::Autolock autoLock(mLock); 3830 3831 return mOutputFormat; 3832} 3833 3834status_t OMXCodec::read( 3835 MediaBuffer **buffer, const ReadOptions *options) { 3836 status_t err = OK; 3837 *buffer = NULL; 3838 3839 Mutex::Autolock autoLock(mLock); 3840 3841 if (mState != EXECUTING && mState != RECONFIGURING) { 3842 return UNKNOWN_ERROR; 3843 } 3844 3845 bool seeking = false; 3846 int64_t seekTimeUs; 3847 ReadOptions::SeekMode seekMode; 3848 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 3849 seeking = true; 3850 } 3851 3852 if (mInitialBufferSubmit) { 3853 mInitialBufferSubmit = false; 3854 3855 if (seeking) { 3856 CHECK(seekTimeUs >= 0); 3857 mSeekTimeUs = seekTimeUs; 3858 mSeekMode = seekMode; 3859 3860 // There's no reason to trigger the code below, there's 3861 // nothing to flush yet. 3862 seeking = false; 3863 mPaused = false; 3864 } 3865 3866 drainInputBuffers(); 3867 3868 if (mState == EXECUTING) { 3869 // Otherwise mState == RECONFIGURING and this code will trigger 3870 // after the output port is reenabled. 3871 fillOutputBuffers(); 3872 } 3873 } 3874 3875 if (seeking) { 3876 while (mState == RECONFIGURING) { 3877 if ((err = waitForBufferFilled_l()) != OK) { 3878 return err; 3879 } 3880 } 3881 3882 if (mState != EXECUTING) { 3883 return UNKNOWN_ERROR; 3884 } 3885 3886 CODEC_LOGV("seeking to %" PRId64 " us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 3887 3888 mSignalledEOS = false; 3889 3890 CHECK(seekTimeUs >= 0); 3891 mSeekTimeUs = seekTimeUs; 3892 mSeekMode = seekMode; 3893 3894 mFilledBuffers.clear(); 3895 3896 CHECK_EQ((int)mState, (int)EXECUTING); 3897 3898 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 3899 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 3900 3901 if (emulateInputFlushCompletion) { 3902 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3903 } 3904 3905 if (emulateOutputFlushCompletion) { 3906 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3907 } 3908 3909 while (mSeekTimeUs >= 0) { 3910 if ((err = waitForBufferFilled_l()) != OK) { 3911 return err; 3912 } 3913 } 3914 } 3915 3916 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 3917 if ((err = waitForBufferFilled_l()) != OK) { 3918 return err; 3919 } 3920 } 3921 3922 if (mState == ERROR) { 3923 return UNKNOWN_ERROR; 3924 } 3925 3926 if (mFilledBuffers.empty()) { 3927 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 3928 } 3929 3930 if (mOutputPortSettingsHaveChanged) { 3931 mOutputPortSettingsHaveChanged = false; 3932 3933 return INFO_FORMAT_CHANGED; 3934 } 3935 3936 size_t index = *mFilledBuffers.begin(); 3937 mFilledBuffers.erase(mFilledBuffers.begin()); 3938 3939 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 3940 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3941 info->mStatus = OWNED_BY_CLIENT; 3942 3943 info->mMediaBuffer->add_ref(); 3944 if (mSkipCutBuffer != NULL) { 3945 mSkipCutBuffer->submit(info->mMediaBuffer); 3946 } 3947 *buffer = info->mMediaBuffer; 3948 3949 return OK; 3950} 3951 3952void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 3953 Mutex::Autolock autoLock(mLock); 3954 3955 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3956 for (size_t i = 0; i < buffers->size(); ++i) { 3957 BufferInfo *info = &buffers->editItemAt(i); 3958 3959 if (info->mMediaBuffer == buffer) { 3960 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 3961 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT); 3962 3963 info->mStatus = OWNED_BY_US; 3964 3965 if (buffer->graphicBuffer() == 0) { 3966 fillOutputBuffer(info); 3967 } else { 3968 sp<MetaData> metaData = info->mMediaBuffer->meta_data(); 3969 int32_t rendered = 0; 3970 if (!metaData->findInt32(kKeyRendered, &rendered)) { 3971 rendered = 0; 3972 } 3973 if (!rendered) { 3974 status_t err = cancelBufferToNativeWindow(info); 3975 if (err < 0) { 3976 return; 3977 } 3978 } 3979 3980 info->mStatus = OWNED_BY_NATIVE_WINDOW; 3981 3982 // Dequeue the next buffer from the native window. 3983 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow(); 3984 if (nextBufInfo == 0) { 3985 return; 3986 } 3987 3988 // Give the buffer to the OMX node to fill. 3989 fillOutputBuffer(nextBufInfo); 3990 } 3991 return; 3992 } 3993 } 3994 3995 CHECK(!"should not be here."); 3996} 3997 3998static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 3999 static const char *kNames[] = { 4000 "OMX_IMAGE_CodingUnused", 4001 "OMX_IMAGE_CodingAutoDetect", 4002 "OMX_IMAGE_CodingJPEG", 4003 "OMX_IMAGE_CodingJPEG2K", 4004 "OMX_IMAGE_CodingEXIF", 4005 "OMX_IMAGE_CodingTIFF", 4006 "OMX_IMAGE_CodingGIF", 4007 "OMX_IMAGE_CodingPNG", 4008 "OMX_IMAGE_CodingLZW", 4009 "OMX_IMAGE_CodingBMP", 4010 }; 4011 4012 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4013 4014 if (type < 0 || (size_t)type >= numNames) { 4015 return "UNKNOWN"; 4016 } else { 4017 return kNames[type]; 4018 } 4019} 4020 4021static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 4022 static const char *kNames[] = { 4023 "OMX_COLOR_FormatUnused", 4024 "OMX_COLOR_FormatMonochrome", 4025 "OMX_COLOR_Format8bitRGB332", 4026 "OMX_COLOR_Format12bitRGB444", 4027 "OMX_COLOR_Format16bitARGB4444", 4028 "OMX_COLOR_Format16bitARGB1555", 4029 "OMX_COLOR_Format16bitRGB565", 4030 "OMX_COLOR_Format16bitBGR565", 4031 "OMX_COLOR_Format18bitRGB666", 4032 "OMX_COLOR_Format18bitARGB1665", 4033 "OMX_COLOR_Format19bitARGB1666", 4034 "OMX_COLOR_Format24bitRGB888", 4035 "OMX_COLOR_Format24bitBGR888", 4036 "OMX_COLOR_Format24bitARGB1887", 4037 "OMX_COLOR_Format25bitARGB1888", 4038 "OMX_COLOR_Format32bitBGRA8888", 4039 "OMX_COLOR_Format32bitARGB8888", 4040 "OMX_COLOR_FormatYUV411Planar", 4041 "OMX_COLOR_FormatYUV411PackedPlanar", 4042 "OMX_COLOR_FormatYUV420Planar", 4043 "OMX_COLOR_FormatYUV420PackedPlanar", 4044 "OMX_COLOR_FormatYUV420SemiPlanar", 4045 "OMX_COLOR_FormatYUV422Planar", 4046 "OMX_COLOR_FormatYUV422PackedPlanar", 4047 "OMX_COLOR_FormatYUV422SemiPlanar", 4048 "OMX_COLOR_FormatYCbYCr", 4049 "OMX_COLOR_FormatYCrYCb", 4050 "OMX_COLOR_FormatCbYCrY", 4051 "OMX_COLOR_FormatCrYCbY", 4052 "OMX_COLOR_FormatYUV444Interleaved", 4053 "OMX_COLOR_FormatRawBayer8bit", 4054 "OMX_COLOR_FormatRawBayer10bit", 4055 "OMX_COLOR_FormatRawBayer8bitcompressed", 4056 "OMX_COLOR_FormatL2", 4057 "OMX_COLOR_FormatL4", 4058 "OMX_COLOR_FormatL8", 4059 "OMX_COLOR_FormatL16", 4060 "OMX_COLOR_FormatL24", 4061 "OMX_COLOR_FormatL32", 4062 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 4063 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 4064 "OMX_COLOR_Format18BitBGR666", 4065 "OMX_COLOR_Format24BitARGB6666", 4066 "OMX_COLOR_Format24BitABGR6666", 4067 }; 4068 4069 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4070 4071 if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 4072 return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; 4073 } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 4074 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 4075 } else if (type < 0 || (size_t)type >= numNames) { 4076 return "UNKNOWN"; 4077 } else { 4078 return kNames[type]; 4079 } 4080} 4081 4082static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 4083 static const char *kNames[] = { 4084 "OMX_VIDEO_CodingUnused", 4085 "OMX_VIDEO_CodingAutoDetect", 4086 "OMX_VIDEO_CodingMPEG2", 4087 "OMX_VIDEO_CodingH263", 4088 "OMX_VIDEO_CodingMPEG4", 4089 "OMX_VIDEO_CodingWMV", 4090 "OMX_VIDEO_CodingRV", 4091 "OMX_VIDEO_CodingAVC", 4092 "OMX_VIDEO_CodingMJPEG", 4093 }; 4094 4095 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4096 4097 if (type < 0 || (size_t)type >= numNames) { 4098 return "UNKNOWN"; 4099 } else { 4100 return kNames[type]; 4101 } 4102} 4103 4104static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 4105 static const char *kNames[] = { 4106 "OMX_AUDIO_CodingUnused", 4107 "OMX_AUDIO_CodingAutoDetect", 4108 "OMX_AUDIO_CodingPCM", 4109 "OMX_AUDIO_CodingADPCM", 4110 "OMX_AUDIO_CodingAMR", 4111 "OMX_AUDIO_CodingGSMFR", 4112 "OMX_AUDIO_CodingGSMEFR", 4113 "OMX_AUDIO_CodingGSMHR", 4114 "OMX_AUDIO_CodingPDCFR", 4115 "OMX_AUDIO_CodingPDCEFR", 4116 "OMX_AUDIO_CodingPDCHR", 4117 "OMX_AUDIO_CodingTDMAFR", 4118 "OMX_AUDIO_CodingTDMAEFR", 4119 "OMX_AUDIO_CodingQCELP8", 4120 "OMX_AUDIO_CodingQCELP13", 4121 "OMX_AUDIO_CodingEVRC", 4122 "OMX_AUDIO_CodingSMV", 4123 "OMX_AUDIO_CodingG711", 4124 "OMX_AUDIO_CodingG723", 4125 "OMX_AUDIO_CodingG726", 4126 "OMX_AUDIO_CodingG729", 4127 "OMX_AUDIO_CodingAAC", 4128 "OMX_AUDIO_CodingMP3", 4129 "OMX_AUDIO_CodingSBC", 4130 "OMX_AUDIO_CodingVORBIS", 4131 "OMX_AUDIO_CodingWMA", 4132 "OMX_AUDIO_CodingRA", 4133 "OMX_AUDIO_CodingMIDI", 4134 }; 4135 4136 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4137 4138 if (type < 0 || (size_t)type >= numNames) { 4139 return "UNKNOWN"; 4140 } else { 4141 return kNames[type]; 4142 } 4143} 4144 4145static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 4146 static const char *kNames[] = { 4147 "OMX_AUDIO_PCMModeLinear", 4148 "OMX_AUDIO_PCMModeALaw", 4149 "OMX_AUDIO_PCMModeMULaw", 4150 }; 4151 4152 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4153 4154 if (type < 0 || (size_t)type >= numNames) { 4155 return "UNKNOWN"; 4156 } else { 4157 return kNames[type]; 4158 } 4159} 4160 4161static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 4162 static const char *kNames[] = { 4163 "OMX_AUDIO_AMRBandModeUnused", 4164 "OMX_AUDIO_AMRBandModeNB0", 4165 "OMX_AUDIO_AMRBandModeNB1", 4166 "OMX_AUDIO_AMRBandModeNB2", 4167 "OMX_AUDIO_AMRBandModeNB3", 4168 "OMX_AUDIO_AMRBandModeNB4", 4169 "OMX_AUDIO_AMRBandModeNB5", 4170 "OMX_AUDIO_AMRBandModeNB6", 4171 "OMX_AUDIO_AMRBandModeNB7", 4172 "OMX_AUDIO_AMRBandModeWB0", 4173 "OMX_AUDIO_AMRBandModeWB1", 4174 "OMX_AUDIO_AMRBandModeWB2", 4175 "OMX_AUDIO_AMRBandModeWB3", 4176 "OMX_AUDIO_AMRBandModeWB4", 4177 "OMX_AUDIO_AMRBandModeWB5", 4178 "OMX_AUDIO_AMRBandModeWB6", 4179 "OMX_AUDIO_AMRBandModeWB7", 4180 "OMX_AUDIO_AMRBandModeWB8", 4181 }; 4182 4183 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4184 4185 if (type < 0 || (size_t)type >= numNames) { 4186 return "UNKNOWN"; 4187 } else { 4188 return kNames[type]; 4189 } 4190} 4191 4192static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 4193 static const char *kNames[] = { 4194 "OMX_AUDIO_AMRFrameFormatConformance", 4195 "OMX_AUDIO_AMRFrameFormatIF1", 4196 "OMX_AUDIO_AMRFrameFormatIF2", 4197 "OMX_AUDIO_AMRFrameFormatFSF", 4198 "OMX_AUDIO_AMRFrameFormatRTPPayload", 4199 "OMX_AUDIO_AMRFrameFormatITU", 4200 }; 4201 4202 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4203 4204 if (type < 0 || (size_t)type >= numNames) { 4205 return "UNKNOWN"; 4206 } else { 4207 return kNames[type]; 4208 } 4209} 4210 4211void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 4212 OMX_PARAM_PORTDEFINITIONTYPE def; 4213 InitOMXParams(&def); 4214 def.nPortIndex = portIndex; 4215 4216 status_t err = mOMX->getParameter( 4217 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4218 CHECK_EQ(err, (status_t)OK); 4219 4220 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 4221 4222 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 4223 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 4224 4225 printf(" nBufferCountActual = %" PRIu32 "\n", def.nBufferCountActual); 4226 printf(" nBufferCountMin = %" PRIu32 "\n", def.nBufferCountMin); 4227 printf(" nBufferSize = %" PRIu32 "\n", def.nBufferSize); 4228 4229 switch (def.eDomain) { 4230 case OMX_PortDomainImage: 4231 { 4232 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4233 4234 printf("\n"); 4235 printf(" // Image\n"); 4236 printf(" nFrameWidth = %" PRIu32 "\n", imageDef->nFrameWidth); 4237 printf(" nFrameHeight = %" PRIu32 "\n", imageDef->nFrameHeight); 4238 printf(" nStride = %" PRIu32 "\n", imageDef->nStride); 4239 4240 printf(" eCompressionFormat = %s\n", 4241 imageCompressionFormatString(imageDef->eCompressionFormat)); 4242 4243 printf(" eColorFormat = %s\n", 4244 colorFormatString(imageDef->eColorFormat)); 4245 4246 break; 4247 } 4248 4249 case OMX_PortDomainVideo: 4250 { 4251 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4252 4253 printf("\n"); 4254 printf(" // Video\n"); 4255 printf(" nFrameWidth = %" PRIu32 "\n", videoDef->nFrameWidth); 4256 printf(" nFrameHeight = %" PRIu32 "\n", videoDef->nFrameHeight); 4257 printf(" nStride = %" PRIu32 "\n", videoDef->nStride); 4258 4259 printf(" eCompressionFormat = %s\n", 4260 videoCompressionFormatString(videoDef->eCompressionFormat)); 4261 4262 printf(" eColorFormat = %s\n", 4263 colorFormatString(videoDef->eColorFormat)); 4264 4265 break; 4266 } 4267 4268 case OMX_PortDomainAudio: 4269 { 4270 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4271 4272 printf("\n"); 4273 printf(" // Audio\n"); 4274 printf(" eEncoding = %s\n", 4275 audioCodingTypeString(audioDef->eEncoding)); 4276 4277 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 4278 OMX_AUDIO_PARAM_PCMMODETYPE params; 4279 InitOMXParams(¶ms); 4280 params.nPortIndex = portIndex; 4281 4282 err = mOMX->getParameter( 4283 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4284 CHECK_EQ(err, (status_t)OK); 4285 4286 printf(" nSamplingRate = %" PRIu32 "\n", params.nSamplingRate); 4287 printf(" nChannels = %" PRIu32 "\n", params.nChannels); 4288 printf(" bInterleaved = %d\n", params.bInterleaved); 4289 printf(" nBitPerSample = %" PRIu32 "\n", params.nBitPerSample); 4290 4291 printf(" eNumData = %s\n", 4292 params.eNumData == OMX_NumericalDataSigned 4293 ? "signed" : "unsigned"); 4294 4295 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 4296 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 4297 OMX_AUDIO_PARAM_AMRTYPE amr; 4298 InitOMXParams(&amr); 4299 amr.nPortIndex = portIndex; 4300 4301 err = mOMX->getParameter( 4302 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4303 CHECK_EQ(err, (status_t)OK); 4304 4305 printf(" nChannels = %" PRIu32 "\n", amr.nChannels); 4306 printf(" eAMRBandMode = %s\n", 4307 amrBandModeString(amr.eAMRBandMode)); 4308 printf(" eAMRFrameFormat = %s\n", 4309 amrFrameFormatString(amr.eAMRFrameFormat)); 4310 } 4311 4312 break; 4313 } 4314 4315 default: 4316 { 4317 printf(" // Unknown\n"); 4318 break; 4319 } 4320 } 4321 4322 printf("}\n"); 4323} 4324 4325status_t OMXCodec::initNativeWindow() { 4326 // Enable use of a GraphicBuffer as the output for this node. This must 4327 // happen before getting the IndexParamPortDefinition parameter because it 4328 // will affect the pixel format that the node reports. 4329 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 4330 if (err != 0) { 4331 return err; 4332 } 4333 4334 return OK; 4335} 4336 4337void OMXCodec::initNativeWindowCrop() { 4338 int32_t left, top, right, bottom; 4339 4340 CHECK(mOutputFormat->findRect( 4341 kKeyCropRect, 4342 &left, &top, &right, &bottom)); 4343 4344 android_native_rect_t crop; 4345 crop.left = left; 4346 crop.top = top; 4347 crop.right = right + 1; 4348 crop.bottom = bottom + 1; 4349 4350 // We'll ignore any errors here, if the surface is 4351 // already invalid, we'll know soon enough. 4352 native_window_set_crop(mNativeWindow.get(), &crop); 4353} 4354 4355void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 4356 mOutputFormat = new MetaData; 4357 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 4358 if (mIsEncoder) { 4359 int32_t timeScale; 4360 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) { 4361 mOutputFormat->setInt32(kKeyTimeScale, timeScale); 4362 } 4363 } 4364 4365 OMX_PARAM_PORTDEFINITIONTYPE def; 4366 InitOMXParams(&def); 4367 def.nPortIndex = kPortIndexOutput; 4368 4369 status_t err = mOMX->getParameter( 4370 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4371 CHECK_EQ(err, (status_t)OK); 4372 4373 switch (def.eDomain) { 4374 case OMX_PortDomainImage: 4375 { 4376 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4377 CHECK_EQ((int)imageDef->eCompressionFormat, 4378 (int)OMX_IMAGE_CodingUnused); 4379 4380 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4381 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 4382 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 4383 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 4384 break; 4385 } 4386 4387 case OMX_PortDomainAudio: 4388 { 4389 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 4390 4391 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 4392 OMX_AUDIO_PARAM_PCMMODETYPE params; 4393 InitOMXParams(¶ms); 4394 params.nPortIndex = kPortIndexOutput; 4395 4396 err = mOMX->getParameter( 4397 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4398 CHECK_EQ(err, (status_t)OK); 4399 4400 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 4401 CHECK_EQ(params.nBitPerSample, 16u); 4402 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 4403 4404 int32_t numChannels, sampleRate; 4405 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4406 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4407 4408 if ((OMX_U32)numChannels != params.nChannels) { 4409 ALOGV("Codec outputs a different number of channels than " 4410 "the input stream contains (contains %d channels, " 4411 "codec outputs %ld channels).", 4412 numChannels, params.nChannels); 4413 } 4414 4415 if (sampleRate != (int32_t)params.nSamplingRate) { 4416 ALOGV("Codec outputs at different sampling rate than " 4417 "what the input stream contains (contains data at " 4418 "%d Hz, codec outputs %lu Hz)", 4419 sampleRate, params.nSamplingRate); 4420 } 4421 4422 mOutputFormat->setCString( 4423 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 4424 4425 // Use the codec-advertised number of channels, as some 4426 // codecs appear to output stereo even if the input data is 4427 // mono. If we know the codec lies about this information, 4428 // use the actual number of channels instead. 4429 mOutputFormat->setInt32( 4430 kKeyChannelCount, 4431 (mQuirks & kDecoderLiesAboutNumberOfChannels) 4432 ? numChannels : params.nChannels); 4433 4434 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate); 4435 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 4436 OMX_AUDIO_PARAM_AMRTYPE amr; 4437 InitOMXParams(&amr); 4438 amr.nPortIndex = kPortIndexOutput; 4439 4440 err = mOMX->getParameter( 4441 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4442 CHECK_EQ(err, (status_t)OK); 4443 4444 CHECK_EQ(amr.nChannels, 1u); 4445 mOutputFormat->setInt32(kKeyChannelCount, 1); 4446 4447 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 4448 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 4449 mOutputFormat->setCString( 4450 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 4451 mOutputFormat->setInt32(kKeySampleRate, 8000); 4452 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 4453 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 4454 mOutputFormat->setCString( 4455 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 4456 mOutputFormat->setInt32(kKeySampleRate, 16000); 4457 } else { 4458 CHECK(!"Unknown AMR band mode."); 4459 } 4460 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 4461 mOutputFormat->setCString( 4462 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 4463 int32_t numChannels, sampleRate, bitRate; 4464 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4465 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4466 inputFormat->findInt32(kKeyBitRate, &bitRate); 4467 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 4468 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 4469 mOutputFormat->setInt32(kKeyBitRate, bitRate); 4470 } else if (audio_def->eEncoding == 4471 (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidAC3) { 4472 mOutputFormat->setCString( 4473 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); 4474 int32_t numChannels, sampleRate, bitRate; 4475 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4476 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4477 inputFormat->findInt32(kKeyBitRate, &bitRate); 4478 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 4479 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 4480 mOutputFormat->setInt32(kKeyBitRate, bitRate); 4481 } else { 4482 CHECK(!"Should not be here. Unknown audio encoding."); 4483 } 4484 break; 4485 } 4486 4487 case OMX_PortDomainVideo: 4488 { 4489 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4490 4491 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 4492 mOutputFormat->setCString( 4493 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4494 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4495 mOutputFormat->setCString( 4496 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 4497 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 4498 mOutputFormat->setCString( 4499 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 4500 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 4501 mOutputFormat->setCString( 4502 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 4503 } else { 4504 CHECK(!"Unknown compression format."); 4505 } 4506 4507 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 4508 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 4509 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 4510 4511 if (!mIsEncoder) { 4512 OMX_CONFIG_RECTTYPE rect; 4513 InitOMXParams(&rect); 4514 rect.nPortIndex = kPortIndexOutput; 4515 status_t err = 4516 mOMX->getConfig( 4517 mNode, OMX_IndexConfigCommonOutputCrop, 4518 &rect, sizeof(rect)); 4519 4520 CODEC_LOGI( 4521 "video dimensions are %ld x %ld", 4522 video_def->nFrameWidth, video_def->nFrameHeight); 4523 4524 if (err == OK) { 4525 CHECK_GE(rect.nLeft, 0); 4526 CHECK_GE(rect.nTop, 0); 4527 CHECK_GE(rect.nWidth, 0u); 4528 CHECK_GE(rect.nHeight, 0u); 4529 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth); 4530 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight); 4531 4532 mOutputFormat->setRect( 4533 kKeyCropRect, 4534 rect.nLeft, 4535 rect.nTop, 4536 rect.nLeft + rect.nWidth - 1, 4537 rect.nTop + rect.nHeight - 1); 4538 4539 CODEC_LOGI( 4540 "Crop rect is %ld x %ld @ (%ld, %ld)", 4541 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop); 4542 } else { 4543 mOutputFormat->setRect( 4544 kKeyCropRect, 4545 0, 0, 4546 video_def->nFrameWidth - 1, 4547 video_def->nFrameHeight - 1); 4548 } 4549 4550 if (mNativeWindow != NULL) { 4551 initNativeWindowCrop(); 4552 } 4553 } 4554 break; 4555 } 4556 4557 default: 4558 { 4559 CHECK(!"should not be here, neither audio nor video."); 4560 break; 4561 } 4562 } 4563 4564 // If the input format contains rotation information, flag the output 4565 // format accordingly. 4566 4567 int32_t rotationDegrees; 4568 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) { 4569 mOutputFormat->setInt32(kKeyRotation, rotationDegrees); 4570 } 4571} 4572 4573status_t OMXCodec::pause() { 4574 Mutex::Autolock autoLock(mLock); 4575 4576 mPaused = true; 4577 4578 return OK; 4579} 4580 4581//////////////////////////////////////////////////////////////////////////////// 4582 4583status_t QueryCodecs( 4584 const sp<IOMX> &omx, 4585 const char *mime, bool queryDecoders, bool hwCodecOnly, 4586 Vector<CodecCapabilities> *results) { 4587 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 4588 results->clear(); 4589 4590 OMXCodec::findMatchingCodecs(mime, 4591 !queryDecoders /*createEncoder*/, 4592 NULL /*matchComponentName*/, 4593 hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/, 4594 &matchingCodecs); 4595 4596 for (size_t c = 0; c < matchingCodecs.size(); c++) { 4597 const char *componentName = matchingCodecs.itemAt(c).mName.string(); 4598 4599 results->push(); 4600 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4601 4602 status_t err = 4603 QueryCodec(omx, componentName, mime, !queryDecoders, caps); 4604 4605 if (err != OK) { 4606 results->removeAt(results->size() - 1); 4607 } 4608 } 4609 4610 return OK; 4611} 4612 4613status_t QueryCodec( 4614 const sp<IOMX> &omx, 4615 const char *componentName, const char *mime, 4616 bool isEncoder, 4617 CodecCapabilities *caps) { 4618 if (strncmp(componentName, "OMX.", 4)) { 4619 // Not an OpenMax component but a software codec. 4620 caps->mFlags = 0; 4621 caps->mComponentName = componentName; 4622 return OK; 4623 } 4624 4625 sp<OMXCodecObserver> observer = new OMXCodecObserver; 4626 IOMX::node_id node; 4627 status_t err = omx->allocateNode(componentName, observer, &node); 4628 4629 if (err != OK) { 4630 return err; 4631 } 4632 4633 OMXCodec::setComponentRole(omx, node, isEncoder, mime); 4634 4635 caps->mFlags = 0; 4636 caps->mComponentName = componentName; 4637 4638 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 4639 InitOMXParams(¶m); 4640 4641 param.nPortIndex = !isEncoder ? 0 : 1; 4642 4643 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 4644 err = omx->getParameter( 4645 node, OMX_IndexParamVideoProfileLevelQuerySupported, 4646 ¶m, sizeof(param)); 4647 4648 if (err != OK) { 4649 break; 4650 } 4651 4652 CodecProfileLevel profileLevel; 4653 profileLevel.mProfile = param.eProfile; 4654 profileLevel.mLevel = param.eLevel; 4655 4656 caps->mProfileLevels.push(profileLevel); 4657 } 4658 4659 // Color format query 4660 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 4661 InitOMXParams(&portFormat); 4662 portFormat.nPortIndex = !isEncoder ? 1 : 0; 4663 for (portFormat.nIndex = 0;; ++portFormat.nIndex) { 4664 err = omx->getParameter( 4665 node, OMX_IndexParamVideoPortFormat, 4666 &portFormat, sizeof(portFormat)); 4667 if (err != OK) { 4668 break; 4669 } 4670 caps->mColorFormats.push(portFormat.eColorFormat); 4671 } 4672 4673 if (!isEncoder && !strncmp(mime, "video/", 6)) { 4674 if (omx->storeMetaDataInBuffers( 4675 node, 1 /* port index */, OMX_TRUE) == OK || 4676 omx->prepareForAdaptivePlayback( 4677 node, 1 /* port index */, OMX_TRUE, 4678 1280 /* width */, 720 /* height */) == OK) { 4679 caps->mFlags |= CodecCapabilities::kFlagSupportsAdaptivePlayback; 4680 } 4681 } 4682 4683 CHECK_EQ(omx->freeNode(node), (status_t)OK); 4684 4685 return OK; 4686} 4687 4688status_t QueryCodecs( 4689 const sp<IOMX> &omx, 4690 const char *mimeType, bool queryDecoders, 4691 Vector<CodecCapabilities> *results) { 4692 return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results); 4693} 4694 4695// These are supposed be equivalent to the logic in 4696// "audio_channel_out_mask_from_count". 4697status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 4698 switch (numChannels) { 4699 case 1: 4700 map[0] = OMX_AUDIO_ChannelCF; 4701 break; 4702 case 2: 4703 map[0] = OMX_AUDIO_ChannelLF; 4704 map[1] = OMX_AUDIO_ChannelRF; 4705 break; 4706 case 3: 4707 map[0] = OMX_AUDIO_ChannelLF; 4708 map[1] = OMX_AUDIO_ChannelRF; 4709 map[2] = OMX_AUDIO_ChannelCF; 4710 break; 4711 case 4: 4712 map[0] = OMX_AUDIO_ChannelLF; 4713 map[1] = OMX_AUDIO_ChannelRF; 4714 map[2] = OMX_AUDIO_ChannelLR; 4715 map[3] = OMX_AUDIO_ChannelRR; 4716 break; 4717 case 5: 4718 map[0] = OMX_AUDIO_ChannelLF; 4719 map[1] = OMX_AUDIO_ChannelRF; 4720 map[2] = OMX_AUDIO_ChannelCF; 4721 map[3] = OMX_AUDIO_ChannelLR; 4722 map[4] = OMX_AUDIO_ChannelRR; 4723 break; 4724 case 6: 4725 map[0] = OMX_AUDIO_ChannelLF; 4726 map[1] = OMX_AUDIO_ChannelRF; 4727 map[2] = OMX_AUDIO_ChannelCF; 4728 map[3] = OMX_AUDIO_ChannelLFE; 4729 map[4] = OMX_AUDIO_ChannelLR; 4730 map[5] = OMX_AUDIO_ChannelRR; 4731 break; 4732 case 7: 4733 map[0] = OMX_AUDIO_ChannelLF; 4734 map[1] = OMX_AUDIO_ChannelRF; 4735 map[2] = OMX_AUDIO_ChannelCF; 4736 map[3] = OMX_AUDIO_ChannelLFE; 4737 map[4] = OMX_AUDIO_ChannelLR; 4738 map[5] = OMX_AUDIO_ChannelRR; 4739 map[6] = OMX_AUDIO_ChannelCS; 4740 break; 4741 case 8: 4742 map[0] = OMX_AUDIO_ChannelLF; 4743 map[1] = OMX_AUDIO_ChannelRF; 4744 map[2] = OMX_AUDIO_ChannelCF; 4745 map[3] = OMX_AUDIO_ChannelLFE; 4746 map[4] = OMX_AUDIO_ChannelLR; 4747 map[5] = OMX_AUDIO_ChannelRR; 4748 map[6] = OMX_AUDIO_ChannelLS; 4749 map[7] = OMX_AUDIO_ChannelRS; 4750 break; 4751 default: 4752 return -EINVAL; 4753 } 4754 4755 return OK; 4756} 4757 4758} // namespace android 4759