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