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