OMXCodec.cpp revision 284f513a4ce2c5aa0e250c07c873731aedb0be26
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#if 1 503 if (!strcmp("OMX.TI.Video.Decoder", mComponentName) 504 && !strcasecmp("video/avc", mime)) { 505 OMX_PARAM_COMPONENTROLETYPE role; 506 role.nSize = sizeof(role); 507 role.nVersion.s.nVersionMajor = 1; 508 role.nVersion.s.nVersionMinor = 1; 509 strncpy((char *)role.cRole, "video_decoder.avc", 510 OMX_MAX_STRINGNAME_SIZE - 1); 511 role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 512 513 status_t err = mOMX->set_parameter( 514 mNode, OMX_IndexParamStandardComponentRole, 515 &role, sizeof(role)); 516 CHECK_EQ(err, OK); 517 } 518#endif 519 520 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 521 if (!strcasecmp("video/avc", mime)) { 522 compressionFormat = OMX_VIDEO_CodingAVC; 523 } else if (!strcasecmp("video/mp4v-es", mime)) { 524 compressionFormat = OMX_VIDEO_CodingMPEG4; 525 } else if (!strcasecmp("video/3gpp", mime)) { 526 compressionFormat = OMX_VIDEO_CodingH263; 527 } else { 528 LOGE("Not a supported video mime type: %s", mime); 529 CHECK(!"Should not be here. Not a supported video mime type."); 530 } 531 532 setVideoPortFormatType( 533 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 534 535#if 1 536 { 537 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 538 format.nSize = sizeof(format); 539 format.nVersion.s.nVersionMajor = 1; 540 format.nVersion.s.nVersionMinor = 1; 541 format.nPortIndex = kPortIndexOutput; 542 format.nIndex = 0; 543 544 status_t err = mOMX->get_parameter( 545 mNode, OMX_IndexParamVideoPortFormat, 546 &format, sizeof(format)); 547 CHECK_EQ(err, OK); 548 CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused); 549 550 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 551 552 CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 553 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 554 || format.eColorFormat == OMX_COLOR_FormatCbYCrY 555 || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 556 557 err = mOMX->set_parameter( 558 mNode, OMX_IndexParamVideoPortFormat, 559 &format, sizeof(format)); 560 CHECK_EQ(err, OK); 561 } 562#endif 563 564 OMX_PARAM_PORTDEFINITIONTYPE def; 565 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 566 567 def.nSize = sizeof(def); 568 def.nVersion.s.nVersionMajor = 1; 569 def.nVersion.s.nVersionMinor = 1; 570 def.nPortIndex = kPortIndexInput; 571 572 status_t err = mOMX->get_parameter( 573 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 574 575 CHECK_EQ(err, OK); 576 577#if 1 578 // XXX Need a (much) better heuristic to compute input buffer sizes. 579 const size_t X = 64 * 1024; 580 if (def.nBufferSize < X) { 581 def.nBufferSize = X; 582 } 583#endif 584 585 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 586 587 video_def->nFrameWidth = width; 588 video_def->nFrameHeight = height; 589 590 video_def->eColorFormat = OMX_COLOR_FormatUnused; 591 592 err = mOMX->set_parameter( 593 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 594 CHECK_EQ(err, OK); 595 596 //////////////////////////////////////////////////////////////////////////// 597 598 def.nSize = sizeof(def); 599 def.nVersion.s.nVersionMajor = 1; 600 def.nVersion.s.nVersionMinor = 1; 601 def.nPortIndex = kPortIndexOutput; 602 603 err = mOMX->get_parameter( 604 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 605 CHECK_EQ(err, OK); 606 CHECK_EQ(def.eDomain, OMX_PortDomainVideo); 607 608#if 0 609 def.nBufferSize = 610 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 611#endif 612 613 video_def->nFrameWidth = width; 614 video_def->nFrameHeight = height; 615 616 err = mOMX->set_parameter( 617 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 618 CHECK_EQ(err, OK); 619} 620 621 622OMXCodec::OMXCodec( 623 const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, 624 bool isEncoder, 625 const char *mime, 626 const char *componentName, 627 const sp<MediaSource> &source) 628 : mOMX(omx), 629 mNode(node), 630 mQuirks(quirks), 631 mIsEncoder(isEncoder), 632 mMIME(strdup(mime)), 633 mComponentName(strdup(componentName)), 634 mSource(source), 635 mCodecSpecificDataIndex(0), 636 mState(LOADED), 637 mInitialBufferSubmit(true), 638 mSignalledEOS(false), 639 mNoMoreOutputData(false), 640 mSeekTimeUs(-1) { 641 mPortStatus[kPortIndexInput] = ENABLED; 642 mPortStatus[kPortIndexOutput] = ENABLED; 643 644 mObserver = new OMXCodecObserver(this); 645 mOMX->observe_node(mNode, mObserver); 646} 647 648OMXCodec::~OMXCodec() { 649 CHECK(mState == LOADED || mState == ERROR); 650 651 status_t err = mOMX->observe_node(mNode, NULL); 652 CHECK_EQ(err, OK); 653 654 err = mOMX->free_node(mNode); 655 CHECK_EQ(err, OK); 656 657 mNode = NULL; 658 setState(DEAD); 659 660 clearCodecSpecificData(); 661 662 free(mComponentName); 663 mComponentName = NULL; 664 665 free(mMIME); 666 mMIME = NULL; 667} 668 669status_t OMXCodec::init() { 670 // mLock is held. 671 672 CHECK_EQ(mState, LOADED); 673 674 status_t err; 675 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 676 err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 677 CHECK_EQ(err, OK); 678 679 setState(LOADED_TO_IDLE); 680 } 681 682 err = allocateBuffers(); 683 CHECK_EQ(err, OK); 684 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 while (mState != EXECUTING && mState != ERROR) { 693 mAsyncCompletion.wait(mLock); 694 } 695 696 return mState == ERROR ? UNKNOWN_ERROR : OK; 697} 698 699// static 700bool OMXCodec::isIntermediateState(State state) { 701 return state == LOADED_TO_IDLE 702 || state == IDLE_TO_EXECUTING 703 || state == EXECUTING_TO_IDLE 704 || state == IDLE_TO_LOADED 705 || state == RECONFIGURING; 706} 707 708status_t OMXCodec::allocateBuffers() { 709 status_t err = allocateBuffersOnPort(kPortIndexInput); 710 711 if (err != OK) { 712 return err; 713 } 714 715 return allocateBuffersOnPort(kPortIndexOutput); 716} 717 718status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 719 OMX_PARAM_PORTDEFINITIONTYPE def; 720 def.nSize = sizeof(def); 721 def.nVersion.s.nVersionMajor = 1; 722 def.nVersion.s.nVersionMinor = 1; 723 def.nVersion.s.nRevision = 0; 724 def.nVersion.s.nStep = 0; 725 def.nPortIndex = portIndex; 726 727 status_t err = mOMX->get_parameter( 728 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 729 730 if (err != OK) { 731 return err; 732 } 733 734 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 735 mDealer[portIndex] = new MemoryDealer(totalSize); 736 737 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 738 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 739 CHECK(mem.get() != NULL); 740 741 IOMX::buffer_id buffer; 742 if (portIndex == kPortIndexInput 743 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) { 744 err = mOMX->allocate_buffer_with_backup( 745 mNode, portIndex, mem, &buffer); 746 } else if (portIndex == kPortIndexOutput 747 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 748 err = mOMX->allocate_buffer( 749 mNode, portIndex, def.nBufferSize, &buffer); 750 } else { 751 err = mOMX->use_buffer(mNode, portIndex, mem, &buffer); 752 } 753 754 if (err != OK) { 755 LOGE("allocate_buffer_with_backup failed"); 756 return err; 757 } 758 759 BufferInfo info; 760 info.mBuffer = buffer; 761 info.mOwnedByComponent = false; 762 info.mMem = mem; 763 info.mMediaBuffer = NULL; 764 765 if (portIndex == kPortIndexOutput) { 766 info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size()); 767 info.mMediaBuffer->setObserver(this); 768 } 769 770 mPortBuffers[portIndex].push(info); 771 772 LOGV("allocated buffer %p on %s port", buffer, 773 portIndex == kPortIndexInput ? "input" : "output"); 774 } 775 776 dumpPortStatus(portIndex); 777 778 return OK; 779} 780 781void OMXCodec::on_message(const omx_message &msg) { 782 Mutex::Autolock autoLock(mLock); 783 784 switch (msg.type) { 785 case omx_message::EVENT: 786 { 787 onEvent( 788 msg.u.event_data.event, msg.u.event_data.data1, 789 msg.u.event_data.data2); 790 791 break; 792 } 793 794 case omx_message::EMPTY_BUFFER_DONE: 795 { 796 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 797 798 LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 799 800 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 801 size_t i = 0; 802 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 803 ++i; 804 } 805 806 CHECK(i < buffers->size()); 807 if (!(*buffers)[i].mOwnedByComponent) { 808 LOGW("We already own input buffer %p, yet received " 809 "an EMPTY_BUFFER_DONE.", buffer); 810 } 811 812 buffers->editItemAt(i).mOwnedByComponent = false; 813 814 if (mPortStatus[kPortIndexInput] == DISABLING) { 815 LOGV("Port is disabled, freeing buffer %p", buffer); 816 817 status_t err = 818 mOMX->free_buffer(mNode, kPortIndexInput, buffer); 819 CHECK_EQ(err, OK); 820 821 buffers->removeAt(i); 822 } else if (mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 823 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED); 824 drainInputBuffer(&buffers->editItemAt(i)); 825 } 826 827 break; 828 } 829 830 case omx_message::FILL_BUFFER_DONE: 831 { 832 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 833 OMX_U32 flags = msg.u.extended_buffer_data.flags; 834 835 LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)", 836 buffer, 837 msg.u.extended_buffer_data.range_length, 838 flags); 839 840 LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))", 841 msg.u.extended_buffer_data.timestamp, 842 msg.u.extended_buffer_data.timestamp / 1E6); 843 844 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 845 size_t i = 0; 846 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 847 ++i; 848 } 849 850 CHECK(i < buffers->size()); 851 BufferInfo *info = &buffers->editItemAt(i); 852 853 if (!info->mOwnedByComponent) { 854 LOGW("We already own output buffer %p, yet received " 855 "a FILL_BUFFER_DONE.", buffer); 856 } 857 858 info->mOwnedByComponent = false; 859 860 if (mPortStatus[kPortIndexOutput] == DISABLING) { 861 LOGV("Port is disabled, freeing buffer %p", buffer); 862 863 status_t err = 864 mOMX->free_buffer(mNode, kPortIndexOutput, buffer); 865 CHECK_EQ(err, OK); 866 867 buffers->removeAt(i); 868 } else if (mPortStatus[kPortIndexOutput] == ENABLED 869 && (flags & OMX_BUFFERFLAG_EOS)) { 870 LOGV("No more output data."); 871 mNoMoreOutputData = true; 872 mBufferFilled.signal(); 873 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 874 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 875 876 MediaBuffer *buffer = info->mMediaBuffer; 877 878 buffer->set_range( 879 msg.u.extended_buffer_data.range_offset, 880 msg.u.extended_buffer_data.range_length); 881 882 buffer->meta_data()->clear(); 883 884 buffer->meta_data()->setInt32( 885 kKeyTimeUnits, 886 (msg.u.extended_buffer_data.timestamp + 500) / 1000); 887 888 buffer->meta_data()->setInt32( 889 kKeyTimeScale, 1000); 890 891 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 892 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 893 } 894 895 buffer->meta_data()->setPointer( 896 kKeyPlatformPrivate, 897 msg.u.extended_buffer_data.platform_private); 898 899 buffer->meta_data()->setPointer( 900 kKeyBufferID, 901 msg.u.extended_buffer_data.buffer); 902 903 mFilledBuffers.push_back(i); 904 mBufferFilled.signal(); 905 } 906 907 break; 908 } 909 910 default: 911 { 912 CHECK(!"should not be here."); 913 break; 914 } 915 } 916} 917 918void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 919 switch (event) { 920 case OMX_EventCmdComplete: 921 { 922 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 923 break; 924 } 925 926 case OMX_EventError: 927 { 928 LOGE("ERROR(%ld, %ld)", data1, data2); 929 930 setState(ERROR); 931 break; 932 } 933 934 case OMX_EventPortSettingsChanged: 935 { 936 onPortSettingsChanged(data1); 937 break; 938 } 939 940 case OMX_EventBufferFlag: 941 { 942 LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 943 944 if (data1 == kPortIndexOutput) { 945 mNoMoreOutputData = true; 946 } 947 break; 948 } 949 950 default: 951 { 952 LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 953 break; 954 } 955 } 956} 957 958void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 959 switch (cmd) { 960 case OMX_CommandStateSet: 961 { 962 onStateChange((OMX_STATETYPE)data); 963 break; 964 } 965 966 case OMX_CommandPortDisable: 967 { 968 OMX_U32 portIndex = data; 969 LOGV("PORT_DISABLED(%ld)", portIndex); 970 971 CHECK(mState == EXECUTING || mState == RECONFIGURING); 972 CHECK_EQ(mPortStatus[portIndex], DISABLING); 973 CHECK_EQ(mPortBuffers[portIndex].size(), 0); 974 975 mPortStatus[portIndex] = DISABLED; 976 977 if (mState == RECONFIGURING) { 978 CHECK_EQ(portIndex, kPortIndexOutput); 979 980 enablePortAsync(portIndex); 981 982 status_t err = allocateBuffersOnPort(portIndex); 983 CHECK_EQ(err, OK); 984 } 985 break; 986 } 987 988 case OMX_CommandPortEnable: 989 { 990 OMX_U32 portIndex = data; 991 LOGV("PORT_ENABLED(%ld)", portIndex); 992 993 CHECK(mState == EXECUTING || mState == RECONFIGURING); 994 CHECK_EQ(mPortStatus[portIndex], ENABLING); 995 996 mPortStatus[portIndex] = ENABLED; 997 998 if (mState == RECONFIGURING) { 999 CHECK_EQ(portIndex, kPortIndexOutput); 1000 1001 setState(EXECUTING); 1002 1003 fillOutputBuffers(); 1004 } 1005 break; 1006 } 1007 1008 case OMX_CommandFlush: 1009 { 1010 OMX_U32 portIndex = data; 1011 1012 LOGV("FLUSH_DONE(%ld)", portIndex); 1013 1014 CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); 1015 mPortStatus[portIndex] = ENABLED; 1016 1017 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 1018 mPortBuffers[portIndex].size()); 1019 1020 if (mState == RECONFIGURING) { 1021 CHECK_EQ(portIndex, kPortIndexOutput); 1022 1023 disablePortAsync(portIndex); 1024 } else if (mState == EXECUTING_TO_IDLE) { 1025 if (mPortStatus[kPortIndexInput] == ENABLED 1026 && mPortStatus[kPortIndexOutput] == ENABLED) { 1027 LOGV("Finished flushing both ports, now completing " 1028 "transition from EXECUTING to IDLE."); 1029 1030 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1031 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1032 1033 status_t err = 1034 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 1035 CHECK_EQ(err, OK); 1036 } 1037 } else { 1038 // We're flushing both ports in preparation for seeking. 1039 1040 if (mPortStatus[kPortIndexInput] == ENABLED 1041 && mPortStatus[kPortIndexOutput] == ENABLED) { 1042 LOGV("Finished flushing both ports, now continuing from" 1043 " seek-time."); 1044 1045 drainInputBuffers(); 1046 fillOutputBuffers(); 1047 } 1048 } 1049 1050 break; 1051 } 1052 1053 default: 1054 { 1055 LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1056 break; 1057 } 1058 } 1059} 1060 1061void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1062 switch (newState) { 1063 case OMX_StateIdle: 1064 { 1065 LOGV("Now Idle."); 1066 if (mState == LOADED_TO_IDLE) { 1067 status_t err = mOMX->send_command( 1068 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1069 1070 CHECK_EQ(err, OK); 1071 1072 setState(IDLE_TO_EXECUTING); 1073 } else { 1074 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1075 1076 CHECK_EQ( 1077 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1078 mPortBuffers[kPortIndexInput].size()); 1079 1080 CHECK_EQ( 1081 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1082 mPortBuffers[kPortIndexOutput].size()); 1083 1084 status_t err = mOMX->send_command( 1085 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1086 1087 CHECK_EQ(err, OK); 1088 1089 err = freeBuffersOnPort(kPortIndexInput); 1090 CHECK_EQ(err, OK); 1091 1092 err = freeBuffersOnPort(kPortIndexOutput); 1093 CHECK_EQ(err, OK); 1094 1095 mPortStatus[kPortIndexInput] = ENABLED; 1096 mPortStatus[kPortIndexOutput] = ENABLED; 1097 1098 setState(IDLE_TO_LOADED); 1099 } 1100 break; 1101 } 1102 1103 case OMX_StateExecuting: 1104 { 1105 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1106 1107 LOGV("Now Executing."); 1108 1109 setState(EXECUTING); 1110 1111 // Buffers will be submitted to the component in the first 1112 // call to OMXCodec::read as mInitialBufferSubmit is true at 1113 // this point. This ensures that this on_message call returns, 1114 // releases the lock and ::init can notice the state change and 1115 // itself return. 1116 break; 1117 } 1118 1119 case OMX_StateLoaded: 1120 { 1121 CHECK_EQ(mState, IDLE_TO_LOADED); 1122 1123 LOGV("Now Loaded."); 1124 1125 setState(LOADED); 1126 break; 1127 } 1128 1129 default: 1130 { 1131 CHECK(!"should not be here."); 1132 break; 1133 } 1134 } 1135} 1136 1137// static 1138size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1139 size_t n = 0; 1140 for (size_t i = 0; i < buffers.size(); ++i) { 1141 if (!buffers[i].mOwnedByComponent) { 1142 ++n; 1143 } 1144 } 1145 1146 return n; 1147} 1148 1149status_t OMXCodec::freeBuffersOnPort( 1150 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1151 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1152 1153 status_t stickyErr = OK; 1154 1155 for (size_t i = buffers->size(); i-- > 0;) { 1156 BufferInfo *info = &buffers->editItemAt(i); 1157 1158 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1159 continue; 1160 } 1161 1162 CHECK_EQ(info->mOwnedByComponent, false); 1163 1164 status_t err = 1165 mOMX->free_buffer(mNode, portIndex, info->mBuffer); 1166 1167 if (err != OK) { 1168 stickyErr = err; 1169 } 1170 1171 if (info->mMediaBuffer != NULL) { 1172 info->mMediaBuffer->setObserver(NULL); 1173 1174 // Make sure nobody but us owns this buffer at this point. 1175 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1176 1177 info->mMediaBuffer->release(); 1178 } 1179 1180 buffers->removeAt(i); 1181 } 1182 1183 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1184 1185 return stickyErr; 1186} 1187 1188void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1189 LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1190 1191 CHECK_EQ(mState, EXECUTING); 1192 CHECK_EQ(portIndex, kPortIndexOutput); 1193 setState(RECONFIGURING); 1194 1195 if (mQuirks & kNeedsFlushBeforeDisable) { 1196 if (!flushPortAsync(portIndex)) { 1197 onCmdComplete(OMX_CommandFlush, portIndex); 1198 } 1199 } else { 1200 disablePortAsync(portIndex); 1201 } 1202} 1203 1204bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1205 CHECK(mState == EXECUTING || mState == RECONFIGURING 1206 || mState == EXECUTING_TO_IDLE); 1207 1208 LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1209 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1210 mPortBuffers[portIndex].size()); 1211 1212 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1213 mPortStatus[portIndex] = SHUTTING_DOWN; 1214 1215 if ((mQuirks & kRequiresFlushCompleteEmulation) 1216 && countBuffersWeOwn(mPortBuffers[portIndex]) 1217 == mPortBuffers[portIndex].size()) { 1218 // No flush is necessary and this component fails to send a 1219 // flush-complete event in this case. 1220 1221 return false; 1222 } 1223 1224 status_t err = 1225 mOMX->send_command(mNode, OMX_CommandFlush, portIndex); 1226 CHECK_EQ(err, OK); 1227 1228 return true; 1229} 1230 1231void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1232 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1233 1234 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1235 mPortStatus[portIndex] = DISABLING; 1236 1237 status_t err = 1238 mOMX->send_command(mNode, OMX_CommandPortDisable, portIndex); 1239 CHECK_EQ(err, OK); 1240 1241 freeBuffersOnPort(portIndex, true); 1242} 1243 1244void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1245 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1246 1247 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1248 mPortStatus[portIndex] = ENABLING; 1249 1250 status_t err = 1251 mOMX->send_command(mNode, OMX_CommandPortEnable, portIndex); 1252 CHECK_EQ(err, OK); 1253} 1254 1255void OMXCodec::fillOutputBuffers() { 1256 CHECK_EQ(mState, EXECUTING); 1257 1258 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1259 for (size_t i = 0; i < buffers->size(); ++i) { 1260 fillOutputBuffer(&buffers->editItemAt(i)); 1261 } 1262} 1263 1264void OMXCodec::drainInputBuffers() { 1265 CHECK_EQ(mState, EXECUTING); 1266 1267 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1268 for (size_t i = 0; i < buffers->size(); ++i) { 1269 drainInputBuffer(&buffers->editItemAt(i)); 1270 } 1271} 1272 1273void OMXCodec::drainInputBuffer(BufferInfo *info) { 1274 CHECK_EQ(info->mOwnedByComponent, false); 1275 1276 if (mSignalledEOS) { 1277 return; 1278 } 1279 1280 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 1281 const CodecSpecificData *specific = 1282 mCodecSpecificData[mCodecSpecificDataIndex]; 1283 1284 size_t size = specific->mSize; 1285 1286 if (!strcasecmp("video/avc", mMIME) 1287 && !(mQuirks & kWantsNALFragments)) { 1288 static const uint8_t kNALStartCode[4] = 1289 { 0x00, 0x00, 0x00, 0x01 }; 1290 1291 CHECK(info->mMem->size() >= specific->mSize + 4); 1292 1293 size += 4; 1294 1295 memcpy(info->mMem->pointer(), kNALStartCode, 4); 1296 memcpy((uint8_t *)info->mMem->pointer() + 4, 1297 specific->mData, specific->mSize); 1298 } else { 1299 CHECK(info->mMem->size() >= specific->mSize); 1300 memcpy(info->mMem->pointer(), specific->mData, specific->mSize); 1301 } 1302 1303 mOMX->empty_buffer( 1304 mNode, info->mBuffer, 0, size, 1305 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 1306 0); 1307 1308 info->mOwnedByComponent = true; 1309 1310 ++mCodecSpecificDataIndex; 1311 return; 1312 } 1313 1314 MediaBuffer *srcBuffer; 1315 status_t err; 1316 if (mSeekTimeUs >= 0) { 1317 MediaSource::ReadOptions options; 1318 options.setSeekTo(mSeekTimeUs); 1319 mSeekTimeUs = -1; 1320 1321 err = mSource->read(&srcBuffer, &options); 1322 } else { 1323 err = mSource->read(&srcBuffer); 1324 } 1325 1326 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1327 OMX_TICKS timestamp = 0; 1328 size_t srcLength = 0; 1329 1330 if (err != OK) { 1331 LOGV("signalling end of input stream."); 1332 flags |= OMX_BUFFERFLAG_EOS; 1333 1334 mSignalledEOS = true; 1335 } else { 1336 srcLength = srcBuffer->range_length(); 1337 1338 if (info->mMem->size() < srcLength) { 1339 LOGE("info->mMem->size() = %d, srcLength = %d", 1340 info->mMem->size(), srcLength); 1341 } 1342 CHECK(info->mMem->size() >= srcLength); 1343 memcpy(info->mMem->pointer(), 1344 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1345 srcLength); 1346 1347 int32_t units, scale; 1348 if (srcBuffer->meta_data()->findInt32(kKeyTimeUnits, &units) 1349 && srcBuffer->meta_data()->findInt32(kKeyTimeScale, &scale)) { 1350 timestamp = ((OMX_TICKS)units * 1000000) / scale; 1351 1352 LOGV("Calling empty_buffer on buffer %p (length %d)", 1353 info->mBuffer, srcLength); 1354 LOGV("Calling empty_buffer with timestamp %lld us (%.2f secs)", 1355 timestamp, timestamp / 1E6); 1356 } 1357 } 1358 1359 mOMX->empty_buffer( 1360 mNode, info->mBuffer, 0, srcLength, 1361 flags, timestamp); 1362 1363 info->mOwnedByComponent = true; 1364 1365 if (srcBuffer != NULL) { 1366 srcBuffer->release(); 1367 srcBuffer = NULL; 1368 } 1369} 1370 1371void OMXCodec::fillOutputBuffer(BufferInfo *info) { 1372 CHECK_EQ(info->mOwnedByComponent, false); 1373 1374 if (mNoMoreOutputData) { 1375 LOGV("There is no more output data available, not " 1376 "calling fillOutputBuffer"); 1377 return; 1378 } 1379 1380 LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 1381 mOMX->fill_buffer(mNode, info->mBuffer); 1382 1383 info->mOwnedByComponent = true; 1384} 1385 1386void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 1387 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1388 for (size_t i = 0; i < buffers->size(); ++i) { 1389 if ((*buffers)[i].mBuffer == buffer) { 1390 drainInputBuffer(&buffers->editItemAt(i)); 1391 return; 1392 } 1393 } 1394 1395 CHECK(!"should not be here."); 1396} 1397 1398void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 1399 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1400 for (size_t i = 0; i < buffers->size(); ++i) { 1401 if ((*buffers)[i].mBuffer == buffer) { 1402 fillOutputBuffer(&buffers->editItemAt(i)); 1403 return; 1404 } 1405 } 1406 1407 CHECK(!"should not be here."); 1408} 1409 1410void OMXCodec::setState(State newState) { 1411 mState = newState; 1412 mAsyncCompletion.signal(); 1413 1414 // This may cause some spurious wakeups but is necessary to 1415 // unblock the reader if we enter ERROR state. 1416 mBufferFilled.signal(); 1417} 1418 1419void OMXCodec::setAMRFormat() { 1420 if (!mIsEncoder) { 1421 OMX_AUDIO_PARAM_AMRTYPE def; 1422 def.nSize = sizeof(def); 1423 def.nVersion.s.nVersionMajor = 1; 1424 def.nVersion.s.nVersionMinor = 1; 1425 def.nPortIndex = kPortIndexInput; 1426 1427 status_t err = 1428 mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1429 1430 CHECK_EQ(err, OK); 1431 1432 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 1433 def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; 1434 1435 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1436 CHECK_EQ(err, OK); 1437 } 1438 1439 //////////////////////// 1440 1441 if (mIsEncoder) { 1442 sp<MetaData> format = mSource->getFormat(); 1443 int32_t sampleRate; 1444 int32_t numChannels; 1445 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 1446 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 1447 1448 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 1449 pcmParams.nSize = sizeof(pcmParams); 1450 pcmParams.nVersion.s.nVersionMajor = 1; 1451 pcmParams.nVersion.s.nVersionMinor = 1; 1452 pcmParams.nPortIndex = kPortIndexInput; 1453 1454 status_t err = mOMX->get_parameter( 1455 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1456 1457 CHECK_EQ(err, OK); 1458 1459 pcmParams.nChannels = numChannels; 1460 pcmParams.eNumData = OMX_NumericalDataSigned; 1461 pcmParams.bInterleaved = OMX_TRUE; 1462 pcmParams.nBitPerSample = 16; 1463 pcmParams.nSamplingRate = sampleRate; 1464 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 1465 1466 if (numChannels == 1) { 1467 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 1468 } else { 1469 CHECK_EQ(numChannels, 2); 1470 1471 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 1472 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 1473 } 1474 1475 err = mOMX->set_parameter( 1476 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1477 1478 CHECK_EQ(err, OK); 1479 } 1480} 1481 1482void OMXCodec::setAACFormat() { 1483 OMX_AUDIO_PARAM_AACPROFILETYPE def; 1484 def.nSize = sizeof(def); 1485 def.nVersion.s.nVersionMajor = 1; 1486 def.nVersion.s.nVersionMinor = 1; 1487 def.nPortIndex = kPortIndexInput; 1488 1489 status_t err = 1490 mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def)); 1491 CHECK_EQ(err, OK); 1492 1493 def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 1494 1495 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def)); 1496 CHECK_EQ(err, OK); 1497} 1498 1499void OMXCodec::setImageOutputFormat( 1500 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 1501 LOGV("setImageOutputFormat(%ld, %ld)", width, height); 1502 1503#if 0 1504 OMX_INDEXTYPE index; 1505 status_t err = mOMX->get_extension_index( 1506 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 1507 CHECK_EQ(err, OK); 1508 1509 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 1510 CHECK_EQ(err, OK); 1511#endif 1512 1513 OMX_PARAM_PORTDEFINITIONTYPE def; 1514 def.nSize = sizeof(def); 1515 def.nVersion.s.nVersionMajor = 1; 1516 def.nVersion.s.nVersionMinor = 1; 1517 def.nPortIndex = kPortIndexOutput; 1518 1519 status_t err = mOMX->get_parameter( 1520 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1521 CHECK_EQ(err, OK); 1522 1523 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 1524 1525 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1526 1527 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 1528 imageDef->eColorFormat = format; 1529 imageDef->nFrameWidth = width; 1530 imageDef->nFrameHeight = height; 1531 1532 switch (format) { 1533 case OMX_COLOR_FormatYUV420PackedPlanar: 1534 case OMX_COLOR_FormatYUV411Planar: 1535 { 1536 def.nBufferSize = (width * height * 3) / 2; 1537 break; 1538 } 1539 1540 case OMX_COLOR_FormatCbYCrY: 1541 { 1542 def.nBufferSize = width * height * 2; 1543 break; 1544 } 1545 1546 case OMX_COLOR_Format32bitARGB8888: 1547 { 1548 def.nBufferSize = width * height * 4; 1549 break; 1550 } 1551 1552 default: 1553 CHECK(!"Should not be here. Unknown color format."); 1554 break; 1555 } 1556 1557 def.nBufferCountActual = def.nBufferCountMin; 1558 1559 err = mOMX->set_parameter( 1560 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1561 CHECK_EQ(err, OK); 1562} 1563 1564void OMXCodec::setJPEGInputFormat( 1565 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 1566 OMX_PARAM_PORTDEFINITIONTYPE def; 1567 def.nSize = sizeof(def); 1568 def.nVersion.s.nVersionMajor = 1; 1569 def.nVersion.s.nVersionMinor = 1; 1570 def.nPortIndex = kPortIndexInput; 1571 1572 status_t err = mOMX->get_parameter( 1573 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1574 CHECK_EQ(err, OK); 1575 1576 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 1577 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1578 1579 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 1580 imageDef->nFrameWidth = width; 1581 imageDef->nFrameHeight = height; 1582 1583 def.nBufferSize = compressedSize; 1584 def.nBufferCountActual = def.nBufferCountMin; 1585 1586 err = mOMX->set_parameter( 1587 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1588 CHECK_EQ(err, OK); 1589} 1590 1591void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 1592 CodecSpecificData *specific = 1593 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 1594 1595 specific->mSize = size; 1596 memcpy(specific->mData, data, size); 1597 1598 mCodecSpecificData.push(specific); 1599} 1600 1601void OMXCodec::clearCodecSpecificData() { 1602 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 1603 free(mCodecSpecificData.editItemAt(i)); 1604 } 1605 mCodecSpecificData.clear(); 1606 mCodecSpecificDataIndex = 0; 1607} 1608 1609status_t OMXCodec::start(MetaData *) { 1610 Mutex::Autolock autoLock(mLock); 1611 1612 if (mState != LOADED) { 1613 return UNKNOWN_ERROR; 1614 } 1615 1616 sp<MetaData> params = new MetaData; 1617 if (mQuirks & kWantsNALFragments) { 1618 params->setInt32(kKeyWantsNALFragments, true); 1619 } 1620 status_t err = mSource->start(params.get()); 1621 1622 if (err != OK) { 1623 return err; 1624 } 1625 1626 mCodecSpecificDataIndex = 0; 1627 mInitialBufferSubmit = true; 1628 mSignalledEOS = false; 1629 mNoMoreOutputData = false; 1630 mSeekTimeUs = -1; 1631 mFilledBuffers.clear(); 1632 1633 return init(); 1634} 1635 1636status_t OMXCodec::stop() { 1637 LOGV("stop"); 1638 1639 Mutex::Autolock autoLock(mLock); 1640 1641 while (isIntermediateState(mState)) { 1642 mAsyncCompletion.wait(mLock); 1643 } 1644 1645 switch (mState) { 1646 case LOADED: 1647 case ERROR: 1648 break; 1649 1650 case EXECUTING: 1651 { 1652 setState(EXECUTING_TO_IDLE); 1653 1654 if (mQuirks & kRequiresFlushBeforeShutdown) { 1655 LOGV("This component requires a flush before transitioning " 1656 "from EXECUTING to IDLE..."); 1657 1658 bool emulateInputFlushCompletion = 1659 !flushPortAsync(kPortIndexInput); 1660 1661 bool emulateOutputFlushCompletion = 1662 !flushPortAsync(kPortIndexOutput); 1663 1664 if (emulateInputFlushCompletion) { 1665 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 1666 } 1667 1668 if (emulateOutputFlushCompletion) { 1669 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 1670 } 1671 } else { 1672 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1673 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1674 1675 status_t err = 1676 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 1677 CHECK_EQ(err, OK); 1678 } 1679 1680 while (mState != LOADED && mState != ERROR) { 1681 mAsyncCompletion.wait(mLock); 1682 } 1683 1684 break; 1685 } 1686 1687 default: 1688 { 1689 CHECK(!"should not be here."); 1690 break; 1691 } 1692 } 1693 1694 mSource->stop(); 1695 1696 return OK; 1697} 1698 1699sp<MetaData> OMXCodec::getFormat() { 1700 return mOutputFormat; 1701} 1702 1703status_t OMXCodec::read( 1704 MediaBuffer **buffer, const ReadOptions *options) { 1705 *buffer = NULL; 1706 1707 Mutex::Autolock autoLock(mLock); 1708 1709 if (mInitialBufferSubmit) { 1710 mInitialBufferSubmit = false; 1711 1712 drainInputBuffers(); 1713 fillOutputBuffers(); 1714 } 1715 1716 if (mState != EXECUTING && mState != RECONFIGURING) { 1717 return UNKNOWN_ERROR; 1718 } 1719 1720 int64_t seekTimeUs; 1721 if (options && options->getSeekTo(&seekTimeUs)) { 1722 LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 1723 1724 mSignalledEOS = false; 1725 mNoMoreOutputData = false; 1726 1727 CHECK(seekTimeUs >= 0); 1728 mSeekTimeUs = seekTimeUs; 1729 1730 mFilledBuffers.clear(); 1731 1732 CHECK_EQ(mState, EXECUTING); 1733 1734 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 1735 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 1736 1737 if (emulateInputFlushCompletion) { 1738 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 1739 } 1740 1741 if (emulateOutputFlushCompletion) { 1742 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 1743 } 1744 } 1745 1746 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 1747 mBufferFilled.wait(mLock); 1748 } 1749 1750 if (mState == ERROR) { 1751 return UNKNOWN_ERROR; 1752 } 1753 1754 if (mFilledBuffers.empty()) { 1755 return ERROR_END_OF_STREAM; 1756 } 1757 1758 size_t index = *mFilledBuffers.begin(); 1759 mFilledBuffers.erase(mFilledBuffers.begin()); 1760 1761 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1762 info->mMediaBuffer->add_ref(); 1763 *buffer = info->mMediaBuffer; 1764 1765 return OK; 1766} 1767 1768void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 1769 Mutex::Autolock autoLock(mLock); 1770 1771 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1772 for (size_t i = 0; i < buffers->size(); ++i) { 1773 BufferInfo *info = &buffers->editItemAt(i); 1774 1775 if (info->mMediaBuffer == buffer) { 1776 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1777 fillOutputBuffer(info); 1778 return; 1779 } 1780 } 1781 1782 CHECK(!"should not be here."); 1783} 1784 1785static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 1786 static const char *kNames[] = { 1787 "OMX_IMAGE_CodingUnused", 1788 "OMX_IMAGE_CodingAutoDetect", 1789 "OMX_IMAGE_CodingJPEG", 1790 "OMX_IMAGE_CodingJPEG2K", 1791 "OMX_IMAGE_CodingEXIF", 1792 "OMX_IMAGE_CodingTIFF", 1793 "OMX_IMAGE_CodingGIF", 1794 "OMX_IMAGE_CodingPNG", 1795 "OMX_IMAGE_CodingLZW", 1796 "OMX_IMAGE_CodingBMP", 1797 }; 1798 1799 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1800 1801 if (type < 0 || (size_t)type >= numNames) { 1802 return "UNKNOWN"; 1803 } else { 1804 return kNames[type]; 1805 } 1806} 1807 1808static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 1809 static const char *kNames[] = { 1810 "OMX_COLOR_FormatUnused", 1811 "OMX_COLOR_FormatMonochrome", 1812 "OMX_COLOR_Format8bitRGB332", 1813 "OMX_COLOR_Format12bitRGB444", 1814 "OMX_COLOR_Format16bitARGB4444", 1815 "OMX_COLOR_Format16bitARGB1555", 1816 "OMX_COLOR_Format16bitRGB565", 1817 "OMX_COLOR_Format16bitBGR565", 1818 "OMX_COLOR_Format18bitRGB666", 1819 "OMX_COLOR_Format18bitARGB1665", 1820 "OMX_COLOR_Format19bitARGB1666", 1821 "OMX_COLOR_Format24bitRGB888", 1822 "OMX_COLOR_Format24bitBGR888", 1823 "OMX_COLOR_Format24bitARGB1887", 1824 "OMX_COLOR_Format25bitARGB1888", 1825 "OMX_COLOR_Format32bitBGRA8888", 1826 "OMX_COLOR_Format32bitARGB8888", 1827 "OMX_COLOR_FormatYUV411Planar", 1828 "OMX_COLOR_FormatYUV411PackedPlanar", 1829 "OMX_COLOR_FormatYUV420Planar", 1830 "OMX_COLOR_FormatYUV420PackedPlanar", 1831 "OMX_COLOR_FormatYUV420SemiPlanar", 1832 "OMX_COLOR_FormatYUV422Planar", 1833 "OMX_COLOR_FormatYUV422PackedPlanar", 1834 "OMX_COLOR_FormatYUV422SemiPlanar", 1835 "OMX_COLOR_FormatYCbYCr", 1836 "OMX_COLOR_FormatYCrYCb", 1837 "OMX_COLOR_FormatCbYCrY", 1838 "OMX_COLOR_FormatCrYCbY", 1839 "OMX_COLOR_FormatYUV444Interleaved", 1840 "OMX_COLOR_FormatRawBayer8bit", 1841 "OMX_COLOR_FormatRawBayer10bit", 1842 "OMX_COLOR_FormatRawBayer8bitcompressed", 1843 "OMX_COLOR_FormatL2", 1844 "OMX_COLOR_FormatL4", 1845 "OMX_COLOR_FormatL8", 1846 "OMX_COLOR_FormatL16", 1847 "OMX_COLOR_FormatL24", 1848 "OMX_COLOR_FormatL32", 1849 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 1850 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 1851 "OMX_COLOR_Format18BitBGR666", 1852 "OMX_COLOR_Format24BitARGB6666", 1853 "OMX_COLOR_Format24BitABGR6666", 1854 }; 1855 1856 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1857 1858 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 1859 1860 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 1861 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 1862 } else if (type < 0 || (size_t)type >= numNames) { 1863 return "UNKNOWN"; 1864 } else { 1865 return kNames[type]; 1866 } 1867} 1868 1869static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 1870 static const char *kNames[] = { 1871 "OMX_VIDEO_CodingUnused", 1872 "OMX_VIDEO_CodingAutoDetect", 1873 "OMX_VIDEO_CodingMPEG2", 1874 "OMX_VIDEO_CodingH263", 1875 "OMX_VIDEO_CodingMPEG4", 1876 "OMX_VIDEO_CodingWMV", 1877 "OMX_VIDEO_CodingRV", 1878 "OMX_VIDEO_CodingAVC", 1879 "OMX_VIDEO_CodingMJPEG", 1880 }; 1881 1882 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1883 1884 if (type < 0 || (size_t)type >= numNames) { 1885 return "UNKNOWN"; 1886 } else { 1887 return kNames[type]; 1888 } 1889} 1890 1891static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 1892 static const char *kNames[] = { 1893 "OMX_AUDIO_CodingUnused", 1894 "OMX_AUDIO_CodingAutoDetect", 1895 "OMX_AUDIO_CodingPCM", 1896 "OMX_AUDIO_CodingADPCM", 1897 "OMX_AUDIO_CodingAMR", 1898 "OMX_AUDIO_CodingGSMFR", 1899 "OMX_AUDIO_CodingGSMEFR", 1900 "OMX_AUDIO_CodingGSMHR", 1901 "OMX_AUDIO_CodingPDCFR", 1902 "OMX_AUDIO_CodingPDCEFR", 1903 "OMX_AUDIO_CodingPDCHR", 1904 "OMX_AUDIO_CodingTDMAFR", 1905 "OMX_AUDIO_CodingTDMAEFR", 1906 "OMX_AUDIO_CodingQCELP8", 1907 "OMX_AUDIO_CodingQCELP13", 1908 "OMX_AUDIO_CodingEVRC", 1909 "OMX_AUDIO_CodingSMV", 1910 "OMX_AUDIO_CodingG711", 1911 "OMX_AUDIO_CodingG723", 1912 "OMX_AUDIO_CodingG726", 1913 "OMX_AUDIO_CodingG729", 1914 "OMX_AUDIO_CodingAAC", 1915 "OMX_AUDIO_CodingMP3", 1916 "OMX_AUDIO_CodingSBC", 1917 "OMX_AUDIO_CodingVORBIS", 1918 "OMX_AUDIO_CodingWMA", 1919 "OMX_AUDIO_CodingRA", 1920 "OMX_AUDIO_CodingMIDI", 1921 }; 1922 1923 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1924 1925 if (type < 0 || (size_t)type >= numNames) { 1926 return "UNKNOWN"; 1927 } else { 1928 return kNames[type]; 1929 } 1930} 1931 1932static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 1933 static const char *kNames[] = { 1934 "OMX_AUDIO_PCMModeLinear", 1935 "OMX_AUDIO_PCMModeALaw", 1936 "OMX_AUDIO_PCMModeMULaw", 1937 }; 1938 1939 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1940 1941 if (type < 0 || (size_t)type >= numNames) { 1942 return "UNKNOWN"; 1943 } else { 1944 return kNames[type]; 1945 } 1946} 1947 1948 1949void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 1950 OMX_PARAM_PORTDEFINITIONTYPE def; 1951 def.nSize = sizeof(def); 1952 def.nVersion.s.nVersionMajor = 1; 1953 def.nVersion.s.nVersionMinor = 1; 1954 def.nPortIndex = portIndex; 1955 1956 status_t err = mOMX->get_parameter( 1957 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1958 CHECK_EQ(err, OK); 1959 1960 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 1961 1962 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 1963 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 1964 1965 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 1966 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 1967 printf(" nBufferSize = %ld\n", def.nBufferSize); 1968 1969 switch (def.eDomain) { 1970 case OMX_PortDomainImage: 1971 { 1972 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1973 1974 printf("\n"); 1975 printf(" // Image\n"); 1976 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 1977 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 1978 printf(" nStride = %ld\n", imageDef->nStride); 1979 1980 printf(" eCompressionFormat = %s\n", 1981 imageCompressionFormatString(imageDef->eCompressionFormat)); 1982 1983 printf(" eColorFormat = %s\n", 1984 colorFormatString(imageDef->eColorFormat)); 1985 1986 break; 1987 } 1988 1989 case OMX_PortDomainVideo: 1990 { 1991 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 1992 1993 printf("\n"); 1994 printf(" // Video\n"); 1995 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 1996 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 1997 printf(" nStride = %ld\n", videoDef->nStride); 1998 1999 printf(" eCompressionFormat = %s\n", 2000 videoCompressionFormatString(videoDef->eCompressionFormat)); 2001 2002 printf(" eColorFormat = %s\n", 2003 colorFormatString(videoDef->eColorFormat)); 2004 2005 break; 2006 } 2007 2008 case OMX_PortDomainAudio: 2009 { 2010 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2011 2012 printf("\n"); 2013 printf(" // Audio\n"); 2014 printf(" eEncoding = %s\n", 2015 audioCodingTypeString(audioDef->eEncoding)); 2016 2017 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2018 OMX_AUDIO_PARAM_PCMMODETYPE params; 2019 params.nSize = sizeof(params); 2020 params.nVersion.s.nVersionMajor = 1; 2021 params.nVersion.s.nVersionMinor = 1; 2022 params.nPortIndex = portIndex; 2023 2024 err = mOMX->get_parameter( 2025 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2026 CHECK_EQ(err, OK); 2027 2028 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2029 printf(" nChannels = %ld\n", params.nChannels); 2030 printf(" bInterleaved = %d\n", params.bInterleaved); 2031 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2032 2033 printf(" eNumData = %s\n", 2034 params.eNumData == OMX_NumericalDataSigned 2035 ? "signed" : "unsigned"); 2036 2037 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2038 } 2039 2040 break; 2041 } 2042 2043 default: 2044 { 2045 printf(" // Unknown\n"); 2046 break; 2047 } 2048 } 2049 2050 printf("}\n"); 2051} 2052 2053void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2054 mOutputFormat = new MetaData; 2055 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2056 2057 OMX_PARAM_PORTDEFINITIONTYPE def; 2058 def.nSize = sizeof(def); 2059 def.nVersion.s.nVersionMajor = 1; 2060 def.nVersion.s.nVersionMinor = 1; 2061 def.nPortIndex = kPortIndexOutput; 2062 2063 status_t err = mOMX->get_parameter( 2064 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2065 CHECK_EQ(err, OK); 2066 2067 switch (def.eDomain) { 2068 case OMX_PortDomainImage: 2069 { 2070 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2071 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2072 2073 mOutputFormat->setCString(kKeyMIMEType, "image/raw"); 2074 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2075 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2076 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2077 break; 2078 } 2079 2080 case OMX_PortDomainAudio: 2081 { 2082 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2083 2084 CHECK_EQ(audio_def->eEncoding, OMX_AUDIO_CodingPCM); 2085 2086 OMX_AUDIO_PARAM_PCMMODETYPE params; 2087 params.nSize = sizeof(params); 2088 params.nVersion.s.nVersionMajor = 1; 2089 params.nVersion.s.nVersionMinor = 1; 2090 params.nPortIndex = kPortIndexOutput; 2091 2092 err = mOMX->get_parameter( 2093 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2094 CHECK_EQ(err, OK); 2095 2096 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2097 CHECK_EQ(params.nBitPerSample, 16); 2098 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2099 2100 int32_t numChannels, sampleRate; 2101 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2102 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2103 2104 mOutputFormat->setCString(kKeyMIMEType, "audio/raw"); 2105 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 2106 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2107 break; 2108 } 2109 2110 case OMX_PortDomainVideo: 2111 { 2112 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2113 2114 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2115 mOutputFormat->setCString(kKeyMIMEType, "video/raw"); 2116 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2117 mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es"); 2118 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2119 mOutputFormat->setCString(kKeyMIMEType, "video/3gpp"); 2120 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2121 mOutputFormat->setCString(kKeyMIMEType, "video/avc"); 2122 } else { 2123 CHECK(!"Unknown compression format."); 2124 } 2125 2126 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2127 // This component appears to be lying to me. 2128 mOutputFormat->setInt32( 2129 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2130 mOutputFormat->setInt32( 2131 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2132 } else { 2133 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2134 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2135 } 2136 2137 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2138 break; 2139 } 2140 2141 default: 2142 { 2143 CHECK(!"should not be here, neither audio nor video."); 2144 break; 2145 } 2146 } 2147} 2148 2149} // namespace android 2150