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