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