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