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