OMXCodec.cpp revision 450bf4b0d25c933431b790d911a5fcae750fe38d
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 <binder/IServiceManager.h> 22#include <binder/MemoryDealer.h> 23#include <binder/ProcessState.h> 24#include <media/IMediaPlayerService.h> 25#include <media/stagefright/ESDS.h> 26#include <media/stagefright/MediaBuffer.h> 27#include <media/stagefright/MediaBufferGroup.h> 28#include <media/stagefright/MediaDebug.h> 29#include <media/stagefright/MediaExtractor.h> 30#include <media/stagefright/MetaData.h> 31#include <media/stagefright/MmapSource.h> 32#include <media/stagefright/OMXCodec.h> 33#include <media/stagefright/Utils.h> 34#include <utils/Vector.h> 35 36#include <OMX_Audio.h> 37#include <OMX_Component.h> 38 39namespace android { 40 41struct CodecInfo { 42 const char *mime; 43 const char *codec; 44}; 45 46static const CodecInfo kDecoderInfo[] = { 47 { "image/jpeg", "OMX.TI.JPEG.decode" }, 48 { "audio/mpeg", "OMX.TI.MP3.decode" }, 49 { "audio/mpeg", "OMX.PV.mp3dec" }, 50 { "audio/3gpp", "OMX.TI.AMR.decode" }, 51 { "audio/3gpp", "OMX.PV.amrdec" }, 52 { "audio/mp4a-latm", "OMX.TI.AAC.decode" }, 53 { "audio/mp4a-latm", "OMX.PV.aacdec" }, 54 { "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" }, 55 { "video/mp4v-es", "OMX.TI.Video.Decoder" }, 56 { "video/mp4v-es", "OMX.PV.mpeg4dec" }, 57 { "video/3gpp", "OMX.qcom.video.decoder.h263" }, 58 { "video/3gpp", "OMX.TI.Video.Decoder" }, 59 { "video/3gpp", "OMX.PV.h263dec" }, 60 { "video/avc", "OMX.qcom.video.decoder.avc" }, 61 { "video/avc", "OMX.TI.Video.Decoder" }, 62 { "video/avc", "OMX.PV.avcdec" }, 63}; 64 65static const CodecInfo kEncoderInfo[] = { 66 { "audio/3gpp", "OMX.TI.AMR.encode" }, 67 { "audio/3gpp", "OMX.PV.amrencnb" }, 68 { "audio/mp4a-latm", "OMX.TI.AAC.encode" }, 69 { "audio/mp4a-latm", "OMX.PV.aacenc" }, 70 { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" }, 71 { "video/mp4v-es", "OMX.TI.Video.encoder" }, 72 { "video/mp4v-es", "OMX.PV.mpeg4enc" }, 73 { "video/3gpp", "OMX.qcom.video.encoder.h263" }, 74 { "video/3gpp", "OMX.TI.Video.encoder" }, 75 { "video/3gpp", "OMX.PV.h263enc" }, 76 { "video/avc", "OMX.TI.Video.encoder" }, 77 { "video/avc", "OMX.PV.avcenc" }, 78}; 79 80struct OMXCodecObserver : public BnOMXObserver { 81 OMXCodecObserver(const wp<OMXCodec> &target) 82 : mTarget(target) { 83 } 84 85 // from IOMXObserver 86 virtual void on_message(const omx_message &msg) { 87 sp<OMXCodec> codec = mTarget.promote(); 88 89 if (codec.get() != NULL) { 90 codec->on_message(msg); 91 } 92 } 93 94protected: 95 virtual ~OMXCodecObserver() {} 96 97private: 98 wp<OMXCodec> mTarget; 99 100 OMXCodecObserver(const OMXCodecObserver &); 101 OMXCodecObserver &operator=(const OMXCodecObserver &); 102}; 103 104static const char *GetCodec(const CodecInfo *info, size_t numInfos, 105 const char *mime, int index) { 106 CHECK(index >= 0); 107 for(size_t i = 0; i < numInfos; ++i) { 108 if (!strcasecmp(mime, info[i].mime)) { 109 if (index == 0) { 110 return info[i].codec; 111 } 112 113 --index; 114 } 115 } 116 117 return NULL; 118} 119 120enum { 121 kAVCProfileBaseline = 0x42, 122 kAVCProfileMain = 0x4d, 123 kAVCProfileExtended = 0x58, 124 kAVCProfileHigh = 0x64, 125 kAVCProfileHigh10 = 0x6e, 126 kAVCProfileHigh422 = 0x7a, 127 kAVCProfileHigh444 = 0xf4, 128 kAVCProfileCAVLC444Intra = 0x2c 129}; 130 131static const char *AVCProfileToString(uint8_t profile) { 132 switch (profile) { 133 case kAVCProfileBaseline: 134 return "Baseline"; 135 case kAVCProfileMain: 136 return "Main"; 137 case kAVCProfileExtended: 138 return "Extended"; 139 case kAVCProfileHigh: 140 return "High"; 141 case kAVCProfileHigh10: 142 return "High 10"; 143 case kAVCProfileHigh422: 144 return "High 422"; 145 case kAVCProfileHigh444: 146 return "High 444"; 147 case kAVCProfileCAVLC444Intra: 148 return "CAVLC 444 Intra"; 149 default: return "Unknown"; 150 } 151} 152 153// static 154sp<OMXCodec> OMXCodec::Create( 155 const sp<IOMX> &omx, 156 const sp<MetaData> &meta, bool createEncoder, 157 const sp<MediaSource> &source) { 158 const char *mime; 159 bool success = meta->findCString(kKeyMIMEType, &mime); 160 CHECK(success); 161 162 const char *componentName = NULL; 163 IOMX::node_id node = 0; 164 for (int index = 0;; ++index) { 165 if (createEncoder) { 166 componentName = GetCodec( 167 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 168 mime, index); 169 } else { 170 componentName = GetCodec( 171 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 172 mime, index); 173 } 174 175 if (!componentName) { 176 return NULL; 177 } 178 179 LOGV("Attempting to allocate OMX node '%s'", componentName); 180 181 status_t err = omx->allocate_node(componentName, &node); 182 if (err == OK) { 183 break; 184 } 185 } 186 187 uint32_t quirks = 0; 188 if (!strcmp(componentName, "OMX.PV.avcdec")) { 189 quirks |= kWantsNALFragments; 190 } 191 if (!strcmp(componentName, "OMX.TI.MP3.decode")) { 192 quirks |= kNeedsFlushBeforeDisable; 193 } 194 if (!strcmp(componentName, "OMX.TI.AAC.decode")) { 195 quirks |= kNeedsFlushBeforeDisable; 196 quirks |= kRequiresFlushCompleteEmulation; 197 198 // The following is currently necessary for proper shutdown 199 // behaviour, but NOT enabled by default in order to make the 200 // bug reproducible... 201 // quirks |= kRequiresFlushBeforeShutdown; 202 } 203 if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) { 204 quirks |= kRequiresLoadedToIdleAfterAllocation; 205 quirks |= kRequiresAllocateBufferOnInputPorts; 206 } 207 208 sp<OMXCodec> codec = new OMXCodec( 209 omx, node, quirks, createEncoder, mime, componentName, 210 source); 211 212 uint32_t type; 213 const void *data; 214 size_t size; 215 if (meta->findData(kKeyESDS, &type, &data, &size)) { 216 ESDS esds((const char *)data, size); 217 CHECK_EQ(esds.InitCheck(), OK); 218 219 const void *codec_specific_data; 220 size_t codec_specific_data_size; 221 esds.getCodecSpecificInfo( 222 &codec_specific_data, &codec_specific_data_size); 223 224 printf("found codec-specific data of size %d\n", 225 codec_specific_data_size); 226 227 codec->addCodecSpecificData( 228 codec_specific_data, codec_specific_data_size); 229 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 230 printf("found avcc of size %d\n", size); 231 232 // Parse the AVCDecoderConfigurationRecord 233 234 const uint8_t *ptr = (const uint8_t *)data; 235 236 CHECK(size >= 7); 237 CHECK_EQ(ptr[0], 1); // configurationVersion == 1 238 uint8_t profile = ptr[1]; 239 uint8_t level = ptr[3]; 240 241 CHECK((ptr[4] >> 2) == 0x3f); // reserved 242 243 size_t lengthSize = 1 + (ptr[4] & 3); 244 245 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 246 // violates it... 247 // CHECK((ptr[5] >> 5) == 7); // reserved 248 249 size_t numSeqParameterSets = ptr[5] & 31; 250 251 ptr += 6; 252 size -= 6; 253 254 for (size_t i = 0; i < numSeqParameterSets; ++i) { 255 CHECK(size >= 2); 256 size_t length = U16_AT(ptr); 257 258 ptr += 2; 259 size -= 2; 260 261 CHECK(size >= length); 262 263 codec->addCodecSpecificData(ptr, length); 264 265 ptr += length; 266 size -= length; 267 } 268 269 CHECK(size >= 1); 270 size_t numPictureParameterSets = *ptr; 271 ++ptr; 272 --size; 273 274 for (size_t i = 0; i < numPictureParameterSets; ++i) { 275 CHECK(size >= 2); 276 size_t length = U16_AT(ptr); 277 278 ptr += 2; 279 size -= 2; 280 281 CHECK(size >= length); 282 283 codec->addCodecSpecificData(ptr, length); 284 285 ptr += length; 286 size -= length; 287 } 288 289 LOGI("AVC profile = %d (%s), level = %d", 290 (int)profile, AVCProfileToString(profile), (int)level / 10); 291 292 if (!strcmp(componentName, "OMX.TI.Video.Decoder") 293 && (profile != kAVCProfileBaseline || level > 39)) { 294 // This stream exceeds the decoder's capabilities. 295 296 LOGE("Profile and/or level exceed the decoder's capabilities."); 297 return NULL; 298 } 299 } 300 301 if (!strcasecmp("audio/3gpp", mime)) { 302 codec->setAMRFormat(); 303 } 304 if (!createEncoder && !strcasecmp("audio/mp4a-latm", mime)) { 305 codec->setAACFormat(); 306 } 307 if (!strncasecmp(mime, "video/", 6)) { 308 int32_t width, height; 309 bool success = meta->findInt32(kKeyWidth, &width); 310 success = success && meta->findInt32(kKeyHeight, &height); 311 CHECK(success); 312 313 if (createEncoder) { 314 codec->setVideoInputFormat(mime, width, height); 315 } else { 316 codec->setVideoOutputFormat(mime, width, height); 317 } 318 } 319 if (!strcasecmp(mime, "image/jpeg") 320 && !strcmp(componentName, "OMX.TI.JPEG.decode")) { 321 OMX_COLOR_FORMATTYPE format = 322 OMX_COLOR_Format32bitARGB8888; 323 // OMX_COLOR_FormatYUV420PackedPlanar; 324 // OMX_COLOR_FormatCbYCrY; 325 // OMX_COLOR_FormatYUV411Planar; 326 327 int32_t width, height; 328 bool success = meta->findInt32(kKeyWidth, &width); 329 success = success && meta->findInt32(kKeyHeight, &height); 330 331 int32_t compressedSize; 332 success = success && meta->findInt32( 333 kKeyCompressedSize, &compressedSize); 334 335 CHECK(success); 336 CHECK(compressedSize > 0); 337 338 codec->setImageOutputFormat(format, width, height); 339 codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize); 340 } 341 342 codec->initOutputFormat(meta); 343 344 return codec; 345} 346 347status_t OMXCodec::setVideoPortFormatType( 348 OMX_U32 portIndex, 349 OMX_VIDEO_CODINGTYPE compressionFormat, 350 OMX_COLOR_FORMATTYPE colorFormat) { 351 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 352 format.nSize = sizeof(format); 353 format.nVersion.s.nVersionMajor = 1; 354 format.nVersion.s.nVersionMinor = 1; 355 format.nPortIndex = portIndex; 356 format.nIndex = 0; 357 bool found = false; 358 359 OMX_U32 index = 0; 360 for (;;) { 361 format.nIndex = index; 362 status_t err = mOMX->get_parameter( 363 mNode, OMX_IndexParamVideoPortFormat, 364 &format, sizeof(format)); 365 366 if (err != OK) { 367 return err; 368 } 369 370 // The following assertion is violated by TI's video decoder. 371 // CHECK_EQ(format.nIndex, index); 372 373#if 1 374 LOGI("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", 375 portIndex, 376 index, format.eCompressionFormat, format.eColorFormat); 377#endif 378 379 if (!strcmp("OMX.TI.Video.encoder", mComponentName)) { 380 if (portIndex == kPortIndexInput 381 && colorFormat == format.eColorFormat) { 382 // eCompressionFormat does not seem right. 383 found = true; 384 break; 385 } 386 if (portIndex == kPortIndexOutput 387 && compressionFormat == format.eCompressionFormat) { 388 // eColorFormat does not seem right. 389 found = true; 390 break; 391 } 392 } 393 394 if (format.eCompressionFormat == compressionFormat 395 && format.eColorFormat == colorFormat) { 396 found = true; 397 break; 398 } 399 400 ++index; 401 } 402 403 if (!found) { 404 return UNKNOWN_ERROR; 405 } 406 407 LOGI("found a match."); 408 status_t err = mOMX->set_parameter( 409 mNode, OMX_IndexParamVideoPortFormat, 410 &format, sizeof(format)); 411 412 return err; 413} 414 415void OMXCodec::setVideoInputFormat( 416 const char *mime, OMX_U32 width, OMX_U32 height) { 417 LOGI("setVideoInputFormat width=%ld, height=%ld", width, height); 418 419 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 420 if (!strcasecmp("video/avc", mime)) { 421 compressionFormat = OMX_VIDEO_CodingAVC; 422 } else if (!strcasecmp("video/mp4v-es", mime)) { 423 compressionFormat = OMX_VIDEO_CodingMPEG4; 424 } else if (!strcasecmp("video/3gpp", mime)) { 425 compressionFormat = OMX_VIDEO_CodingH263; 426 } else { 427 LOGE("Not a supported video mime type: %s", mime); 428 CHECK(!"Should not be here. Not a supported video mime type."); 429 } 430 431 OMX_COLOR_FORMATTYPE colorFormat = 432 0 ? OMX_COLOR_FormatYCbYCr : OMX_COLOR_FormatCbYCrY; 433 434 if (!strncmp("OMX.qcom.video.encoder.", mComponentName, 23)) { 435 colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 436 } 437 438 setVideoPortFormatType( 439 kPortIndexInput, OMX_VIDEO_CodingUnused, 440 colorFormat); 441 442 setVideoPortFormatType( 443 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 444 445 OMX_PARAM_PORTDEFINITIONTYPE def; 446 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 447 448 def.nSize = sizeof(def); 449 def.nVersion.s.nVersionMajor = 1; 450 def.nVersion.s.nVersionMinor = 1; 451 def.nPortIndex = kPortIndexOutput; 452 453 status_t err = mOMX->get_parameter( 454 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 455 456 CHECK_EQ(err, OK); 457 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 458 459 video_def->nFrameWidth = width; 460 video_def->nFrameHeight = height; 461 462 video_def->eCompressionFormat = compressionFormat; 463 video_def->eColorFormat = OMX_COLOR_FormatUnused; 464 465 err = mOMX->set_parameter( 466 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 467 CHECK_EQ(err, OK); 468 469 //////////////////////////////////////////////////////////////////////////// 470 471 def.nSize = sizeof(def); 472 def.nVersion.s.nVersionMajor = 1; 473 def.nVersion.s.nVersionMinor = 1; 474 def.nPortIndex = kPortIndexInput; 475 476 err = mOMX->get_parameter( 477 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 478 CHECK_EQ(err, OK); 479 480 def.nBufferSize = (width * height * 2); // (width * height * 3) / 2; 481 LOGI("setting nBufferSize = %ld", def.nBufferSize); 482 483 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 484 485 video_def->nFrameWidth = width; 486 video_def->nFrameHeight = height; 487 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 488 video_def->eColorFormat = colorFormat; 489 490 err = mOMX->set_parameter( 491 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 492 CHECK_EQ(err, OK); 493} 494 495void OMXCodec::setVideoOutputFormat( 496 const char *mime, OMX_U32 width, OMX_U32 height) { 497 LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height); 498 499 // Enabling this code appears to be the right thing(tm), but,... 500 // the TI decoder then loses the ability to output YUV420 and only outputs 501 // YCbYCr (16bit) 502 503#if 1 504 if (!strcmp("OMX.TI.Video.Decoder", mComponentName)) { 505 OMX_PARAM_COMPONENTROLETYPE role; 506 role.nSize = sizeof(role); 507 role.nVersion.s.nVersionMajor = 1; 508 role.nVersion.s.nVersionMinor = 1; 509 510 if (!strcasecmp("video/avc", mime)) { 511 strncpy((char *)role.cRole, "video_decoder.avc", 512 OMX_MAX_STRINGNAME_SIZE - 1); 513 } else if (!strcasecmp("video/mp4v-es", mime)) { 514 strncpy((char *)role.cRole, "video_decoder.mpeg4", 515 OMX_MAX_STRINGNAME_SIZE - 1); 516 } else if (!strcasecmp("video/3gpp", mime)) { 517 strncpy((char *)role.cRole, "video_decoder.h263", 518 OMX_MAX_STRINGNAME_SIZE - 1); 519 } 520 521 role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 522 523 status_t err = mOMX->set_parameter( 524 mNode, OMX_IndexParamStandardComponentRole, 525 &role, sizeof(role)); 526 CHECK_EQ(err, OK); 527 } 528#endif 529 530 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 531 if (!strcasecmp("video/avc", mime)) { 532 compressionFormat = OMX_VIDEO_CodingAVC; 533 } else if (!strcasecmp("video/mp4v-es", mime)) { 534 compressionFormat = OMX_VIDEO_CodingMPEG4; 535 } else if (!strcasecmp("video/3gpp", mime)) { 536 compressionFormat = OMX_VIDEO_CodingH263; 537 } else { 538 LOGE("Not a supported video mime type: %s", mime); 539 CHECK(!"Should not be here. Not a supported video mime type."); 540 } 541 542 setVideoPortFormatType( 543 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 544 545#if 1 546 { 547 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 548 format.nSize = sizeof(format); 549 format.nVersion.s.nVersionMajor = 1; 550 format.nVersion.s.nVersionMinor = 1; 551 format.nPortIndex = kPortIndexOutput; 552 format.nIndex = 0; 553 554 status_t err = mOMX->get_parameter( 555 mNode, OMX_IndexParamVideoPortFormat, 556 &format, sizeof(format)); 557 CHECK_EQ(err, OK); 558 CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused); 559 560 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 561 562 CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 563 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 564 || format.eColorFormat == OMX_COLOR_FormatCbYCrY 565 || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 566 567 err = mOMX->set_parameter( 568 mNode, OMX_IndexParamVideoPortFormat, 569 &format, sizeof(format)); 570 CHECK_EQ(err, OK); 571 } 572#endif 573 574 OMX_PARAM_PORTDEFINITIONTYPE def; 575 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 576 577 def.nSize = sizeof(def); 578 def.nVersion.s.nVersionMajor = 1; 579 def.nVersion.s.nVersionMinor = 1; 580 def.nPortIndex = kPortIndexInput; 581 582 status_t err = mOMX->get_parameter( 583 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 584 585 CHECK_EQ(err, OK); 586 587#if 1 588 // XXX Need a (much) better heuristic to compute input buffer sizes. 589 const size_t X = 64 * 1024; 590 if (def.nBufferSize < X) { 591 def.nBufferSize = X; 592 } 593#endif 594 595 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 596 597 video_def->nFrameWidth = width; 598 video_def->nFrameHeight = height; 599 600 video_def->eColorFormat = OMX_COLOR_FormatUnused; 601 602 err = mOMX->set_parameter( 603 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 604 CHECK_EQ(err, OK); 605 606 //////////////////////////////////////////////////////////////////////////// 607 608 def.nSize = sizeof(def); 609 def.nVersion.s.nVersionMajor = 1; 610 def.nVersion.s.nVersionMinor = 1; 611 def.nPortIndex = kPortIndexOutput; 612 613 err = mOMX->get_parameter( 614 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 615 CHECK_EQ(err, OK); 616 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 617 618#if 0 619 def.nBufferSize = 620 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 621#endif 622 623 video_def->nFrameWidth = width; 624 video_def->nFrameHeight = height; 625 626 err = mOMX->set_parameter( 627 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 628 CHECK_EQ(err, OK); 629} 630 631 632OMXCodec::OMXCodec( 633 const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, 634 bool isEncoder, 635 const char *mime, 636 const char *componentName, 637 const sp<MediaSource> &source) 638 : mOMX(omx), 639 mNode(node), 640 mQuirks(quirks), 641 mIsEncoder(isEncoder), 642 mMIME(strdup(mime)), 643 mComponentName(strdup(componentName)), 644 mSource(source), 645 mCodecSpecificDataIndex(0), 646 mState(LOADED), 647 mInitialBufferSubmit(true), 648 mSignalledEOS(false), 649 mNoMoreOutputData(false), 650 mSeekTimeUs(-1) { 651 mPortStatus[kPortIndexInput] = ENABLED; 652 mPortStatus[kPortIndexOutput] = ENABLED; 653 654 mObserver = new OMXCodecObserver(this); 655 mOMX->observe_node(mNode, mObserver); 656} 657 658OMXCodec::~OMXCodec() { 659 CHECK(mState == LOADED || mState == ERROR); 660 661 status_t err = mOMX->observe_node(mNode, NULL); 662 CHECK_EQ(err, OK); 663 664 err = mOMX->free_node(mNode); 665 CHECK_EQ(err, OK); 666 667 mNode = NULL; 668 setState(DEAD); 669 670 clearCodecSpecificData(); 671 672 free(mComponentName); 673 mComponentName = NULL; 674 675 free(mMIME); 676 mMIME = NULL; 677} 678 679status_t OMXCodec::init() { 680 // mLock is held. 681 682 CHECK_EQ(mState, LOADED); 683 684 status_t err; 685 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 686 err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 687 CHECK_EQ(err, OK); 688 689 setState(LOADED_TO_IDLE); 690 } 691 692 err = allocateBuffers(); 693 CHECK_EQ(err, OK); 694 695 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 696 err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 697 CHECK_EQ(err, OK); 698 699 setState(LOADED_TO_IDLE); 700 } 701 702 while (mState != EXECUTING && mState != ERROR) { 703 mAsyncCompletion.wait(mLock); 704 } 705 706 return mState == ERROR ? UNKNOWN_ERROR : OK; 707} 708 709// static 710bool OMXCodec::isIntermediateState(State state) { 711 return state == LOADED_TO_IDLE 712 || state == IDLE_TO_EXECUTING 713 || state == EXECUTING_TO_IDLE 714 || state == IDLE_TO_LOADED 715 || state == RECONFIGURING; 716} 717 718status_t OMXCodec::allocateBuffers() { 719 status_t err = allocateBuffersOnPort(kPortIndexInput); 720 721 if (err != OK) { 722 return err; 723 } 724 725 return allocateBuffersOnPort(kPortIndexOutput); 726} 727 728status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 729 OMX_PARAM_PORTDEFINITIONTYPE def; 730 def.nSize = sizeof(def); 731 def.nVersion.s.nVersionMajor = 1; 732 def.nVersion.s.nVersionMinor = 1; 733 def.nVersion.s.nRevision = 0; 734 def.nVersion.s.nStep = 0; 735 def.nPortIndex = portIndex; 736 737 status_t err = mOMX->get_parameter( 738 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 739 740 if (err != OK) { 741 return err; 742 } 743 744 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 745 mDealer[portIndex] = new MemoryDealer(totalSize); 746 747 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 748 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 749 CHECK(mem.get() != NULL); 750 751 IOMX::buffer_id buffer; 752 if (portIndex == kPortIndexInput 753 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) { 754 err = mOMX->allocate_buffer_with_backup( 755 mNode, portIndex, mem, &buffer); 756 } else if (portIndex == kPortIndexOutput 757 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 758 err = mOMX->allocate_buffer( 759 mNode, portIndex, def.nBufferSize, &buffer); 760 } else { 761 err = mOMX->use_buffer(mNode, portIndex, mem, &buffer); 762 } 763 764 if (err != OK) { 765 LOGE("allocate_buffer_with_backup failed"); 766 return err; 767 } 768 769 BufferInfo info; 770 info.mBuffer = buffer; 771 info.mOwnedByComponent = false; 772 info.mMem = mem; 773 info.mMediaBuffer = NULL; 774 775 if (portIndex == kPortIndexOutput) { 776 info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size()); 777 info.mMediaBuffer->setObserver(this); 778 } 779 780 mPortBuffers[portIndex].push(info); 781 782 LOGV("allocated buffer %p on %s port", buffer, 783 portIndex == kPortIndexInput ? "input" : "output"); 784 } 785 786 dumpPortStatus(portIndex); 787 788 return OK; 789} 790 791void OMXCodec::on_message(const omx_message &msg) { 792 Mutex::Autolock autoLock(mLock); 793 794 switch (msg.type) { 795 case omx_message::EVENT: 796 { 797 onEvent( 798 msg.u.event_data.event, msg.u.event_data.data1, 799 msg.u.event_data.data2); 800 801 break; 802 } 803 804 case omx_message::EMPTY_BUFFER_DONE: 805 { 806 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 807 808 LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 809 810 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 811 size_t i = 0; 812 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 813 ++i; 814 } 815 816 CHECK(i < buffers->size()); 817 if (!(*buffers)[i].mOwnedByComponent) { 818 LOGW("We already own input buffer %p, yet received " 819 "an EMPTY_BUFFER_DONE.", buffer); 820 } 821 822 buffers->editItemAt(i).mOwnedByComponent = false; 823 824 if (mPortStatus[kPortIndexInput] == DISABLING) { 825 LOGV("Port is disabled, freeing buffer %p", buffer); 826 827 status_t err = 828 mOMX->free_buffer(mNode, kPortIndexInput, buffer); 829 CHECK_EQ(err, OK); 830 831 buffers->removeAt(i); 832 } else if (mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 833 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED); 834 drainInputBuffer(&buffers->editItemAt(i)); 835 } 836 837 break; 838 } 839 840 case omx_message::FILL_BUFFER_DONE: 841 { 842 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 843 OMX_U32 flags = msg.u.extended_buffer_data.flags; 844 845 LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)", 846 buffer, 847 msg.u.extended_buffer_data.range_length, 848 flags); 849 850 LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))", 851 msg.u.extended_buffer_data.timestamp, 852 msg.u.extended_buffer_data.timestamp / 1E6); 853 854 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 855 size_t i = 0; 856 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 857 ++i; 858 } 859 860 CHECK(i < buffers->size()); 861 BufferInfo *info = &buffers->editItemAt(i); 862 863 if (!info->mOwnedByComponent) { 864 LOGW("We already own output buffer %p, yet received " 865 "a FILL_BUFFER_DONE.", buffer); 866 } 867 868 info->mOwnedByComponent = false; 869 870 if (mPortStatus[kPortIndexOutput] == DISABLING) { 871 LOGV("Port is disabled, freeing buffer %p", buffer); 872 873 status_t err = 874 mOMX->free_buffer(mNode, kPortIndexOutput, buffer); 875 CHECK_EQ(err, OK); 876 877 buffers->removeAt(i); 878 } else if (mPortStatus[kPortIndexOutput] == ENABLED 879 && (flags & OMX_BUFFERFLAG_EOS)) { 880 LOGV("No more output data."); 881 mNoMoreOutputData = true; 882 mBufferFilled.signal(); 883 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 884 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 885 886 MediaBuffer *buffer = info->mMediaBuffer; 887 888 buffer->set_range( 889 msg.u.extended_buffer_data.range_offset, 890 msg.u.extended_buffer_data.range_length); 891 892 buffer->meta_data()->clear(); 893 894 buffer->meta_data()->setInt32( 895 kKeyTimeUnits, 896 (msg.u.extended_buffer_data.timestamp + 500) / 1000); 897 898 buffer->meta_data()->setInt32( 899 kKeyTimeScale, 1000); 900 901 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 902 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 903 } 904 905 buffer->meta_data()->setPointer( 906 kKeyPlatformPrivate, 907 msg.u.extended_buffer_data.platform_private); 908 909 buffer->meta_data()->setPointer( 910 kKeyBufferID, 911 msg.u.extended_buffer_data.buffer); 912 913 mFilledBuffers.push_back(i); 914 mBufferFilled.signal(); 915 } 916 917 break; 918 } 919 920 default: 921 { 922 CHECK(!"should not be here."); 923 break; 924 } 925 } 926} 927 928void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 929 switch (event) { 930 case OMX_EventCmdComplete: 931 { 932 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 933 break; 934 } 935 936 case OMX_EventError: 937 { 938 LOGE("ERROR(%ld, %ld)", data1, data2); 939 940 setState(ERROR); 941 break; 942 } 943 944 case OMX_EventPortSettingsChanged: 945 { 946 onPortSettingsChanged(data1); 947 break; 948 } 949 950 case OMX_EventBufferFlag: 951 { 952 LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 953 954 if (data1 == kPortIndexOutput) { 955 mNoMoreOutputData = true; 956 } 957 break; 958 } 959 960 default: 961 { 962 LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 963 break; 964 } 965 } 966} 967 968void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 969 switch (cmd) { 970 case OMX_CommandStateSet: 971 { 972 onStateChange((OMX_STATETYPE)data); 973 break; 974 } 975 976 case OMX_CommandPortDisable: 977 { 978 OMX_U32 portIndex = data; 979 LOGV("PORT_DISABLED(%ld)", portIndex); 980 981 CHECK(mState == EXECUTING || mState == RECONFIGURING); 982 CHECK_EQ(mPortStatus[portIndex], DISABLING); 983 CHECK_EQ(mPortBuffers[portIndex].size(), 0); 984 985 mPortStatus[portIndex] = DISABLED; 986 987 if (mState == RECONFIGURING) { 988 CHECK_EQ(portIndex, kPortIndexOutput); 989 990 enablePortAsync(portIndex); 991 992 status_t err = allocateBuffersOnPort(portIndex); 993 CHECK_EQ(err, OK); 994 } 995 break; 996 } 997 998 case OMX_CommandPortEnable: 999 { 1000 OMX_U32 portIndex = data; 1001 LOGV("PORT_ENABLED(%ld)", portIndex); 1002 1003 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1004 CHECK_EQ(mPortStatus[portIndex], ENABLING); 1005 1006 mPortStatus[portIndex] = ENABLED; 1007 1008 if (mState == RECONFIGURING) { 1009 CHECK_EQ(portIndex, kPortIndexOutput); 1010 1011 setState(EXECUTING); 1012 1013 fillOutputBuffers(); 1014 } 1015 break; 1016 } 1017 1018 case OMX_CommandFlush: 1019 { 1020 OMX_U32 portIndex = data; 1021 1022 LOGV("FLUSH_DONE(%ld)", portIndex); 1023 1024 CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); 1025 mPortStatus[portIndex] = ENABLED; 1026 1027 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 1028 mPortBuffers[portIndex].size()); 1029 1030 if (mState == RECONFIGURING) { 1031 CHECK_EQ(portIndex, kPortIndexOutput); 1032 1033 disablePortAsync(portIndex); 1034 } else if (mState == EXECUTING_TO_IDLE) { 1035 if (mPortStatus[kPortIndexInput] == ENABLED 1036 && mPortStatus[kPortIndexOutput] == ENABLED) { 1037 LOGV("Finished flushing both ports, now completing " 1038 "transition from EXECUTING to IDLE."); 1039 1040 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1041 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1042 1043 status_t err = 1044 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 1045 CHECK_EQ(err, OK); 1046 } 1047 } else { 1048 // We're flushing both ports in preparation for seeking. 1049 1050 if (mPortStatus[kPortIndexInput] == ENABLED 1051 && mPortStatus[kPortIndexOutput] == ENABLED) { 1052 LOGV("Finished flushing both ports, now continuing from" 1053 " seek-time."); 1054 1055 drainInputBuffers(); 1056 fillOutputBuffers(); 1057 } 1058 } 1059 1060 break; 1061 } 1062 1063 default: 1064 { 1065 LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1066 break; 1067 } 1068 } 1069} 1070 1071void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1072 switch (newState) { 1073 case OMX_StateIdle: 1074 { 1075 LOGV("Now Idle."); 1076 if (mState == LOADED_TO_IDLE) { 1077 status_t err = mOMX->send_command( 1078 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1079 1080 CHECK_EQ(err, OK); 1081 1082 setState(IDLE_TO_EXECUTING); 1083 } else { 1084 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1085 1086 CHECK_EQ( 1087 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1088 mPortBuffers[kPortIndexInput].size()); 1089 1090 CHECK_EQ( 1091 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1092 mPortBuffers[kPortIndexOutput].size()); 1093 1094 status_t err = mOMX->send_command( 1095 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1096 1097 CHECK_EQ(err, OK); 1098 1099 err = freeBuffersOnPort(kPortIndexInput); 1100 CHECK_EQ(err, OK); 1101 1102 err = freeBuffersOnPort(kPortIndexOutput); 1103 CHECK_EQ(err, OK); 1104 1105 mPortStatus[kPortIndexInput] = ENABLED; 1106 mPortStatus[kPortIndexOutput] = ENABLED; 1107 1108 setState(IDLE_TO_LOADED); 1109 } 1110 break; 1111 } 1112 1113 case OMX_StateExecuting: 1114 { 1115 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1116 1117 LOGV("Now Executing."); 1118 1119 setState(EXECUTING); 1120 1121 // Buffers will be submitted to the component in the first 1122 // call to OMXCodec::read as mInitialBufferSubmit is true at 1123 // this point. This ensures that this on_message call returns, 1124 // releases the lock and ::init can notice the state change and 1125 // itself return. 1126 break; 1127 } 1128 1129 case OMX_StateLoaded: 1130 { 1131 CHECK_EQ(mState, IDLE_TO_LOADED); 1132 1133 LOGV("Now Loaded."); 1134 1135 setState(LOADED); 1136 break; 1137 } 1138 1139 default: 1140 { 1141 CHECK(!"should not be here."); 1142 break; 1143 } 1144 } 1145} 1146 1147// static 1148size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1149 size_t n = 0; 1150 for (size_t i = 0; i < buffers.size(); ++i) { 1151 if (!buffers[i].mOwnedByComponent) { 1152 ++n; 1153 } 1154 } 1155 1156 return n; 1157} 1158 1159status_t OMXCodec::freeBuffersOnPort( 1160 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1161 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1162 1163 status_t stickyErr = OK; 1164 1165 for (size_t i = buffers->size(); i-- > 0;) { 1166 BufferInfo *info = &buffers->editItemAt(i); 1167 1168 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1169 continue; 1170 } 1171 1172 CHECK_EQ(info->mOwnedByComponent, false); 1173 1174 status_t err = 1175 mOMX->free_buffer(mNode, portIndex, info->mBuffer); 1176 1177 if (err != OK) { 1178 stickyErr = err; 1179 } 1180 1181 if (info->mMediaBuffer != NULL) { 1182 info->mMediaBuffer->setObserver(NULL); 1183 1184 // Make sure nobody but us owns this buffer at this point. 1185 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1186 1187 info->mMediaBuffer->release(); 1188 } 1189 1190 buffers->removeAt(i); 1191 } 1192 1193 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1194 1195 return stickyErr; 1196} 1197 1198void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1199 LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1200 1201 CHECK_EQ(mState, EXECUTING); 1202 CHECK_EQ(portIndex, kPortIndexOutput); 1203 setState(RECONFIGURING); 1204 1205 if (mQuirks & kNeedsFlushBeforeDisable) { 1206 if (!flushPortAsync(portIndex)) { 1207 onCmdComplete(OMX_CommandFlush, portIndex); 1208 } 1209 } else { 1210 disablePortAsync(portIndex); 1211 } 1212} 1213 1214bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1215 CHECK(mState == EXECUTING || mState == RECONFIGURING 1216 || mState == EXECUTING_TO_IDLE); 1217 1218 LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1219 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1220 mPortBuffers[portIndex].size()); 1221 1222 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1223 mPortStatus[portIndex] = SHUTTING_DOWN; 1224 1225 if ((mQuirks & kRequiresFlushCompleteEmulation) 1226 && countBuffersWeOwn(mPortBuffers[portIndex]) 1227 == mPortBuffers[portIndex].size()) { 1228 // No flush is necessary and this component fails to send a 1229 // flush-complete event in this case. 1230 1231 return false; 1232 } 1233 1234 status_t err = 1235 mOMX->send_command(mNode, OMX_CommandFlush, portIndex); 1236 CHECK_EQ(err, OK); 1237 1238 return true; 1239} 1240 1241void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1242 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1243 1244 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1245 mPortStatus[portIndex] = DISABLING; 1246 1247 status_t err = 1248 mOMX->send_command(mNode, OMX_CommandPortDisable, portIndex); 1249 CHECK_EQ(err, OK); 1250 1251 freeBuffersOnPort(portIndex, true); 1252} 1253 1254void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1255 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1256 1257 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1258 mPortStatus[portIndex] = ENABLING; 1259 1260 status_t err = 1261 mOMX->send_command(mNode, OMX_CommandPortEnable, portIndex); 1262 CHECK_EQ(err, OK); 1263} 1264 1265void OMXCodec::fillOutputBuffers() { 1266 CHECK_EQ(mState, EXECUTING); 1267 1268 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1269 for (size_t i = 0; i < buffers->size(); ++i) { 1270 fillOutputBuffer(&buffers->editItemAt(i)); 1271 } 1272} 1273 1274void OMXCodec::drainInputBuffers() { 1275 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1276 1277 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1278 for (size_t i = 0; i < buffers->size(); ++i) { 1279 drainInputBuffer(&buffers->editItemAt(i)); 1280 } 1281} 1282 1283void OMXCodec::drainInputBuffer(BufferInfo *info) { 1284 CHECK_EQ(info->mOwnedByComponent, false); 1285 1286 if (mSignalledEOS) { 1287 return; 1288 } 1289 1290 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 1291 const CodecSpecificData *specific = 1292 mCodecSpecificData[mCodecSpecificDataIndex]; 1293 1294 size_t size = specific->mSize; 1295 1296 if (!strcasecmp("video/avc", mMIME) 1297 && !(mQuirks & kWantsNALFragments)) { 1298 static const uint8_t kNALStartCode[4] = 1299 { 0x00, 0x00, 0x00, 0x01 }; 1300 1301 CHECK(info->mMem->size() >= specific->mSize + 4); 1302 1303 size += 4; 1304 1305 memcpy(info->mMem->pointer(), kNALStartCode, 4); 1306 memcpy((uint8_t *)info->mMem->pointer() + 4, 1307 specific->mData, specific->mSize); 1308 } else { 1309 CHECK(info->mMem->size() >= specific->mSize); 1310 memcpy(info->mMem->pointer(), specific->mData, specific->mSize); 1311 } 1312 1313 mOMX->empty_buffer( 1314 mNode, info->mBuffer, 0, size, 1315 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 1316 0); 1317 1318 info->mOwnedByComponent = true; 1319 1320 ++mCodecSpecificDataIndex; 1321 return; 1322 } 1323 1324 MediaBuffer *srcBuffer; 1325 status_t err; 1326 if (mSeekTimeUs >= 0) { 1327 MediaSource::ReadOptions options; 1328 options.setSeekTo(mSeekTimeUs); 1329 mSeekTimeUs = -1; 1330 1331 err = mSource->read(&srcBuffer, &options); 1332 } else { 1333 err = mSource->read(&srcBuffer); 1334 } 1335 1336 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1337 OMX_TICKS timestamp = 0; 1338 size_t srcLength = 0; 1339 1340 if (err != OK) { 1341 LOGV("signalling end of input stream."); 1342 flags |= OMX_BUFFERFLAG_EOS; 1343 1344 mSignalledEOS = true; 1345 } else { 1346 srcLength = srcBuffer->range_length(); 1347 1348 if (info->mMem->size() < srcLength) { 1349 LOGE("info->mMem->size() = %d, srcLength = %d", 1350 info->mMem->size(), srcLength); 1351 } 1352 CHECK(info->mMem->size() >= srcLength); 1353 memcpy(info->mMem->pointer(), 1354 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1355 srcLength); 1356 1357 int32_t units, scale; 1358 if (srcBuffer->meta_data()->findInt32(kKeyTimeUnits, &units) 1359 && srcBuffer->meta_data()->findInt32(kKeyTimeScale, &scale)) { 1360 timestamp = ((OMX_TICKS)units * 1000000) / scale; 1361 1362 LOGV("Calling empty_buffer on buffer %p (length %d)", 1363 info->mBuffer, srcLength); 1364 LOGV("Calling empty_buffer with timestamp %lld us (%.2f secs)", 1365 timestamp, timestamp / 1E6); 1366 } 1367 } 1368 1369 mOMX->empty_buffer( 1370 mNode, info->mBuffer, 0, srcLength, 1371 flags, timestamp); 1372 1373 info->mOwnedByComponent = true; 1374 1375 if (srcBuffer != NULL) { 1376 srcBuffer->release(); 1377 srcBuffer = NULL; 1378 } 1379} 1380 1381void OMXCodec::fillOutputBuffer(BufferInfo *info) { 1382 CHECK_EQ(info->mOwnedByComponent, false); 1383 1384 if (mNoMoreOutputData) { 1385 LOGV("There is no more output data available, not " 1386 "calling fillOutputBuffer"); 1387 return; 1388 } 1389 1390 LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 1391 mOMX->fill_buffer(mNode, info->mBuffer); 1392 1393 info->mOwnedByComponent = true; 1394} 1395 1396void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 1397 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1398 for (size_t i = 0; i < buffers->size(); ++i) { 1399 if ((*buffers)[i].mBuffer == buffer) { 1400 drainInputBuffer(&buffers->editItemAt(i)); 1401 return; 1402 } 1403 } 1404 1405 CHECK(!"should not be here."); 1406} 1407 1408void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 1409 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1410 for (size_t i = 0; i < buffers->size(); ++i) { 1411 if ((*buffers)[i].mBuffer == buffer) { 1412 fillOutputBuffer(&buffers->editItemAt(i)); 1413 return; 1414 } 1415 } 1416 1417 CHECK(!"should not be here."); 1418} 1419 1420void OMXCodec::setState(State newState) { 1421 mState = newState; 1422 mAsyncCompletion.signal(); 1423 1424 // This may cause some spurious wakeups but is necessary to 1425 // unblock the reader if we enter ERROR state. 1426 mBufferFilled.signal(); 1427} 1428 1429void OMXCodec::setAMRFormat() { 1430 if (!mIsEncoder) { 1431 OMX_AUDIO_PARAM_AMRTYPE def; 1432 def.nSize = sizeof(def); 1433 def.nVersion.s.nVersionMajor = 1; 1434 def.nVersion.s.nVersionMinor = 1; 1435 def.nPortIndex = kPortIndexInput; 1436 1437 status_t err = 1438 mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1439 1440 CHECK_EQ(err, OK); 1441 1442 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 1443 def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; 1444 1445 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1446 CHECK_EQ(err, OK); 1447 } 1448 1449 //////////////////////// 1450 1451 if (mIsEncoder) { 1452 sp<MetaData> format = mSource->getFormat(); 1453 int32_t sampleRate; 1454 int32_t numChannels; 1455 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 1456 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 1457 1458 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 1459 pcmParams.nSize = sizeof(pcmParams); 1460 pcmParams.nVersion.s.nVersionMajor = 1; 1461 pcmParams.nVersion.s.nVersionMinor = 1; 1462 pcmParams.nPortIndex = kPortIndexInput; 1463 1464 status_t err = mOMX->get_parameter( 1465 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1466 1467 CHECK_EQ(err, OK); 1468 1469 pcmParams.nChannels = numChannels; 1470 pcmParams.eNumData = OMX_NumericalDataSigned; 1471 pcmParams.bInterleaved = OMX_TRUE; 1472 pcmParams.nBitPerSample = 16; 1473 pcmParams.nSamplingRate = sampleRate; 1474 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 1475 1476 if (numChannels == 1) { 1477 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 1478 } else { 1479 CHECK_EQ(numChannels, 2); 1480 1481 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 1482 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 1483 } 1484 1485 err = mOMX->set_parameter( 1486 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1487 1488 CHECK_EQ(err, OK); 1489 } 1490} 1491 1492void OMXCodec::setAACFormat() { 1493 OMX_AUDIO_PARAM_AACPROFILETYPE def; 1494 def.nSize = sizeof(def); 1495 def.nVersion.s.nVersionMajor = 1; 1496 def.nVersion.s.nVersionMinor = 1; 1497 def.nPortIndex = kPortIndexInput; 1498 1499 status_t err = 1500 mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def)); 1501 CHECK_EQ(err, OK); 1502 1503 def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 1504 1505 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def)); 1506 CHECK_EQ(err, OK); 1507} 1508 1509void OMXCodec::setImageOutputFormat( 1510 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 1511 LOGV("setImageOutputFormat(%ld, %ld)", width, height); 1512 1513#if 0 1514 OMX_INDEXTYPE index; 1515 status_t err = mOMX->get_extension_index( 1516 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 1517 CHECK_EQ(err, OK); 1518 1519 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 1520 CHECK_EQ(err, OK); 1521#endif 1522 1523 OMX_PARAM_PORTDEFINITIONTYPE def; 1524 def.nSize = sizeof(def); 1525 def.nVersion.s.nVersionMajor = 1; 1526 def.nVersion.s.nVersionMinor = 1; 1527 def.nPortIndex = kPortIndexOutput; 1528 1529 status_t err = mOMX->get_parameter( 1530 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1531 CHECK_EQ(err, OK); 1532 1533 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 1534 1535 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1536 1537 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 1538 imageDef->eColorFormat = format; 1539 imageDef->nFrameWidth = width; 1540 imageDef->nFrameHeight = height; 1541 1542 switch (format) { 1543 case OMX_COLOR_FormatYUV420PackedPlanar: 1544 case OMX_COLOR_FormatYUV411Planar: 1545 { 1546 def.nBufferSize = (width * height * 3) / 2; 1547 break; 1548 } 1549 1550 case OMX_COLOR_FormatCbYCrY: 1551 { 1552 def.nBufferSize = width * height * 2; 1553 break; 1554 } 1555 1556 case OMX_COLOR_Format32bitARGB8888: 1557 { 1558 def.nBufferSize = width * height * 4; 1559 break; 1560 } 1561 1562 default: 1563 CHECK(!"Should not be here. Unknown color format."); 1564 break; 1565 } 1566 1567 def.nBufferCountActual = def.nBufferCountMin; 1568 1569 err = mOMX->set_parameter( 1570 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1571 CHECK_EQ(err, OK); 1572} 1573 1574void OMXCodec::setJPEGInputFormat( 1575 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 1576 OMX_PARAM_PORTDEFINITIONTYPE def; 1577 def.nSize = sizeof(def); 1578 def.nVersion.s.nVersionMajor = 1; 1579 def.nVersion.s.nVersionMinor = 1; 1580 def.nPortIndex = kPortIndexInput; 1581 1582 status_t err = mOMX->get_parameter( 1583 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1584 CHECK_EQ(err, OK); 1585 1586 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 1587 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1588 1589 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 1590 imageDef->nFrameWidth = width; 1591 imageDef->nFrameHeight = height; 1592 1593 def.nBufferSize = compressedSize; 1594 def.nBufferCountActual = def.nBufferCountMin; 1595 1596 err = mOMX->set_parameter( 1597 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1598 CHECK_EQ(err, OK); 1599} 1600 1601void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 1602 CodecSpecificData *specific = 1603 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 1604 1605 specific->mSize = size; 1606 memcpy(specific->mData, data, size); 1607 1608 mCodecSpecificData.push(specific); 1609} 1610 1611void OMXCodec::clearCodecSpecificData() { 1612 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 1613 free(mCodecSpecificData.editItemAt(i)); 1614 } 1615 mCodecSpecificData.clear(); 1616 mCodecSpecificDataIndex = 0; 1617} 1618 1619status_t OMXCodec::start(MetaData *) { 1620 Mutex::Autolock autoLock(mLock); 1621 1622 if (mState != LOADED) { 1623 return UNKNOWN_ERROR; 1624 } 1625 1626 sp<MetaData> params = new MetaData; 1627 if (mQuirks & kWantsNALFragments) { 1628 params->setInt32(kKeyWantsNALFragments, true); 1629 } 1630 status_t err = mSource->start(params.get()); 1631 1632 if (err != OK) { 1633 return err; 1634 } 1635 1636 mCodecSpecificDataIndex = 0; 1637 mInitialBufferSubmit = true; 1638 mSignalledEOS = false; 1639 mNoMoreOutputData = false; 1640 mSeekTimeUs = -1; 1641 mFilledBuffers.clear(); 1642 1643 return init(); 1644} 1645 1646status_t OMXCodec::stop() { 1647 LOGV("stop"); 1648 1649 Mutex::Autolock autoLock(mLock); 1650 1651 while (isIntermediateState(mState)) { 1652 mAsyncCompletion.wait(mLock); 1653 } 1654 1655 switch (mState) { 1656 case LOADED: 1657 case ERROR: 1658 break; 1659 1660 case EXECUTING: 1661 { 1662 setState(EXECUTING_TO_IDLE); 1663 1664 if (mQuirks & kRequiresFlushBeforeShutdown) { 1665 LOGV("This component requires a flush before transitioning " 1666 "from EXECUTING to IDLE..."); 1667 1668 bool emulateInputFlushCompletion = 1669 !flushPortAsync(kPortIndexInput); 1670 1671 bool emulateOutputFlushCompletion = 1672 !flushPortAsync(kPortIndexOutput); 1673 1674 if (emulateInputFlushCompletion) { 1675 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 1676 } 1677 1678 if (emulateOutputFlushCompletion) { 1679 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 1680 } 1681 } else { 1682 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1683 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1684 1685 status_t err = 1686 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 1687 CHECK_EQ(err, OK); 1688 } 1689 1690 while (mState != LOADED && mState != ERROR) { 1691 mAsyncCompletion.wait(mLock); 1692 } 1693 1694 break; 1695 } 1696 1697 default: 1698 { 1699 CHECK(!"should not be here."); 1700 break; 1701 } 1702 } 1703 1704 mSource->stop(); 1705 1706 return OK; 1707} 1708 1709sp<MetaData> OMXCodec::getFormat() { 1710 return mOutputFormat; 1711} 1712 1713status_t OMXCodec::read( 1714 MediaBuffer **buffer, const ReadOptions *options) { 1715 *buffer = NULL; 1716 1717 Mutex::Autolock autoLock(mLock); 1718 1719 if (mState != EXECUTING && mState != RECONFIGURING) { 1720 return UNKNOWN_ERROR; 1721 } 1722 1723 if (mInitialBufferSubmit) { 1724 mInitialBufferSubmit = false; 1725 1726 drainInputBuffers(); 1727 1728 if (mState == EXECUTING) { 1729 // Otherwise mState == RECONFIGURING and this code will trigger 1730 // after the output port is reenabled. 1731 fillOutputBuffers(); 1732 } 1733 } 1734 1735 int64_t seekTimeUs; 1736 if (options && options->getSeekTo(&seekTimeUs)) { 1737 LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 1738 1739 mSignalledEOS = false; 1740 mNoMoreOutputData = false; 1741 1742 CHECK(seekTimeUs >= 0); 1743 mSeekTimeUs = seekTimeUs; 1744 1745 mFilledBuffers.clear(); 1746 1747 CHECK_EQ(mState, EXECUTING); 1748 1749 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 1750 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 1751 1752 if (emulateInputFlushCompletion) { 1753 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 1754 } 1755 1756 if (emulateOutputFlushCompletion) { 1757 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 1758 } 1759 } 1760 1761 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 1762 mBufferFilled.wait(mLock); 1763 } 1764 1765 if (mState == ERROR) { 1766 return UNKNOWN_ERROR; 1767 } 1768 1769 if (mFilledBuffers.empty()) { 1770 return ERROR_END_OF_STREAM; 1771 } 1772 1773 size_t index = *mFilledBuffers.begin(); 1774 mFilledBuffers.erase(mFilledBuffers.begin()); 1775 1776 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1777 info->mMediaBuffer->add_ref(); 1778 *buffer = info->mMediaBuffer; 1779 1780 return OK; 1781} 1782 1783void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 1784 Mutex::Autolock autoLock(mLock); 1785 1786 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1787 for (size_t i = 0; i < buffers->size(); ++i) { 1788 BufferInfo *info = &buffers->editItemAt(i); 1789 1790 if (info->mMediaBuffer == buffer) { 1791 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1792 fillOutputBuffer(info); 1793 return; 1794 } 1795 } 1796 1797 CHECK(!"should not be here."); 1798} 1799 1800static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 1801 static const char *kNames[] = { 1802 "OMX_IMAGE_CodingUnused", 1803 "OMX_IMAGE_CodingAutoDetect", 1804 "OMX_IMAGE_CodingJPEG", 1805 "OMX_IMAGE_CodingJPEG2K", 1806 "OMX_IMAGE_CodingEXIF", 1807 "OMX_IMAGE_CodingTIFF", 1808 "OMX_IMAGE_CodingGIF", 1809 "OMX_IMAGE_CodingPNG", 1810 "OMX_IMAGE_CodingLZW", 1811 "OMX_IMAGE_CodingBMP", 1812 }; 1813 1814 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1815 1816 if (type < 0 || (size_t)type >= numNames) { 1817 return "UNKNOWN"; 1818 } else { 1819 return kNames[type]; 1820 } 1821} 1822 1823static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 1824 static const char *kNames[] = { 1825 "OMX_COLOR_FormatUnused", 1826 "OMX_COLOR_FormatMonochrome", 1827 "OMX_COLOR_Format8bitRGB332", 1828 "OMX_COLOR_Format12bitRGB444", 1829 "OMX_COLOR_Format16bitARGB4444", 1830 "OMX_COLOR_Format16bitARGB1555", 1831 "OMX_COLOR_Format16bitRGB565", 1832 "OMX_COLOR_Format16bitBGR565", 1833 "OMX_COLOR_Format18bitRGB666", 1834 "OMX_COLOR_Format18bitARGB1665", 1835 "OMX_COLOR_Format19bitARGB1666", 1836 "OMX_COLOR_Format24bitRGB888", 1837 "OMX_COLOR_Format24bitBGR888", 1838 "OMX_COLOR_Format24bitARGB1887", 1839 "OMX_COLOR_Format25bitARGB1888", 1840 "OMX_COLOR_Format32bitBGRA8888", 1841 "OMX_COLOR_Format32bitARGB8888", 1842 "OMX_COLOR_FormatYUV411Planar", 1843 "OMX_COLOR_FormatYUV411PackedPlanar", 1844 "OMX_COLOR_FormatYUV420Planar", 1845 "OMX_COLOR_FormatYUV420PackedPlanar", 1846 "OMX_COLOR_FormatYUV420SemiPlanar", 1847 "OMX_COLOR_FormatYUV422Planar", 1848 "OMX_COLOR_FormatYUV422PackedPlanar", 1849 "OMX_COLOR_FormatYUV422SemiPlanar", 1850 "OMX_COLOR_FormatYCbYCr", 1851 "OMX_COLOR_FormatYCrYCb", 1852 "OMX_COLOR_FormatCbYCrY", 1853 "OMX_COLOR_FormatCrYCbY", 1854 "OMX_COLOR_FormatYUV444Interleaved", 1855 "OMX_COLOR_FormatRawBayer8bit", 1856 "OMX_COLOR_FormatRawBayer10bit", 1857 "OMX_COLOR_FormatRawBayer8bitcompressed", 1858 "OMX_COLOR_FormatL2", 1859 "OMX_COLOR_FormatL4", 1860 "OMX_COLOR_FormatL8", 1861 "OMX_COLOR_FormatL16", 1862 "OMX_COLOR_FormatL24", 1863 "OMX_COLOR_FormatL32", 1864 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 1865 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 1866 "OMX_COLOR_Format18BitBGR666", 1867 "OMX_COLOR_Format24BitARGB6666", 1868 "OMX_COLOR_Format24BitABGR6666", 1869 }; 1870 1871 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1872 1873 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 1874 1875 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 1876 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 1877 } else if (type < 0 || (size_t)type >= numNames) { 1878 return "UNKNOWN"; 1879 } else { 1880 return kNames[type]; 1881 } 1882} 1883 1884static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 1885 static const char *kNames[] = { 1886 "OMX_VIDEO_CodingUnused", 1887 "OMX_VIDEO_CodingAutoDetect", 1888 "OMX_VIDEO_CodingMPEG2", 1889 "OMX_VIDEO_CodingH263", 1890 "OMX_VIDEO_CodingMPEG4", 1891 "OMX_VIDEO_CodingWMV", 1892 "OMX_VIDEO_CodingRV", 1893 "OMX_VIDEO_CodingAVC", 1894 "OMX_VIDEO_CodingMJPEG", 1895 }; 1896 1897 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1898 1899 if (type < 0 || (size_t)type >= numNames) { 1900 return "UNKNOWN"; 1901 } else { 1902 return kNames[type]; 1903 } 1904} 1905 1906static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 1907 static const char *kNames[] = { 1908 "OMX_AUDIO_CodingUnused", 1909 "OMX_AUDIO_CodingAutoDetect", 1910 "OMX_AUDIO_CodingPCM", 1911 "OMX_AUDIO_CodingADPCM", 1912 "OMX_AUDIO_CodingAMR", 1913 "OMX_AUDIO_CodingGSMFR", 1914 "OMX_AUDIO_CodingGSMEFR", 1915 "OMX_AUDIO_CodingGSMHR", 1916 "OMX_AUDIO_CodingPDCFR", 1917 "OMX_AUDIO_CodingPDCEFR", 1918 "OMX_AUDIO_CodingPDCHR", 1919 "OMX_AUDIO_CodingTDMAFR", 1920 "OMX_AUDIO_CodingTDMAEFR", 1921 "OMX_AUDIO_CodingQCELP8", 1922 "OMX_AUDIO_CodingQCELP13", 1923 "OMX_AUDIO_CodingEVRC", 1924 "OMX_AUDIO_CodingSMV", 1925 "OMX_AUDIO_CodingG711", 1926 "OMX_AUDIO_CodingG723", 1927 "OMX_AUDIO_CodingG726", 1928 "OMX_AUDIO_CodingG729", 1929 "OMX_AUDIO_CodingAAC", 1930 "OMX_AUDIO_CodingMP3", 1931 "OMX_AUDIO_CodingSBC", 1932 "OMX_AUDIO_CodingVORBIS", 1933 "OMX_AUDIO_CodingWMA", 1934 "OMX_AUDIO_CodingRA", 1935 "OMX_AUDIO_CodingMIDI", 1936 }; 1937 1938 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1939 1940 if (type < 0 || (size_t)type >= numNames) { 1941 return "UNKNOWN"; 1942 } else { 1943 return kNames[type]; 1944 } 1945} 1946 1947static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 1948 static const char *kNames[] = { 1949 "OMX_AUDIO_PCMModeLinear", 1950 "OMX_AUDIO_PCMModeALaw", 1951 "OMX_AUDIO_PCMModeMULaw", 1952 }; 1953 1954 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1955 1956 if (type < 0 || (size_t)type >= numNames) { 1957 return "UNKNOWN"; 1958 } else { 1959 return kNames[type]; 1960 } 1961} 1962 1963 1964void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 1965 OMX_PARAM_PORTDEFINITIONTYPE def; 1966 def.nSize = sizeof(def); 1967 def.nVersion.s.nVersionMajor = 1; 1968 def.nVersion.s.nVersionMinor = 1; 1969 def.nPortIndex = portIndex; 1970 1971 status_t err = mOMX->get_parameter( 1972 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1973 CHECK_EQ(err, OK); 1974 1975 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 1976 1977 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 1978 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 1979 1980 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 1981 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 1982 printf(" nBufferSize = %ld\n", def.nBufferSize); 1983 1984 switch (def.eDomain) { 1985 case OMX_PortDomainImage: 1986 { 1987 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1988 1989 printf("\n"); 1990 printf(" // Image\n"); 1991 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 1992 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 1993 printf(" nStride = %ld\n", imageDef->nStride); 1994 1995 printf(" eCompressionFormat = %s\n", 1996 imageCompressionFormatString(imageDef->eCompressionFormat)); 1997 1998 printf(" eColorFormat = %s\n", 1999 colorFormatString(imageDef->eColorFormat)); 2000 2001 break; 2002 } 2003 2004 case OMX_PortDomainVideo: 2005 { 2006 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2007 2008 printf("\n"); 2009 printf(" // Video\n"); 2010 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 2011 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 2012 printf(" nStride = %ld\n", videoDef->nStride); 2013 2014 printf(" eCompressionFormat = %s\n", 2015 videoCompressionFormatString(videoDef->eCompressionFormat)); 2016 2017 printf(" eColorFormat = %s\n", 2018 colorFormatString(videoDef->eColorFormat)); 2019 2020 break; 2021 } 2022 2023 case OMX_PortDomainAudio: 2024 { 2025 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2026 2027 printf("\n"); 2028 printf(" // Audio\n"); 2029 printf(" eEncoding = %s\n", 2030 audioCodingTypeString(audioDef->eEncoding)); 2031 2032 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2033 OMX_AUDIO_PARAM_PCMMODETYPE params; 2034 params.nSize = sizeof(params); 2035 params.nVersion.s.nVersionMajor = 1; 2036 params.nVersion.s.nVersionMinor = 1; 2037 params.nPortIndex = portIndex; 2038 2039 err = mOMX->get_parameter( 2040 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2041 CHECK_EQ(err, OK); 2042 2043 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2044 printf(" nChannels = %ld\n", params.nChannels); 2045 printf(" bInterleaved = %d\n", params.bInterleaved); 2046 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2047 2048 printf(" eNumData = %s\n", 2049 params.eNumData == OMX_NumericalDataSigned 2050 ? "signed" : "unsigned"); 2051 2052 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2053 } 2054 2055 break; 2056 } 2057 2058 default: 2059 { 2060 printf(" // Unknown\n"); 2061 break; 2062 } 2063 } 2064 2065 printf("}\n"); 2066} 2067 2068void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2069 mOutputFormat = new MetaData; 2070 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2071 2072 OMX_PARAM_PORTDEFINITIONTYPE def; 2073 def.nSize = sizeof(def); 2074 def.nVersion.s.nVersionMajor = 1; 2075 def.nVersion.s.nVersionMinor = 1; 2076 def.nPortIndex = kPortIndexOutput; 2077 2078 status_t err = mOMX->get_parameter( 2079 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2080 CHECK_EQ(err, OK); 2081 2082 switch (def.eDomain) { 2083 case OMX_PortDomainImage: 2084 { 2085 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2086 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2087 2088 mOutputFormat->setCString(kKeyMIMEType, "image/raw"); 2089 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2090 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2091 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2092 break; 2093 } 2094 2095 case OMX_PortDomainAudio: 2096 { 2097 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2098 2099 CHECK_EQ(audio_def->eEncoding, OMX_AUDIO_CodingPCM); 2100 2101 OMX_AUDIO_PARAM_PCMMODETYPE params; 2102 params.nSize = sizeof(params); 2103 params.nVersion.s.nVersionMajor = 1; 2104 params.nVersion.s.nVersionMinor = 1; 2105 params.nPortIndex = kPortIndexOutput; 2106 2107 err = mOMX->get_parameter( 2108 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2109 CHECK_EQ(err, OK); 2110 2111 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2112 CHECK_EQ(params.nBitPerSample, 16); 2113 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2114 2115 int32_t numChannels, sampleRate; 2116 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2117 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2118 2119 mOutputFormat->setCString(kKeyMIMEType, "audio/raw"); 2120 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 2121 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2122 break; 2123 } 2124 2125 case OMX_PortDomainVideo: 2126 { 2127 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2128 2129 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2130 mOutputFormat->setCString(kKeyMIMEType, "video/raw"); 2131 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2132 mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es"); 2133 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2134 mOutputFormat->setCString(kKeyMIMEType, "video/3gpp"); 2135 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2136 mOutputFormat->setCString(kKeyMIMEType, "video/avc"); 2137 } else { 2138 CHECK(!"Unknown compression format."); 2139 } 2140 2141 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2142 // This component appears to be lying to me. 2143 mOutputFormat->setInt32( 2144 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2145 mOutputFormat->setInt32( 2146 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2147 } else { 2148 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2149 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2150 } 2151 2152 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2153 break; 2154 } 2155 2156 default: 2157 { 2158 CHECK(!"should not be here, neither audio nor video."); 2159 break; 2160 } 2161 } 2162} 2163 2164} // namespace android 2165