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