OMXCodec.cpp revision 2a3847ee1cbdaa8a65eee397a0173bb02211c459
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "OMXCodec" 19#include <utils/Log.h> 20 21#include "include/AACDecoder.h" 22#include "include/AMRNBDecoder.h" 23#include "include/AMRNBEncoder.h" 24#include "include/AMRWBDecoder.h" 25#include "include/AVCDecoder.h" 26#include "include/M4vH263Decoder.h" 27#include "include/MP3Decoder.h" 28 29#include "include/ESDS.h" 30 31#include <binder/IServiceManager.h> 32#include <binder/MemoryDealer.h> 33#include <binder/ProcessState.h> 34#include <media/IMediaPlayerService.h> 35#include <media/stagefright/MediaBuffer.h> 36#include <media/stagefright/MediaBufferGroup.h> 37#include <media/stagefright/MediaDebug.h> 38#include <media/stagefright/MediaDefs.h> 39#include <media/stagefright/MediaExtractor.h> 40#include <media/stagefright/MetaData.h> 41#include <media/stagefright/OMXCodec.h> 42#include <media/stagefright/Utils.h> 43#include <utils/Vector.h> 44 45#include <OMX_Audio.h> 46#include <OMX_Component.h> 47 48namespace android { 49 50static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 51 52struct CodecInfo { 53 const char *mime; 54 const char *codec; 55}; 56 57#define FACTORY_CREATE(name) \ 58static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \ 59 return new name(source); \ 60} 61 62#define FACTORY_REF(name) { #name, Make##name }, 63 64FACTORY_CREATE(MP3Decoder) 65FACTORY_CREATE(AMRNBDecoder) 66FACTORY_CREATE(AMRWBDecoder) 67FACTORY_CREATE(AACDecoder) 68FACTORY_CREATE(AVCDecoder) 69FACTORY_CREATE(M4vH263Decoder) 70FACTORY_CREATE(AMRNBEncoder) 71 72static sp<MediaSource> InstantiateSoftwareCodec( 73 const char *name, const sp<MediaSource> &source) { 74 struct FactoryInfo { 75 const char *name; 76 sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &); 77 }; 78 79 static const FactoryInfo kFactoryInfo[] = { 80 FACTORY_REF(MP3Decoder) 81 FACTORY_REF(AMRNBDecoder) 82 FACTORY_REF(AMRWBDecoder) 83 FACTORY_REF(AACDecoder) 84 FACTORY_REF(AVCDecoder) 85 FACTORY_REF(M4vH263Decoder) 86 FACTORY_REF(AMRNBEncoder) 87 }; 88 for (size_t i = 0; 89 i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 90 if (!strcmp(name, kFactoryInfo[i].name)) { 91 return (*kFactoryInfo[i].CreateFunc)(source); 92 } 93 } 94 95 return NULL; 96} 97 98#undef FACTORY_REF 99#undef FACTORY_CREATE 100 101static const CodecInfo kDecoderInfo[] = { 102 { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" }, 103 { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, 104 { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" }, 105 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" }, 106 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" }, 107 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" }, 108 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" }, 109 { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" }, 110 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" }, 111 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, 112 { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" }, 113 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, 114 { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" }, 115 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, 116 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, 117 { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" }, 118}; 119 120static const CodecInfo kEncoderInfo[] = { 121 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" }, 122 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" }, 123 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" }, 124 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, 125 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" }, 126 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, 127 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, 128 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" }, 129 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, 130 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, 131 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" }, 132 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, 133 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" }, 134}; 135 136#undef OPTIONAL 137 138#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 139#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 140#define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__) 141 142struct OMXCodecObserver : public BnOMXObserver { 143 OMXCodecObserver() { 144 } 145 146 void setCodec(const sp<OMXCodec> &target) { 147 mTarget = target; 148 } 149 150 // from IOMXObserver 151 virtual void onMessage(const omx_message &msg) { 152 sp<OMXCodec> codec = mTarget.promote(); 153 154 if (codec.get() != NULL) { 155 codec->on_message(msg); 156 } 157 } 158 159protected: 160 virtual ~OMXCodecObserver() {} 161 162private: 163 wp<OMXCodec> mTarget; 164 165 OMXCodecObserver(const OMXCodecObserver &); 166 OMXCodecObserver &operator=(const OMXCodecObserver &); 167}; 168 169static const char *GetCodec(const CodecInfo *info, size_t numInfos, 170 const char *mime, int index) { 171 CHECK(index >= 0); 172 for(size_t i = 0; i < numInfos; ++i) { 173 if (!strcasecmp(mime, info[i].mime)) { 174 if (index == 0) { 175 return info[i].codec; 176 } 177 178 --index; 179 } 180 } 181 182 return NULL; 183} 184 185enum { 186 kAVCProfileBaseline = 0x42, 187 kAVCProfileMain = 0x4d, 188 kAVCProfileExtended = 0x58, 189 kAVCProfileHigh = 0x64, 190 kAVCProfileHigh10 = 0x6e, 191 kAVCProfileHigh422 = 0x7a, 192 kAVCProfileHigh444 = 0xf4, 193 kAVCProfileCAVLC444Intra = 0x2c 194}; 195 196static const char *AVCProfileToString(uint8_t profile) { 197 switch (profile) { 198 case kAVCProfileBaseline: 199 return "Baseline"; 200 case kAVCProfileMain: 201 return "Main"; 202 case kAVCProfileExtended: 203 return "Extended"; 204 case kAVCProfileHigh: 205 return "High"; 206 case kAVCProfileHigh10: 207 return "High 10"; 208 case kAVCProfileHigh422: 209 return "High 422"; 210 case kAVCProfileHigh444: 211 return "High 444"; 212 case kAVCProfileCAVLC444Intra: 213 return "CAVLC 444 Intra"; 214 default: return "Unknown"; 215 } 216} 217 218template<class T> 219static void InitOMXParams(T *params) { 220 params->nSize = sizeof(T); 221 params->nVersion.s.nVersionMajor = 1; 222 params->nVersion.s.nVersionMinor = 0; 223 params->nVersion.s.nRevision = 0; 224 params->nVersion.s.nStep = 0; 225} 226 227static bool IsSoftwareCodec(const char *componentName) { 228 if (!strncmp("OMX.PV.", componentName, 7)) { 229 return true; 230 } 231 232 return false; 233} 234 235// A sort order in which non-OMX components are first, 236// followed by software codecs, i.e. OMX.PV.*, followed 237// by all the others. 238static int CompareSoftwareCodecsFirst( 239 const String8 *elem1, const String8 *elem2) { 240 bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4); 241 bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4); 242 243 if (isNotOMX1) { 244 if (isNotOMX2) { return 0; } 245 return -1; 246 } 247 if (isNotOMX2) { 248 return 1; 249 } 250 251 bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string()); 252 bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string()); 253 254 if (isSoftwareCodec1) { 255 if (isSoftwareCodec2) { return 0; } 256 return -1; 257 } 258 259 if (isSoftwareCodec2) { 260 return 1; 261 } 262 263 return 0; 264} 265 266// static 267uint32_t OMXCodec::getComponentQuirks(const char *componentName) { 268 uint32_t quirks = 0; 269 270 if (!strcmp(componentName, "OMX.PV.avcdec")) { 271 quirks |= kWantsNALFragments; 272 } 273 if (!strcmp(componentName, "OMX.TI.MP3.decode")) { 274 quirks |= kNeedsFlushBeforeDisable; 275 quirks |= kDecoderLiesAboutNumberOfChannels; 276 } 277 if (!strcmp(componentName, "OMX.TI.AAC.decode")) { 278 quirks |= kNeedsFlushBeforeDisable; 279 quirks |= kRequiresFlushCompleteEmulation; 280 } 281 if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) { 282 quirks |= kRequiresLoadedToIdleAfterAllocation; 283 quirks |= kRequiresAllocateBufferOnInputPorts; 284 quirks |= kRequiresAllocateBufferOnOutputPorts; 285 } 286 if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) { 287 quirks |= kRequiresAllocateBufferOnOutputPorts; 288 quirks |= kDefersOutputBufferAllocation; 289 } 290 291 if (!strncmp(componentName, "OMX.TI.", 7)) { 292 // Apparently I must not use OMX_UseBuffer on either input or 293 // output ports on any of the TI components or quote: 294 // "(I) may have unexpected problem (sic) which can be timing related 295 // and hard to reproduce." 296 297 quirks |= kRequiresAllocateBufferOnInputPorts; 298 quirks |= kRequiresAllocateBufferOnOutputPorts; 299 } 300 301 if (!strcmp(componentName, "OMX.TI.Video.Decoder")) { 302 quirks |= kInputBufferSizesAreBogus; 303 } 304 305 return quirks; 306} 307 308// static 309void OMXCodec::findMatchingCodecs( 310 const char *mime, 311 bool createEncoder, const char *matchComponentName, 312 uint32_t flags, 313 Vector<String8> *matchingCodecs) { 314 matchingCodecs->clear(); 315 316 for (int index = 0;; ++index) { 317 const char *componentName; 318 319 if (createEncoder) { 320 componentName = GetCodec( 321 kEncoderInfo, 322 sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 323 mime, index); 324 } else { 325 componentName = GetCodec( 326 kDecoderInfo, 327 sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 328 mime, index); 329 } 330 331 if (!componentName) { 332 break; 333 } 334 335 // If a specific codec is requested, skip the non-matching ones. 336 if (matchComponentName && strcmp(componentName, matchComponentName)) { 337 continue; 338 } 339 340 matchingCodecs->push(String8(componentName)); 341 } 342 343 if (flags & kPreferSoftwareCodecs) { 344 matchingCodecs->sort(CompareSoftwareCodecsFirst); 345 } 346} 347 348// static 349sp<MediaSource> OMXCodec::Create( 350 const sp<IOMX> &omx, 351 const sp<MetaData> &meta, bool createEncoder, 352 const sp<MediaSource> &source, 353 const char *matchComponentName, 354 uint32_t flags) { 355 const char *mime; 356 bool success = meta->findCString(kKeyMIMEType, &mime); 357 CHECK(success); 358 359 Vector<String8> matchingCodecs; 360 findMatchingCodecs( 361 mime, createEncoder, matchComponentName, flags, &matchingCodecs); 362 363 if (matchingCodecs.isEmpty()) { 364 return NULL; 365 } 366 367 sp<OMXCodecObserver> observer = new OMXCodecObserver; 368 IOMX::node_id node = 0; 369 370 const char *componentName; 371 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 372 componentName = matchingCodecs[i].string(); 373 374#if BUILD_WITH_FULL_STAGEFRIGHT 375 sp<MediaSource> softwareCodec = 376 InstantiateSoftwareCodec(componentName, source); 377 378 if (softwareCodec != NULL) { 379 LOGV("Successfully allocated software codec '%s'", componentName); 380 381 return softwareCodec; 382 } 383#endif 384 385 LOGV("Attempting to allocate OMX node '%s'", componentName); 386 387 status_t err = omx->allocateNode(componentName, observer, &node); 388 if (err == OK) { 389 LOGV("Successfully allocated OMX node '%s'", componentName); 390 391 sp<OMXCodec> codec = new OMXCodec( 392 omx, node, getComponentQuirks(componentName), 393 createEncoder, mime, componentName, 394 source); 395 396 observer->setCodec(codec); 397 398 err = codec->configureCodec(meta); 399 400 if (err == OK) { 401 return codec; 402 } 403 404 LOGV("Failed to configure codec '%s'", componentName); 405 } 406 } 407 408 return NULL; 409} 410 411status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { 412 uint32_t type; 413 const void *data; 414 size_t size; 415 if (meta->findData(kKeyESDS, &type, &data, &size)) { 416 ESDS esds((const char *)data, size); 417 CHECK_EQ(esds.InitCheck(), OK); 418 419 const void *codec_specific_data; 420 size_t codec_specific_data_size; 421 esds.getCodecSpecificInfo( 422 &codec_specific_data, &codec_specific_data_size); 423 424 addCodecSpecificData( 425 codec_specific_data, codec_specific_data_size); 426 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 427 // Parse the AVCDecoderConfigurationRecord 428 429 const uint8_t *ptr = (const uint8_t *)data; 430 431 CHECK(size >= 7); 432 CHECK_EQ(ptr[0], 1); // configurationVersion == 1 433 uint8_t profile = ptr[1]; 434 uint8_t level = ptr[3]; 435 436 // There is decodable content out there that fails the following 437 // assertion, let's be lenient for now... 438 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 439 440 size_t lengthSize = 1 + (ptr[4] & 3); 441 442 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 443 // violates it... 444 // CHECK((ptr[5] >> 5) == 7); // reserved 445 446 size_t numSeqParameterSets = ptr[5] & 31; 447 448 ptr += 6; 449 size -= 6; 450 451 for (size_t i = 0; i < numSeqParameterSets; ++i) { 452 CHECK(size >= 2); 453 size_t length = U16_AT(ptr); 454 455 ptr += 2; 456 size -= 2; 457 458 CHECK(size >= length); 459 460 addCodecSpecificData(ptr, length); 461 462 ptr += length; 463 size -= length; 464 } 465 466 CHECK(size >= 1); 467 size_t numPictureParameterSets = *ptr; 468 ++ptr; 469 --size; 470 471 for (size_t i = 0; i < numPictureParameterSets; ++i) { 472 CHECK(size >= 2); 473 size_t length = U16_AT(ptr); 474 475 ptr += 2; 476 size -= 2; 477 478 CHECK(size >= length); 479 480 addCodecSpecificData(ptr, length); 481 482 ptr += length; 483 size -= length; 484 } 485 486 LOGV("AVC profile = %d (%s), level = %d", 487 (int)profile, AVCProfileToString(profile), (int)level / 10); 488 489 if (!strcmp(mComponentName, "OMX.TI.Video.Decoder") 490 && (profile != kAVCProfileBaseline || level > 39)) { 491 // This stream exceeds the decoder's capabilities. The decoder 492 // does not handle this gracefully and would clobber the heap 493 // and wreak havoc instead... 494 495 LOGE("Profile and/or level exceed the decoder's capabilities."); 496 return ERROR_UNSUPPORTED; 497 } 498 } 499 500 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) { 501 setAMRFormat(false /* isWAMR */); 502 } 503 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) { 504 setAMRFormat(true /* isWAMR */); 505 } 506 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) { 507 int32_t numChannels, sampleRate; 508 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 509 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 510 511 setAACFormat(numChannels, sampleRate); 512 } 513 if (!strncasecmp(mMIME, "video/", 6)) { 514 int32_t width, height; 515 bool success = meta->findInt32(kKeyWidth, &width); 516 success = success && meta->findInt32(kKeyHeight, &height); 517 CHECK(success); 518 519 if (mIsEncoder) { 520 setVideoInputFormat(mMIME, width, height); 521 } else { 522 status_t err = setVideoOutputFormat( 523 mMIME, width, height); 524 525 if (err != OK) { 526 return err; 527 } 528 } 529 } 530 if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG) 531 && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) { 532 OMX_COLOR_FORMATTYPE format = 533 OMX_COLOR_Format32bitARGB8888; 534 // OMX_COLOR_FormatYUV420PackedPlanar; 535 // OMX_COLOR_FormatCbYCrY; 536 // OMX_COLOR_FormatYUV411Planar; 537 538 int32_t width, height; 539 bool success = meta->findInt32(kKeyWidth, &width); 540 success = success && meta->findInt32(kKeyHeight, &height); 541 542 int32_t compressedSize; 543 success = success && meta->findInt32( 544 kKeyMaxInputSize, &compressedSize); 545 546 CHECK(success); 547 CHECK(compressedSize > 0); 548 549 setImageOutputFormat(format, width, height); 550 setJPEGInputFormat(width, height, (OMX_U32)compressedSize); 551 } 552 553 int32_t maxInputSize; 554 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 555 setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize); 556 } 557 558 if (!strcmp(mComponentName, "OMX.TI.AMR.encode") 559 || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) { 560 setMinBufferSize(kPortIndexOutput, 8192); // XXX 561 } 562 563 initOutputFormat(meta); 564 565 return OK; 566} 567 568void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { 569 OMX_PARAM_PORTDEFINITIONTYPE def; 570 InitOMXParams(&def); 571 def.nPortIndex = portIndex; 572 573 status_t err = mOMX->getParameter( 574 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 575 CHECK_EQ(err, OK); 576 577 if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus)) 578 || (def.nBufferSize < size)) { 579 def.nBufferSize = size; 580 } 581 582 err = mOMX->setParameter( 583 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 584 CHECK_EQ(err, OK); 585 586 err = mOMX->getParameter( 587 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 588 CHECK_EQ(err, OK); 589 590 // Make sure the setting actually stuck. 591 if (portIndex == kPortIndexInput 592 && (mQuirks & kInputBufferSizesAreBogus)) { 593 CHECK_EQ(def.nBufferSize, size); 594 } else { 595 CHECK(def.nBufferSize >= size); 596 } 597} 598 599status_t OMXCodec::setVideoPortFormatType( 600 OMX_U32 portIndex, 601 OMX_VIDEO_CODINGTYPE compressionFormat, 602 OMX_COLOR_FORMATTYPE colorFormat) { 603 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 604 InitOMXParams(&format); 605 format.nPortIndex = portIndex; 606 format.nIndex = 0; 607 bool found = false; 608 609 OMX_U32 index = 0; 610 for (;;) { 611 format.nIndex = index; 612 status_t err = mOMX->getParameter( 613 mNode, OMX_IndexParamVideoPortFormat, 614 &format, sizeof(format)); 615 616 if (err != OK) { 617 return err; 618 } 619 620 // The following assertion is violated by TI's video decoder. 621 // CHECK_EQ(format.nIndex, index); 622 623#if 1 624 CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", 625 portIndex, 626 index, format.eCompressionFormat, format.eColorFormat); 627#endif 628 629 if (!strcmp("OMX.TI.Video.encoder", mComponentName)) { 630 if (portIndex == kPortIndexInput 631 && colorFormat == format.eColorFormat) { 632 // eCompressionFormat does not seem right. 633 found = true; 634 break; 635 } 636 if (portIndex == kPortIndexOutput 637 && compressionFormat == format.eCompressionFormat) { 638 // eColorFormat does not seem right. 639 found = true; 640 break; 641 } 642 } 643 644 if (format.eCompressionFormat == compressionFormat 645 && format.eColorFormat == colorFormat) { 646 found = true; 647 break; 648 } 649 650 ++index; 651 } 652 653 if (!found) { 654 return UNKNOWN_ERROR; 655 } 656 657 CODEC_LOGV("found a match."); 658 status_t err = mOMX->setParameter( 659 mNode, OMX_IndexParamVideoPortFormat, 660 &format, sizeof(format)); 661 662 return err; 663} 664 665static size_t getFrameSize( 666 OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) { 667 switch (colorFormat) { 668 case OMX_COLOR_FormatYCbYCr: 669 case OMX_COLOR_FormatCbYCrY: 670 return width * height * 2; 671 672 case OMX_COLOR_FormatYUV420SemiPlanar: 673 return (width * height * 3) / 2; 674 675 default: 676 CHECK(!"Should not be here. Unsupported color format."); 677 break; 678 } 679} 680 681void OMXCodec::setVideoInputFormat( 682 const char *mime, OMX_U32 width, OMX_U32 height) { 683 CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height); 684 685 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 686 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 687 compressionFormat = OMX_VIDEO_CodingAVC; 688 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 689 compressionFormat = OMX_VIDEO_CodingMPEG4; 690 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 691 compressionFormat = OMX_VIDEO_CodingH263; 692 } else { 693 LOGE("Not a supported video mime type: %s", mime); 694 CHECK(!"Should not be here. Not a supported video mime type."); 695 } 696 697 OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 698 if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) { 699 colorFormat = OMX_COLOR_FormatYCbYCr; 700 } 701 702 CHECK_EQ(setVideoPortFormatType( 703 kPortIndexInput, OMX_VIDEO_CodingUnused, 704 colorFormat), OK); 705 706 CHECK_EQ(setVideoPortFormatType( 707 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused), 708 OK); 709 710 OMX_PARAM_PORTDEFINITIONTYPE def; 711 InitOMXParams(&def); 712 def.nPortIndex = kPortIndexOutput; 713 714 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 715 716 status_t err = mOMX->getParameter( 717 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 718 719 CHECK_EQ(err, OK); 720 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 721 722 video_def->nFrameWidth = width; 723 video_def->nFrameHeight = height; 724 725 video_def->eCompressionFormat = compressionFormat; 726 video_def->eColorFormat = OMX_COLOR_FormatUnused; 727 728 err = mOMX->setParameter( 729 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 730 CHECK_EQ(err, OK); 731 732 //////////////////////////////////////////////////////////////////////////// 733 734 InitOMXParams(&def); 735 def.nPortIndex = kPortIndexInput; 736 737 err = mOMX->getParameter( 738 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 739 CHECK_EQ(err, OK); 740 741 def.nBufferSize = getFrameSize(colorFormat, width, height); 742 CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize); 743 744 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 745 746 video_def->nFrameWidth = width; 747 video_def->nFrameHeight = height; 748 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 749 video_def->eColorFormat = colorFormat; 750 751 video_def->xFramerate = 24 << 16; // XXX crucial! 752 753 err = mOMX->setParameter( 754 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 755 CHECK_EQ(err, OK); 756 757 switch (compressionFormat) { 758 case OMX_VIDEO_CodingMPEG4: 759 { 760 CHECK_EQ(setupMPEG4EncoderParameters(), OK); 761 break; 762 } 763 764 case OMX_VIDEO_CodingH263: 765 break; 766 767 case OMX_VIDEO_CodingAVC: 768 { 769 CHECK_EQ(setupAVCEncoderParameters(), OK); 770 break; 771 } 772 773 default: 774 CHECK(!"Support for this compressionFormat to be implemented."); 775 break; 776 } 777} 778 779status_t OMXCodec::setupMPEG4EncoderParameters() { 780 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 781 InitOMXParams(&mpeg4type); 782 mpeg4type.nPortIndex = kPortIndexOutput; 783 784 status_t err = mOMX->getParameter( 785 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 786 CHECK_EQ(err, OK); 787 788 mpeg4type.nSliceHeaderSpacing = 0; 789 mpeg4type.bSVH = OMX_FALSE; 790 mpeg4type.bGov = OMX_FALSE; 791 792 mpeg4type.nAllowedPictureTypes = 793 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 794 795 mpeg4type.nPFrames = 23; 796 mpeg4type.nBFrames = 0; 797 798 mpeg4type.nIDCVLCThreshold = 0; 799 mpeg4type.bACPred = OMX_TRUE; 800 mpeg4type.nMaxPacketSize = 256; 801 mpeg4type.nTimeIncRes = 1000; 802 mpeg4type.nHeaderExtension = 0; 803 mpeg4type.bReversibleVLC = OMX_FALSE; 804 805 mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore; 806 mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2; 807 808 err = mOMX->setParameter( 809 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 810 CHECK_EQ(err, OK); 811 812 // ---------------- 813 814 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 815 InitOMXParams(&bitrateType); 816 bitrateType.nPortIndex = kPortIndexOutput; 817 818 err = mOMX->getParameter( 819 mNode, OMX_IndexParamVideoBitrate, 820 &bitrateType, sizeof(bitrateType)); 821 CHECK_EQ(err, OK); 822 823 bitrateType.eControlRate = OMX_Video_ControlRateVariable; 824 bitrateType.nTargetBitrate = 1000000; 825 826 err = mOMX->setParameter( 827 mNode, OMX_IndexParamVideoBitrate, 828 &bitrateType, sizeof(bitrateType)); 829 CHECK_EQ(err, OK); 830 831 // ---------------- 832 833 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 834 InitOMXParams(&errorCorrectionType); 835 errorCorrectionType.nPortIndex = kPortIndexOutput; 836 837 err = mOMX->getParameter( 838 mNode, OMX_IndexParamVideoErrorCorrection, 839 &errorCorrectionType, sizeof(errorCorrectionType)); 840 CHECK_EQ(err, OK); 841 842 errorCorrectionType.bEnableHEC = OMX_FALSE; 843 errorCorrectionType.bEnableResync = OMX_TRUE; 844 errorCorrectionType.nResynchMarkerSpacing = 256; 845 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 846 errorCorrectionType.bEnableRVLC = OMX_FALSE; 847 848 err = mOMX->setParameter( 849 mNode, OMX_IndexParamVideoErrorCorrection, 850 &errorCorrectionType, sizeof(errorCorrectionType)); 851 CHECK_EQ(err, OK); 852 853 return OK; 854} 855 856status_t OMXCodec::setupAVCEncoderParameters() { 857 OMX_VIDEO_PARAM_AVCTYPE h264type; 858 InitOMXParams(&h264type); 859 h264type.nPortIndex = kPortIndexOutput; 860 861 status_t err = mOMX->getParameter( 862 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 863 CHECK_EQ(err, OK); 864 865 h264type.nAllowedPictureTypes = 866 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 867 868 h264type.nSliceHeaderSpacing = 0; 869 h264type.nBFrames = 0; 870 h264type.bUseHadamard = OMX_TRUE; 871 h264type.nRefFrames = 1; 872 h264type.nRefIdx10ActiveMinus1 = 0; 873 h264type.nRefIdx11ActiveMinus1 = 0; 874 h264type.bEnableUEP = OMX_FALSE; 875 h264type.bEnableFMO = OMX_FALSE; 876 h264type.bEnableASO = OMX_FALSE; 877 h264type.bEnableRS = OMX_FALSE; 878 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 879 h264type.eLevel = OMX_VIDEO_AVCLevel1b; 880 h264type.bFrameMBsOnly = OMX_TRUE; 881 h264type.bMBAFF = OMX_FALSE; 882 h264type.bEntropyCodingCABAC = OMX_FALSE; 883 h264type.bWeightedPPrediction = OMX_FALSE; 884 h264type.bconstIpred = OMX_FALSE; 885 h264type.bDirect8x8Inference = OMX_FALSE; 886 h264type.bDirectSpatialTemporal = OMX_FALSE; 887 h264type.nCabacInitIdc = 0; 888 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 889 890 err = mOMX->setParameter( 891 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 892 CHECK_EQ(err, OK); 893 894 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 895 InitOMXParams(&bitrateType); 896 bitrateType.nPortIndex = kPortIndexOutput; 897 898 err = mOMX->getParameter( 899 mNode, OMX_IndexParamVideoBitrate, 900 &bitrateType, sizeof(bitrateType)); 901 CHECK_EQ(err, OK); 902 903 bitrateType.eControlRate = OMX_Video_ControlRateVariable; 904 bitrateType.nTargetBitrate = 1000000; 905 906 err = mOMX->setParameter( 907 mNode, OMX_IndexParamVideoBitrate, 908 &bitrateType, sizeof(bitrateType)); 909 CHECK_EQ(err, OK); 910 911 return OK; 912} 913 914status_t OMXCodec::setVideoOutputFormat( 915 const char *mime, OMX_U32 width, OMX_U32 height) { 916 CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); 917 918 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 919 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 920 compressionFormat = OMX_VIDEO_CodingAVC; 921 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 922 compressionFormat = OMX_VIDEO_CodingMPEG4; 923 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 924 compressionFormat = OMX_VIDEO_CodingH263; 925 } else { 926 LOGE("Not a supported video mime type: %s", mime); 927 CHECK(!"Should not be here. Not a supported video mime type."); 928 } 929 930 status_t err = setVideoPortFormatType( 931 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 932 933 if (err != OK) { 934 return err; 935 } 936 937#if 1 938 { 939 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 940 InitOMXParams(&format); 941 format.nPortIndex = kPortIndexOutput; 942 format.nIndex = 0; 943 944 status_t err = mOMX->getParameter( 945 mNode, OMX_IndexParamVideoPortFormat, 946 &format, sizeof(format)); 947 CHECK_EQ(err, OK); 948 CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused); 949 950 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 951 952 CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 953 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 954 || format.eColorFormat == OMX_COLOR_FormatCbYCrY 955 || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 956 957 err = mOMX->setParameter( 958 mNode, OMX_IndexParamVideoPortFormat, 959 &format, sizeof(format)); 960 961 if (err != OK) { 962 return err; 963 } 964 } 965#endif 966 967 OMX_PARAM_PORTDEFINITIONTYPE def; 968 InitOMXParams(&def); 969 def.nPortIndex = kPortIndexInput; 970 971 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 972 973 err = mOMX->getParameter( 974 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 975 976 CHECK_EQ(err, OK); 977 978#if 1 979 // XXX Need a (much) better heuristic to compute input buffer sizes. 980 const size_t X = 64 * 1024; 981 if (def.nBufferSize < X) { 982 def.nBufferSize = X; 983 } 984#endif 985 986 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 987 988 video_def->nFrameWidth = width; 989 video_def->nFrameHeight = height; 990 991 video_def->eCompressionFormat = compressionFormat; 992 video_def->eColorFormat = OMX_COLOR_FormatUnused; 993 994 err = mOMX->setParameter( 995 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 996 997 if (err != OK) { 998 return err; 999 } 1000 1001 //////////////////////////////////////////////////////////////////////////// 1002 1003 InitOMXParams(&def); 1004 def.nPortIndex = kPortIndexOutput; 1005 1006 err = mOMX->getParameter( 1007 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1008 CHECK_EQ(err, OK); 1009 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 1010 1011#if 0 1012 def.nBufferSize = 1013 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 1014#endif 1015 1016 video_def->nFrameWidth = width; 1017 video_def->nFrameHeight = height; 1018 1019 err = mOMX->setParameter( 1020 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1021 1022 return err; 1023} 1024 1025OMXCodec::OMXCodec( 1026 const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, 1027 bool isEncoder, 1028 const char *mime, 1029 const char *componentName, 1030 const sp<MediaSource> &source) 1031 : mOMX(omx), 1032 mOMXLivesLocally(omx->livesLocally(getpid())), 1033 mNode(node), 1034 mQuirks(quirks), 1035 mIsEncoder(isEncoder), 1036 mMIME(strdup(mime)), 1037 mComponentName(strdup(componentName)), 1038 mSource(source), 1039 mCodecSpecificDataIndex(0), 1040 mState(LOADED), 1041 mInitialBufferSubmit(true), 1042 mSignalledEOS(false), 1043 mNoMoreOutputData(false), 1044 mOutputPortSettingsHaveChanged(false), 1045 mSeekTimeUs(-1) { 1046 mPortStatus[kPortIndexInput] = ENABLED; 1047 mPortStatus[kPortIndexOutput] = ENABLED; 1048 1049 setComponentRole(); 1050} 1051 1052// static 1053void OMXCodec::setComponentRole( 1054 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, 1055 const char *mime) { 1056 struct MimeToRole { 1057 const char *mime; 1058 const char *decoderRole; 1059 const char *encoderRole; 1060 }; 1061 1062 static const MimeToRole kMimeToRole[] = { 1063 { MEDIA_MIMETYPE_AUDIO_MPEG, 1064 "audio_decoder.mp3", "audio_encoder.mp3" }, 1065 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1066 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1067 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1068 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1069 { MEDIA_MIMETYPE_AUDIO_AAC, 1070 "audio_decoder.aac", "audio_encoder.aac" }, 1071 { MEDIA_MIMETYPE_VIDEO_AVC, 1072 "video_decoder.avc", "video_encoder.avc" }, 1073 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1074 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1075 { MEDIA_MIMETYPE_VIDEO_H263, 1076 "video_decoder.h263", "video_encoder.h263" }, 1077 }; 1078 1079 static const size_t kNumMimeToRole = 1080 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1081 1082 size_t i; 1083 for (i = 0; i < kNumMimeToRole; ++i) { 1084 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1085 break; 1086 } 1087 } 1088 1089 if (i == kNumMimeToRole) { 1090 return; 1091 } 1092 1093 const char *role = 1094 isEncoder ? kMimeToRole[i].encoderRole 1095 : kMimeToRole[i].decoderRole; 1096 1097 if (role != NULL) { 1098 OMX_PARAM_COMPONENTROLETYPE roleParams; 1099 InitOMXParams(&roleParams); 1100 1101 strncpy((char *)roleParams.cRole, 1102 role, OMX_MAX_STRINGNAME_SIZE - 1); 1103 1104 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1105 1106 status_t err = omx->setParameter( 1107 node, OMX_IndexParamStandardComponentRole, 1108 &roleParams, sizeof(roleParams)); 1109 1110 if (err != OK) { 1111 LOGW("Failed to set standard component role '%s'.", role); 1112 } 1113 } 1114} 1115 1116void OMXCodec::setComponentRole() { 1117 setComponentRole(mOMX, mNode, mIsEncoder, mMIME); 1118} 1119 1120OMXCodec::~OMXCodec() { 1121 CHECK(mState == LOADED || mState == ERROR); 1122 1123 status_t err = mOMX->freeNode(mNode); 1124 CHECK_EQ(err, OK); 1125 1126 mNode = NULL; 1127 setState(DEAD); 1128 1129 clearCodecSpecificData(); 1130 1131 free(mComponentName); 1132 mComponentName = NULL; 1133 1134 free(mMIME); 1135 mMIME = NULL; 1136} 1137 1138status_t OMXCodec::init() { 1139 // mLock is held. 1140 1141 CHECK_EQ(mState, LOADED); 1142 1143 status_t err; 1144 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 1145 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1146 CHECK_EQ(err, OK); 1147 setState(LOADED_TO_IDLE); 1148 } 1149 1150 err = allocateBuffers(); 1151 CHECK_EQ(err, OK); 1152 1153 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 1154 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1155 CHECK_EQ(err, OK); 1156 1157 setState(LOADED_TO_IDLE); 1158 } 1159 1160 while (mState != EXECUTING && mState != ERROR) { 1161 mAsyncCompletion.wait(mLock); 1162 } 1163 1164 return mState == ERROR ? UNKNOWN_ERROR : OK; 1165} 1166 1167// static 1168bool OMXCodec::isIntermediateState(State state) { 1169 return state == LOADED_TO_IDLE 1170 || state == IDLE_TO_EXECUTING 1171 || state == EXECUTING_TO_IDLE 1172 || state == IDLE_TO_LOADED 1173 || state == RECONFIGURING; 1174} 1175 1176status_t OMXCodec::allocateBuffers() { 1177 status_t err = allocateBuffersOnPort(kPortIndexInput); 1178 1179 if (err != OK) { 1180 return err; 1181 } 1182 1183 return allocateBuffersOnPort(kPortIndexOutput); 1184} 1185 1186status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 1187 OMX_PARAM_PORTDEFINITIONTYPE def; 1188 InitOMXParams(&def); 1189 def.nPortIndex = portIndex; 1190 1191 status_t err = mOMX->getParameter( 1192 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1193 1194 if (err != OK) { 1195 return err; 1196 } 1197 1198 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 1199 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 1200 1201 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 1202 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 1203 CHECK(mem.get() != NULL); 1204 1205 BufferInfo info; 1206 info.mData = NULL; 1207 info.mSize = def.nBufferSize; 1208 1209 IOMX::buffer_id buffer; 1210 if (portIndex == kPortIndexInput 1211 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) { 1212 if (mOMXLivesLocally) { 1213 mem.clear(); 1214 1215 err = mOMX->allocateBuffer( 1216 mNode, portIndex, def.nBufferSize, &buffer, 1217 &info.mData); 1218 } else { 1219 err = mOMX->allocateBufferWithBackup( 1220 mNode, portIndex, mem, &buffer); 1221 } 1222 } else if (portIndex == kPortIndexOutput 1223 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 1224 if (mOMXLivesLocally) { 1225 mem.clear(); 1226 1227 err = mOMX->allocateBuffer( 1228 mNode, portIndex, def.nBufferSize, &buffer, 1229 &info.mData); 1230 } else { 1231 err = mOMX->allocateBufferWithBackup( 1232 mNode, portIndex, mem, &buffer); 1233 } 1234 } else { 1235 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 1236 } 1237 1238 if (err != OK) { 1239 LOGE("allocate_buffer_with_backup failed"); 1240 return err; 1241 } 1242 1243 if (mem != NULL) { 1244 info.mData = mem->pointer(); 1245 } 1246 1247 info.mBuffer = buffer; 1248 info.mOwnedByComponent = false; 1249 info.mMem = mem; 1250 info.mMediaBuffer = NULL; 1251 1252 if (portIndex == kPortIndexOutput) { 1253 if (!(mOMXLivesLocally 1254 && (mQuirks & kRequiresAllocateBufferOnOutputPorts) 1255 && (mQuirks & kDefersOutputBufferAllocation))) { 1256 // If the node does not fill in the buffer ptr at this time, 1257 // we will defer creating the MediaBuffer until receiving 1258 // the first FILL_BUFFER_DONE notification instead. 1259 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); 1260 info.mMediaBuffer->setObserver(this); 1261 } 1262 } 1263 1264 mPortBuffers[portIndex].push(info); 1265 1266 CODEC_LOGV("allocated buffer %p on %s port", buffer, 1267 portIndex == kPortIndexInput ? "input" : "output"); 1268 } 1269 1270 // dumpPortStatus(portIndex); 1271 1272 return OK; 1273} 1274 1275void OMXCodec::on_message(const omx_message &msg) { 1276 Mutex::Autolock autoLock(mLock); 1277 1278 switch (msg.type) { 1279 case omx_message::EVENT: 1280 { 1281 onEvent( 1282 msg.u.event_data.event, msg.u.event_data.data1, 1283 msg.u.event_data.data2); 1284 1285 break; 1286 } 1287 1288 case omx_message::EMPTY_BUFFER_DONE: 1289 { 1290 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 1291 1292 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 1293 1294 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1295 size_t i = 0; 1296 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 1297 ++i; 1298 } 1299 1300 CHECK(i < buffers->size()); 1301 if (!(*buffers)[i].mOwnedByComponent) { 1302 LOGW("We already own input buffer %p, yet received " 1303 "an EMPTY_BUFFER_DONE.", buffer); 1304 } 1305 1306 buffers->editItemAt(i).mOwnedByComponent = false; 1307 1308 if (mPortStatus[kPortIndexInput] == DISABLING) { 1309 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 1310 1311 status_t err = 1312 mOMX->freeBuffer(mNode, kPortIndexInput, buffer); 1313 CHECK_EQ(err, OK); 1314 1315 buffers->removeAt(i); 1316 } else if (mState != ERROR 1317 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 1318 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED); 1319 drainInputBuffer(&buffers->editItemAt(i)); 1320 } 1321 break; 1322 } 1323 1324 case omx_message::FILL_BUFFER_DONE: 1325 { 1326 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 1327 OMX_U32 flags = msg.u.extended_buffer_data.flags; 1328 1329 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 1330 buffer, 1331 msg.u.extended_buffer_data.range_length, 1332 flags, 1333 msg.u.extended_buffer_data.timestamp, 1334 msg.u.extended_buffer_data.timestamp / 1E6); 1335 1336 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1337 size_t i = 0; 1338 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 1339 ++i; 1340 } 1341 1342 CHECK(i < buffers->size()); 1343 BufferInfo *info = &buffers->editItemAt(i); 1344 1345 if (!info->mOwnedByComponent) { 1346 LOGW("We already own output buffer %p, yet received " 1347 "a FILL_BUFFER_DONE.", buffer); 1348 } 1349 1350 info->mOwnedByComponent = false; 1351 1352 if (mPortStatus[kPortIndexOutput] == DISABLING) { 1353 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 1354 1355 status_t err = 1356 mOMX->freeBuffer(mNode, kPortIndexOutput, buffer); 1357 CHECK_EQ(err, OK); 1358 1359 buffers->removeAt(i); 1360#if 0 1361 } else if (mPortStatus[kPortIndexOutput] == ENABLED 1362 && (flags & OMX_BUFFERFLAG_EOS)) { 1363 CODEC_LOGV("No more output data."); 1364 mNoMoreOutputData = true; 1365 mBufferFilled.signal(); 1366#endif 1367 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 1368 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1369 1370 if (info->mMediaBuffer == NULL) { 1371 CHECK(mOMXLivesLocally); 1372 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 1373 CHECK(mQuirks & kDefersOutputBufferAllocation); 1374 1375 // The qcom video decoders on Nexus don't actually allocate 1376 // output buffer memory on a call to OMX_AllocateBuffer 1377 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 1378 // structure is only filled in later. 1379 1380 info->mMediaBuffer = new MediaBuffer( 1381 msg.u.extended_buffer_data.data_ptr, 1382 info->mSize); 1383 info->mMediaBuffer->setObserver(this); 1384 } 1385 1386 MediaBuffer *buffer = info->mMediaBuffer; 1387 1388 buffer->set_range( 1389 msg.u.extended_buffer_data.range_offset, 1390 msg.u.extended_buffer_data.range_length); 1391 1392 buffer->meta_data()->clear(); 1393 1394 buffer->meta_data()->setInt64( 1395 kKeyTime, msg.u.extended_buffer_data.timestamp); 1396 1397 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 1398 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 1399 } 1400 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 1401 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 1402 } 1403 1404 buffer->meta_data()->setPointer( 1405 kKeyPlatformPrivate, 1406 msg.u.extended_buffer_data.platform_private); 1407 1408 buffer->meta_data()->setPointer( 1409 kKeyBufferID, 1410 msg.u.extended_buffer_data.buffer); 1411 1412 mFilledBuffers.push_back(i); 1413 mBufferFilled.signal(); 1414 1415 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 1416 CODEC_LOGV("No more output data."); 1417 mNoMoreOutputData = true; 1418 } 1419 } 1420 1421 break; 1422 } 1423 1424 default: 1425 { 1426 CHECK(!"should not be here."); 1427 break; 1428 } 1429 } 1430} 1431 1432void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1433 switch (event) { 1434 case OMX_EventCmdComplete: 1435 { 1436 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 1437 break; 1438 } 1439 1440 case OMX_EventError: 1441 { 1442 LOGE("ERROR(0x%08lx, %ld)", data1, data2); 1443 1444 setState(ERROR); 1445 break; 1446 } 1447 1448 case OMX_EventPortSettingsChanged: 1449 { 1450 onPortSettingsChanged(data1); 1451 break; 1452 } 1453 1454#if 0 1455 case OMX_EventBufferFlag: 1456 { 1457 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 1458 1459 if (data1 == kPortIndexOutput) { 1460 mNoMoreOutputData = true; 1461 } 1462 break; 1463 } 1464#endif 1465 1466 default: 1467 { 1468 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 1469 break; 1470 } 1471 } 1472} 1473 1474// Has the format changed in any way that the client would have to be aware of? 1475static bool formatHasNotablyChanged( 1476 const sp<MetaData> &from, const sp<MetaData> &to) { 1477 if (from.get() == NULL && to.get() == NULL) { 1478 return false; 1479 } 1480 1481 if ((from.get() == NULL && to.get() != NULL) 1482 || (from.get() != NULL && to.get() == NULL)) { 1483 return true; 1484 } 1485 1486 const char *mime_from, *mime_to; 1487 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 1488 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 1489 1490 if (strcasecmp(mime_from, mime_to)) { 1491 return true; 1492 } 1493 1494 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 1495 int32_t colorFormat_from, colorFormat_to; 1496 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 1497 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 1498 1499 if (colorFormat_from != colorFormat_to) { 1500 return true; 1501 } 1502 1503 int32_t width_from, width_to; 1504 CHECK(from->findInt32(kKeyWidth, &width_from)); 1505 CHECK(to->findInt32(kKeyWidth, &width_to)); 1506 1507 if (width_from != width_to) { 1508 return true; 1509 } 1510 1511 int32_t height_from, height_to; 1512 CHECK(from->findInt32(kKeyHeight, &height_from)); 1513 CHECK(to->findInt32(kKeyHeight, &height_to)); 1514 1515 if (height_from != height_to) { 1516 return true; 1517 } 1518 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 1519 int32_t numChannels_from, numChannels_to; 1520 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 1521 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 1522 1523 if (numChannels_from != numChannels_to) { 1524 return true; 1525 } 1526 1527 int32_t sampleRate_from, sampleRate_to; 1528 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 1529 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 1530 1531 if (sampleRate_from != sampleRate_to) { 1532 return true; 1533 } 1534 } 1535 1536 return false; 1537} 1538 1539void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 1540 switch (cmd) { 1541 case OMX_CommandStateSet: 1542 { 1543 onStateChange((OMX_STATETYPE)data); 1544 break; 1545 } 1546 1547 case OMX_CommandPortDisable: 1548 { 1549 OMX_U32 portIndex = data; 1550 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 1551 1552 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1553 CHECK_EQ(mPortStatus[portIndex], DISABLING); 1554 CHECK_EQ(mPortBuffers[portIndex].size(), 0); 1555 1556 mPortStatus[portIndex] = DISABLED; 1557 1558 if (mState == RECONFIGURING) { 1559 CHECK_EQ(portIndex, kPortIndexOutput); 1560 1561 sp<MetaData> oldOutputFormat = mOutputFormat; 1562 initOutputFormat(mSource->getFormat()); 1563 1564 // Don't notify clients if the output port settings change 1565 // wasn't of importance to them, i.e. it may be that just the 1566 // number of buffers has changed and nothing else. 1567 mOutputPortSettingsHaveChanged = 1568 formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 1569 1570 enablePortAsync(portIndex); 1571 1572 status_t err = allocateBuffersOnPort(portIndex); 1573 CHECK_EQ(err, OK); 1574 } 1575 break; 1576 } 1577 1578 case OMX_CommandPortEnable: 1579 { 1580 OMX_U32 portIndex = data; 1581 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 1582 1583 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1584 CHECK_EQ(mPortStatus[portIndex], ENABLING); 1585 1586 mPortStatus[portIndex] = ENABLED; 1587 1588 if (mState == RECONFIGURING) { 1589 CHECK_EQ(portIndex, kPortIndexOutput); 1590 1591 setState(EXECUTING); 1592 1593 fillOutputBuffers(); 1594 } 1595 break; 1596 } 1597 1598 case OMX_CommandFlush: 1599 { 1600 OMX_U32 portIndex = data; 1601 1602 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 1603 1604 CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); 1605 mPortStatus[portIndex] = ENABLED; 1606 1607 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 1608 mPortBuffers[portIndex].size()); 1609 1610 if (mState == RECONFIGURING) { 1611 CHECK_EQ(portIndex, kPortIndexOutput); 1612 1613 disablePortAsync(portIndex); 1614 } else if (mState == EXECUTING_TO_IDLE) { 1615 if (mPortStatus[kPortIndexInput] == ENABLED 1616 && mPortStatus[kPortIndexOutput] == ENABLED) { 1617 CODEC_LOGV("Finished flushing both ports, now completing " 1618 "transition from EXECUTING to IDLE."); 1619 1620 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1621 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1622 1623 status_t err = 1624 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1625 CHECK_EQ(err, OK); 1626 } 1627 } else { 1628 // We're flushing both ports in preparation for seeking. 1629 1630 if (mPortStatus[kPortIndexInput] == ENABLED 1631 && mPortStatus[kPortIndexOutput] == ENABLED) { 1632 CODEC_LOGV("Finished flushing both ports, now continuing from" 1633 " seek-time."); 1634 1635 drainInputBuffers(); 1636 fillOutputBuffers(); 1637 } 1638 } 1639 1640 break; 1641 } 1642 1643 default: 1644 { 1645 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1646 break; 1647 } 1648 } 1649} 1650 1651void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1652 CODEC_LOGV("onStateChange %d", newState); 1653 1654 switch (newState) { 1655 case OMX_StateIdle: 1656 { 1657 CODEC_LOGV("Now Idle."); 1658 if (mState == LOADED_TO_IDLE) { 1659 status_t err = mOMX->sendCommand( 1660 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1661 1662 CHECK_EQ(err, OK); 1663 1664 setState(IDLE_TO_EXECUTING); 1665 } else { 1666 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1667 1668 CHECK_EQ( 1669 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1670 mPortBuffers[kPortIndexInput].size()); 1671 1672 CHECK_EQ( 1673 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1674 mPortBuffers[kPortIndexOutput].size()); 1675 1676 status_t err = mOMX->sendCommand( 1677 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1678 1679 CHECK_EQ(err, OK); 1680 1681 err = freeBuffersOnPort(kPortIndexInput); 1682 CHECK_EQ(err, OK); 1683 1684 err = freeBuffersOnPort(kPortIndexOutput); 1685 CHECK_EQ(err, OK); 1686 1687 mPortStatus[kPortIndexInput] = ENABLED; 1688 mPortStatus[kPortIndexOutput] = ENABLED; 1689 1690 setState(IDLE_TO_LOADED); 1691 } 1692 break; 1693 } 1694 1695 case OMX_StateExecuting: 1696 { 1697 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1698 1699 CODEC_LOGV("Now Executing."); 1700 1701 setState(EXECUTING); 1702 1703 // Buffers will be submitted to the component in the first 1704 // call to OMXCodec::read as mInitialBufferSubmit is true at 1705 // this point. This ensures that this on_message call returns, 1706 // releases the lock and ::init can notice the state change and 1707 // itself return. 1708 break; 1709 } 1710 1711 case OMX_StateLoaded: 1712 { 1713 CHECK_EQ(mState, IDLE_TO_LOADED); 1714 1715 CODEC_LOGV("Now Loaded."); 1716 1717 setState(LOADED); 1718 break; 1719 } 1720 1721 case OMX_StateInvalid: 1722 { 1723 setState(ERROR); 1724 break; 1725 } 1726 1727 default: 1728 { 1729 CHECK(!"should not be here."); 1730 break; 1731 } 1732 } 1733} 1734 1735// static 1736size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1737 size_t n = 0; 1738 for (size_t i = 0; i < buffers.size(); ++i) { 1739 if (!buffers[i].mOwnedByComponent) { 1740 ++n; 1741 } 1742 } 1743 1744 return n; 1745} 1746 1747status_t OMXCodec::freeBuffersOnPort( 1748 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1749 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1750 1751 status_t stickyErr = OK; 1752 1753 for (size_t i = buffers->size(); i-- > 0;) { 1754 BufferInfo *info = &buffers->editItemAt(i); 1755 1756 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1757 continue; 1758 } 1759 1760 CHECK_EQ(info->mOwnedByComponent, false); 1761 1762 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 1763 1764 status_t err = 1765 mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 1766 1767 if (err != OK) { 1768 stickyErr = err; 1769 } 1770 1771 if (info->mMediaBuffer != NULL) { 1772 info->mMediaBuffer->setObserver(NULL); 1773 1774 // Make sure nobody but us owns this buffer at this point. 1775 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1776 1777 info->mMediaBuffer->release(); 1778 } 1779 1780 buffers->removeAt(i); 1781 } 1782 1783 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1784 1785 return stickyErr; 1786} 1787 1788void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1789 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1790 1791 CHECK_EQ(mState, EXECUTING); 1792 CHECK_EQ(portIndex, kPortIndexOutput); 1793 setState(RECONFIGURING); 1794 1795 if (mQuirks & kNeedsFlushBeforeDisable) { 1796 if (!flushPortAsync(portIndex)) { 1797 onCmdComplete(OMX_CommandFlush, portIndex); 1798 } 1799 } else { 1800 disablePortAsync(portIndex); 1801 } 1802} 1803 1804bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1805 CHECK(mState == EXECUTING || mState == RECONFIGURING 1806 || mState == EXECUTING_TO_IDLE); 1807 1808 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1809 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1810 mPortBuffers[portIndex].size()); 1811 1812 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1813 mPortStatus[portIndex] = SHUTTING_DOWN; 1814 1815 if ((mQuirks & kRequiresFlushCompleteEmulation) 1816 && countBuffersWeOwn(mPortBuffers[portIndex]) 1817 == mPortBuffers[portIndex].size()) { 1818 // No flush is necessary and this component fails to send a 1819 // flush-complete event in this case. 1820 1821 return false; 1822 } 1823 1824 status_t err = 1825 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 1826 CHECK_EQ(err, OK); 1827 1828 return true; 1829} 1830 1831void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1832 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1833 1834 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1835 mPortStatus[portIndex] = DISABLING; 1836 1837 status_t err = 1838 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 1839 CHECK_EQ(err, OK); 1840 1841 freeBuffersOnPort(portIndex, true); 1842} 1843 1844void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1845 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1846 1847 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1848 mPortStatus[portIndex] = ENABLING; 1849 1850 status_t err = 1851 mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 1852 CHECK_EQ(err, OK); 1853} 1854 1855void OMXCodec::fillOutputBuffers() { 1856 CHECK_EQ(mState, EXECUTING); 1857 1858 // This is a workaround for some decoders not properly reporting 1859 // end-of-output-stream. If we own all input buffers and also own 1860 // all output buffers and we already signalled end-of-input-stream, 1861 // the end-of-output-stream is implied. 1862 if (mSignalledEOS 1863 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 1864 == mPortBuffers[kPortIndexInput].size() 1865 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 1866 == mPortBuffers[kPortIndexOutput].size()) { 1867 mNoMoreOutputData = true; 1868 mBufferFilled.signal(); 1869 1870 return; 1871 } 1872 1873 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1874 for (size_t i = 0; i < buffers->size(); ++i) { 1875 fillOutputBuffer(&buffers->editItemAt(i)); 1876 } 1877} 1878 1879void OMXCodec::drainInputBuffers() { 1880 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1881 1882 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1883 for (size_t i = 0; i < buffers->size(); ++i) { 1884 drainInputBuffer(&buffers->editItemAt(i)); 1885 } 1886} 1887 1888void OMXCodec::drainInputBuffer(BufferInfo *info) { 1889 CHECK_EQ(info->mOwnedByComponent, false); 1890 1891 if (mSignalledEOS) { 1892 return; 1893 } 1894 1895 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 1896 const CodecSpecificData *specific = 1897 mCodecSpecificData[mCodecSpecificDataIndex]; 1898 1899 size_t size = specific->mSize; 1900 1901 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 1902 && !(mQuirks & kWantsNALFragments)) { 1903 static const uint8_t kNALStartCode[4] = 1904 { 0x00, 0x00, 0x00, 0x01 }; 1905 1906 CHECK(info->mSize >= specific->mSize + 4); 1907 1908 size += 4; 1909 1910 memcpy(info->mData, kNALStartCode, 4); 1911 memcpy((uint8_t *)info->mData + 4, 1912 specific->mData, specific->mSize); 1913 } else { 1914 CHECK(info->mSize >= specific->mSize); 1915 memcpy(info->mData, specific->mData, specific->mSize); 1916 } 1917 1918 mNoMoreOutputData = false; 1919 1920 CODEC_LOGV("calling emptyBuffer with codec specific data"); 1921 1922 status_t err = mOMX->emptyBuffer( 1923 mNode, info->mBuffer, 0, size, 1924 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 1925 0); 1926 CHECK_EQ(err, OK); 1927 1928 info->mOwnedByComponent = true; 1929 1930 ++mCodecSpecificDataIndex; 1931 return; 1932 } 1933 1934 MediaBuffer *srcBuffer; 1935 status_t err; 1936 if (mSeekTimeUs >= 0) { 1937 MediaSource::ReadOptions options; 1938 options.setSeekTo(mSeekTimeUs); 1939 1940 mSeekTimeUs = -1; 1941 mBufferFilled.signal(); 1942 1943 err = mSource->read(&srcBuffer, &options); 1944 } else { 1945 err = mSource->read(&srcBuffer); 1946 } 1947 1948 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1949 OMX_TICKS timestampUs = 0; 1950 size_t srcLength = 0; 1951 1952 if (err != OK) { 1953 CODEC_LOGV("signalling end of input stream."); 1954 flags |= OMX_BUFFERFLAG_EOS; 1955 1956 mFinalStatus = err; 1957 mSignalledEOS = true; 1958 } else { 1959 mNoMoreOutputData = false; 1960 1961 srcLength = srcBuffer->range_length(); 1962 1963 if (info->mSize < srcLength) { 1964 CODEC_LOGE( 1965 "Codec's input buffers are too small to accomodate " 1966 "buffer read from source (info->mSize = %d, srcLength = %d)", 1967 info->mSize, srcLength); 1968 1969 srcBuffer->release(); 1970 srcBuffer = NULL; 1971 1972 setState(ERROR); 1973 return; 1974 } 1975 memcpy(info->mData, 1976 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1977 srcLength); 1978 1979 if (srcBuffer->meta_data()->findInt64(kKeyTime, ×tampUs)) { 1980 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 1981 "timestamp %lld us (%.2f secs)", 1982 info->mBuffer, srcLength, 1983 timestampUs, timestampUs / 1E6); 1984 } 1985 } 1986 1987 if (srcBuffer != NULL) { 1988 srcBuffer->release(); 1989 srcBuffer = NULL; 1990 } 1991 1992 err = mOMX->emptyBuffer( 1993 mNode, info->mBuffer, 0, srcLength, 1994 flags, timestampUs); 1995 1996 if (err != OK) { 1997 setState(ERROR); 1998 return; 1999 } 2000 2001 info->mOwnedByComponent = true; 2002 2003 // This component does not ever signal the EOS flag on output buffers, 2004 // Thanks for nothing. 2005 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 2006 mNoMoreOutputData = true; 2007 mBufferFilled.signal(); 2008 } 2009} 2010 2011void OMXCodec::fillOutputBuffer(BufferInfo *info) { 2012 CHECK_EQ(info->mOwnedByComponent, false); 2013 2014 if (mNoMoreOutputData) { 2015 CODEC_LOGV("There is no more output data available, not " 2016 "calling fillOutputBuffer"); 2017 return; 2018 } 2019 2020 CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 2021 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 2022 CHECK_EQ(err, OK); 2023 2024 info->mOwnedByComponent = true; 2025} 2026 2027void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 2028 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2029 for (size_t i = 0; i < buffers->size(); ++i) { 2030 if ((*buffers)[i].mBuffer == buffer) { 2031 drainInputBuffer(&buffers->editItemAt(i)); 2032 return; 2033 } 2034 } 2035 2036 CHECK(!"should not be here."); 2037} 2038 2039void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 2040 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2041 for (size_t i = 0; i < buffers->size(); ++i) { 2042 if ((*buffers)[i].mBuffer == buffer) { 2043 fillOutputBuffer(&buffers->editItemAt(i)); 2044 return; 2045 } 2046 } 2047 2048 CHECK(!"should not be here."); 2049} 2050 2051void OMXCodec::setState(State newState) { 2052 mState = newState; 2053 mAsyncCompletion.signal(); 2054 2055 // This may cause some spurious wakeups but is necessary to 2056 // unblock the reader if we enter ERROR state. 2057 mBufferFilled.signal(); 2058} 2059 2060void OMXCodec::setRawAudioFormat( 2061 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 2062 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2063 InitOMXParams(&pcmParams); 2064 pcmParams.nPortIndex = portIndex; 2065 2066 status_t err = mOMX->getParameter( 2067 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2068 2069 CHECK_EQ(err, OK); 2070 2071 pcmParams.nChannels = numChannels; 2072 pcmParams.eNumData = OMX_NumericalDataSigned; 2073 pcmParams.bInterleaved = OMX_TRUE; 2074 pcmParams.nBitPerSample = 16; 2075 pcmParams.nSamplingRate = sampleRate; 2076 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2077 2078 if (numChannels == 1) { 2079 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 2080 } else { 2081 CHECK_EQ(numChannels, 2); 2082 2083 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 2084 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 2085 } 2086 2087 err = mOMX->setParameter( 2088 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2089 2090 CHECK_EQ(err, OK); 2091} 2092 2093void OMXCodec::setAMRFormat(bool isWAMR) { 2094 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 2095 2096 OMX_AUDIO_PARAM_AMRTYPE def; 2097 InitOMXParams(&def); 2098 def.nPortIndex = portIndex; 2099 2100 status_t err = 2101 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2102 2103 CHECK_EQ(err, OK); 2104 2105 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2106 def.eAMRBandMode = 2107 isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0; 2108 2109 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2110 CHECK_EQ(err, OK); 2111 2112 //////////////////////// 2113 2114 if (mIsEncoder) { 2115 sp<MetaData> format = mSource->getFormat(); 2116 int32_t sampleRate; 2117 int32_t numChannels; 2118 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 2119 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 2120 2121 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2122 } 2123} 2124 2125void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { 2126 if (mIsEncoder) { 2127 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2128 } else { 2129 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2130 InitOMXParams(&profile); 2131 profile.nPortIndex = kPortIndexInput; 2132 2133 status_t err = mOMX->getParameter( 2134 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2135 CHECK_EQ(err, OK); 2136 2137 profile.nChannels = numChannels; 2138 profile.nSampleRate = sampleRate; 2139 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 2140 2141 err = mOMX->setParameter( 2142 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2143 CHECK_EQ(err, OK); 2144 } 2145} 2146 2147void OMXCodec::setImageOutputFormat( 2148 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 2149 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 2150 2151#if 0 2152 OMX_INDEXTYPE index; 2153 status_t err = mOMX->get_extension_index( 2154 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 2155 CHECK_EQ(err, OK); 2156 2157 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 2158 CHECK_EQ(err, OK); 2159#endif 2160 2161 OMX_PARAM_PORTDEFINITIONTYPE def; 2162 InitOMXParams(&def); 2163 def.nPortIndex = kPortIndexOutput; 2164 2165 status_t err = mOMX->getParameter( 2166 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2167 CHECK_EQ(err, OK); 2168 2169 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2170 2171 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2172 2173 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2174 imageDef->eColorFormat = format; 2175 imageDef->nFrameWidth = width; 2176 imageDef->nFrameHeight = height; 2177 2178 switch (format) { 2179 case OMX_COLOR_FormatYUV420PackedPlanar: 2180 case OMX_COLOR_FormatYUV411Planar: 2181 { 2182 def.nBufferSize = (width * height * 3) / 2; 2183 break; 2184 } 2185 2186 case OMX_COLOR_FormatCbYCrY: 2187 { 2188 def.nBufferSize = width * height * 2; 2189 break; 2190 } 2191 2192 case OMX_COLOR_Format32bitARGB8888: 2193 { 2194 def.nBufferSize = width * height * 4; 2195 break; 2196 } 2197 2198 case OMX_COLOR_Format16bitARGB4444: 2199 case OMX_COLOR_Format16bitARGB1555: 2200 case OMX_COLOR_Format16bitRGB565: 2201 case OMX_COLOR_Format16bitBGR565: 2202 { 2203 def.nBufferSize = width * height * 2; 2204 break; 2205 } 2206 2207 default: 2208 CHECK(!"Should not be here. Unknown color format."); 2209 break; 2210 } 2211 2212 def.nBufferCountActual = def.nBufferCountMin; 2213 2214 err = mOMX->setParameter( 2215 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2216 CHECK_EQ(err, OK); 2217} 2218 2219void OMXCodec::setJPEGInputFormat( 2220 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 2221 OMX_PARAM_PORTDEFINITIONTYPE def; 2222 InitOMXParams(&def); 2223 def.nPortIndex = kPortIndexInput; 2224 2225 status_t err = mOMX->getParameter( 2226 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2227 CHECK_EQ(err, OK); 2228 2229 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2230 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2231 2232 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 2233 imageDef->nFrameWidth = width; 2234 imageDef->nFrameHeight = height; 2235 2236 def.nBufferSize = compressedSize; 2237 def.nBufferCountActual = def.nBufferCountMin; 2238 2239 err = mOMX->setParameter( 2240 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2241 CHECK_EQ(err, OK); 2242} 2243 2244void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 2245 CodecSpecificData *specific = 2246 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 2247 2248 specific->mSize = size; 2249 memcpy(specific->mData, data, size); 2250 2251 mCodecSpecificData.push(specific); 2252} 2253 2254void OMXCodec::clearCodecSpecificData() { 2255 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 2256 free(mCodecSpecificData.editItemAt(i)); 2257 } 2258 mCodecSpecificData.clear(); 2259 mCodecSpecificDataIndex = 0; 2260} 2261 2262status_t OMXCodec::start(MetaData *) { 2263 Mutex::Autolock autoLock(mLock); 2264 2265 if (mState != LOADED) { 2266 return UNKNOWN_ERROR; 2267 } 2268 2269 sp<MetaData> params = new MetaData; 2270 if (mQuirks & kWantsNALFragments) { 2271 params->setInt32(kKeyWantsNALFragments, true); 2272 } 2273 status_t err = mSource->start(params.get()); 2274 2275 if (err != OK) { 2276 return err; 2277 } 2278 2279 mCodecSpecificDataIndex = 0; 2280 mInitialBufferSubmit = true; 2281 mSignalledEOS = false; 2282 mNoMoreOutputData = false; 2283 mOutputPortSettingsHaveChanged = false; 2284 mSeekTimeUs = -1; 2285 mFilledBuffers.clear(); 2286 2287 return init(); 2288} 2289 2290status_t OMXCodec::stop() { 2291 CODEC_LOGV("stop mState=%d", mState); 2292 2293 Mutex::Autolock autoLock(mLock); 2294 2295 while (isIntermediateState(mState)) { 2296 mAsyncCompletion.wait(mLock); 2297 } 2298 2299 switch (mState) { 2300 case LOADED: 2301 case ERROR: 2302 break; 2303 2304 case EXECUTING: 2305 { 2306 setState(EXECUTING_TO_IDLE); 2307 2308 if (mQuirks & kRequiresFlushBeforeShutdown) { 2309 CODEC_LOGV("This component requires a flush before transitioning " 2310 "from EXECUTING to IDLE..."); 2311 2312 bool emulateInputFlushCompletion = 2313 !flushPortAsync(kPortIndexInput); 2314 2315 bool emulateOutputFlushCompletion = 2316 !flushPortAsync(kPortIndexOutput); 2317 2318 if (emulateInputFlushCompletion) { 2319 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2320 } 2321 2322 if (emulateOutputFlushCompletion) { 2323 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2324 } 2325 } else { 2326 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2327 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2328 2329 status_t err = 2330 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2331 CHECK_EQ(err, OK); 2332 } 2333 2334 while (mState != LOADED && mState != ERROR) { 2335 mAsyncCompletion.wait(mLock); 2336 } 2337 2338 break; 2339 } 2340 2341 default: 2342 { 2343 CHECK(!"should not be here."); 2344 break; 2345 } 2346 } 2347 2348 mSource->stop(); 2349 2350 CODEC_LOGV("stopped"); 2351 2352 return OK; 2353} 2354 2355sp<MetaData> OMXCodec::getFormat() { 2356 Mutex::Autolock autoLock(mLock); 2357 2358 return mOutputFormat; 2359} 2360 2361status_t OMXCodec::read( 2362 MediaBuffer **buffer, const ReadOptions *options) { 2363 *buffer = NULL; 2364 2365 Mutex::Autolock autoLock(mLock); 2366 2367 if (mState != EXECUTING && mState != RECONFIGURING) { 2368 return UNKNOWN_ERROR; 2369 } 2370 2371 bool seeking = false; 2372 int64_t seekTimeUs; 2373 if (options && options->getSeekTo(&seekTimeUs)) { 2374 seeking = true; 2375 } 2376 2377 if (mInitialBufferSubmit) { 2378 mInitialBufferSubmit = false; 2379 2380 if (seeking) { 2381 CHECK(seekTimeUs >= 0); 2382 mSeekTimeUs = seekTimeUs; 2383 2384 // There's no reason to trigger the code below, there's 2385 // nothing to flush yet. 2386 seeking = false; 2387 } 2388 2389 drainInputBuffers(); 2390 2391 if (mState == EXECUTING) { 2392 // Otherwise mState == RECONFIGURING and this code will trigger 2393 // after the output port is reenabled. 2394 fillOutputBuffers(); 2395 } 2396 } 2397 2398 if (seeking) { 2399 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 2400 2401 mSignalledEOS = false; 2402 2403 CHECK(seekTimeUs >= 0); 2404 mSeekTimeUs = seekTimeUs; 2405 2406 mFilledBuffers.clear(); 2407 2408 CHECK_EQ(mState, EXECUTING); 2409 2410 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 2411 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 2412 2413 if (emulateInputFlushCompletion) { 2414 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2415 } 2416 2417 if (emulateOutputFlushCompletion) { 2418 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2419 } 2420 2421 while (mSeekTimeUs >= 0) { 2422 mBufferFilled.wait(mLock); 2423 } 2424 } 2425 2426 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 2427 mBufferFilled.wait(mLock); 2428 } 2429 2430 if (mState == ERROR) { 2431 return UNKNOWN_ERROR; 2432 } 2433 2434 if (mFilledBuffers.empty()) { 2435 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 2436 } 2437 2438 if (mOutputPortSettingsHaveChanged) { 2439 mOutputPortSettingsHaveChanged = false; 2440 2441 return INFO_FORMAT_CHANGED; 2442 } 2443 2444 size_t index = *mFilledBuffers.begin(); 2445 mFilledBuffers.erase(mFilledBuffers.begin()); 2446 2447 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 2448 info->mMediaBuffer->add_ref(); 2449 *buffer = info->mMediaBuffer; 2450 2451 return OK; 2452} 2453 2454void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 2455 Mutex::Autolock autoLock(mLock); 2456 2457 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2458 for (size_t i = 0; i < buffers->size(); ++i) { 2459 BufferInfo *info = &buffers->editItemAt(i); 2460 2461 if (info->mMediaBuffer == buffer) { 2462 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 2463 fillOutputBuffer(info); 2464 return; 2465 } 2466 } 2467 2468 CHECK(!"should not be here."); 2469} 2470 2471static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 2472 static const char *kNames[] = { 2473 "OMX_IMAGE_CodingUnused", 2474 "OMX_IMAGE_CodingAutoDetect", 2475 "OMX_IMAGE_CodingJPEG", 2476 "OMX_IMAGE_CodingJPEG2K", 2477 "OMX_IMAGE_CodingEXIF", 2478 "OMX_IMAGE_CodingTIFF", 2479 "OMX_IMAGE_CodingGIF", 2480 "OMX_IMAGE_CodingPNG", 2481 "OMX_IMAGE_CodingLZW", 2482 "OMX_IMAGE_CodingBMP", 2483 }; 2484 2485 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2486 2487 if (type < 0 || (size_t)type >= numNames) { 2488 return "UNKNOWN"; 2489 } else { 2490 return kNames[type]; 2491 } 2492} 2493 2494static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 2495 static const char *kNames[] = { 2496 "OMX_COLOR_FormatUnused", 2497 "OMX_COLOR_FormatMonochrome", 2498 "OMX_COLOR_Format8bitRGB332", 2499 "OMX_COLOR_Format12bitRGB444", 2500 "OMX_COLOR_Format16bitARGB4444", 2501 "OMX_COLOR_Format16bitARGB1555", 2502 "OMX_COLOR_Format16bitRGB565", 2503 "OMX_COLOR_Format16bitBGR565", 2504 "OMX_COLOR_Format18bitRGB666", 2505 "OMX_COLOR_Format18bitARGB1665", 2506 "OMX_COLOR_Format19bitARGB1666", 2507 "OMX_COLOR_Format24bitRGB888", 2508 "OMX_COLOR_Format24bitBGR888", 2509 "OMX_COLOR_Format24bitARGB1887", 2510 "OMX_COLOR_Format25bitARGB1888", 2511 "OMX_COLOR_Format32bitBGRA8888", 2512 "OMX_COLOR_Format32bitARGB8888", 2513 "OMX_COLOR_FormatYUV411Planar", 2514 "OMX_COLOR_FormatYUV411PackedPlanar", 2515 "OMX_COLOR_FormatYUV420Planar", 2516 "OMX_COLOR_FormatYUV420PackedPlanar", 2517 "OMX_COLOR_FormatYUV420SemiPlanar", 2518 "OMX_COLOR_FormatYUV422Planar", 2519 "OMX_COLOR_FormatYUV422PackedPlanar", 2520 "OMX_COLOR_FormatYUV422SemiPlanar", 2521 "OMX_COLOR_FormatYCbYCr", 2522 "OMX_COLOR_FormatYCrYCb", 2523 "OMX_COLOR_FormatCbYCrY", 2524 "OMX_COLOR_FormatCrYCbY", 2525 "OMX_COLOR_FormatYUV444Interleaved", 2526 "OMX_COLOR_FormatRawBayer8bit", 2527 "OMX_COLOR_FormatRawBayer10bit", 2528 "OMX_COLOR_FormatRawBayer8bitcompressed", 2529 "OMX_COLOR_FormatL2", 2530 "OMX_COLOR_FormatL4", 2531 "OMX_COLOR_FormatL8", 2532 "OMX_COLOR_FormatL16", 2533 "OMX_COLOR_FormatL24", 2534 "OMX_COLOR_FormatL32", 2535 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 2536 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 2537 "OMX_COLOR_Format18BitBGR666", 2538 "OMX_COLOR_Format24BitARGB6666", 2539 "OMX_COLOR_Format24BitABGR6666", 2540 }; 2541 2542 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2543 2544 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 2545 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 2546 } else if (type < 0 || (size_t)type >= numNames) { 2547 return "UNKNOWN"; 2548 } else { 2549 return kNames[type]; 2550 } 2551} 2552 2553static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 2554 static const char *kNames[] = { 2555 "OMX_VIDEO_CodingUnused", 2556 "OMX_VIDEO_CodingAutoDetect", 2557 "OMX_VIDEO_CodingMPEG2", 2558 "OMX_VIDEO_CodingH263", 2559 "OMX_VIDEO_CodingMPEG4", 2560 "OMX_VIDEO_CodingWMV", 2561 "OMX_VIDEO_CodingRV", 2562 "OMX_VIDEO_CodingAVC", 2563 "OMX_VIDEO_CodingMJPEG", 2564 }; 2565 2566 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2567 2568 if (type < 0 || (size_t)type >= numNames) { 2569 return "UNKNOWN"; 2570 } else { 2571 return kNames[type]; 2572 } 2573} 2574 2575static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 2576 static const char *kNames[] = { 2577 "OMX_AUDIO_CodingUnused", 2578 "OMX_AUDIO_CodingAutoDetect", 2579 "OMX_AUDIO_CodingPCM", 2580 "OMX_AUDIO_CodingADPCM", 2581 "OMX_AUDIO_CodingAMR", 2582 "OMX_AUDIO_CodingGSMFR", 2583 "OMX_AUDIO_CodingGSMEFR", 2584 "OMX_AUDIO_CodingGSMHR", 2585 "OMX_AUDIO_CodingPDCFR", 2586 "OMX_AUDIO_CodingPDCEFR", 2587 "OMX_AUDIO_CodingPDCHR", 2588 "OMX_AUDIO_CodingTDMAFR", 2589 "OMX_AUDIO_CodingTDMAEFR", 2590 "OMX_AUDIO_CodingQCELP8", 2591 "OMX_AUDIO_CodingQCELP13", 2592 "OMX_AUDIO_CodingEVRC", 2593 "OMX_AUDIO_CodingSMV", 2594 "OMX_AUDIO_CodingG711", 2595 "OMX_AUDIO_CodingG723", 2596 "OMX_AUDIO_CodingG726", 2597 "OMX_AUDIO_CodingG729", 2598 "OMX_AUDIO_CodingAAC", 2599 "OMX_AUDIO_CodingMP3", 2600 "OMX_AUDIO_CodingSBC", 2601 "OMX_AUDIO_CodingVORBIS", 2602 "OMX_AUDIO_CodingWMA", 2603 "OMX_AUDIO_CodingRA", 2604 "OMX_AUDIO_CodingMIDI", 2605 }; 2606 2607 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2608 2609 if (type < 0 || (size_t)type >= numNames) { 2610 return "UNKNOWN"; 2611 } else { 2612 return kNames[type]; 2613 } 2614} 2615 2616static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 2617 static const char *kNames[] = { 2618 "OMX_AUDIO_PCMModeLinear", 2619 "OMX_AUDIO_PCMModeALaw", 2620 "OMX_AUDIO_PCMModeMULaw", 2621 }; 2622 2623 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2624 2625 if (type < 0 || (size_t)type >= numNames) { 2626 return "UNKNOWN"; 2627 } else { 2628 return kNames[type]; 2629 } 2630} 2631 2632static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 2633 static const char *kNames[] = { 2634 "OMX_AUDIO_AMRBandModeUnused", 2635 "OMX_AUDIO_AMRBandModeNB0", 2636 "OMX_AUDIO_AMRBandModeNB1", 2637 "OMX_AUDIO_AMRBandModeNB2", 2638 "OMX_AUDIO_AMRBandModeNB3", 2639 "OMX_AUDIO_AMRBandModeNB4", 2640 "OMX_AUDIO_AMRBandModeNB5", 2641 "OMX_AUDIO_AMRBandModeNB6", 2642 "OMX_AUDIO_AMRBandModeNB7", 2643 "OMX_AUDIO_AMRBandModeWB0", 2644 "OMX_AUDIO_AMRBandModeWB1", 2645 "OMX_AUDIO_AMRBandModeWB2", 2646 "OMX_AUDIO_AMRBandModeWB3", 2647 "OMX_AUDIO_AMRBandModeWB4", 2648 "OMX_AUDIO_AMRBandModeWB5", 2649 "OMX_AUDIO_AMRBandModeWB6", 2650 "OMX_AUDIO_AMRBandModeWB7", 2651 "OMX_AUDIO_AMRBandModeWB8", 2652 }; 2653 2654 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2655 2656 if (type < 0 || (size_t)type >= numNames) { 2657 return "UNKNOWN"; 2658 } else { 2659 return kNames[type]; 2660 } 2661} 2662 2663static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 2664 static const char *kNames[] = { 2665 "OMX_AUDIO_AMRFrameFormatConformance", 2666 "OMX_AUDIO_AMRFrameFormatIF1", 2667 "OMX_AUDIO_AMRFrameFormatIF2", 2668 "OMX_AUDIO_AMRFrameFormatFSF", 2669 "OMX_AUDIO_AMRFrameFormatRTPPayload", 2670 "OMX_AUDIO_AMRFrameFormatITU", 2671 }; 2672 2673 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2674 2675 if (type < 0 || (size_t)type >= numNames) { 2676 return "UNKNOWN"; 2677 } else { 2678 return kNames[type]; 2679 } 2680} 2681 2682void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 2683 OMX_PARAM_PORTDEFINITIONTYPE def; 2684 InitOMXParams(&def); 2685 def.nPortIndex = portIndex; 2686 2687 status_t err = mOMX->getParameter( 2688 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2689 CHECK_EQ(err, OK); 2690 2691 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 2692 2693 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 2694 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 2695 2696 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 2697 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 2698 printf(" nBufferSize = %ld\n", def.nBufferSize); 2699 2700 switch (def.eDomain) { 2701 case OMX_PortDomainImage: 2702 { 2703 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2704 2705 printf("\n"); 2706 printf(" // Image\n"); 2707 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 2708 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 2709 printf(" nStride = %ld\n", imageDef->nStride); 2710 2711 printf(" eCompressionFormat = %s\n", 2712 imageCompressionFormatString(imageDef->eCompressionFormat)); 2713 2714 printf(" eColorFormat = %s\n", 2715 colorFormatString(imageDef->eColorFormat)); 2716 2717 break; 2718 } 2719 2720 case OMX_PortDomainVideo: 2721 { 2722 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2723 2724 printf("\n"); 2725 printf(" // Video\n"); 2726 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 2727 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 2728 printf(" nStride = %ld\n", videoDef->nStride); 2729 2730 printf(" eCompressionFormat = %s\n", 2731 videoCompressionFormatString(videoDef->eCompressionFormat)); 2732 2733 printf(" eColorFormat = %s\n", 2734 colorFormatString(videoDef->eColorFormat)); 2735 2736 break; 2737 } 2738 2739 case OMX_PortDomainAudio: 2740 { 2741 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2742 2743 printf("\n"); 2744 printf(" // Audio\n"); 2745 printf(" eEncoding = %s\n", 2746 audioCodingTypeString(audioDef->eEncoding)); 2747 2748 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2749 OMX_AUDIO_PARAM_PCMMODETYPE params; 2750 InitOMXParams(¶ms); 2751 params.nPortIndex = portIndex; 2752 2753 err = mOMX->getParameter( 2754 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2755 CHECK_EQ(err, OK); 2756 2757 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2758 printf(" nChannels = %ld\n", params.nChannels); 2759 printf(" bInterleaved = %d\n", params.bInterleaved); 2760 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2761 2762 printf(" eNumData = %s\n", 2763 params.eNumData == OMX_NumericalDataSigned 2764 ? "signed" : "unsigned"); 2765 2766 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2767 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 2768 OMX_AUDIO_PARAM_AMRTYPE amr; 2769 InitOMXParams(&amr); 2770 amr.nPortIndex = portIndex; 2771 2772 err = mOMX->getParameter( 2773 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2774 CHECK_EQ(err, OK); 2775 2776 printf(" nChannels = %ld\n", amr.nChannels); 2777 printf(" eAMRBandMode = %s\n", 2778 amrBandModeString(amr.eAMRBandMode)); 2779 printf(" eAMRFrameFormat = %s\n", 2780 amrFrameFormatString(amr.eAMRFrameFormat)); 2781 } 2782 2783 break; 2784 } 2785 2786 default: 2787 { 2788 printf(" // Unknown\n"); 2789 break; 2790 } 2791 } 2792 2793 printf("}\n"); 2794} 2795 2796void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2797 mOutputFormat = new MetaData; 2798 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2799 2800 OMX_PARAM_PORTDEFINITIONTYPE def; 2801 InitOMXParams(&def); 2802 def.nPortIndex = kPortIndexOutput; 2803 2804 status_t err = mOMX->getParameter( 2805 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2806 CHECK_EQ(err, OK); 2807 2808 switch (def.eDomain) { 2809 case OMX_PortDomainImage: 2810 { 2811 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2812 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2813 2814 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2815 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2816 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2817 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2818 break; 2819 } 2820 2821 case OMX_PortDomainAudio: 2822 { 2823 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2824 2825 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 2826 OMX_AUDIO_PARAM_PCMMODETYPE params; 2827 InitOMXParams(¶ms); 2828 params.nPortIndex = kPortIndexOutput; 2829 2830 err = mOMX->getParameter( 2831 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2832 CHECK_EQ(err, OK); 2833 2834 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2835 CHECK_EQ(params.nBitPerSample, 16); 2836 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2837 2838 int32_t numChannels, sampleRate; 2839 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2840 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2841 2842 if ((OMX_U32)numChannels != params.nChannels) { 2843 LOGW("Codec outputs a different number of channels than " 2844 "the input stream contains (contains %d channels, " 2845 "codec outputs %ld channels).", 2846 numChannels, params.nChannels); 2847 } 2848 2849 mOutputFormat->setCString( 2850 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2851 2852 // Use the codec-advertised number of channels, as some 2853 // codecs appear to output stereo even if the input data is 2854 // mono. If we know the codec lies about this information, 2855 // use the actual number of channels instead. 2856 mOutputFormat->setInt32( 2857 kKeyChannelCount, 2858 (mQuirks & kDecoderLiesAboutNumberOfChannels) 2859 ? numChannels : params.nChannels); 2860 2861 // The codec-reported sampleRate is not reliable... 2862 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2863 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 2864 OMX_AUDIO_PARAM_AMRTYPE amr; 2865 InitOMXParams(&amr); 2866 amr.nPortIndex = kPortIndexOutput; 2867 2868 err = mOMX->getParameter( 2869 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2870 CHECK_EQ(err, OK); 2871 2872 CHECK_EQ(amr.nChannels, 1); 2873 mOutputFormat->setInt32(kKeyChannelCount, 1); 2874 2875 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 2876 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 2877 mOutputFormat->setCString( 2878 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 2879 mOutputFormat->setInt32(kKeySampleRate, 8000); 2880 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 2881 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 2882 mOutputFormat->setCString( 2883 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 2884 mOutputFormat->setInt32(kKeySampleRate, 16000); 2885 } else { 2886 CHECK(!"Unknown AMR band mode."); 2887 } 2888 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 2889 mOutputFormat->setCString( 2890 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 2891 } else { 2892 CHECK(!"Should not be here. Unknown audio encoding."); 2893 } 2894 break; 2895 } 2896 2897 case OMX_PortDomainVideo: 2898 { 2899 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2900 2901 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2902 mOutputFormat->setCString( 2903 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2904 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2905 mOutputFormat->setCString( 2906 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 2907 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2908 mOutputFormat->setCString( 2909 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 2910 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2911 mOutputFormat->setCString( 2912 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 2913 } else { 2914 CHECK(!"Unknown compression format."); 2915 } 2916 2917 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2918 // This component appears to be lying to me. 2919 mOutputFormat->setInt32( 2920 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2921 mOutputFormat->setInt32( 2922 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2923 } else { 2924 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2925 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2926 } 2927 2928 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2929 break; 2930 } 2931 2932 default: 2933 { 2934 CHECK(!"should not be here, neither audio nor video."); 2935 break; 2936 } 2937 } 2938} 2939 2940//////////////////////////////////////////////////////////////////////////////// 2941 2942status_t QueryCodecs( 2943 const sp<IOMX> &omx, 2944 const char *mime, bool queryDecoders, 2945 Vector<CodecCapabilities> *results) { 2946 results->clear(); 2947 2948 for (int index = 0;; ++index) { 2949 const char *componentName; 2950 2951 if (!queryDecoders) { 2952 componentName = GetCodec( 2953 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 2954 mime, index); 2955 } else { 2956 componentName = GetCodec( 2957 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 2958 mime, index); 2959 } 2960 2961 if (!componentName) { 2962 return OK; 2963 } 2964 2965 sp<OMXCodecObserver> observer = new OMXCodecObserver; 2966 IOMX::node_id node; 2967 status_t err = omx->allocateNode(componentName, observer, &node); 2968 2969 if (err != OK) { 2970 continue; 2971 } 2972 2973 OMXCodec::setComponentRole(omx, node, queryDecoders, mime); 2974 2975 results->push(); 2976 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 2977 caps->mComponentName = componentName; 2978 2979 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 2980 InitOMXParams(¶m); 2981 2982 param.nPortIndex = queryDecoders ? 0 : 1; 2983 2984 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 2985 err = omx->getParameter( 2986 node, OMX_IndexParamVideoProfileLevelQuerySupported, 2987 ¶m, sizeof(param)); 2988 2989 if (err != OK) { 2990 break; 2991 } 2992 2993 CodecProfileLevel profileLevel; 2994 profileLevel.mProfile = param.eProfile; 2995 profileLevel.mLevel = param.eLevel; 2996 2997 caps->mProfileLevels.push(profileLevel); 2998 } 2999 3000 CHECK_EQ(omx->freeNode(node), OK); 3001 } 3002} 3003 3004} // namespace android 3005