OMXCodec.cpp revision 758cc74ff08487ded45f7ff4476c200fe727b366
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, "M4vH263Decoder" }, 116 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, 117 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, 118 { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" }, 119}; 120 121static const CodecInfo kEncoderInfo[] = { 122 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" }, 123 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" }, 124 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" }, 125 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, 126 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" }, 127 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, 128 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, 129 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" }, 130 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, 131 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, 132 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" }, 133 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, 134 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" }, 135}; 136 137#undef OPTIONAL 138 139#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 140#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 141#define CODEC_LOGE(x, ...) LOGE("[%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 CODEC_LOGE( 1935 "Codec's input buffers are too small to accomodate " 1936 "buffer read from source (info->mSize = %d, srcLength = %d)", 1937 info->mSize, srcLength); 1938 1939 srcBuffer->release(); 1940 srcBuffer = NULL; 1941 1942 setState(ERROR); 1943 return; 1944 } 1945 memcpy(info->mData, 1946 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1947 srcLength); 1948 1949 if (srcBuffer->meta_data()->findInt64(kKeyTime, ×tampUs)) { 1950 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 1951 "timestamp %lld us (%.2f secs)", 1952 info->mBuffer, srcLength, 1953 timestampUs, timestampUs / 1E6); 1954 } 1955 } 1956 1957 if (srcBuffer != NULL) { 1958 srcBuffer->release(); 1959 srcBuffer = NULL; 1960 } 1961 1962 err = mOMX->emptyBuffer( 1963 mNode, info->mBuffer, 0, srcLength, 1964 flags, timestampUs); 1965 1966 if (err != OK) { 1967 setState(ERROR); 1968 return; 1969 } 1970 1971 info->mOwnedByComponent = true; 1972 1973 // This component does not ever signal the EOS flag on output buffers, 1974 // Thanks for nothing. 1975 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 1976 mNoMoreOutputData = true; 1977 mBufferFilled.signal(); 1978 } 1979} 1980 1981void OMXCodec::fillOutputBuffer(BufferInfo *info) { 1982 CHECK_EQ(info->mOwnedByComponent, false); 1983 1984 if (mNoMoreOutputData) { 1985 CODEC_LOGV("There is no more output data available, not " 1986 "calling fillOutputBuffer"); 1987 return; 1988 } 1989 1990 CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 1991 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 1992 CHECK_EQ(err, OK); 1993 1994 info->mOwnedByComponent = true; 1995} 1996 1997void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 1998 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1999 for (size_t i = 0; i < buffers->size(); ++i) { 2000 if ((*buffers)[i].mBuffer == buffer) { 2001 drainInputBuffer(&buffers->editItemAt(i)); 2002 return; 2003 } 2004 } 2005 2006 CHECK(!"should not be here."); 2007} 2008 2009void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 2010 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2011 for (size_t i = 0; i < buffers->size(); ++i) { 2012 if ((*buffers)[i].mBuffer == buffer) { 2013 fillOutputBuffer(&buffers->editItemAt(i)); 2014 return; 2015 } 2016 } 2017 2018 CHECK(!"should not be here."); 2019} 2020 2021void OMXCodec::setState(State newState) { 2022 mState = newState; 2023 mAsyncCompletion.signal(); 2024 2025 // This may cause some spurious wakeups but is necessary to 2026 // unblock the reader if we enter ERROR state. 2027 mBufferFilled.signal(); 2028} 2029 2030void OMXCodec::setRawAudioFormat( 2031 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 2032 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2033 InitOMXParams(&pcmParams); 2034 pcmParams.nPortIndex = portIndex; 2035 2036 status_t err = mOMX->getParameter( 2037 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2038 2039 CHECK_EQ(err, OK); 2040 2041 pcmParams.nChannels = numChannels; 2042 pcmParams.eNumData = OMX_NumericalDataSigned; 2043 pcmParams.bInterleaved = OMX_TRUE; 2044 pcmParams.nBitPerSample = 16; 2045 pcmParams.nSamplingRate = sampleRate; 2046 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2047 2048 if (numChannels == 1) { 2049 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 2050 } else { 2051 CHECK_EQ(numChannels, 2); 2052 2053 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 2054 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 2055 } 2056 2057 err = mOMX->setParameter( 2058 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2059 2060 CHECK_EQ(err, OK); 2061} 2062 2063void OMXCodec::setAMRFormat(bool isWAMR) { 2064 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 2065 2066 OMX_AUDIO_PARAM_AMRTYPE def; 2067 InitOMXParams(&def); 2068 def.nPortIndex = portIndex; 2069 2070 status_t err = 2071 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2072 2073 CHECK_EQ(err, OK); 2074 2075 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2076 def.eAMRBandMode = 2077 isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0; 2078 2079 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2080 CHECK_EQ(err, OK); 2081 2082 //////////////////////// 2083 2084 if (mIsEncoder) { 2085 sp<MetaData> format = mSource->getFormat(); 2086 int32_t sampleRate; 2087 int32_t numChannels; 2088 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 2089 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 2090 2091 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2092 } 2093} 2094 2095void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { 2096 if (mIsEncoder) { 2097 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2098 } else { 2099 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2100 InitOMXParams(&profile); 2101 profile.nPortIndex = kPortIndexInput; 2102 2103 status_t err = mOMX->getParameter( 2104 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2105 CHECK_EQ(err, OK); 2106 2107 profile.nChannels = numChannels; 2108 profile.nSampleRate = sampleRate; 2109 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 2110 2111 err = mOMX->setParameter( 2112 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2113 CHECK_EQ(err, OK); 2114 } 2115} 2116 2117void OMXCodec::setImageOutputFormat( 2118 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 2119 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 2120 2121#if 0 2122 OMX_INDEXTYPE index; 2123 status_t err = mOMX->get_extension_index( 2124 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 2125 CHECK_EQ(err, OK); 2126 2127 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 2128 CHECK_EQ(err, OK); 2129#endif 2130 2131 OMX_PARAM_PORTDEFINITIONTYPE def; 2132 InitOMXParams(&def); 2133 def.nPortIndex = kPortIndexOutput; 2134 2135 status_t err = mOMX->getParameter( 2136 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2137 CHECK_EQ(err, OK); 2138 2139 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2140 2141 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2142 2143 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2144 imageDef->eColorFormat = format; 2145 imageDef->nFrameWidth = width; 2146 imageDef->nFrameHeight = height; 2147 2148 switch (format) { 2149 case OMX_COLOR_FormatYUV420PackedPlanar: 2150 case OMX_COLOR_FormatYUV411Planar: 2151 { 2152 def.nBufferSize = (width * height * 3) / 2; 2153 break; 2154 } 2155 2156 case OMX_COLOR_FormatCbYCrY: 2157 { 2158 def.nBufferSize = width * height * 2; 2159 break; 2160 } 2161 2162 case OMX_COLOR_Format32bitARGB8888: 2163 { 2164 def.nBufferSize = width * height * 4; 2165 break; 2166 } 2167 2168 case OMX_COLOR_Format16bitARGB4444: 2169 case OMX_COLOR_Format16bitARGB1555: 2170 case OMX_COLOR_Format16bitRGB565: 2171 case OMX_COLOR_Format16bitBGR565: 2172 { 2173 def.nBufferSize = width * height * 2; 2174 break; 2175 } 2176 2177 default: 2178 CHECK(!"Should not be here. Unknown color format."); 2179 break; 2180 } 2181 2182 def.nBufferCountActual = def.nBufferCountMin; 2183 2184 err = mOMX->setParameter( 2185 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2186 CHECK_EQ(err, OK); 2187} 2188 2189void OMXCodec::setJPEGInputFormat( 2190 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 2191 OMX_PARAM_PORTDEFINITIONTYPE def; 2192 InitOMXParams(&def); 2193 def.nPortIndex = kPortIndexInput; 2194 2195 status_t err = mOMX->getParameter( 2196 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2197 CHECK_EQ(err, OK); 2198 2199 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2200 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2201 2202 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 2203 imageDef->nFrameWidth = width; 2204 imageDef->nFrameHeight = height; 2205 2206 def.nBufferSize = compressedSize; 2207 def.nBufferCountActual = def.nBufferCountMin; 2208 2209 err = mOMX->setParameter( 2210 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2211 CHECK_EQ(err, OK); 2212} 2213 2214void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 2215 CodecSpecificData *specific = 2216 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 2217 2218 specific->mSize = size; 2219 memcpy(specific->mData, data, size); 2220 2221 mCodecSpecificData.push(specific); 2222} 2223 2224void OMXCodec::clearCodecSpecificData() { 2225 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 2226 free(mCodecSpecificData.editItemAt(i)); 2227 } 2228 mCodecSpecificData.clear(); 2229 mCodecSpecificDataIndex = 0; 2230} 2231 2232status_t OMXCodec::start(MetaData *) { 2233 Mutex::Autolock autoLock(mLock); 2234 2235 if (mState != LOADED) { 2236 return UNKNOWN_ERROR; 2237 } 2238 2239 sp<MetaData> params = new MetaData; 2240 if (mQuirks & kWantsNALFragments) { 2241 params->setInt32(kKeyWantsNALFragments, true); 2242 } 2243 status_t err = mSource->start(params.get()); 2244 2245 if (err != OK) { 2246 return err; 2247 } 2248 2249 mCodecSpecificDataIndex = 0; 2250 mInitialBufferSubmit = true; 2251 mSignalledEOS = false; 2252 mNoMoreOutputData = false; 2253 mOutputPortSettingsHaveChanged = false; 2254 mSeekTimeUs = -1; 2255 mFilledBuffers.clear(); 2256 2257 return init(); 2258} 2259 2260status_t OMXCodec::stop() { 2261 CODEC_LOGV("stop mState=%d", mState); 2262 2263 Mutex::Autolock autoLock(mLock); 2264 2265 while (isIntermediateState(mState)) { 2266 mAsyncCompletion.wait(mLock); 2267 } 2268 2269 switch (mState) { 2270 case LOADED: 2271 case ERROR: 2272 break; 2273 2274 case EXECUTING: 2275 { 2276 setState(EXECUTING_TO_IDLE); 2277 2278 if (mQuirks & kRequiresFlushBeforeShutdown) { 2279 CODEC_LOGV("This component requires a flush before transitioning " 2280 "from EXECUTING to IDLE..."); 2281 2282 bool emulateInputFlushCompletion = 2283 !flushPortAsync(kPortIndexInput); 2284 2285 bool emulateOutputFlushCompletion = 2286 !flushPortAsync(kPortIndexOutput); 2287 2288 if (emulateInputFlushCompletion) { 2289 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2290 } 2291 2292 if (emulateOutputFlushCompletion) { 2293 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2294 } 2295 } else { 2296 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2297 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2298 2299 status_t err = 2300 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2301 CHECK_EQ(err, OK); 2302 } 2303 2304 while (mState != LOADED && mState != ERROR) { 2305 mAsyncCompletion.wait(mLock); 2306 } 2307 2308 break; 2309 } 2310 2311 default: 2312 { 2313 CHECK(!"should not be here."); 2314 break; 2315 } 2316 } 2317 2318 mSource->stop(); 2319 2320 CODEC_LOGV("stopped"); 2321 2322 return OK; 2323} 2324 2325sp<MetaData> OMXCodec::getFormat() { 2326 Mutex::Autolock autoLock(mLock); 2327 2328 return mOutputFormat; 2329} 2330 2331status_t OMXCodec::read( 2332 MediaBuffer **buffer, const ReadOptions *options) { 2333 *buffer = NULL; 2334 2335 Mutex::Autolock autoLock(mLock); 2336 2337 if (mState != EXECUTING && mState != RECONFIGURING) { 2338 return UNKNOWN_ERROR; 2339 } 2340 2341 bool seeking = false; 2342 int64_t seekTimeUs; 2343 if (options && options->getSeekTo(&seekTimeUs)) { 2344 seeking = true; 2345 } 2346 2347 if (mInitialBufferSubmit) { 2348 mInitialBufferSubmit = false; 2349 2350 if (seeking) { 2351 CHECK(seekTimeUs >= 0); 2352 mSeekTimeUs = seekTimeUs; 2353 2354 // There's no reason to trigger the code below, there's 2355 // nothing to flush yet. 2356 seeking = false; 2357 } 2358 2359 drainInputBuffers(); 2360 2361 if (mState == EXECUTING) { 2362 // Otherwise mState == RECONFIGURING and this code will trigger 2363 // after the output port is reenabled. 2364 fillOutputBuffers(); 2365 } 2366 } 2367 2368 if (seeking) { 2369 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 2370 2371 mSignalledEOS = false; 2372 2373 CHECK(seekTimeUs >= 0); 2374 mSeekTimeUs = seekTimeUs; 2375 2376 mFilledBuffers.clear(); 2377 2378 CHECK_EQ(mState, EXECUTING); 2379 2380 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 2381 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 2382 2383 if (emulateInputFlushCompletion) { 2384 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2385 } 2386 2387 if (emulateOutputFlushCompletion) { 2388 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2389 } 2390 2391 while (mSeekTimeUs >= 0) { 2392 mBufferFilled.wait(mLock); 2393 } 2394 } 2395 2396 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 2397 mBufferFilled.wait(mLock); 2398 } 2399 2400 if (mState == ERROR) { 2401 return UNKNOWN_ERROR; 2402 } 2403 2404 if (mFilledBuffers.empty()) { 2405 return ERROR_END_OF_STREAM; 2406 } 2407 2408 if (mOutputPortSettingsHaveChanged) { 2409 mOutputPortSettingsHaveChanged = false; 2410 2411 return INFO_FORMAT_CHANGED; 2412 } 2413 2414 size_t index = *mFilledBuffers.begin(); 2415 mFilledBuffers.erase(mFilledBuffers.begin()); 2416 2417 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 2418 info->mMediaBuffer->add_ref(); 2419 *buffer = info->mMediaBuffer; 2420 2421 return OK; 2422} 2423 2424void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 2425 Mutex::Autolock autoLock(mLock); 2426 2427 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2428 for (size_t i = 0; i < buffers->size(); ++i) { 2429 BufferInfo *info = &buffers->editItemAt(i); 2430 2431 if (info->mMediaBuffer == buffer) { 2432 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 2433 fillOutputBuffer(info); 2434 return; 2435 } 2436 } 2437 2438 CHECK(!"should not be here."); 2439} 2440 2441static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 2442 static const char *kNames[] = { 2443 "OMX_IMAGE_CodingUnused", 2444 "OMX_IMAGE_CodingAutoDetect", 2445 "OMX_IMAGE_CodingJPEG", 2446 "OMX_IMAGE_CodingJPEG2K", 2447 "OMX_IMAGE_CodingEXIF", 2448 "OMX_IMAGE_CodingTIFF", 2449 "OMX_IMAGE_CodingGIF", 2450 "OMX_IMAGE_CodingPNG", 2451 "OMX_IMAGE_CodingLZW", 2452 "OMX_IMAGE_CodingBMP", 2453 }; 2454 2455 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2456 2457 if (type < 0 || (size_t)type >= numNames) { 2458 return "UNKNOWN"; 2459 } else { 2460 return kNames[type]; 2461 } 2462} 2463 2464static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 2465 static const char *kNames[] = { 2466 "OMX_COLOR_FormatUnused", 2467 "OMX_COLOR_FormatMonochrome", 2468 "OMX_COLOR_Format8bitRGB332", 2469 "OMX_COLOR_Format12bitRGB444", 2470 "OMX_COLOR_Format16bitARGB4444", 2471 "OMX_COLOR_Format16bitARGB1555", 2472 "OMX_COLOR_Format16bitRGB565", 2473 "OMX_COLOR_Format16bitBGR565", 2474 "OMX_COLOR_Format18bitRGB666", 2475 "OMX_COLOR_Format18bitARGB1665", 2476 "OMX_COLOR_Format19bitARGB1666", 2477 "OMX_COLOR_Format24bitRGB888", 2478 "OMX_COLOR_Format24bitBGR888", 2479 "OMX_COLOR_Format24bitARGB1887", 2480 "OMX_COLOR_Format25bitARGB1888", 2481 "OMX_COLOR_Format32bitBGRA8888", 2482 "OMX_COLOR_Format32bitARGB8888", 2483 "OMX_COLOR_FormatYUV411Planar", 2484 "OMX_COLOR_FormatYUV411PackedPlanar", 2485 "OMX_COLOR_FormatYUV420Planar", 2486 "OMX_COLOR_FormatYUV420PackedPlanar", 2487 "OMX_COLOR_FormatYUV420SemiPlanar", 2488 "OMX_COLOR_FormatYUV422Planar", 2489 "OMX_COLOR_FormatYUV422PackedPlanar", 2490 "OMX_COLOR_FormatYUV422SemiPlanar", 2491 "OMX_COLOR_FormatYCbYCr", 2492 "OMX_COLOR_FormatYCrYCb", 2493 "OMX_COLOR_FormatCbYCrY", 2494 "OMX_COLOR_FormatCrYCbY", 2495 "OMX_COLOR_FormatYUV444Interleaved", 2496 "OMX_COLOR_FormatRawBayer8bit", 2497 "OMX_COLOR_FormatRawBayer10bit", 2498 "OMX_COLOR_FormatRawBayer8bitcompressed", 2499 "OMX_COLOR_FormatL2", 2500 "OMX_COLOR_FormatL4", 2501 "OMX_COLOR_FormatL8", 2502 "OMX_COLOR_FormatL16", 2503 "OMX_COLOR_FormatL24", 2504 "OMX_COLOR_FormatL32", 2505 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 2506 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 2507 "OMX_COLOR_Format18BitBGR666", 2508 "OMX_COLOR_Format24BitARGB6666", 2509 "OMX_COLOR_Format24BitABGR6666", 2510 }; 2511 2512 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2513 2514 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 2515 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 2516 } else if (type < 0 || (size_t)type >= numNames) { 2517 return "UNKNOWN"; 2518 } else { 2519 return kNames[type]; 2520 } 2521} 2522 2523static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 2524 static const char *kNames[] = { 2525 "OMX_VIDEO_CodingUnused", 2526 "OMX_VIDEO_CodingAutoDetect", 2527 "OMX_VIDEO_CodingMPEG2", 2528 "OMX_VIDEO_CodingH263", 2529 "OMX_VIDEO_CodingMPEG4", 2530 "OMX_VIDEO_CodingWMV", 2531 "OMX_VIDEO_CodingRV", 2532 "OMX_VIDEO_CodingAVC", 2533 "OMX_VIDEO_CodingMJPEG", 2534 }; 2535 2536 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2537 2538 if (type < 0 || (size_t)type >= numNames) { 2539 return "UNKNOWN"; 2540 } else { 2541 return kNames[type]; 2542 } 2543} 2544 2545static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 2546 static const char *kNames[] = { 2547 "OMX_AUDIO_CodingUnused", 2548 "OMX_AUDIO_CodingAutoDetect", 2549 "OMX_AUDIO_CodingPCM", 2550 "OMX_AUDIO_CodingADPCM", 2551 "OMX_AUDIO_CodingAMR", 2552 "OMX_AUDIO_CodingGSMFR", 2553 "OMX_AUDIO_CodingGSMEFR", 2554 "OMX_AUDIO_CodingGSMHR", 2555 "OMX_AUDIO_CodingPDCFR", 2556 "OMX_AUDIO_CodingPDCEFR", 2557 "OMX_AUDIO_CodingPDCHR", 2558 "OMX_AUDIO_CodingTDMAFR", 2559 "OMX_AUDIO_CodingTDMAEFR", 2560 "OMX_AUDIO_CodingQCELP8", 2561 "OMX_AUDIO_CodingQCELP13", 2562 "OMX_AUDIO_CodingEVRC", 2563 "OMX_AUDIO_CodingSMV", 2564 "OMX_AUDIO_CodingG711", 2565 "OMX_AUDIO_CodingG723", 2566 "OMX_AUDIO_CodingG726", 2567 "OMX_AUDIO_CodingG729", 2568 "OMX_AUDIO_CodingAAC", 2569 "OMX_AUDIO_CodingMP3", 2570 "OMX_AUDIO_CodingSBC", 2571 "OMX_AUDIO_CodingVORBIS", 2572 "OMX_AUDIO_CodingWMA", 2573 "OMX_AUDIO_CodingRA", 2574 "OMX_AUDIO_CodingMIDI", 2575 }; 2576 2577 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2578 2579 if (type < 0 || (size_t)type >= numNames) { 2580 return "UNKNOWN"; 2581 } else { 2582 return kNames[type]; 2583 } 2584} 2585 2586static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 2587 static const char *kNames[] = { 2588 "OMX_AUDIO_PCMModeLinear", 2589 "OMX_AUDIO_PCMModeALaw", 2590 "OMX_AUDIO_PCMModeMULaw", 2591 }; 2592 2593 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2594 2595 if (type < 0 || (size_t)type >= numNames) { 2596 return "UNKNOWN"; 2597 } else { 2598 return kNames[type]; 2599 } 2600} 2601 2602static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 2603 static const char *kNames[] = { 2604 "OMX_AUDIO_AMRBandModeUnused", 2605 "OMX_AUDIO_AMRBandModeNB0", 2606 "OMX_AUDIO_AMRBandModeNB1", 2607 "OMX_AUDIO_AMRBandModeNB2", 2608 "OMX_AUDIO_AMRBandModeNB3", 2609 "OMX_AUDIO_AMRBandModeNB4", 2610 "OMX_AUDIO_AMRBandModeNB5", 2611 "OMX_AUDIO_AMRBandModeNB6", 2612 "OMX_AUDIO_AMRBandModeNB7", 2613 "OMX_AUDIO_AMRBandModeWB0", 2614 "OMX_AUDIO_AMRBandModeWB1", 2615 "OMX_AUDIO_AMRBandModeWB2", 2616 "OMX_AUDIO_AMRBandModeWB3", 2617 "OMX_AUDIO_AMRBandModeWB4", 2618 "OMX_AUDIO_AMRBandModeWB5", 2619 "OMX_AUDIO_AMRBandModeWB6", 2620 "OMX_AUDIO_AMRBandModeWB7", 2621 "OMX_AUDIO_AMRBandModeWB8", 2622 }; 2623 2624 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2625 2626 if (type < 0 || (size_t)type >= numNames) { 2627 return "UNKNOWN"; 2628 } else { 2629 return kNames[type]; 2630 } 2631} 2632 2633static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 2634 static const char *kNames[] = { 2635 "OMX_AUDIO_AMRFrameFormatConformance", 2636 "OMX_AUDIO_AMRFrameFormatIF1", 2637 "OMX_AUDIO_AMRFrameFormatIF2", 2638 "OMX_AUDIO_AMRFrameFormatFSF", 2639 "OMX_AUDIO_AMRFrameFormatRTPPayload", 2640 "OMX_AUDIO_AMRFrameFormatITU", 2641 }; 2642 2643 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2644 2645 if (type < 0 || (size_t)type >= numNames) { 2646 return "UNKNOWN"; 2647 } else { 2648 return kNames[type]; 2649 } 2650} 2651 2652void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 2653 OMX_PARAM_PORTDEFINITIONTYPE def; 2654 InitOMXParams(&def); 2655 def.nPortIndex = portIndex; 2656 2657 status_t err = mOMX->getParameter( 2658 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2659 CHECK_EQ(err, OK); 2660 2661 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 2662 2663 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 2664 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 2665 2666 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 2667 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 2668 printf(" nBufferSize = %ld\n", def.nBufferSize); 2669 2670 switch (def.eDomain) { 2671 case OMX_PortDomainImage: 2672 { 2673 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2674 2675 printf("\n"); 2676 printf(" // Image\n"); 2677 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 2678 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 2679 printf(" nStride = %ld\n", imageDef->nStride); 2680 2681 printf(" eCompressionFormat = %s\n", 2682 imageCompressionFormatString(imageDef->eCompressionFormat)); 2683 2684 printf(" eColorFormat = %s\n", 2685 colorFormatString(imageDef->eColorFormat)); 2686 2687 break; 2688 } 2689 2690 case OMX_PortDomainVideo: 2691 { 2692 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2693 2694 printf("\n"); 2695 printf(" // Video\n"); 2696 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 2697 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 2698 printf(" nStride = %ld\n", videoDef->nStride); 2699 2700 printf(" eCompressionFormat = %s\n", 2701 videoCompressionFormatString(videoDef->eCompressionFormat)); 2702 2703 printf(" eColorFormat = %s\n", 2704 colorFormatString(videoDef->eColorFormat)); 2705 2706 break; 2707 } 2708 2709 case OMX_PortDomainAudio: 2710 { 2711 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2712 2713 printf("\n"); 2714 printf(" // Audio\n"); 2715 printf(" eEncoding = %s\n", 2716 audioCodingTypeString(audioDef->eEncoding)); 2717 2718 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2719 OMX_AUDIO_PARAM_PCMMODETYPE params; 2720 InitOMXParams(¶ms); 2721 params.nPortIndex = portIndex; 2722 2723 err = mOMX->getParameter( 2724 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2725 CHECK_EQ(err, OK); 2726 2727 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2728 printf(" nChannels = %ld\n", params.nChannels); 2729 printf(" bInterleaved = %d\n", params.bInterleaved); 2730 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2731 2732 printf(" eNumData = %s\n", 2733 params.eNumData == OMX_NumericalDataSigned 2734 ? "signed" : "unsigned"); 2735 2736 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2737 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 2738 OMX_AUDIO_PARAM_AMRTYPE amr; 2739 InitOMXParams(&amr); 2740 amr.nPortIndex = portIndex; 2741 2742 err = mOMX->getParameter( 2743 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2744 CHECK_EQ(err, OK); 2745 2746 printf(" nChannels = %ld\n", amr.nChannels); 2747 printf(" eAMRBandMode = %s\n", 2748 amrBandModeString(amr.eAMRBandMode)); 2749 printf(" eAMRFrameFormat = %s\n", 2750 amrFrameFormatString(amr.eAMRFrameFormat)); 2751 } 2752 2753 break; 2754 } 2755 2756 default: 2757 { 2758 printf(" // Unknown\n"); 2759 break; 2760 } 2761 } 2762 2763 printf("}\n"); 2764} 2765 2766void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2767 mOutputFormat = new MetaData; 2768 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2769 2770 OMX_PARAM_PORTDEFINITIONTYPE def; 2771 InitOMXParams(&def); 2772 def.nPortIndex = kPortIndexOutput; 2773 2774 status_t err = mOMX->getParameter( 2775 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2776 CHECK_EQ(err, OK); 2777 2778 switch (def.eDomain) { 2779 case OMX_PortDomainImage: 2780 { 2781 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2782 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2783 2784 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2785 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2786 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2787 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2788 break; 2789 } 2790 2791 case OMX_PortDomainAudio: 2792 { 2793 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2794 2795 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 2796 OMX_AUDIO_PARAM_PCMMODETYPE params; 2797 InitOMXParams(¶ms); 2798 params.nPortIndex = kPortIndexOutput; 2799 2800 err = mOMX->getParameter( 2801 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2802 CHECK_EQ(err, OK); 2803 2804 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2805 CHECK_EQ(params.nBitPerSample, 16); 2806 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2807 2808 int32_t numChannels, sampleRate; 2809 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2810 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2811 2812 if ((OMX_U32)numChannels != params.nChannels) { 2813 LOGW("Codec outputs a different number of channels than " 2814 "the input stream contains (contains %d channels, " 2815 "codec outputs %ld channels).", 2816 numChannels, params.nChannels); 2817 } 2818 2819 mOutputFormat->setCString( 2820 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2821 2822 // Use the codec-advertised number of channels, as some 2823 // codecs appear to output stereo even if the input data is 2824 // mono. If we know the codec lies about this information, 2825 // use the actual number of channels instead. 2826 mOutputFormat->setInt32( 2827 kKeyChannelCount, 2828 (mQuirks & kDecoderLiesAboutNumberOfChannels) 2829 ? numChannels : params.nChannels); 2830 2831 // The codec-reported sampleRate is not reliable... 2832 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2833 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 2834 OMX_AUDIO_PARAM_AMRTYPE amr; 2835 InitOMXParams(&amr); 2836 amr.nPortIndex = kPortIndexOutput; 2837 2838 err = mOMX->getParameter( 2839 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2840 CHECK_EQ(err, OK); 2841 2842 CHECK_EQ(amr.nChannels, 1); 2843 mOutputFormat->setInt32(kKeyChannelCount, 1); 2844 2845 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 2846 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 2847 mOutputFormat->setCString( 2848 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 2849 mOutputFormat->setInt32(kKeySampleRate, 8000); 2850 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 2851 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 2852 mOutputFormat->setCString( 2853 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 2854 mOutputFormat->setInt32(kKeySampleRate, 16000); 2855 } else { 2856 CHECK(!"Unknown AMR band mode."); 2857 } 2858 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 2859 mOutputFormat->setCString( 2860 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 2861 } else { 2862 CHECK(!"Should not be here. Unknown audio encoding."); 2863 } 2864 break; 2865 } 2866 2867 case OMX_PortDomainVideo: 2868 { 2869 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2870 2871 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2872 mOutputFormat->setCString( 2873 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2874 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2875 mOutputFormat->setCString( 2876 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 2877 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2878 mOutputFormat->setCString( 2879 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 2880 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2881 mOutputFormat->setCString( 2882 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 2883 } else { 2884 CHECK(!"Unknown compression format."); 2885 } 2886 2887 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2888 // This component appears to be lying to me. 2889 mOutputFormat->setInt32( 2890 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2891 mOutputFormat->setInt32( 2892 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2893 } else { 2894 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2895 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2896 } 2897 2898 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2899 break; 2900 } 2901 2902 default: 2903 { 2904 CHECK(!"should not be here, neither audio nor video."); 2905 break; 2906 } 2907 } 2908} 2909 2910//////////////////////////////////////////////////////////////////////////////// 2911 2912status_t QueryCodecs( 2913 const sp<IOMX> &omx, 2914 const char *mime, bool queryDecoders, 2915 Vector<CodecCapabilities> *results) { 2916 results->clear(); 2917 2918 for (int index = 0;; ++index) { 2919 const char *componentName; 2920 2921 if (!queryDecoders) { 2922 componentName = GetCodec( 2923 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 2924 mime, index); 2925 } else { 2926 componentName = GetCodec( 2927 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 2928 mime, index); 2929 } 2930 2931 if (!componentName) { 2932 return OK; 2933 } 2934 2935 sp<OMXCodecObserver> observer = new OMXCodecObserver; 2936 IOMX::node_id node; 2937 status_t err = omx->allocateNode(componentName, observer, &node); 2938 2939 if (err != OK) { 2940 continue; 2941 } 2942 2943 OMXCodec::setComponentRole(omx, node, queryDecoders, mime); 2944 2945 results->push(); 2946 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 2947 caps->mComponentName = componentName; 2948 2949 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 2950 InitOMXParams(¶m); 2951 2952 param.nPortIndex = queryDecoders ? 0 : 1; 2953 2954 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 2955 err = omx->getParameter( 2956 node, OMX_IndexParamVideoProfileLevelQuerySupported, 2957 ¶m, sizeof(param)); 2958 2959 if (err != OK) { 2960 break; 2961 } 2962 2963 CodecProfileLevel profileLevel; 2964 profileLevel.mProfile = param.eProfile; 2965 profileLevel.mLevel = param.eLevel; 2966 2967 caps->mProfileLevels.push(profileLevel); 2968 } 2969 2970 CHECK_EQ(omx->freeNode(node), OK); 2971 } 2972} 2973 2974} // namespace android 2975