OMXCodec.cpp revision ec9dd59902c8beea4ba6a842f3a843d46150d949
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 (mState != ERROR 1288 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 1289 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED); 1290 drainInputBuffer(&buffers->editItemAt(i)); 1291 } 1292 break; 1293 } 1294 1295 case omx_message::FILL_BUFFER_DONE: 1296 { 1297 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 1298 OMX_U32 flags = msg.u.extended_buffer_data.flags; 1299 1300 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 1301 buffer, 1302 msg.u.extended_buffer_data.range_length, 1303 flags, 1304 msg.u.extended_buffer_data.timestamp, 1305 msg.u.extended_buffer_data.timestamp / 1E6); 1306 1307 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1308 size_t i = 0; 1309 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 1310 ++i; 1311 } 1312 1313 CHECK(i < buffers->size()); 1314 BufferInfo *info = &buffers->editItemAt(i); 1315 1316 if (!info->mOwnedByComponent) { 1317 LOGW("We already own output buffer %p, yet received " 1318 "a FILL_BUFFER_DONE.", buffer); 1319 } 1320 1321 info->mOwnedByComponent = false; 1322 1323 if (mPortStatus[kPortIndexOutput] == DISABLING) { 1324 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 1325 1326 status_t err = 1327 mOMX->freeBuffer(mNode, kPortIndexOutput, buffer); 1328 CHECK_EQ(err, OK); 1329 1330 buffers->removeAt(i); 1331#if 0 1332 } else if (mPortStatus[kPortIndexOutput] == ENABLED 1333 && (flags & OMX_BUFFERFLAG_EOS)) { 1334 CODEC_LOGV("No more output data."); 1335 mNoMoreOutputData = true; 1336 mBufferFilled.signal(); 1337#endif 1338 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 1339 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1340 1341 if (info->mMediaBuffer == NULL) { 1342 CHECK(mOMXLivesLocally); 1343 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 1344 CHECK(mQuirks & kDefersOutputBufferAllocation); 1345 1346 // The qcom video decoders on Nexus don't actually allocate 1347 // output buffer memory on a call to OMX_AllocateBuffer 1348 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 1349 // structure is only filled in later. 1350 1351 info->mMediaBuffer = new MediaBuffer( 1352 msg.u.extended_buffer_data.data_ptr, 1353 info->mSize); 1354 info->mMediaBuffer->setObserver(this); 1355 } 1356 1357 MediaBuffer *buffer = info->mMediaBuffer; 1358 1359 buffer->set_range( 1360 msg.u.extended_buffer_data.range_offset, 1361 msg.u.extended_buffer_data.range_length); 1362 1363 buffer->meta_data()->clear(); 1364 1365 buffer->meta_data()->setInt64( 1366 kKeyTime, msg.u.extended_buffer_data.timestamp); 1367 1368 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 1369 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 1370 } 1371 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 1372 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 1373 } 1374 1375 buffer->meta_data()->setPointer( 1376 kKeyPlatformPrivate, 1377 msg.u.extended_buffer_data.platform_private); 1378 1379 buffer->meta_data()->setPointer( 1380 kKeyBufferID, 1381 msg.u.extended_buffer_data.buffer); 1382 1383 mFilledBuffers.push_back(i); 1384 mBufferFilled.signal(); 1385 1386 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 1387 CODEC_LOGV("No more output data."); 1388 mNoMoreOutputData = true; 1389 } 1390 } 1391 1392 break; 1393 } 1394 1395 default: 1396 { 1397 CHECK(!"should not be here."); 1398 break; 1399 } 1400 } 1401} 1402 1403void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1404 switch (event) { 1405 case OMX_EventCmdComplete: 1406 { 1407 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 1408 break; 1409 } 1410 1411 case OMX_EventError: 1412 { 1413 LOGE("ERROR(0x%08lx, %ld)", data1, data2); 1414 1415 setState(ERROR); 1416 break; 1417 } 1418 1419 case OMX_EventPortSettingsChanged: 1420 { 1421 onPortSettingsChanged(data1); 1422 break; 1423 } 1424 1425#if 0 1426 case OMX_EventBufferFlag: 1427 { 1428 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 1429 1430 if (data1 == kPortIndexOutput) { 1431 mNoMoreOutputData = true; 1432 } 1433 break; 1434 } 1435#endif 1436 1437 default: 1438 { 1439 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 1440 break; 1441 } 1442 } 1443} 1444 1445// Has the format changed in any way that the client would have to be aware of? 1446static bool formatHasNotablyChanged( 1447 const sp<MetaData> &from, const sp<MetaData> &to) { 1448 if (from.get() == NULL && to.get() == NULL) { 1449 return false; 1450 } 1451 1452 if ((from.get() == NULL && to.get() != NULL) 1453 || (from.get() != NULL && to.get() == NULL)) { 1454 return true; 1455 } 1456 1457 const char *mime_from, *mime_to; 1458 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 1459 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 1460 1461 if (strcasecmp(mime_from, mime_to)) { 1462 return true; 1463 } 1464 1465 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 1466 int32_t colorFormat_from, colorFormat_to; 1467 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 1468 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 1469 1470 if (colorFormat_from != colorFormat_to) { 1471 return true; 1472 } 1473 1474 int32_t width_from, width_to; 1475 CHECK(from->findInt32(kKeyWidth, &width_from)); 1476 CHECK(to->findInt32(kKeyWidth, &width_to)); 1477 1478 if (width_from != width_to) { 1479 return true; 1480 } 1481 1482 int32_t height_from, height_to; 1483 CHECK(from->findInt32(kKeyHeight, &height_from)); 1484 CHECK(to->findInt32(kKeyHeight, &height_to)); 1485 1486 if (height_from != height_to) { 1487 return true; 1488 } 1489 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 1490 int32_t numChannels_from, numChannels_to; 1491 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 1492 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 1493 1494 if (numChannels_from != numChannels_to) { 1495 return true; 1496 } 1497 1498 int32_t sampleRate_from, sampleRate_to; 1499 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 1500 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 1501 1502 if (sampleRate_from != sampleRate_to) { 1503 return true; 1504 } 1505 } 1506 1507 return false; 1508} 1509 1510void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 1511 switch (cmd) { 1512 case OMX_CommandStateSet: 1513 { 1514 onStateChange((OMX_STATETYPE)data); 1515 break; 1516 } 1517 1518 case OMX_CommandPortDisable: 1519 { 1520 OMX_U32 portIndex = data; 1521 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 1522 1523 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1524 CHECK_EQ(mPortStatus[portIndex], DISABLING); 1525 CHECK_EQ(mPortBuffers[portIndex].size(), 0); 1526 1527 mPortStatus[portIndex] = DISABLED; 1528 1529 if (mState == RECONFIGURING) { 1530 CHECK_EQ(portIndex, kPortIndexOutput); 1531 1532 sp<MetaData> oldOutputFormat = mOutputFormat; 1533 initOutputFormat(mSource->getFormat()); 1534 1535 // Don't notify clients if the output port settings change 1536 // wasn't of importance to them, i.e. it may be that just the 1537 // number of buffers has changed and nothing else. 1538 mOutputPortSettingsHaveChanged = 1539 formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 1540 1541 enablePortAsync(portIndex); 1542 1543 status_t err = allocateBuffersOnPort(portIndex); 1544 CHECK_EQ(err, OK); 1545 } 1546 break; 1547 } 1548 1549 case OMX_CommandPortEnable: 1550 { 1551 OMX_U32 portIndex = data; 1552 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 1553 1554 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1555 CHECK_EQ(mPortStatus[portIndex], ENABLING); 1556 1557 mPortStatus[portIndex] = ENABLED; 1558 1559 if (mState == RECONFIGURING) { 1560 CHECK_EQ(portIndex, kPortIndexOutput); 1561 1562 setState(EXECUTING); 1563 1564 fillOutputBuffers(); 1565 } 1566 break; 1567 } 1568 1569 case OMX_CommandFlush: 1570 { 1571 OMX_U32 portIndex = data; 1572 1573 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 1574 1575 CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); 1576 mPortStatus[portIndex] = ENABLED; 1577 1578 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 1579 mPortBuffers[portIndex].size()); 1580 1581 if (mState == RECONFIGURING) { 1582 CHECK_EQ(portIndex, kPortIndexOutput); 1583 1584 disablePortAsync(portIndex); 1585 } else if (mState == EXECUTING_TO_IDLE) { 1586 if (mPortStatus[kPortIndexInput] == ENABLED 1587 && mPortStatus[kPortIndexOutput] == ENABLED) { 1588 CODEC_LOGV("Finished flushing both ports, now completing " 1589 "transition from EXECUTING to IDLE."); 1590 1591 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1592 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1593 1594 status_t err = 1595 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1596 CHECK_EQ(err, OK); 1597 } 1598 } else { 1599 // We're flushing both ports in preparation for seeking. 1600 1601 if (mPortStatus[kPortIndexInput] == ENABLED 1602 && mPortStatus[kPortIndexOutput] == ENABLED) { 1603 CODEC_LOGV("Finished flushing both ports, now continuing from" 1604 " seek-time."); 1605 1606 drainInputBuffers(); 1607 fillOutputBuffers(); 1608 } 1609 } 1610 1611 break; 1612 } 1613 1614 default: 1615 { 1616 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1617 break; 1618 } 1619 } 1620} 1621 1622void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1623 CODEC_LOGV("onStateChange %d", newState); 1624 1625 switch (newState) { 1626 case OMX_StateIdle: 1627 { 1628 CODEC_LOGV("Now Idle."); 1629 if (mState == LOADED_TO_IDLE) { 1630 status_t err = mOMX->sendCommand( 1631 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1632 1633 CHECK_EQ(err, OK); 1634 1635 setState(IDLE_TO_EXECUTING); 1636 } else { 1637 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1638 1639 CHECK_EQ( 1640 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1641 mPortBuffers[kPortIndexInput].size()); 1642 1643 CHECK_EQ( 1644 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1645 mPortBuffers[kPortIndexOutput].size()); 1646 1647 status_t err = mOMX->sendCommand( 1648 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1649 1650 CHECK_EQ(err, OK); 1651 1652 err = freeBuffersOnPort(kPortIndexInput); 1653 CHECK_EQ(err, OK); 1654 1655 err = freeBuffersOnPort(kPortIndexOutput); 1656 CHECK_EQ(err, OK); 1657 1658 mPortStatus[kPortIndexInput] = ENABLED; 1659 mPortStatus[kPortIndexOutput] = ENABLED; 1660 1661 setState(IDLE_TO_LOADED); 1662 } 1663 break; 1664 } 1665 1666 case OMX_StateExecuting: 1667 { 1668 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1669 1670 CODEC_LOGV("Now Executing."); 1671 1672 setState(EXECUTING); 1673 1674 // Buffers will be submitted to the component in the first 1675 // call to OMXCodec::read as mInitialBufferSubmit is true at 1676 // this point. This ensures that this on_message call returns, 1677 // releases the lock and ::init can notice the state change and 1678 // itself return. 1679 break; 1680 } 1681 1682 case OMX_StateLoaded: 1683 { 1684 CHECK_EQ(mState, IDLE_TO_LOADED); 1685 1686 CODEC_LOGV("Now Loaded."); 1687 1688 setState(LOADED); 1689 break; 1690 } 1691 1692 case OMX_StateInvalid: 1693 { 1694 setState(ERROR); 1695 break; 1696 } 1697 1698 default: 1699 { 1700 CHECK(!"should not be here."); 1701 break; 1702 } 1703 } 1704} 1705 1706// static 1707size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1708 size_t n = 0; 1709 for (size_t i = 0; i < buffers.size(); ++i) { 1710 if (!buffers[i].mOwnedByComponent) { 1711 ++n; 1712 } 1713 } 1714 1715 return n; 1716} 1717 1718status_t OMXCodec::freeBuffersOnPort( 1719 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1720 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1721 1722 status_t stickyErr = OK; 1723 1724 for (size_t i = buffers->size(); i-- > 0;) { 1725 BufferInfo *info = &buffers->editItemAt(i); 1726 1727 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1728 continue; 1729 } 1730 1731 CHECK_EQ(info->mOwnedByComponent, false); 1732 1733 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 1734 1735 status_t err = 1736 mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 1737 1738 if (err != OK) { 1739 stickyErr = err; 1740 } 1741 1742 if (info->mMediaBuffer != NULL) { 1743 info->mMediaBuffer->setObserver(NULL); 1744 1745 // Make sure nobody but us owns this buffer at this point. 1746 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1747 1748 info->mMediaBuffer->release(); 1749 } 1750 1751 buffers->removeAt(i); 1752 } 1753 1754 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1755 1756 return stickyErr; 1757} 1758 1759void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1760 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1761 1762 CHECK_EQ(mState, EXECUTING); 1763 CHECK_EQ(portIndex, kPortIndexOutput); 1764 setState(RECONFIGURING); 1765 1766 if (mQuirks & kNeedsFlushBeforeDisable) { 1767 if (!flushPortAsync(portIndex)) { 1768 onCmdComplete(OMX_CommandFlush, portIndex); 1769 } 1770 } else { 1771 disablePortAsync(portIndex); 1772 } 1773} 1774 1775bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1776 CHECK(mState == EXECUTING || mState == RECONFIGURING 1777 || mState == EXECUTING_TO_IDLE); 1778 1779 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1780 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1781 mPortBuffers[portIndex].size()); 1782 1783 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1784 mPortStatus[portIndex] = SHUTTING_DOWN; 1785 1786 if ((mQuirks & kRequiresFlushCompleteEmulation) 1787 && countBuffersWeOwn(mPortBuffers[portIndex]) 1788 == mPortBuffers[portIndex].size()) { 1789 // No flush is necessary and this component fails to send a 1790 // flush-complete event in this case. 1791 1792 return false; 1793 } 1794 1795 status_t err = 1796 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 1797 CHECK_EQ(err, OK); 1798 1799 return true; 1800} 1801 1802void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1803 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1804 1805 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1806 mPortStatus[portIndex] = DISABLING; 1807 1808 status_t err = 1809 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 1810 CHECK_EQ(err, OK); 1811 1812 freeBuffersOnPort(portIndex, true); 1813} 1814 1815void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1816 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1817 1818 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1819 mPortStatus[portIndex] = ENABLING; 1820 1821 status_t err = 1822 mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 1823 CHECK_EQ(err, OK); 1824} 1825 1826void OMXCodec::fillOutputBuffers() { 1827 CHECK_EQ(mState, EXECUTING); 1828 1829 // This is a workaround for some decoders not properly reporting 1830 // end-of-output-stream. If we own all input buffers and also own 1831 // all output buffers and we already signalled end-of-input-stream, 1832 // the end-of-output-stream is implied. 1833 if (mSignalledEOS 1834 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 1835 == mPortBuffers[kPortIndexInput].size() 1836 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 1837 == mPortBuffers[kPortIndexOutput].size()) { 1838 mNoMoreOutputData = true; 1839 mBufferFilled.signal(); 1840 1841 return; 1842 } 1843 1844 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1845 for (size_t i = 0; i < buffers->size(); ++i) { 1846 fillOutputBuffer(&buffers->editItemAt(i)); 1847 } 1848} 1849 1850void OMXCodec::drainInputBuffers() { 1851 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1852 1853 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1854 for (size_t i = 0; i < buffers->size(); ++i) { 1855 drainInputBuffer(&buffers->editItemAt(i)); 1856 } 1857} 1858 1859void OMXCodec::drainInputBuffer(BufferInfo *info) { 1860 CHECK_EQ(info->mOwnedByComponent, false); 1861 1862 if (mSignalledEOS) { 1863 return; 1864 } 1865 1866 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 1867 const CodecSpecificData *specific = 1868 mCodecSpecificData[mCodecSpecificDataIndex]; 1869 1870 size_t size = specific->mSize; 1871 1872 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 1873 && !(mQuirks & kWantsNALFragments)) { 1874 static const uint8_t kNALStartCode[4] = 1875 { 0x00, 0x00, 0x00, 0x01 }; 1876 1877 CHECK(info->mSize >= specific->mSize + 4); 1878 1879 size += 4; 1880 1881 memcpy(info->mData, kNALStartCode, 4); 1882 memcpy((uint8_t *)info->mData + 4, 1883 specific->mData, specific->mSize); 1884 } else { 1885 CHECK(info->mSize >= specific->mSize); 1886 memcpy(info->mData, specific->mData, specific->mSize); 1887 } 1888 1889 mNoMoreOutputData = false; 1890 1891 CODEC_LOGV("calling emptyBuffer with codec specific data"); 1892 1893 status_t err = mOMX->emptyBuffer( 1894 mNode, info->mBuffer, 0, size, 1895 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 1896 0); 1897 CHECK_EQ(err, OK); 1898 1899 info->mOwnedByComponent = true; 1900 1901 ++mCodecSpecificDataIndex; 1902 return; 1903 } 1904 1905 MediaBuffer *srcBuffer; 1906 status_t err; 1907 if (mSeekTimeUs >= 0) { 1908 MediaSource::ReadOptions options; 1909 options.setSeekTo(mSeekTimeUs); 1910 1911 mSeekTimeUs = -1; 1912 mBufferFilled.signal(); 1913 1914 err = mSource->read(&srcBuffer, &options); 1915 } else { 1916 err = mSource->read(&srcBuffer); 1917 } 1918 1919 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1920 OMX_TICKS timestampUs = 0; 1921 size_t srcLength = 0; 1922 1923 if (err != OK) { 1924 CODEC_LOGV("signalling end of input stream."); 1925 flags |= OMX_BUFFERFLAG_EOS; 1926 1927 mSignalledEOS = true; 1928 } else { 1929 mNoMoreOutputData = false; 1930 1931 srcLength = srcBuffer->range_length(); 1932 1933 if (info->mSize < srcLength) { 1934 LOGE("info->mSize = %d, srcLength = %d", 1935 info->mSize, srcLength); 1936 } 1937 CHECK(info->mSize >= srcLength); 1938 memcpy(info->mData, 1939 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1940 srcLength); 1941 1942 if (srcBuffer->meta_data()->findInt64(kKeyTime, ×tampUs)) { 1943 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 1944 "timestamp %lld us (%.2f secs)", 1945 info->mBuffer, srcLength, 1946 timestampUs, timestampUs / 1E6); 1947 } 1948 } 1949 1950 if (srcBuffer != NULL) { 1951 srcBuffer->release(); 1952 srcBuffer = NULL; 1953 } 1954 1955 err = mOMX->emptyBuffer( 1956 mNode, info->mBuffer, 0, srcLength, 1957 flags, timestampUs); 1958 1959 if (err != OK) { 1960 setState(ERROR); 1961 return; 1962 } 1963 1964 info->mOwnedByComponent = true; 1965 1966 // This component does not ever signal the EOS flag on output buffers, 1967 // Thanks for nothing. 1968 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 1969 mNoMoreOutputData = true; 1970 mBufferFilled.signal(); 1971 } 1972} 1973 1974void OMXCodec::fillOutputBuffer(BufferInfo *info) { 1975 CHECK_EQ(info->mOwnedByComponent, false); 1976 1977 if (mNoMoreOutputData) { 1978 CODEC_LOGV("There is no more output data available, not " 1979 "calling fillOutputBuffer"); 1980 return; 1981 } 1982 1983 CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 1984 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 1985 CHECK_EQ(err, OK); 1986 1987 info->mOwnedByComponent = true; 1988} 1989 1990void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 1991 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1992 for (size_t i = 0; i < buffers->size(); ++i) { 1993 if ((*buffers)[i].mBuffer == buffer) { 1994 drainInputBuffer(&buffers->editItemAt(i)); 1995 return; 1996 } 1997 } 1998 1999 CHECK(!"should not be here."); 2000} 2001 2002void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 2003 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2004 for (size_t i = 0; i < buffers->size(); ++i) { 2005 if ((*buffers)[i].mBuffer == buffer) { 2006 fillOutputBuffer(&buffers->editItemAt(i)); 2007 return; 2008 } 2009 } 2010 2011 CHECK(!"should not be here."); 2012} 2013 2014void OMXCodec::setState(State newState) { 2015 mState = newState; 2016 mAsyncCompletion.signal(); 2017 2018 // This may cause some spurious wakeups but is necessary to 2019 // unblock the reader if we enter ERROR state. 2020 mBufferFilled.signal(); 2021} 2022 2023void OMXCodec::setRawAudioFormat( 2024 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 2025 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2026 InitOMXParams(&pcmParams); 2027 pcmParams.nPortIndex = portIndex; 2028 2029 status_t err = mOMX->getParameter( 2030 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2031 2032 CHECK_EQ(err, OK); 2033 2034 pcmParams.nChannels = numChannels; 2035 pcmParams.eNumData = OMX_NumericalDataSigned; 2036 pcmParams.bInterleaved = OMX_TRUE; 2037 pcmParams.nBitPerSample = 16; 2038 pcmParams.nSamplingRate = sampleRate; 2039 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2040 2041 if (numChannels == 1) { 2042 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 2043 } else { 2044 CHECK_EQ(numChannels, 2); 2045 2046 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 2047 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 2048 } 2049 2050 err = mOMX->setParameter( 2051 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2052 2053 CHECK_EQ(err, OK); 2054} 2055 2056void OMXCodec::setAMRFormat(bool isWAMR) { 2057 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 2058 2059 OMX_AUDIO_PARAM_AMRTYPE def; 2060 InitOMXParams(&def); 2061 def.nPortIndex = portIndex; 2062 2063 status_t err = 2064 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2065 2066 CHECK_EQ(err, OK); 2067 2068 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2069 def.eAMRBandMode = 2070 isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0; 2071 2072 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2073 CHECK_EQ(err, OK); 2074 2075 //////////////////////// 2076 2077 if (mIsEncoder) { 2078 sp<MetaData> format = mSource->getFormat(); 2079 int32_t sampleRate; 2080 int32_t numChannels; 2081 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 2082 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 2083 2084 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2085 } 2086} 2087 2088void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { 2089 if (mIsEncoder) { 2090 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2091 } else { 2092 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2093 InitOMXParams(&profile); 2094 profile.nPortIndex = kPortIndexInput; 2095 2096 status_t err = mOMX->getParameter( 2097 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2098 CHECK_EQ(err, OK); 2099 2100 profile.nChannels = numChannels; 2101 profile.nSampleRate = sampleRate; 2102 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 2103 2104 err = mOMX->setParameter( 2105 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2106 CHECK_EQ(err, OK); 2107 } 2108} 2109 2110void OMXCodec::setImageOutputFormat( 2111 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 2112 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 2113 2114#if 0 2115 OMX_INDEXTYPE index; 2116 status_t err = mOMX->get_extension_index( 2117 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 2118 CHECK_EQ(err, OK); 2119 2120 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 2121 CHECK_EQ(err, OK); 2122#endif 2123 2124 OMX_PARAM_PORTDEFINITIONTYPE def; 2125 InitOMXParams(&def); 2126 def.nPortIndex = kPortIndexOutput; 2127 2128 status_t err = mOMX->getParameter( 2129 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2130 CHECK_EQ(err, OK); 2131 2132 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2133 2134 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2135 2136 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2137 imageDef->eColorFormat = format; 2138 imageDef->nFrameWidth = width; 2139 imageDef->nFrameHeight = height; 2140 2141 switch (format) { 2142 case OMX_COLOR_FormatYUV420PackedPlanar: 2143 case OMX_COLOR_FormatYUV411Planar: 2144 { 2145 def.nBufferSize = (width * height * 3) / 2; 2146 break; 2147 } 2148 2149 case OMX_COLOR_FormatCbYCrY: 2150 { 2151 def.nBufferSize = width * height * 2; 2152 break; 2153 } 2154 2155 case OMX_COLOR_Format32bitARGB8888: 2156 { 2157 def.nBufferSize = width * height * 4; 2158 break; 2159 } 2160 2161 case OMX_COLOR_Format16bitARGB4444: 2162 case OMX_COLOR_Format16bitARGB1555: 2163 case OMX_COLOR_Format16bitRGB565: 2164 case OMX_COLOR_Format16bitBGR565: 2165 { 2166 def.nBufferSize = width * height * 2; 2167 break; 2168 } 2169 2170 default: 2171 CHECK(!"Should not be here. Unknown color format."); 2172 break; 2173 } 2174 2175 def.nBufferCountActual = def.nBufferCountMin; 2176 2177 err = mOMX->setParameter( 2178 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2179 CHECK_EQ(err, OK); 2180} 2181 2182void OMXCodec::setJPEGInputFormat( 2183 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 2184 OMX_PARAM_PORTDEFINITIONTYPE def; 2185 InitOMXParams(&def); 2186 def.nPortIndex = kPortIndexInput; 2187 2188 status_t err = mOMX->getParameter( 2189 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2190 CHECK_EQ(err, OK); 2191 2192 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2193 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2194 2195 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 2196 imageDef->nFrameWidth = width; 2197 imageDef->nFrameHeight = height; 2198 2199 def.nBufferSize = compressedSize; 2200 def.nBufferCountActual = def.nBufferCountMin; 2201 2202 err = mOMX->setParameter( 2203 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2204 CHECK_EQ(err, OK); 2205} 2206 2207void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 2208 CodecSpecificData *specific = 2209 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 2210 2211 specific->mSize = size; 2212 memcpy(specific->mData, data, size); 2213 2214 mCodecSpecificData.push(specific); 2215} 2216 2217void OMXCodec::clearCodecSpecificData() { 2218 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 2219 free(mCodecSpecificData.editItemAt(i)); 2220 } 2221 mCodecSpecificData.clear(); 2222 mCodecSpecificDataIndex = 0; 2223} 2224 2225status_t OMXCodec::start(MetaData *) { 2226 Mutex::Autolock autoLock(mLock); 2227 2228 if (mState != LOADED) { 2229 return UNKNOWN_ERROR; 2230 } 2231 2232 sp<MetaData> params = new MetaData; 2233 if (mQuirks & kWantsNALFragments) { 2234 params->setInt32(kKeyWantsNALFragments, true); 2235 } 2236 status_t err = mSource->start(params.get()); 2237 2238 if (err != OK) { 2239 return err; 2240 } 2241 2242 mCodecSpecificDataIndex = 0; 2243 mInitialBufferSubmit = true; 2244 mSignalledEOS = false; 2245 mNoMoreOutputData = false; 2246 mOutputPortSettingsHaveChanged = false; 2247 mSeekTimeUs = -1; 2248 mFilledBuffers.clear(); 2249 2250 return init(); 2251} 2252 2253status_t OMXCodec::stop() { 2254 CODEC_LOGV("stop mState=%d", mState); 2255 2256 Mutex::Autolock autoLock(mLock); 2257 2258 while (isIntermediateState(mState)) { 2259 mAsyncCompletion.wait(mLock); 2260 } 2261 2262 switch (mState) { 2263 case LOADED: 2264 case ERROR: 2265 break; 2266 2267 case EXECUTING: 2268 { 2269 setState(EXECUTING_TO_IDLE); 2270 2271 if (mQuirks & kRequiresFlushBeforeShutdown) { 2272 CODEC_LOGV("This component requires a flush before transitioning " 2273 "from EXECUTING to IDLE..."); 2274 2275 bool emulateInputFlushCompletion = 2276 !flushPortAsync(kPortIndexInput); 2277 2278 bool emulateOutputFlushCompletion = 2279 !flushPortAsync(kPortIndexOutput); 2280 2281 if (emulateInputFlushCompletion) { 2282 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2283 } 2284 2285 if (emulateOutputFlushCompletion) { 2286 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2287 } 2288 } else { 2289 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2290 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2291 2292 status_t err = 2293 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2294 CHECK_EQ(err, OK); 2295 } 2296 2297 while (mState != LOADED && mState != ERROR) { 2298 mAsyncCompletion.wait(mLock); 2299 } 2300 2301 break; 2302 } 2303 2304 default: 2305 { 2306 CHECK(!"should not be here."); 2307 break; 2308 } 2309 } 2310 2311 mSource->stop(); 2312 2313 CODEC_LOGV("stopped"); 2314 2315 return OK; 2316} 2317 2318sp<MetaData> OMXCodec::getFormat() { 2319 Mutex::Autolock autoLock(mLock); 2320 2321 return mOutputFormat; 2322} 2323 2324status_t OMXCodec::read( 2325 MediaBuffer **buffer, const ReadOptions *options) { 2326 *buffer = NULL; 2327 2328 Mutex::Autolock autoLock(mLock); 2329 2330 if (mState != EXECUTING && mState != RECONFIGURING) { 2331 return UNKNOWN_ERROR; 2332 } 2333 2334 bool seeking = false; 2335 int64_t seekTimeUs; 2336 if (options && options->getSeekTo(&seekTimeUs)) { 2337 seeking = true; 2338 } 2339 2340 if (mInitialBufferSubmit) { 2341 mInitialBufferSubmit = false; 2342 2343 if (seeking) { 2344 CHECK(seekTimeUs >= 0); 2345 mSeekTimeUs = seekTimeUs; 2346 2347 // There's no reason to trigger the code below, there's 2348 // nothing to flush yet. 2349 seeking = false; 2350 } 2351 2352 drainInputBuffers(); 2353 2354 if (mState == EXECUTING) { 2355 // Otherwise mState == RECONFIGURING and this code will trigger 2356 // after the output port is reenabled. 2357 fillOutputBuffers(); 2358 } 2359 } 2360 2361 if (seeking) { 2362 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 2363 2364 mSignalledEOS = false; 2365 2366 CHECK(seekTimeUs >= 0); 2367 mSeekTimeUs = seekTimeUs; 2368 2369 mFilledBuffers.clear(); 2370 2371 CHECK_EQ(mState, EXECUTING); 2372 2373 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 2374 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 2375 2376 if (emulateInputFlushCompletion) { 2377 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2378 } 2379 2380 if (emulateOutputFlushCompletion) { 2381 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2382 } 2383 2384 while (mSeekTimeUs >= 0) { 2385 mBufferFilled.wait(mLock); 2386 } 2387 } 2388 2389 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 2390 mBufferFilled.wait(mLock); 2391 } 2392 2393 if (mState == ERROR) { 2394 return UNKNOWN_ERROR; 2395 } 2396 2397 if (mFilledBuffers.empty()) { 2398 return ERROR_END_OF_STREAM; 2399 } 2400 2401 if (mOutputPortSettingsHaveChanged) { 2402 mOutputPortSettingsHaveChanged = false; 2403 2404 return INFO_FORMAT_CHANGED; 2405 } 2406 2407 size_t index = *mFilledBuffers.begin(); 2408 mFilledBuffers.erase(mFilledBuffers.begin()); 2409 2410 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 2411 info->mMediaBuffer->add_ref(); 2412 *buffer = info->mMediaBuffer; 2413 2414 return OK; 2415} 2416 2417void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 2418 Mutex::Autolock autoLock(mLock); 2419 2420 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2421 for (size_t i = 0; i < buffers->size(); ++i) { 2422 BufferInfo *info = &buffers->editItemAt(i); 2423 2424 if (info->mMediaBuffer == buffer) { 2425 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 2426 fillOutputBuffer(info); 2427 return; 2428 } 2429 } 2430 2431 CHECK(!"should not be here."); 2432} 2433 2434static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 2435 static const char *kNames[] = { 2436 "OMX_IMAGE_CodingUnused", 2437 "OMX_IMAGE_CodingAutoDetect", 2438 "OMX_IMAGE_CodingJPEG", 2439 "OMX_IMAGE_CodingJPEG2K", 2440 "OMX_IMAGE_CodingEXIF", 2441 "OMX_IMAGE_CodingTIFF", 2442 "OMX_IMAGE_CodingGIF", 2443 "OMX_IMAGE_CodingPNG", 2444 "OMX_IMAGE_CodingLZW", 2445 "OMX_IMAGE_CodingBMP", 2446 }; 2447 2448 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2449 2450 if (type < 0 || (size_t)type >= numNames) { 2451 return "UNKNOWN"; 2452 } else { 2453 return kNames[type]; 2454 } 2455} 2456 2457static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 2458 static const char *kNames[] = { 2459 "OMX_COLOR_FormatUnused", 2460 "OMX_COLOR_FormatMonochrome", 2461 "OMX_COLOR_Format8bitRGB332", 2462 "OMX_COLOR_Format12bitRGB444", 2463 "OMX_COLOR_Format16bitARGB4444", 2464 "OMX_COLOR_Format16bitARGB1555", 2465 "OMX_COLOR_Format16bitRGB565", 2466 "OMX_COLOR_Format16bitBGR565", 2467 "OMX_COLOR_Format18bitRGB666", 2468 "OMX_COLOR_Format18bitARGB1665", 2469 "OMX_COLOR_Format19bitARGB1666", 2470 "OMX_COLOR_Format24bitRGB888", 2471 "OMX_COLOR_Format24bitBGR888", 2472 "OMX_COLOR_Format24bitARGB1887", 2473 "OMX_COLOR_Format25bitARGB1888", 2474 "OMX_COLOR_Format32bitBGRA8888", 2475 "OMX_COLOR_Format32bitARGB8888", 2476 "OMX_COLOR_FormatYUV411Planar", 2477 "OMX_COLOR_FormatYUV411PackedPlanar", 2478 "OMX_COLOR_FormatYUV420Planar", 2479 "OMX_COLOR_FormatYUV420PackedPlanar", 2480 "OMX_COLOR_FormatYUV420SemiPlanar", 2481 "OMX_COLOR_FormatYUV422Planar", 2482 "OMX_COLOR_FormatYUV422PackedPlanar", 2483 "OMX_COLOR_FormatYUV422SemiPlanar", 2484 "OMX_COLOR_FormatYCbYCr", 2485 "OMX_COLOR_FormatYCrYCb", 2486 "OMX_COLOR_FormatCbYCrY", 2487 "OMX_COLOR_FormatCrYCbY", 2488 "OMX_COLOR_FormatYUV444Interleaved", 2489 "OMX_COLOR_FormatRawBayer8bit", 2490 "OMX_COLOR_FormatRawBayer10bit", 2491 "OMX_COLOR_FormatRawBayer8bitcompressed", 2492 "OMX_COLOR_FormatL2", 2493 "OMX_COLOR_FormatL4", 2494 "OMX_COLOR_FormatL8", 2495 "OMX_COLOR_FormatL16", 2496 "OMX_COLOR_FormatL24", 2497 "OMX_COLOR_FormatL32", 2498 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 2499 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 2500 "OMX_COLOR_Format18BitBGR666", 2501 "OMX_COLOR_Format24BitARGB6666", 2502 "OMX_COLOR_Format24BitABGR6666", 2503 }; 2504 2505 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2506 2507 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 2508 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 2509 } else if (type < 0 || (size_t)type >= numNames) { 2510 return "UNKNOWN"; 2511 } else { 2512 return kNames[type]; 2513 } 2514} 2515 2516static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 2517 static const char *kNames[] = { 2518 "OMX_VIDEO_CodingUnused", 2519 "OMX_VIDEO_CodingAutoDetect", 2520 "OMX_VIDEO_CodingMPEG2", 2521 "OMX_VIDEO_CodingH263", 2522 "OMX_VIDEO_CodingMPEG4", 2523 "OMX_VIDEO_CodingWMV", 2524 "OMX_VIDEO_CodingRV", 2525 "OMX_VIDEO_CodingAVC", 2526 "OMX_VIDEO_CodingMJPEG", 2527 }; 2528 2529 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2530 2531 if (type < 0 || (size_t)type >= numNames) { 2532 return "UNKNOWN"; 2533 } else { 2534 return kNames[type]; 2535 } 2536} 2537 2538static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 2539 static const char *kNames[] = { 2540 "OMX_AUDIO_CodingUnused", 2541 "OMX_AUDIO_CodingAutoDetect", 2542 "OMX_AUDIO_CodingPCM", 2543 "OMX_AUDIO_CodingADPCM", 2544 "OMX_AUDIO_CodingAMR", 2545 "OMX_AUDIO_CodingGSMFR", 2546 "OMX_AUDIO_CodingGSMEFR", 2547 "OMX_AUDIO_CodingGSMHR", 2548 "OMX_AUDIO_CodingPDCFR", 2549 "OMX_AUDIO_CodingPDCEFR", 2550 "OMX_AUDIO_CodingPDCHR", 2551 "OMX_AUDIO_CodingTDMAFR", 2552 "OMX_AUDIO_CodingTDMAEFR", 2553 "OMX_AUDIO_CodingQCELP8", 2554 "OMX_AUDIO_CodingQCELP13", 2555 "OMX_AUDIO_CodingEVRC", 2556 "OMX_AUDIO_CodingSMV", 2557 "OMX_AUDIO_CodingG711", 2558 "OMX_AUDIO_CodingG723", 2559 "OMX_AUDIO_CodingG726", 2560 "OMX_AUDIO_CodingG729", 2561 "OMX_AUDIO_CodingAAC", 2562 "OMX_AUDIO_CodingMP3", 2563 "OMX_AUDIO_CodingSBC", 2564 "OMX_AUDIO_CodingVORBIS", 2565 "OMX_AUDIO_CodingWMA", 2566 "OMX_AUDIO_CodingRA", 2567 "OMX_AUDIO_CodingMIDI", 2568 }; 2569 2570 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2571 2572 if (type < 0 || (size_t)type >= numNames) { 2573 return "UNKNOWN"; 2574 } else { 2575 return kNames[type]; 2576 } 2577} 2578 2579static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 2580 static const char *kNames[] = { 2581 "OMX_AUDIO_PCMModeLinear", 2582 "OMX_AUDIO_PCMModeALaw", 2583 "OMX_AUDIO_PCMModeMULaw", 2584 }; 2585 2586 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2587 2588 if (type < 0 || (size_t)type >= numNames) { 2589 return "UNKNOWN"; 2590 } else { 2591 return kNames[type]; 2592 } 2593} 2594 2595static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 2596 static const char *kNames[] = { 2597 "OMX_AUDIO_AMRBandModeUnused", 2598 "OMX_AUDIO_AMRBandModeNB0", 2599 "OMX_AUDIO_AMRBandModeNB1", 2600 "OMX_AUDIO_AMRBandModeNB2", 2601 "OMX_AUDIO_AMRBandModeNB3", 2602 "OMX_AUDIO_AMRBandModeNB4", 2603 "OMX_AUDIO_AMRBandModeNB5", 2604 "OMX_AUDIO_AMRBandModeNB6", 2605 "OMX_AUDIO_AMRBandModeNB7", 2606 "OMX_AUDIO_AMRBandModeWB0", 2607 "OMX_AUDIO_AMRBandModeWB1", 2608 "OMX_AUDIO_AMRBandModeWB2", 2609 "OMX_AUDIO_AMRBandModeWB3", 2610 "OMX_AUDIO_AMRBandModeWB4", 2611 "OMX_AUDIO_AMRBandModeWB5", 2612 "OMX_AUDIO_AMRBandModeWB6", 2613 "OMX_AUDIO_AMRBandModeWB7", 2614 "OMX_AUDIO_AMRBandModeWB8", 2615 }; 2616 2617 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2618 2619 if (type < 0 || (size_t)type >= numNames) { 2620 return "UNKNOWN"; 2621 } else { 2622 return kNames[type]; 2623 } 2624} 2625 2626static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 2627 static const char *kNames[] = { 2628 "OMX_AUDIO_AMRFrameFormatConformance", 2629 "OMX_AUDIO_AMRFrameFormatIF1", 2630 "OMX_AUDIO_AMRFrameFormatIF2", 2631 "OMX_AUDIO_AMRFrameFormatFSF", 2632 "OMX_AUDIO_AMRFrameFormatRTPPayload", 2633 "OMX_AUDIO_AMRFrameFormatITU", 2634 }; 2635 2636 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2637 2638 if (type < 0 || (size_t)type >= numNames) { 2639 return "UNKNOWN"; 2640 } else { 2641 return kNames[type]; 2642 } 2643} 2644 2645void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 2646 OMX_PARAM_PORTDEFINITIONTYPE def; 2647 InitOMXParams(&def); 2648 def.nPortIndex = portIndex; 2649 2650 status_t err = mOMX->getParameter( 2651 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2652 CHECK_EQ(err, OK); 2653 2654 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 2655 2656 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 2657 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 2658 2659 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 2660 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 2661 printf(" nBufferSize = %ld\n", def.nBufferSize); 2662 2663 switch (def.eDomain) { 2664 case OMX_PortDomainImage: 2665 { 2666 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2667 2668 printf("\n"); 2669 printf(" // Image\n"); 2670 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 2671 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 2672 printf(" nStride = %ld\n", imageDef->nStride); 2673 2674 printf(" eCompressionFormat = %s\n", 2675 imageCompressionFormatString(imageDef->eCompressionFormat)); 2676 2677 printf(" eColorFormat = %s\n", 2678 colorFormatString(imageDef->eColorFormat)); 2679 2680 break; 2681 } 2682 2683 case OMX_PortDomainVideo: 2684 { 2685 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2686 2687 printf("\n"); 2688 printf(" // Video\n"); 2689 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 2690 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 2691 printf(" nStride = %ld\n", videoDef->nStride); 2692 2693 printf(" eCompressionFormat = %s\n", 2694 videoCompressionFormatString(videoDef->eCompressionFormat)); 2695 2696 printf(" eColorFormat = %s\n", 2697 colorFormatString(videoDef->eColorFormat)); 2698 2699 break; 2700 } 2701 2702 case OMX_PortDomainAudio: 2703 { 2704 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2705 2706 printf("\n"); 2707 printf(" // Audio\n"); 2708 printf(" eEncoding = %s\n", 2709 audioCodingTypeString(audioDef->eEncoding)); 2710 2711 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2712 OMX_AUDIO_PARAM_PCMMODETYPE params; 2713 InitOMXParams(¶ms); 2714 params.nPortIndex = portIndex; 2715 2716 err = mOMX->getParameter( 2717 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2718 CHECK_EQ(err, OK); 2719 2720 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2721 printf(" nChannels = %ld\n", params.nChannels); 2722 printf(" bInterleaved = %d\n", params.bInterleaved); 2723 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2724 2725 printf(" eNumData = %s\n", 2726 params.eNumData == OMX_NumericalDataSigned 2727 ? "signed" : "unsigned"); 2728 2729 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2730 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 2731 OMX_AUDIO_PARAM_AMRTYPE amr; 2732 InitOMXParams(&amr); 2733 amr.nPortIndex = portIndex; 2734 2735 err = mOMX->getParameter( 2736 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2737 CHECK_EQ(err, OK); 2738 2739 printf(" nChannels = %ld\n", amr.nChannels); 2740 printf(" eAMRBandMode = %s\n", 2741 amrBandModeString(amr.eAMRBandMode)); 2742 printf(" eAMRFrameFormat = %s\n", 2743 amrFrameFormatString(amr.eAMRFrameFormat)); 2744 } 2745 2746 break; 2747 } 2748 2749 default: 2750 { 2751 printf(" // Unknown\n"); 2752 break; 2753 } 2754 } 2755 2756 printf("}\n"); 2757} 2758 2759void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2760 mOutputFormat = new MetaData; 2761 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2762 2763 OMX_PARAM_PORTDEFINITIONTYPE def; 2764 InitOMXParams(&def); 2765 def.nPortIndex = kPortIndexOutput; 2766 2767 status_t err = mOMX->getParameter( 2768 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2769 CHECK_EQ(err, OK); 2770 2771 switch (def.eDomain) { 2772 case OMX_PortDomainImage: 2773 { 2774 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2775 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2776 2777 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2778 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2779 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2780 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2781 break; 2782 } 2783 2784 case OMX_PortDomainAudio: 2785 { 2786 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2787 2788 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 2789 OMX_AUDIO_PARAM_PCMMODETYPE params; 2790 InitOMXParams(¶ms); 2791 params.nPortIndex = kPortIndexOutput; 2792 2793 err = mOMX->getParameter( 2794 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2795 CHECK_EQ(err, OK); 2796 2797 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2798 CHECK_EQ(params.nBitPerSample, 16); 2799 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2800 2801 int32_t numChannels, sampleRate; 2802 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2803 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2804 2805 if ((OMX_U32)numChannels != params.nChannels) { 2806 LOGW("Codec outputs a different number of channels than " 2807 "the input stream contains (contains %d channels, " 2808 "codec outputs %ld channels).", 2809 numChannels, params.nChannels); 2810 } 2811 2812 mOutputFormat->setCString( 2813 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2814 2815 // Use the codec-advertised number of channels, as some 2816 // codecs appear to output stereo even if the input data is 2817 // mono. If we know the codec lies about this information, 2818 // use the actual number of channels instead. 2819 mOutputFormat->setInt32( 2820 kKeyChannelCount, 2821 (mQuirks & kDecoderLiesAboutNumberOfChannels) 2822 ? numChannels : params.nChannels); 2823 2824 // The codec-reported sampleRate is not reliable... 2825 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2826 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 2827 OMX_AUDIO_PARAM_AMRTYPE amr; 2828 InitOMXParams(&amr); 2829 amr.nPortIndex = kPortIndexOutput; 2830 2831 err = mOMX->getParameter( 2832 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2833 CHECK_EQ(err, OK); 2834 2835 CHECK_EQ(amr.nChannels, 1); 2836 mOutputFormat->setInt32(kKeyChannelCount, 1); 2837 2838 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 2839 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 2840 mOutputFormat->setCString( 2841 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 2842 mOutputFormat->setInt32(kKeySampleRate, 8000); 2843 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 2844 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 2845 mOutputFormat->setCString( 2846 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 2847 mOutputFormat->setInt32(kKeySampleRate, 16000); 2848 } else { 2849 CHECK(!"Unknown AMR band mode."); 2850 } 2851 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 2852 mOutputFormat->setCString( 2853 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 2854 } else { 2855 CHECK(!"Should not be here. Unknown audio encoding."); 2856 } 2857 break; 2858 } 2859 2860 case OMX_PortDomainVideo: 2861 { 2862 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2863 2864 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2865 mOutputFormat->setCString( 2866 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2867 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2868 mOutputFormat->setCString( 2869 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 2870 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2871 mOutputFormat->setCString( 2872 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 2873 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2874 mOutputFormat->setCString( 2875 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 2876 } else { 2877 CHECK(!"Unknown compression format."); 2878 } 2879 2880 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2881 // This component appears to be lying to me. 2882 mOutputFormat->setInt32( 2883 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2884 mOutputFormat->setInt32( 2885 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2886 } else { 2887 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2888 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2889 } 2890 2891 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2892 break; 2893 } 2894 2895 default: 2896 { 2897 CHECK(!"should not be here, neither audio nor video."); 2898 break; 2899 } 2900 } 2901} 2902 2903//////////////////////////////////////////////////////////////////////////////// 2904 2905status_t QueryCodecs( 2906 const sp<IOMX> &omx, 2907 const char *mime, bool queryDecoders, 2908 Vector<CodecCapabilities> *results) { 2909 results->clear(); 2910 2911 for (int index = 0;; ++index) { 2912 const char *componentName; 2913 2914 if (!queryDecoders) { 2915 componentName = GetCodec( 2916 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 2917 mime, index); 2918 } else { 2919 componentName = GetCodec( 2920 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 2921 mime, index); 2922 } 2923 2924 if (!componentName) { 2925 return OK; 2926 } 2927 2928 sp<OMXCodecObserver> observer = new OMXCodecObserver; 2929 IOMX::node_id node; 2930 status_t err = omx->allocateNode(componentName, observer, &node); 2931 2932 if (err != OK) { 2933 continue; 2934 } 2935 2936 OMXCodec::setComponentRole(omx, node, queryDecoders, mime); 2937 2938 results->push(); 2939 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 2940 caps->mComponentName = componentName; 2941 2942 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 2943 InitOMXParams(¶m); 2944 2945 param.nPortIndex = queryDecoders ? 0 : 1; 2946 2947 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 2948 err = omx->getParameter( 2949 node, OMX_IndexParamVideoProfileLevelQuerySupported, 2950 ¶m, sizeof(param)); 2951 2952 if (err != OK) { 2953 break; 2954 } 2955 2956 CodecProfileLevel profileLevel; 2957 profileLevel.mProfile = param.eProfile; 2958 profileLevel.mLevel = param.eLevel; 2959 2960 caps->mProfileLevels.push(profileLevel); 2961 } 2962 2963 CHECK_EQ(omx->freeNode(node), OK); 2964 } 2965} 2966 2967} // namespace android 2968