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