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