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