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