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