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