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