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