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