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