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