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