OMXCodec.cpp revision d35bd5fb4e09c2cd8608497c279cbb2ef9c3a029
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 mPaused(false) { 1150 mPortStatus[kPortIndexInput] = ENABLED; 1151 mPortStatus[kPortIndexOutput] = ENABLED; 1152 1153 setComponentRole(); 1154} 1155 1156// static 1157void OMXCodec::setComponentRole( 1158 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, 1159 const char *mime) { 1160 struct MimeToRole { 1161 const char *mime; 1162 const char *decoderRole; 1163 const char *encoderRole; 1164 }; 1165 1166 static const MimeToRole kMimeToRole[] = { 1167 { MEDIA_MIMETYPE_AUDIO_MPEG, 1168 "audio_decoder.mp3", "audio_encoder.mp3" }, 1169 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1170 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1171 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1172 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1173 { MEDIA_MIMETYPE_AUDIO_AAC, 1174 "audio_decoder.aac", "audio_encoder.aac" }, 1175 { MEDIA_MIMETYPE_VIDEO_AVC, 1176 "video_decoder.avc", "video_encoder.avc" }, 1177 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1178 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1179 { MEDIA_MIMETYPE_VIDEO_H263, 1180 "video_decoder.h263", "video_encoder.h263" }, 1181 }; 1182 1183 static const size_t kNumMimeToRole = 1184 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1185 1186 size_t i; 1187 for (i = 0; i < kNumMimeToRole; ++i) { 1188 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1189 break; 1190 } 1191 } 1192 1193 if (i == kNumMimeToRole) { 1194 return; 1195 } 1196 1197 const char *role = 1198 isEncoder ? kMimeToRole[i].encoderRole 1199 : kMimeToRole[i].decoderRole; 1200 1201 if (role != NULL) { 1202 OMX_PARAM_COMPONENTROLETYPE roleParams; 1203 InitOMXParams(&roleParams); 1204 1205 strncpy((char *)roleParams.cRole, 1206 role, OMX_MAX_STRINGNAME_SIZE - 1); 1207 1208 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1209 1210 status_t err = omx->setParameter( 1211 node, OMX_IndexParamStandardComponentRole, 1212 &roleParams, sizeof(roleParams)); 1213 1214 if (err != OK) { 1215 LOGW("Failed to set standard component role '%s'.", role); 1216 } 1217 } 1218} 1219 1220void OMXCodec::setComponentRole() { 1221 setComponentRole(mOMX, mNode, mIsEncoder, mMIME); 1222} 1223 1224OMXCodec::~OMXCodec() { 1225 CHECK(mState == LOADED || mState == ERROR); 1226 1227 status_t err = mOMX->freeNode(mNode); 1228 CHECK_EQ(err, OK); 1229 1230 mNode = NULL; 1231 setState(DEAD); 1232 1233 clearCodecSpecificData(); 1234 1235 free(mComponentName); 1236 mComponentName = NULL; 1237 1238 free(mMIME); 1239 mMIME = NULL; 1240} 1241 1242status_t OMXCodec::init() { 1243 // mLock is held. 1244 1245 CHECK_EQ(mState, LOADED); 1246 1247 status_t err; 1248 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 1249 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1250 CHECK_EQ(err, OK); 1251 setState(LOADED_TO_IDLE); 1252 } 1253 1254 err = allocateBuffers(); 1255 CHECK_EQ(err, OK); 1256 1257 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 1258 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1259 CHECK_EQ(err, OK); 1260 1261 setState(LOADED_TO_IDLE); 1262 } 1263 1264 while (mState != EXECUTING && mState != ERROR) { 1265 mAsyncCompletion.wait(mLock); 1266 } 1267 1268 return mState == ERROR ? UNKNOWN_ERROR : OK; 1269} 1270 1271// static 1272bool OMXCodec::isIntermediateState(State state) { 1273 return state == LOADED_TO_IDLE 1274 || state == IDLE_TO_EXECUTING 1275 || state == EXECUTING_TO_IDLE 1276 || state == IDLE_TO_LOADED 1277 || state == RECONFIGURING; 1278} 1279 1280status_t OMXCodec::allocateBuffers() { 1281 status_t err = allocateBuffersOnPort(kPortIndexInput); 1282 1283 if (err != OK) { 1284 return err; 1285 } 1286 1287 return allocateBuffersOnPort(kPortIndexOutput); 1288} 1289 1290status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 1291 OMX_PARAM_PORTDEFINITIONTYPE def; 1292 InitOMXParams(&def); 1293 def.nPortIndex = portIndex; 1294 1295 status_t err = mOMX->getParameter( 1296 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1297 1298 if (err != OK) { 1299 return err; 1300 } 1301 1302 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 1303 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 1304 1305 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 1306 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 1307 CHECK(mem.get() != NULL); 1308 1309 BufferInfo info; 1310 info.mData = NULL; 1311 info.mSize = def.nBufferSize; 1312 1313 IOMX::buffer_id buffer; 1314 if (portIndex == kPortIndexInput 1315 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) { 1316 if (mOMXLivesLocally) { 1317 mem.clear(); 1318 1319 err = mOMX->allocateBuffer( 1320 mNode, portIndex, def.nBufferSize, &buffer, 1321 &info.mData); 1322 } else { 1323 err = mOMX->allocateBufferWithBackup( 1324 mNode, portIndex, mem, &buffer); 1325 } 1326 } else if (portIndex == kPortIndexOutput 1327 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 1328 if (mOMXLivesLocally) { 1329 mem.clear(); 1330 1331 err = mOMX->allocateBuffer( 1332 mNode, portIndex, def.nBufferSize, &buffer, 1333 &info.mData); 1334 } else { 1335 err = mOMX->allocateBufferWithBackup( 1336 mNode, portIndex, mem, &buffer); 1337 } 1338 } else { 1339 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 1340 } 1341 1342 if (err != OK) { 1343 LOGE("allocate_buffer_with_backup failed"); 1344 return err; 1345 } 1346 1347 if (mem != NULL) { 1348 info.mData = mem->pointer(); 1349 } 1350 1351 info.mBuffer = buffer; 1352 info.mOwnedByComponent = false; 1353 info.mMem = mem; 1354 info.mMediaBuffer = NULL; 1355 1356 if (portIndex == kPortIndexOutput) { 1357 if (!(mOMXLivesLocally 1358 && (mQuirks & kRequiresAllocateBufferOnOutputPorts) 1359 && (mQuirks & kDefersOutputBufferAllocation))) { 1360 // If the node does not fill in the buffer ptr at this time, 1361 // we will defer creating the MediaBuffer until receiving 1362 // the first FILL_BUFFER_DONE notification instead. 1363 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); 1364 info.mMediaBuffer->setObserver(this); 1365 } 1366 } 1367 1368 mPortBuffers[portIndex].push(info); 1369 1370 CODEC_LOGV("allocated buffer %p on %s port", buffer, 1371 portIndex == kPortIndexInput ? "input" : "output"); 1372 } 1373 1374 // dumpPortStatus(portIndex); 1375 1376 return OK; 1377} 1378 1379void OMXCodec::on_message(const omx_message &msg) { 1380 Mutex::Autolock autoLock(mLock); 1381 1382 switch (msg.type) { 1383 case omx_message::EVENT: 1384 { 1385 onEvent( 1386 msg.u.event_data.event, msg.u.event_data.data1, 1387 msg.u.event_data.data2); 1388 1389 break; 1390 } 1391 1392 case omx_message::EMPTY_BUFFER_DONE: 1393 { 1394 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 1395 1396 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 1397 1398 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1399 size_t i = 0; 1400 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 1401 ++i; 1402 } 1403 1404 CHECK(i < buffers->size()); 1405 if (!(*buffers)[i].mOwnedByComponent) { 1406 LOGW("We already own input buffer %p, yet received " 1407 "an EMPTY_BUFFER_DONE.", buffer); 1408 } 1409 1410 buffers->editItemAt(i).mOwnedByComponent = false; 1411 1412 if (mPortStatus[kPortIndexInput] == DISABLING) { 1413 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 1414 1415 status_t err = 1416 mOMX->freeBuffer(mNode, kPortIndexInput, buffer); 1417 CHECK_EQ(err, OK); 1418 1419 buffers->removeAt(i); 1420 } else if (mState != ERROR 1421 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 1422 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED); 1423 drainInputBuffer(&buffers->editItemAt(i)); 1424 } 1425 break; 1426 } 1427 1428 case omx_message::FILL_BUFFER_DONE: 1429 { 1430 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 1431 OMX_U32 flags = msg.u.extended_buffer_data.flags; 1432 1433 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 1434 buffer, 1435 msg.u.extended_buffer_data.range_length, 1436 flags, 1437 msg.u.extended_buffer_data.timestamp, 1438 msg.u.extended_buffer_data.timestamp / 1E6); 1439 1440 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1441 size_t i = 0; 1442 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 1443 ++i; 1444 } 1445 1446 CHECK(i < buffers->size()); 1447 BufferInfo *info = &buffers->editItemAt(i); 1448 1449 if (!info->mOwnedByComponent) { 1450 LOGW("We already own output buffer %p, yet received " 1451 "a FILL_BUFFER_DONE.", buffer); 1452 } 1453 1454 info->mOwnedByComponent = false; 1455 1456 if (mPortStatus[kPortIndexOutput] == DISABLING) { 1457 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 1458 1459 status_t err = 1460 mOMX->freeBuffer(mNode, kPortIndexOutput, buffer); 1461 CHECK_EQ(err, OK); 1462 1463 buffers->removeAt(i); 1464#if 0 1465 } else if (mPortStatus[kPortIndexOutput] == ENABLED 1466 && (flags & OMX_BUFFERFLAG_EOS)) { 1467 CODEC_LOGV("No more output data."); 1468 mNoMoreOutputData = true; 1469 mBufferFilled.signal(); 1470#endif 1471 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 1472 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1473 1474 if (info->mMediaBuffer == NULL) { 1475 CHECK(mOMXLivesLocally); 1476 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 1477 CHECK(mQuirks & kDefersOutputBufferAllocation); 1478 1479 // The qcom video decoders on Nexus don't actually allocate 1480 // output buffer memory on a call to OMX_AllocateBuffer 1481 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 1482 // structure is only filled in later. 1483 1484 info->mMediaBuffer = new MediaBuffer( 1485 msg.u.extended_buffer_data.data_ptr, 1486 info->mSize); 1487 info->mMediaBuffer->setObserver(this); 1488 } 1489 1490 MediaBuffer *buffer = info->mMediaBuffer; 1491 1492 buffer->set_range( 1493 msg.u.extended_buffer_data.range_offset, 1494 msg.u.extended_buffer_data.range_length); 1495 1496 buffer->meta_data()->clear(); 1497 1498 buffer->meta_data()->setInt64( 1499 kKeyTime, msg.u.extended_buffer_data.timestamp); 1500 1501 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 1502 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 1503 } 1504 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 1505 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 1506 } 1507 1508 buffer->meta_data()->setPointer( 1509 kKeyPlatformPrivate, 1510 msg.u.extended_buffer_data.platform_private); 1511 1512 buffer->meta_data()->setPointer( 1513 kKeyBufferID, 1514 msg.u.extended_buffer_data.buffer); 1515 1516 mFilledBuffers.push_back(i); 1517 mBufferFilled.signal(); 1518 1519 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 1520 CODEC_LOGV("No more output data."); 1521 mNoMoreOutputData = true; 1522 } 1523 } 1524 1525 break; 1526 } 1527 1528 default: 1529 { 1530 CHECK(!"should not be here."); 1531 break; 1532 } 1533 } 1534} 1535 1536void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1537 switch (event) { 1538 case OMX_EventCmdComplete: 1539 { 1540 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 1541 break; 1542 } 1543 1544 case OMX_EventError: 1545 { 1546 LOGE("ERROR(0x%08lx, %ld)", data1, data2); 1547 1548 setState(ERROR); 1549 break; 1550 } 1551 1552 case OMX_EventPortSettingsChanged: 1553 { 1554 onPortSettingsChanged(data1); 1555 break; 1556 } 1557 1558#if 0 1559 case OMX_EventBufferFlag: 1560 { 1561 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 1562 1563 if (data1 == kPortIndexOutput) { 1564 mNoMoreOutputData = true; 1565 } 1566 break; 1567 } 1568#endif 1569 1570 default: 1571 { 1572 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 1573 break; 1574 } 1575 } 1576} 1577 1578// Has the format changed in any way that the client would have to be aware of? 1579static bool formatHasNotablyChanged( 1580 const sp<MetaData> &from, const sp<MetaData> &to) { 1581 if (from.get() == NULL && to.get() == NULL) { 1582 return false; 1583 } 1584 1585 if ((from.get() == NULL && to.get() != NULL) 1586 || (from.get() != NULL && to.get() == NULL)) { 1587 return true; 1588 } 1589 1590 const char *mime_from, *mime_to; 1591 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 1592 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 1593 1594 if (strcasecmp(mime_from, mime_to)) { 1595 return true; 1596 } 1597 1598 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 1599 int32_t colorFormat_from, colorFormat_to; 1600 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 1601 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 1602 1603 if (colorFormat_from != colorFormat_to) { 1604 return true; 1605 } 1606 1607 int32_t width_from, width_to; 1608 CHECK(from->findInt32(kKeyWidth, &width_from)); 1609 CHECK(to->findInt32(kKeyWidth, &width_to)); 1610 1611 if (width_from != width_to) { 1612 return true; 1613 } 1614 1615 int32_t height_from, height_to; 1616 CHECK(from->findInt32(kKeyHeight, &height_from)); 1617 CHECK(to->findInt32(kKeyHeight, &height_to)); 1618 1619 if (height_from != height_to) { 1620 return true; 1621 } 1622 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 1623 int32_t numChannels_from, numChannels_to; 1624 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 1625 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 1626 1627 if (numChannels_from != numChannels_to) { 1628 return true; 1629 } 1630 1631 int32_t sampleRate_from, sampleRate_to; 1632 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 1633 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 1634 1635 if (sampleRate_from != sampleRate_to) { 1636 return true; 1637 } 1638 } 1639 1640 return false; 1641} 1642 1643void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 1644 switch (cmd) { 1645 case OMX_CommandStateSet: 1646 { 1647 onStateChange((OMX_STATETYPE)data); 1648 break; 1649 } 1650 1651 case OMX_CommandPortDisable: 1652 { 1653 OMX_U32 portIndex = data; 1654 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 1655 1656 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1657 CHECK_EQ(mPortStatus[portIndex], DISABLING); 1658 CHECK_EQ(mPortBuffers[portIndex].size(), 0); 1659 1660 mPortStatus[portIndex] = DISABLED; 1661 1662 if (mState == RECONFIGURING) { 1663 CHECK_EQ(portIndex, kPortIndexOutput); 1664 1665 sp<MetaData> oldOutputFormat = mOutputFormat; 1666 initOutputFormat(mSource->getFormat()); 1667 1668 // Don't notify clients if the output port settings change 1669 // wasn't of importance to them, i.e. it may be that just the 1670 // number of buffers has changed and nothing else. 1671 mOutputPortSettingsHaveChanged = 1672 formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 1673 1674 enablePortAsync(portIndex); 1675 1676 status_t err = allocateBuffersOnPort(portIndex); 1677 CHECK_EQ(err, OK); 1678 } 1679 break; 1680 } 1681 1682 case OMX_CommandPortEnable: 1683 { 1684 OMX_U32 portIndex = data; 1685 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 1686 1687 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1688 CHECK_EQ(mPortStatus[portIndex], ENABLING); 1689 1690 mPortStatus[portIndex] = ENABLED; 1691 1692 if (mState == RECONFIGURING) { 1693 CHECK_EQ(portIndex, kPortIndexOutput); 1694 1695 setState(EXECUTING); 1696 1697 fillOutputBuffers(); 1698 } 1699 break; 1700 } 1701 1702 case OMX_CommandFlush: 1703 { 1704 OMX_U32 portIndex = data; 1705 1706 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 1707 1708 CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); 1709 mPortStatus[portIndex] = ENABLED; 1710 1711 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 1712 mPortBuffers[portIndex].size()); 1713 1714 if (mState == RECONFIGURING) { 1715 CHECK_EQ(portIndex, kPortIndexOutput); 1716 1717 disablePortAsync(portIndex); 1718 } else if (mState == EXECUTING_TO_IDLE) { 1719 if (mPortStatus[kPortIndexInput] == ENABLED 1720 && mPortStatus[kPortIndexOutput] == ENABLED) { 1721 CODEC_LOGV("Finished flushing both ports, now completing " 1722 "transition from EXECUTING to IDLE."); 1723 1724 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1725 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1726 1727 status_t err = 1728 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1729 CHECK_EQ(err, OK); 1730 } 1731 } else { 1732 // We're flushing both ports in preparation for seeking. 1733 1734 if (mPortStatus[kPortIndexInput] == ENABLED 1735 && mPortStatus[kPortIndexOutput] == ENABLED) { 1736 CODEC_LOGV("Finished flushing both ports, now continuing from" 1737 " seek-time."); 1738 1739 // We implicitly resume pulling on our upstream source. 1740 mPaused = false; 1741 1742 drainInputBuffers(); 1743 fillOutputBuffers(); 1744 } 1745 } 1746 1747 break; 1748 } 1749 1750 default: 1751 { 1752 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1753 break; 1754 } 1755 } 1756} 1757 1758void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1759 CODEC_LOGV("onStateChange %d", newState); 1760 1761 switch (newState) { 1762 case OMX_StateIdle: 1763 { 1764 CODEC_LOGV("Now Idle."); 1765 if (mState == LOADED_TO_IDLE) { 1766 status_t err = mOMX->sendCommand( 1767 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1768 1769 CHECK_EQ(err, OK); 1770 1771 setState(IDLE_TO_EXECUTING); 1772 } else { 1773 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1774 1775 CHECK_EQ( 1776 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1777 mPortBuffers[kPortIndexInput].size()); 1778 1779 CHECK_EQ( 1780 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1781 mPortBuffers[kPortIndexOutput].size()); 1782 1783 status_t err = mOMX->sendCommand( 1784 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1785 1786 CHECK_EQ(err, OK); 1787 1788 err = freeBuffersOnPort(kPortIndexInput); 1789 CHECK_EQ(err, OK); 1790 1791 err = freeBuffersOnPort(kPortIndexOutput); 1792 CHECK_EQ(err, OK); 1793 1794 mPortStatus[kPortIndexInput] = ENABLED; 1795 mPortStatus[kPortIndexOutput] = ENABLED; 1796 1797 setState(IDLE_TO_LOADED); 1798 } 1799 break; 1800 } 1801 1802 case OMX_StateExecuting: 1803 { 1804 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1805 1806 CODEC_LOGV("Now Executing."); 1807 1808 setState(EXECUTING); 1809 1810 // Buffers will be submitted to the component in the first 1811 // call to OMXCodec::read as mInitialBufferSubmit is true at 1812 // this point. This ensures that this on_message call returns, 1813 // releases the lock and ::init can notice the state change and 1814 // itself return. 1815 break; 1816 } 1817 1818 case OMX_StateLoaded: 1819 { 1820 CHECK_EQ(mState, IDLE_TO_LOADED); 1821 1822 CODEC_LOGV("Now Loaded."); 1823 1824 setState(LOADED); 1825 break; 1826 } 1827 1828 case OMX_StateInvalid: 1829 { 1830 setState(ERROR); 1831 break; 1832 } 1833 1834 default: 1835 { 1836 CHECK(!"should not be here."); 1837 break; 1838 } 1839 } 1840} 1841 1842// static 1843size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1844 size_t n = 0; 1845 for (size_t i = 0; i < buffers.size(); ++i) { 1846 if (!buffers[i].mOwnedByComponent) { 1847 ++n; 1848 } 1849 } 1850 1851 return n; 1852} 1853 1854status_t OMXCodec::freeBuffersOnPort( 1855 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1856 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1857 1858 status_t stickyErr = OK; 1859 1860 for (size_t i = buffers->size(); i-- > 0;) { 1861 BufferInfo *info = &buffers->editItemAt(i); 1862 1863 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1864 continue; 1865 } 1866 1867 CHECK_EQ(info->mOwnedByComponent, false); 1868 1869 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 1870 1871 status_t err = 1872 mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 1873 1874 if (err != OK) { 1875 stickyErr = err; 1876 } 1877 1878 if (info->mMediaBuffer != NULL) { 1879 info->mMediaBuffer->setObserver(NULL); 1880 1881 // Make sure nobody but us owns this buffer at this point. 1882 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1883 1884 info->mMediaBuffer->release(); 1885 } 1886 1887 buffers->removeAt(i); 1888 } 1889 1890 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1891 1892 return stickyErr; 1893} 1894 1895void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1896 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1897 1898 CHECK_EQ(mState, EXECUTING); 1899 CHECK_EQ(portIndex, kPortIndexOutput); 1900 setState(RECONFIGURING); 1901 1902 if (mQuirks & kNeedsFlushBeforeDisable) { 1903 if (!flushPortAsync(portIndex)) { 1904 onCmdComplete(OMX_CommandFlush, portIndex); 1905 } 1906 } else { 1907 disablePortAsync(portIndex); 1908 } 1909} 1910 1911bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1912 CHECK(mState == EXECUTING || mState == RECONFIGURING 1913 || mState == EXECUTING_TO_IDLE); 1914 1915 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1916 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1917 mPortBuffers[portIndex].size()); 1918 1919 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1920 mPortStatus[portIndex] = SHUTTING_DOWN; 1921 1922 if ((mQuirks & kRequiresFlushCompleteEmulation) 1923 && countBuffersWeOwn(mPortBuffers[portIndex]) 1924 == mPortBuffers[portIndex].size()) { 1925 // No flush is necessary and this component fails to send a 1926 // flush-complete event in this case. 1927 1928 return false; 1929 } 1930 1931 status_t err = 1932 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 1933 CHECK_EQ(err, OK); 1934 1935 return true; 1936} 1937 1938void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1939 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1940 1941 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1942 mPortStatus[portIndex] = DISABLING; 1943 1944 status_t err = 1945 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 1946 CHECK_EQ(err, OK); 1947 1948 freeBuffersOnPort(portIndex, true); 1949} 1950 1951void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1952 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1953 1954 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1955 mPortStatus[portIndex] = ENABLING; 1956 1957 status_t err = 1958 mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 1959 CHECK_EQ(err, OK); 1960} 1961 1962void OMXCodec::fillOutputBuffers() { 1963 CHECK_EQ(mState, EXECUTING); 1964 1965 // This is a workaround for some decoders not properly reporting 1966 // end-of-output-stream. If we own all input buffers and also own 1967 // all output buffers and we already signalled end-of-input-stream, 1968 // the end-of-output-stream is implied. 1969 if (mSignalledEOS 1970 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 1971 == mPortBuffers[kPortIndexInput].size() 1972 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 1973 == mPortBuffers[kPortIndexOutput].size()) { 1974 mNoMoreOutputData = true; 1975 mBufferFilled.signal(); 1976 1977 return; 1978 } 1979 1980 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1981 for (size_t i = 0; i < buffers->size(); ++i) { 1982 fillOutputBuffer(&buffers->editItemAt(i)); 1983 } 1984} 1985 1986void OMXCodec::drainInputBuffers() { 1987 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1988 1989 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1990 for (size_t i = 0; i < buffers->size(); ++i) { 1991 drainInputBuffer(&buffers->editItemAt(i)); 1992 } 1993} 1994 1995void OMXCodec::drainInputBuffer(BufferInfo *info) { 1996 CHECK_EQ(info->mOwnedByComponent, false); 1997 1998 if (mSignalledEOS) { 1999 return; 2000 } 2001 2002 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 2003 const CodecSpecificData *specific = 2004 mCodecSpecificData[mCodecSpecificDataIndex]; 2005 2006 size_t size = specific->mSize; 2007 2008 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 2009 && !(mQuirks & kWantsNALFragments)) { 2010 static const uint8_t kNALStartCode[4] = 2011 { 0x00, 0x00, 0x00, 0x01 }; 2012 2013 CHECK(info->mSize >= specific->mSize + 4); 2014 2015 size += 4; 2016 2017 memcpy(info->mData, kNALStartCode, 4); 2018 memcpy((uint8_t *)info->mData + 4, 2019 specific->mData, specific->mSize); 2020 } else { 2021 CHECK(info->mSize >= specific->mSize); 2022 memcpy(info->mData, specific->mData, specific->mSize); 2023 } 2024 2025 mNoMoreOutputData = false; 2026 2027 CODEC_LOGV("calling emptyBuffer with codec specific data"); 2028 2029 status_t err = mOMX->emptyBuffer( 2030 mNode, info->mBuffer, 0, size, 2031 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 2032 0); 2033 CHECK_EQ(err, OK); 2034 2035 info->mOwnedByComponent = true; 2036 2037 ++mCodecSpecificDataIndex; 2038 return; 2039 } 2040 2041 if (mPaused) { 2042 return; 2043 } 2044 2045 status_t err; 2046 2047 bool signalEOS = false; 2048 int64_t timestampUs = 0; 2049 2050 size_t offset = 0; 2051 int32_t n = 0; 2052 for (;;) { 2053 MediaBuffer *srcBuffer; 2054 if (mSeekTimeUs >= 0) { 2055 if (mLeftOverBuffer) { 2056 mLeftOverBuffer->release(); 2057 mLeftOverBuffer = NULL; 2058 } 2059 2060 MediaSource::ReadOptions options; 2061 options.setSeekTo(mSeekTimeUs); 2062 2063 mSeekTimeUs = -1; 2064 mBufferFilled.signal(); 2065 2066 err = mSource->read(&srcBuffer, &options); 2067 } else if (mLeftOverBuffer) { 2068 srcBuffer = mLeftOverBuffer; 2069 mLeftOverBuffer = NULL; 2070 2071 err = OK; 2072 } else { 2073 err = mSource->read(&srcBuffer); 2074 } 2075 2076 if (err != OK) { 2077 signalEOS = true; 2078 mFinalStatus = err; 2079 mSignalledEOS = true; 2080 break; 2081 } 2082 2083 size_t remainingBytes = info->mSize - offset; 2084 2085 if (srcBuffer->range_length() > remainingBytes) { 2086 if (offset == 0) { 2087 CODEC_LOGE( 2088 "Codec's input buffers are too small to accomodate " 2089 "buffer read from source (info->mSize = %d, srcLength = %d)", 2090 info->mSize, srcBuffer->range_length()); 2091 2092 srcBuffer->release(); 2093 srcBuffer = NULL; 2094 2095 setState(ERROR); 2096 return; 2097 } 2098 2099 mLeftOverBuffer = srcBuffer; 2100 break; 2101 } 2102 2103 if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) { 2104 CHECK(mOMXLivesLocally && offset == 0); 2105 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *) info->mBuffer; 2106 header->pBuffer = (OMX_U8 *) srcBuffer->data() + srcBuffer->range_offset(); 2107 } else { 2108 memcpy((uint8_t *)info->mData + offset, 2109 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 2110 srcBuffer->range_length()); 2111 } 2112 2113 int64_t lastBufferTimeUs; 2114 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); 2115 CHECK(timestampUs >= 0); 2116 2117 if (offset == 0) { 2118 timestampUs = lastBufferTimeUs; 2119 } 2120 2121 offset += srcBuffer->range_length(); 2122 2123 srcBuffer->release(); 2124 srcBuffer = NULL; 2125 2126 ++n; 2127 2128 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) { 2129 break; 2130 } 2131 2132 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs; 2133 2134 if (coalescedDurationUs > 250000ll) { 2135 // Don't coalesce more than 250ms worth of encoded data at once. 2136 break; 2137 } 2138 } 2139 2140 if (n > 1) { 2141 LOGV("coalesced %d frames into one input buffer", n); 2142 } 2143 2144 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 2145 2146 if (signalEOS) { 2147 flags |= OMX_BUFFERFLAG_EOS; 2148 } else { 2149 mNoMoreOutputData = false; 2150 } 2151 2152 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 2153 "timestamp %lld us (%.2f secs)", 2154 info->mBuffer, offset, 2155 timestampUs, timestampUs / 1E6); 2156 2157 err = mOMX->emptyBuffer( 2158 mNode, info->mBuffer, 0, offset, 2159 flags, timestampUs); 2160 2161 if (err != OK) { 2162 setState(ERROR); 2163 return; 2164 } 2165 2166 info->mOwnedByComponent = true; 2167 2168 // This component does not ever signal the EOS flag on output buffers, 2169 // Thanks for nothing. 2170 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 2171 mNoMoreOutputData = true; 2172 mBufferFilled.signal(); 2173 } 2174} 2175 2176void OMXCodec::fillOutputBuffer(BufferInfo *info) { 2177 CHECK_EQ(info->mOwnedByComponent, false); 2178 2179 if (mNoMoreOutputData) { 2180 CODEC_LOGV("There is no more output data available, not " 2181 "calling fillOutputBuffer"); 2182 return; 2183 } 2184 2185 CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 2186 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 2187 2188 if (err != OK) { 2189 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err); 2190 2191 setState(ERROR); 2192 return; 2193 } 2194 2195 info->mOwnedByComponent = true; 2196} 2197 2198void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 2199 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2200 for (size_t i = 0; i < buffers->size(); ++i) { 2201 if ((*buffers)[i].mBuffer == buffer) { 2202 drainInputBuffer(&buffers->editItemAt(i)); 2203 return; 2204 } 2205 } 2206 2207 CHECK(!"should not be here."); 2208} 2209 2210void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 2211 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2212 for (size_t i = 0; i < buffers->size(); ++i) { 2213 if ((*buffers)[i].mBuffer == buffer) { 2214 fillOutputBuffer(&buffers->editItemAt(i)); 2215 return; 2216 } 2217 } 2218 2219 CHECK(!"should not be here."); 2220} 2221 2222void OMXCodec::setState(State newState) { 2223 mState = newState; 2224 mAsyncCompletion.signal(); 2225 2226 // This may cause some spurious wakeups but is necessary to 2227 // unblock the reader if we enter ERROR state. 2228 mBufferFilled.signal(); 2229} 2230 2231void OMXCodec::setRawAudioFormat( 2232 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 2233 2234 // port definition 2235 OMX_PARAM_PORTDEFINITIONTYPE def; 2236 InitOMXParams(&def); 2237 def.nPortIndex = portIndex; 2238 status_t err = mOMX->getParameter( 2239 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2240 CHECK_EQ(err, OK); 2241 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 2242 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 2243 &def, sizeof(def)), OK); 2244 2245 // pcm param 2246 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2247 InitOMXParams(&pcmParams); 2248 pcmParams.nPortIndex = portIndex; 2249 2250 err = mOMX->getParameter( 2251 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2252 2253 CHECK_EQ(err, OK); 2254 2255 pcmParams.nChannels = numChannels; 2256 pcmParams.eNumData = OMX_NumericalDataSigned; 2257 pcmParams.bInterleaved = OMX_TRUE; 2258 pcmParams.nBitPerSample = 16; 2259 pcmParams.nSamplingRate = sampleRate; 2260 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2261 2262 if (numChannels == 1) { 2263 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 2264 } else { 2265 CHECK_EQ(numChannels, 2); 2266 2267 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 2268 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 2269 } 2270 2271 err = mOMX->setParameter( 2272 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2273 2274 CHECK_EQ(err, OK); 2275} 2276 2277static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) { 2278 if (isAMRWB) { 2279 if (bps <= 6600) { 2280 return OMX_AUDIO_AMRBandModeWB0; 2281 } else if (bps <= 8850) { 2282 return OMX_AUDIO_AMRBandModeWB1; 2283 } else if (bps <= 12650) { 2284 return OMX_AUDIO_AMRBandModeWB2; 2285 } else if (bps <= 14250) { 2286 return OMX_AUDIO_AMRBandModeWB3; 2287 } else if (bps <= 15850) { 2288 return OMX_AUDIO_AMRBandModeWB4; 2289 } else if (bps <= 18250) { 2290 return OMX_AUDIO_AMRBandModeWB5; 2291 } else if (bps <= 19850) { 2292 return OMX_AUDIO_AMRBandModeWB6; 2293 } else if (bps <= 23050) { 2294 return OMX_AUDIO_AMRBandModeWB7; 2295 } 2296 2297 // 23850 bps 2298 return OMX_AUDIO_AMRBandModeWB8; 2299 } else { // AMRNB 2300 if (bps <= 4750) { 2301 return OMX_AUDIO_AMRBandModeNB0; 2302 } else if (bps <= 5150) { 2303 return OMX_AUDIO_AMRBandModeNB1; 2304 } else if (bps <= 5900) { 2305 return OMX_AUDIO_AMRBandModeNB2; 2306 } else if (bps <= 6700) { 2307 return OMX_AUDIO_AMRBandModeNB3; 2308 } else if (bps <= 7400) { 2309 return OMX_AUDIO_AMRBandModeNB4; 2310 } else if (bps <= 7950) { 2311 return OMX_AUDIO_AMRBandModeNB5; 2312 } else if (bps <= 10200) { 2313 return OMX_AUDIO_AMRBandModeNB6; 2314 } 2315 2316 // 12200 bps 2317 return OMX_AUDIO_AMRBandModeNB7; 2318 } 2319} 2320 2321void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) { 2322 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 2323 2324 OMX_AUDIO_PARAM_AMRTYPE def; 2325 InitOMXParams(&def); 2326 def.nPortIndex = portIndex; 2327 2328 status_t err = 2329 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2330 2331 CHECK_EQ(err, OK); 2332 2333 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2334 2335 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate); 2336 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2337 CHECK_EQ(err, OK); 2338 2339 //////////////////////// 2340 2341 if (mIsEncoder) { 2342 sp<MetaData> format = mSource->getFormat(); 2343 int32_t sampleRate; 2344 int32_t numChannels; 2345 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 2346 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 2347 2348 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2349 } 2350} 2351 2352void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) { 2353 CHECK(numChannels == 1 || numChannels == 2); 2354 if (mIsEncoder) { 2355 //////////////// input port //////////////////// 2356 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2357 2358 //////////////// output port //////////////////// 2359 // format 2360 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 2361 format.nPortIndex = kPortIndexOutput; 2362 format.nIndex = 0; 2363 status_t err = OMX_ErrorNone; 2364 while (OMX_ErrorNone == err) { 2365 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, 2366 &format, sizeof(format)), OK); 2367 if (format.eEncoding == OMX_AUDIO_CodingAAC) { 2368 break; 2369 } 2370 format.nIndex++; 2371 } 2372 CHECK_EQ(OK, err); 2373 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, 2374 &format, sizeof(format)), OK); 2375 2376 // port definition 2377 OMX_PARAM_PORTDEFINITIONTYPE def; 2378 InitOMXParams(&def); 2379 def.nPortIndex = kPortIndexOutput; 2380 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, 2381 &def, sizeof(def)), OK); 2382 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 2383 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 2384 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 2385 &def, sizeof(def)), OK); 2386 2387 // profile 2388 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2389 InitOMXParams(&profile); 2390 profile.nPortIndex = kPortIndexOutput; 2391 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, 2392 &profile, sizeof(profile)), OK); 2393 profile.nChannels = numChannels; 2394 profile.eChannelMode = (numChannels == 1? 2395 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); 2396 profile.nSampleRate = sampleRate; 2397 profile.nBitRate = bitRate; 2398 profile.nAudioBandWidth = 0; 2399 profile.nFrameLength = 0; 2400 profile.nAACtools = OMX_AUDIO_AACToolAll; 2401 profile.nAACERtools = OMX_AUDIO_AACERNone; 2402 profile.eAACProfile = OMX_AUDIO_AACObjectLC; 2403 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 2404 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac, 2405 &profile, sizeof(profile)), OK); 2406 2407 } else { 2408 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2409 InitOMXParams(&profile); 2410 profile.nPortIndex = kPortIndexInput; 2411 2412 status_t err = mOMX->getParameter( 2413 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2414 CHECK_EQ(err, OK); 2415 2416 profile.nChannels = numChannels; 2417 profile.nSampleRate = sampleRate; 2418 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 2419 2420 err = mOMX->setParameter( 2421 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2422 CHECK_EQ(err, OK); 2423 } 2424} 2425 2426void OMXCodec::setImageOutputFormat( 2427 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 2428 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 2429 2430#if 0 2431 OMX_INDEXTYPE index; 2432 status_t err = mOMX->get_extension_index( 2433 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 2434 CHECK_EQ(err, OK); 2435 2436 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 2437 CHECK_EQ(err, OK); 2438#endif 2439 2440 OMX_PARAM_PORTDEFINITIONTYPE def; 2441 InitOMXParams(&def); 2442 def.nPortIndex = kPortIndexOutput; 2443 2444 status_t err = mOMX->getParameter( 2445 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2446 CHECK_EQ(err, OK); 2447 2448 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2449 2450 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2451 2452 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2453 imageDef->eColorFormat = format; 2454 imageDef->nFrameWidth = width; 2455 imageDef->nFrameHeight = height; 2456 2457 switch (format) { 2458 case OMX_COLOR_FormatYUV420PackedPlanar: 2459 case OMX_COLOR_FormatYUV411Planar: 2460 { 2461 def.nBufferSize = (width * height * 3) / 2; 2462 break; 2463 } 2464 2465 case OMX_COLOR_FormatCbYCrY: 2466 { 2467 def.nBufferSize = width * height * 2; 2468 break; 2469 } 2470 2471 case OMX_COLOR_Format32bitARGB8888: 2472 { 2473 def.nBufferSize = width * height * 4; 2474 break; 2475 } 2476 2477 case OMX_COLOR_Format16bitARGB4444: 2478 case OMX_COLOR_Format16bitARGB1555: 2479 case OMX_COLOR_Format16bitRGB565: 2480 case OMX_COLOR_Format16bitBGR565: 2481 { 2482 def.nBufferSize = width * height * 2; 2483 break; 2484 } 2485 2486 default: 2487 CHECK(!"Should not be here. Unknown color format."); 2488 break; 2489 } 2490 2491 def.nBufferCountActual = def.nBufferCountMin; 2492 2493 err = mOMX->setParameter( 2494 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2495 CHECK_EQ(err, OK); 2496} 2497 2498void OMXCodec::setJPEGInputFormat( 2499 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 2500 OMX_PARAM_PORTDEFINITIONTYPE def; 2501 InitOMXParams(&def); 2502 def.nPortIndex = kPortIndexInput; 2503 2504 status_t err = mOMX->getParameter( 2505 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2506 CHECK_EQ(err, OK); 2507 2508 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2509 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2510 2511 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 2512 imageDef->nFrameWidth = width; 2513 imageDef->nFrameHeight = height; 2514 2515 def.nBufferSize = compressedSize; 2516 def.nBufferCountActual = def.nBufferCountMin; 2517 2518 err = mOMX->setParameter( 2519 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2520 CHECK_EQ(err, OK); 2521} 2522 2523void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 2524 CodecSpecificData *specific = 2525 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 2526 2527 specific->mSize = size; 2528 memcpy(specific->mData, data, size); 2529 2530 mCodecSpecificData.push(specific); 2531} 2532 2533void OMXCodec::clearCodecSpecificData() { 2534 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 2535 free(mCodecSpecificData.editItemAt(i)); 2536 } 2537 mCodecSpecificData.clear(); 2538 mCodecSpecificDataIndex = 0; 2539} 2540 2541status_t OMXCodec::start(MetaData *) { 2542 Mutex::Autolock autoLock(mLock); 2543 2544 if (mState != LOADED) { 2545 return UNKNOWN_ERROR; 2546 } 2547 2548 sp<MetaData> params = new MetaData; 2549 if (mQuirks & kWantsNALFragments) { 2550 params->setInt32(kKeyWantsNALFragments, true); 2551 } 2552 status_t err = mSource->start(params.get()); 2553 2554 if (err != OK) { 2555 return err; 2556 } 2557 2558 mCodecSpecificDataIndex = 0; 2559 mInitialBufferSubmit = true; 2560 mSignalledEOS = false; 2561 mNoMoreOutputData = false; 2562 mOutputPortSettingsHaveChanged = false; 2563 mSeekTimeUs = -1; 2564 mFilledBuffers.clear(); 2565 mPaused = false; 2566 2567 return init(); 2568} 2569 2570status_t OMXCodec::stop() { 2571 CODEC_LOGV("stop mState=%d", mState); 2572 2573 Mutex::Autolock autoLock(mLock); 2574 2575 while (isIntermediateState(mState)) { 2576 mAsyncCompletion.wait(mLock); 2577 } 2578 2579 switch (mState) { 2580 case LOADED: 2581 case ERROR: 2582 break; 2583 2584 case EXECUTING: 2585 { 2586 setState(EXECUTING_TO_IDLE); 2587 2588 if (mQuirks & kRequiresFlushBeforeShutdown) { 2589 CODEC_LOGV("This component requires a flush before transitioning " 2590 "from EXECUTING to IDLE..."); 2591 2592 bool emulateInputFlushCompletion = 2593 !flushPortAsync(kPortIndexInput); 2594 2595 bool emulateOutputFlushCompletion = 2596 !flushPortAsync(kPortIndexOutput); 2597 2598 if (emulateInputFlushCompletion) { 2599 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2600 } 2601 2602 if (emulateOutputFlushCompletion) { 2603 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2604 } 2605 } else { 2606 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2607 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2608 2609 status_t err = 2610 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2611 CHECK_EQ(err, OK); 2612 } 2613 2614 while (mState != LOADED && mState != ERROR) { 2615 mAsyncCompletion.wait(mLock); 2616 } 2617 2618 break; 2619 } 2620 2621 default: 2622 { 2623 CHECK(!"should not be here."); 2624 break; 2625 } 2626 } 2627 2628 if (mLeftOverBuffer) { 2629 mLeftOverBuffer->release(); 2630 mLeftOverBuffer = NULL; 2631 } 2632 2633 mSource->stop(); 2634 2635 CODEC_LOGV("stopped"); 2636 2637 return OK; 2638} 2639 2640sp<MetaData> OMXCodec::getFormat() { 2641 Mutex::Autolock autoLock(mLock); 2642 2643 return mOutputFormat; 2644} 2645 2646status_t OMXCodec::read( 2647 MediaBuffer **buffer, const ReadOptions *options) { 2648 *buffer = NULL; 2649 2650 Mutex::Autolock autoLock(mLock); 2651 2652 if (mState != EXECUTING && mState != RECONFIGURING) { 2653 return UNKNOWN_ERROR; 2654 } 2655 2656 bool seeking = false; 2657 int64_t seekTimeUs; 2658 if (options && options->getSeekTo(&seekTimeUs)) { 2659 seeking = true; 2660 } 2661 2662 if (mInitialBufferSubmit) { 2663 mInitialBufferSubmit = false; 2664 2665 if (seeking) { 2666 CHECK(seekTimeUs >= 0); 2667 mSeekTimeUs = seekTimeUs; 2668 2669 // There's no reason to trigger the code below, there's 2670 // nothing to flush yet. 2671 seeking = false; 2672 mPaused = false; 2673 } 2674 2675 drainInputBuffers(); 2676 2677 if (mState == EXECUTING) { 2678 // Otherwise mState == RECONFIGURING and this code will trigger 2679 // after the output port is reenabled. 2680 fillOutputBuffers(); 2681 } 2682 } 2683 2684 if (seeking) { 2685 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 2686 2687 mSignalledEOS = false; 2688 2689 CHECK(seekTimeUs >= 0); 2690 mSeekTimeUs = seekTimeUs; 2691 2692 mFilledBuffers.clear(); 2693 2694 CHECK_EQ(mState, EXECUTING); 2695 2696 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 2697 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 2698 2699 if (emulateInputFlushCompletion) { 2700 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2701 } 2702 2703 if (emulateOutputFlushCompletion) { 2704 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2705 } 2706 2707 while (mSeekTimeUs >= 0) { 2708 mBufferFilled.wait(mLock); 2709 } 2710 } 2711 2712 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 2713 mBufferFilled.wait(mLock); 2714 } 2715 2716 if (mState == ERROR) { 2717 return UNKNOWN_ERROR; 2718 } 2719 2720 if (mFilledBuffers.empty()) { 2721 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 2722 } 2723 2724 if (mOutputPortSettingsHaveChanged) { 2725 mOutputPortSettingsHaveChanged = false; 2726 2727 return INFO_FORMAT_CHANGED; 2728 } 2729 2730 size_t index = *mFilledBuffers.begin(); 2731 mFilledBuffers.erase(mFilledBuffers.begin()); 2732 2733 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 2734 info->mMediaBuffer->add_ref(); 2735 *buffer = info->mMediaBuffer; 2736 2737 return OK; 2738} 2739 2740void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 2741 Mutex::Autolock autoLock(mLock); 2742 2743 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2744 for (size_t i = 0; i < buffers->size(); ++i) { 2745 BufferInfo *info = &buffers->editItemAt(i); 2746 2747 if (info->mMediaBuffer == buffer) { 2748 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 2749 fillOutputBuffer(info); 2750 return; 2751 } 2752 } 2753 2754 CHECK(!"should not be here."); 2755} 2756 2757static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 2758 static const char *kNames[] = { 2759 "OMX_IMAGE_CodingUnused", 2760 "OMX_IMAGE_CodingAutoDetect", 2761 "OMX_IMAGE_CodingJPEG", 2762 "OMX_IMAGE_CodingJPEG2K", 2763 "OMX_IMAGE_CodingEXIF", 2764 "OMX_IMAGE_CodingTIFF", 2765 "OMX_IMAGE_CodingGIF", 2766 "OMX_IMAGE_CodingPNG", 2767 "OMX_IMAGE_CodingLZW", 2768 "OMX_IMAGE_CodingBMP", 2769 }; 2770 2771 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2772 2773 if (type < 0 || (size_t)type >= numNames) { 2774 return "UNKNOWN"; 2775 } else { 2776 return kNames[type]; 2777 } 2778} 2779 2780static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 2781 static const char *kNames[] = { 2782 "OMX_COLOR_FormatUnused", 2783 "OMX_COLOR_FormatMonochrome", 2784 "OMX_COLOR_Format8bitRGB332", 2785 "OMX_COLOR_Format12bitRGB444", 2786 "OMX_COLOR_Format16bitARGB4444", 2787 "OMX_COLOR_Format16bitARGB1555", 2788 "OMX_COLOR_Format16bitRGB565", 2789 "OMX_COLOR_Format16bitBGR565", 2790 "OMX_COLOR_Format18bitRGB666", 2791 "OMX_COLOR_Format18bitARGB1665", 2792 "OMX_COLOR_Format19bitARGB1666", 2793 "OMX_COLOR_Format24bitRGB888", 2794 "OMX_COLOR_Format24bitBGR888", 2795 "OMX_COLOR_Format24bitARGB1887", 2796 "OMX_COLOR_Format25bitARGB1888", 2797 "OMX_COLOR_Format32bitBGRA8888", 2798 "OMX_COLOR_Format32bitARGB8888", 2799 "OMX_COLOR_FormatYUV411Planar", 2800 "OMX_COLOR_FormatYUV411PackedPlanar", 2801 "OMX_COLOR_FormatYUV420Planar", 2802 "OMX_COLOR_FormatYUV420PackedPlanar", 2803 "OMX_COLOR_FormatYUV420SemiPlanar", 2804 "OMX_COLOR_FormatYUV422Planar", 2805 "OMX_COLOR_FormatYUV422PackedPlanar", 2806 "OMX_COLOR_FormatYUV422SemiPlanar", 2807 "OMX_COLOR_FormatYCbYCr", 2808 "OMX_COLOR_FormatYCrYCb", 2809 "OMX_COLOR_FormatCbYCrY", 2810 "OMX_COLOR_FormatCrYCbY", 2811 "OMX_COLOR_FormatYUV444Interleaved", 2812 "OMX_COLOR_FormatRawBayer8bit", 2813 "OMX_COLOR_FormatRawBayer10bit", 2814 "OMX_COLOR_FormatRawBayer8bitcompressed", 2815 "OMX_COLOR_FormatL2", 2816 "OMX_COLOR_FormatL4", 2817 "OMX_COLOR_FormatL8", 2818 "OMX_COLOR_FormatL16", 2819 "OMX_COLOR_FormatL24", 2820 "OMX_COLOR_FormatL32", 2821 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 2822 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 2823 "OMX_COLOR_Format18BitBGR666", 2824 "OMX_COLOR_Format24BitARGB6666", 2825 "OMX_COLOR_Format24BitABGR6666", 2826 }; 2827 2828 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2829 2830 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 2831 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 2832 } else if (type < 0 || (size_t)type >= numNames) { 2833 return "UNKNOWN"; 2834 } else { 2835 return kNames[type]; 2836 } 2837} 2838 2839static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 2840 static const char *kNames[] = { 2841 "OMX_VIDEO_CodingUnused", 2842 "OMX_VIDEO_CodingAutoDetect", 2843 "OMX_VIDEO_CodingMPEG2", 2844 "OMX_VIDEO_CodingH263", 2845 "OMX_VIDEO_CodingMPEG4", 2846 "OMX_VIDEO_CodingWMV", 2847 "OMX_VIDEO_CodingRV", 2848 "OMX_VIDEO_CodingAVC", 2849 "OMX_VIDEO_CodingMJPEG", 2850 }; 2851 2852 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2853 2854 if (type < 0 || (size_t)type >= numNames) { 2855 return "UNKNOWN"; 2856 } else { 2857 return kNames[type]; 2858 } 2859} 2860 2861static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 2862 static const char *kNames[] = { 2863 "OMX_AUDIO_CodingUnused", 2864 "OMX_AUDIO_CodingAutoDetect", 2865 "OMX_AUDIO_CodingPCM", 2866 "OMX_AUDIO_CodingADPCM", 2867 "OMX_AUDIO_CodingAMR", 2868 "OMX_AUDIO_CodingGSMFR", 2869 "OMX_AUDIO_CodingGSMEFR", 2870 "OMX_AUDIO_CodingGSMHR", 2871 "OMX_AUDIO_CodingPDCFR", 2872 "OMX_AUDIO_CodingPDCEFR", 2873 "OMX_AUDIO_CodingPDCHR", 2874 "OMX_AUDIO_CodingTDMAFR", 2875 "OMX_AUDIO_CodingTDMAEFR", 2876 "OMX_AUDIO_CodingQCELP8", 2877 "OMX_AUDIO_CodingQCELP13", 2878 "OMX_AUDIO_CodingEVRC", 2879 "OMX_AUDIO_CodingSMV", 2880 "OMX_AUDIO_CodingG711", 2881 "OMX_AUDIO_CodingG723", 2882 "OMX_AUDIO_CodingG726", 2883 "OMX_AUDIO_CodingG729", 2884 "OMX_AUDIO_CodingAAC", 2885 "OMX_AUDIO_CodingMP3", 2886 "OMX_AUDIO_CodingSBC", 2887 "OMX_AUDIO_CodingVORBIS", 2888 "OMX_AUDIO_CodingWMA", 2889 "OMX_AUDIO_CodingRA", 2890 "OMX_AUDIO_CodingMIDI", 2891 }; 2892 2893 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2894 2895 if (type < 0 || (size_t)type >= numNames) { 2896 return "UNKNOWN"; 2897 } else { 2898 return kNames[type]; 2899 } 2900} 2901 2902static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 2903 static const char *kNames[] = { 2904 "OMX_AUDIO_PCMModeLinear", 2905 "OMX_AUDIO_PCMModeALaw", 2906 "OMX_AUDIO_PCMModeMULaw", 2907 }; 2908 2909 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2910 2911 if (type < 0 || (size_t)type >= numNames) { 2912 return "UNKNOWN"; 2913 } else { 2914 return kNames[type]; 2915 } 2916} 2917 2918static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 2919 static const char *kNames[] = { 2920 "OMX_AUDIO_AMRBandModeUnused", 2921 "OMX_AUDIO_AMRBandModeNB0", 2922 "OMX_AUDIO_AMRBandModeNB1", 2923 "OMX_AUDIO_AMRBandModeNB2", 2924 "OMX_AUDIO_AMRBandModeNB3", 2925 "OMX_AUDIO_AMRBandModeNB4", 2926 "OMX_AUDIO_AMRBandModeNB5", 2927 "OMX_AUDIO_AMRBandModeNB6", 2928 "OMX_AUDIO_AMRBandModeNB7", 2929 "OMX_AUDIO_AMRBandModeWB0", 2930 "OMX_AUDIO_AMRBandModeWB1", 2931 "OMX_AUDIO_AMRBandModeWB2", 2932 "OMX_AUDIO_AMRBandModeWB3", 2933 "OMX_AUDIO_AMRBandModeWB4", 2934 "OMX_AUDIO_AMRBandModeWB5", 2935 "OMX_AUDIO_AMRBandModeWB6", 2936 "OMX_AUDIO_AMRBandModeWB7", 2937 "OMX_AUDIO_AMRBandModeWB8", 2938 }; 2939 2940 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2941 2942 if (type < 0 || (size_t)type >= numNames) { 2943 return "UNKNOWN"; 2944 } else { 2945 return kNames[type]; 2946 } 2947} 2948 2949static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 2950 static const char *kNames[] = { 2951 "OMX_AUDIO_AMRFrameFormatConformance", 2952 "OMX_AUDIO_AMRFrameFormatIF1", 2953 "OMX_AUDIO_AMRFrameFormatIF2", 2954 "OMX_AUDIO_AMRFrameFormatFSF", 2955 "OMX_AUDIO_AMRFrameFormatRTPPayload", 2956 "OMX_AUDIO_AMRFrameFormatITU", 2957 }; 2958 2959 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2960 2961 if (type < 0 || (size_t)type >= numNames) { 2962 return "UNKNOWN"; 2963 } else { 2964 return kNames[type]; 2965 } 2966} 2967 2968void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 2969 OMX_PARAM_PORTDEFINITIONTYPE def; 2970 InitOMXParams(&def); 2971 def.nPortIndex = portIndex; 2972 2973 status_t err = mOMX->getParameter( 2974 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2975 CHECK_EQ(err, OK); 2976 2977 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 2978 2979 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 2980 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 2981 2982 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 2983 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 2984 printf(" nBufferSize = %ld\n", def.nBufferSize); 2985 2986 switch (def.eDomain) { 2987 case OMX_PortDomainImage: 2988 { 2989 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2990 2991 printf("\n"); 2992 printf(" // Image\n"); 2993 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 2994 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 2995 printf(" nStride = %ld\n", imageDef->nStride); 2996 2997 printf(" eCompressionFormat = %s\n", 2998 imageCompressionFormatString(imageDef->eCompressionFormat)); 2999 3000 printf(" eColorFormat = %s\n", 3001 colorFormatString(imageDef->eColorFormat)); 3002 3003 break; 3004 } 3005 3006 case OMX_PortDomainVideo: 3007 { 3008 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 3009 3010 printf("\n"); 3011 printf(" // Video\n"); 3012 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 3013 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 3014 printf(" nStride = %ld\n", videoDef->nStride); 3015 3016 printf(" eCompressionFormat = %s\n", 3017 videoCompressionFormatString(videoDef->eCompressionFormat)); 3018 3019 printf(" eColorFormat = %s\n", 3020 colorFormatString(videoDef->eColorFormat)); 3021 3022 break; 3023 } 3024 3025 case OMX_PortDomainAudio: 3026 { 3027 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 3028 3029 printf("\n"); 3030 printf(" // Audio\n"); 3031 printf(" eEncoding = %s\n", 3032 audioCodingTypeString(audioDef->eEncoding)); 3033 3034 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 3035 OMX_AUDIO_PARAM_PCMMODETYPE params; 3036 InitOMXParams(¶ms); 3037 params.nPortIndex = portIndex; 3038 3039 err = mOMX->getParameter( 3040 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 3041 CHECK_EQ(err, OK); 3042 3043 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 3044 printf(" nChannels = %ld\n", params.nChannels); 3045 printf(" bInterleaved = %d\n", params.bInterleaved); 3046 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 3047 3048 printf(" eNumData = %s\n", 3049 params.eNumData == OMX_NumericalDataSigned 3050 ? "signed" : "unsigned"); 3051 3052 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 3053 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 3054 OMX_AUDIO_PARAM_AMRTYPE amr; 3055 InitOMXParams(&amr); 3056 amr.nPortIndex = portIndex; 3057 3058 err = mOMX->getParameter( 3059 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 3060 CHECK_EQ(err, OK); 3061 3062 printf(" nChannels = %ld\n", amr.nChannels); 3063 printf(" eAMRBandMode = %s\n", 3064 amrBandModeString(amr.eAMRBandMode)); 3065 printf(" eAMRFrameFormat = %s\n", 3066 amrFrameFormatString(amr.eAMRFrameFormat)); 3067 } 3068 3069 break; 3070 } 3071 3072 default: 3073 { 3074 printf(" // Unknown\n"); 3075 break; 3076 } 3077 } 3078 3079 printf("}\n"); 3080} 3081 3082void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 3083 mOutputFormat = new MetaData; 3084 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 3085 3086 OMX_PARAM_PORTDEFINITIONTYPE def; 3087 InitOMXParams(&def); 3088 def.nPortIndex = kPortIndexOutput; 3089 3090 status_t err = mOMX->getParameter( 3091 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3092 CHECK_EQ(err, OK); 3093 3094 switch (def.eDomain) { 3095 case OMX_PortDomainImage: 3096 { 3097 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3098 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 3099 3100 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 3101 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 3102 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 3103 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 3104 break; 3105 } 3106 3107 case OMX_PortDomainAudio: 3108 { 3109 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 3110 3111 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 3112 OMX_AUDIO_PARAM_PCMMODETYPE params; 3113 InitOMXParams(¶ms); 3114 params.nPortIndex = kPortIndexOutput; 3115 3116 err = mOMX->getParameter( 3117 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 3118 CHECK_EQ(err, OK); 3119 3120 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 3121 CHECK_EQ(params.nBitPerSample, 16); 3122 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 3123 3124 int32_t numChannels, sampleRate; 3125 inputFormat->findInt32(kKeyChannelCount, &numChannels); 3126 inputFormat->findInt32(kKeySampleRate, &sampleRate); 3127 3128 if ((OMX_U32)numChannels != params.nChannels) { 3129 LOGW("Codec outputs a different number of channels than " 3130 "the input stream contains (contains %d channels, " 3131 "codec outputs %ld channels).", 3132 numChannels, params.nChannels); 3133 } 3134 3135 mOutputFormat->setCString( 3136 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 3137 3138 // Use the codec-advertised number of channels, as some 3139 // codecs appear to output stereo even if the input data is 3140 // mono. If we know the codec lies about this information, 3141 // use the actual number of channels instead. 3142 mOutputFormat->setInt32( 3143 kKeyChannelCount, 3144 (mQuirks & kDecoderLiesAboutNumberOfChannels) 3145 ? numChannels : params.nChannels); 3146 3147 // The codec-reported sampleRate is not reliable... 3148 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 3149 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 3150 OMX_AUDIO_PARAM_AMRTYPE amr; 3151 InitOMXParams(&amr); 3152 amr.nPortIndex = kPortIndexOutput; 3153 3154 err = mOMX->getParameter( 3155 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 3156 CHECK_EQ(err, OK); 3157 3158 CHECK_EQ(amr.nChannels, 1); 3159 mOutputFormat->setInt32(kKeyChannelCount, 1); 3160 3161 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 3162 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 3163 mOutputFormat->setCString( 3164 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 3165 mOutputFormat->setInt32(kKeySampleRate, 8000); 3166 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 3167 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 3168 mOutputFormat->setCString( 3169 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 3170 mOutputFormat->setInt32(kKeySampleRate, 16000); 3171 } else { 3172 CHECK(!"Unknown AMR band mode."); 3173 } 3174 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 3175 mOutputFormat->setCString( 3176 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 3177 int32_t numChannels, sampleRate, bitRate; 3178 inputFormat->findInt32(kKeyChannelCount, &numChannels); 3179 inputFormat->findInt32(kKeySampleRate, &sampleRate); 3180 inputFormat->findInt32(kKeyBitRate, &bitRate); 3181 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 3182 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 3183 mOutputFormat->setInt32(kKeyBitRate, bitRate); 3184 } else { 3185 CHECK(!"Should not be here. Unknown audio encoding."); 3186 } 3187 break; 3188 } 3189 3190 case OMX_PortDomainVideo: 3191 { 3192 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 3193 3194 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 3195 mOutputFormat->setCString( 3196 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 3197 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 3198 mOutputFormat->setCString( 3199 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 3200 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 3201 mOutputFormat->setCString( 3202 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 3203 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 3204 mOutputFormat->setCString( 3205 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 3206 } else { 3207 CHECK(!"Unknown compression format."); 3208 } 3209 3210 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 3211 // This component appears to be lying to me. 3212 mOutputFormat->setInt32( 3213 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 3214 mOutputFormat->setInt32( 3215 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 3216 } else { 3217 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 3218 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 3219 } 3220 3221 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 3222 break; 3223 } 3224 3225 default: 3226 { 3227 CHECK(!"should not be here, neither audio nor video."); 3228 break; 3229 } 3230 } 3231} 3232 3233status_t OMXCodec::pause() { 3234 Mutex::Autolock autoLock(mLock); 3235 3236 mPaused = true; 3237 3238 return OK; 3239} 3240 3241//////////////////////////////////////////////////////////////////////////////// 3242 3243status_t QueryCodecs( 3244 const sp<IOMX> &omx, 3245 const char *mime, bool queryDecoders, 3246 Vector<CodecCapabilities> *results) { 3247 results->clear(); 3248 3249 for (int index = 0;; ++index) { 3250 const char *componentName; 3251 3252 if (!queryDecoders) { 3253 componentName = GetCodec( 3254 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 3255 mime, index); 3256 } else { 3257 componentName = GetCodec( 3258 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 3259 mime, index); 3260 } 3261 3262 if (!componentName) { 3263 return OK; 3264 } 3265 3266 if (strncmp(componentName, "OMX.", 4)) { 3267 // Not an OpenMax component but a software codec. 3268 3269 results->push(); 3270 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 3271 caps->mComponentName = componentName; 3272 3273 continue; 3274 } 3275 3276 sp<OMXCodecObserver> observer = new OMXCodecObserver; 3277 IOMX::node_id node; 3278 status_t err = omx->allocateNode(componentName, observer, &node); 3279 3280 if (err != OK) { 3281 continue; 3282 } 3283 3284 OMXCodec::setComponentRole(omx, node, !queryDecoders, mime); 3285 3286 results->push(); 3287 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 3288 caps->mComponentName = componentName; 3289 3290 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 3291 InitOMXParams(¶m); 3292 3293 param.nPortIndex = queryDecoders ? 0 : 1; 3294 3295 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 3296 err = omx->getParameter( 3297 node, OMX_IndexParamVideoProfileLevelQuerySupported, 3298 ¶m, sizeof(param)); 3299 3300 if (err != OK) { 3301 break; 3302 } 3303 3304 CodecProfileLevel profileLevel; 3305 profileLevel.mProfile = param.eProfile; 3306 profileLevel.mLevel = param.eLevel; 3307 3308 caps->mProfileLevels.push(profileLevel); 3309 } 3310 3311 CHECK_EQ(omx->freeNode(node), OK); 3312 } 3313} 3314 3315} // namespace android 3316