OMXCodec.cpp revision b03fd8c97695d381e202f6a64989b51c7024c04a
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/M4vH263Decoder.h" 28#include "include/MP3Decoder.h" 29#endif 30 31#include "include/ESDS.h" 32 33#include <binder/IServiceManager.h> 34#include <binder/MemoryDealer.h> 35#include <binder/ProcessState.h> 36#include <media/IMediaPlayerService.h> 37#include <media/stagefright/MediaBuffer.h> 38#include <media/stagefright/MediaBufferGroup.h> 39#include <media/stagefright/MediaDebug.h> 40#include <media/stagefright/MediaDefs.h> 41#include <media/stagefright/MediaExtractor.h> 42#include <media/stagefright/MetaData.h> 43#include <media/stagefright/OMXCodec.h> 44#include <media/stagefright/Utils.h> 45#include <utils/Vector.h> 46 47#include <OMX_Audio.h> 48#include <OMX_Component.h> 49 50namespace android { 51 52static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 53 54struct CodecInfo { 55 const char *mime; 56 const char *codec; 57}; 58 59#if BUILD_WITH_FULL_STAGEFRIGHT 60#define OPTIONAL(x,y) { x, y }, 61 62#define FACTORY_CREATE(name) \ 63static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \ 64 return new name(source); \ 65} 66 67#define FACTORY_REF(name) { #name, Make##name }, 68 69FACTORY_CREATE(MP3Decoder) 70FACTORY_CREATE(AMRNBDecoder) 71FACTORY_CREATE(AMRWBDecoder) 72FACTORY_CREATE(AACDecoder) 73FACTORY_CREATE(AVCDecoder) 74FACTORY_CREATE(M4vH263Decoder) 75FACTORY_CREATE(AMRNBEncoder) 76 77static sp<MediaSource> InstantiateSoftwareCodec( 78 const char *name, const sp<MediaSource> &source) { 79 struct FactoryInfo { 80 const char *name; 81 sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &); 82 }; 83 84 static const FactoryInfo kFactoryInfo[] = { 85 FACTORY_REF(MP3Decoder) 86 FACTORY_REF(AMRNBDecoder) 87 FACTORY_REF(AMRWBDecoder) 88 FACTORY_REF(AACDecoder) 89 FACTORY_REF(AVCDecoder) 90 FACTORY_REF(M4vH263Decoder) 91 FACTORY_REF(AMRNBEncoder) 92 }; 93 for (size_t i = 0; 94 i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 95 if (!strcmp(name, kFactoryInfo[i].name)) { 96 return (*kFactoryInfo[i].CreateFunc)(source); 97 } 98 } 99 100 return NULL; 101} 102 103#undef FACTORY_REF 104#undef FACTORY_CREATE 105 106#else 107#define OPTIONAL(x,y) 108#endif 109 110static const CodecInfo kDecoderInfo[] = { 111 { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" }, 112 { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, 113 OPTIONAL(MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder") 114 { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" }, 115 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" }, 116 OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder") 117 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" }, 118 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" }, 119 OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder") 120 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" }, 121 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" }, 122 OPTIONAL(MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder") 123 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" }, 124 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" }, 125 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, 126 OPTIONAL(MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder") 127 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" }, 128 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, 129 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" }, 130 OPTIONAL(MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder") 131 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" }, 132 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, 133 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, 134 OPTIONAL(MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder") 135 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" }, 136}; 137 138static const CodecInfo kEncoderInfo[] = { 139 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" }, 140 OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder") 141 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" }, 142 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" }, 143 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, 144 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" }, 145 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, 146 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, 147 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" }, 148 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, 149 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, 150 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" }, 151 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, 152 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" }, 153}; 154 155#undef OPTIONAL 156 157#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 158#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 159 160struct OMXCodecObserver : public BnOMXObserver { 161 OMXCodecObserver() { 162 } 163 164 void setCodec(const sp<OMXCodec> &target) { 165 mTarget = target; 166 } 167 168 // from IOMXObserver 169 virtual void onMessage(const omx_message &msg) { 170 sp<OMXCodec> codec = mTarget.promote(); 171 172 if (codec.get() != NULL) { 173 codec->on_message(msg); 174 } 175 } 176 177protected: 178 virtual ~OMXCodecObserver() {} 179 180private: 181 wp<OMXCodec> mTarget; 182 183 OMXCodecObserver(const OMXCodecObserver &); 184 OMXCodecObserver &operator=(const OMXCodecObserver &); 185}; 186 187static const char *GetCodec(const CodecInfo *info, size_t numInfos, 188 const char *mime, int index) { 189 CHECK(index >= 0); 190 for(size_t i = 0; i < numInfos; ++i) { 191 if (!strcasecmp(mime, info[i].mime)) { 192 if (index == 0) { 193 return info[i].codec; 194 } 195 196 --index; 197 } 198 } 199 200 return NULL; 201} 202 203enum { 204 kAVCProfileBaseline = 0x42, 205 kAVCProfileMain = 0x4d, 206 kAVCProfileExtended = 0x58, 207 kAVCProfileHigh = 0x64, 208 kAVCProfileHigh10 = 0x6e, 209 kAVCProfileHigh422 = 0x7a, 210 kAVCProfileHigh444 = 0xf4, 211 kAVCProfileCAVLC444Intra = 0x2c 212}; 213 214static const char *AVCProfileToString(uint8_t profile) { 215 switch (profile) { 216 case kAVCProfileBaseline: 217 return "Baseline"; 218 case kAVCProfileMain: 219 return "Main"; 220 case kAVCProfileExtended: 221 return "Extended"; 222 case kAVCProfileHigh: 223 return "High"; 224 case kAVCProfileHigh10: 225 return "High 10"; 226 case kAVCProfileHigh422: 227 return "High 422"; 228 case kAVCProfileHigh444: 229 return "High 444"; 230 case kAVCProfileCAVLC444Intra: 231 return "CAVLC 444 Intra"; 232 default: return "Unknown"; 233 } 234} 235 236template<class T> 237static void InitOMXParams(T *params) { 238 params->nSize = sizeof(T); 239 params->nVersion.s.nVersionMajor = 1; 240 params->nVersion.s.nVersionMinor = 0; 241 params->nVersion.s.nRevision = 0; 242 params->nVersion.s.nStep = 0; 243} 244 245static bool IsSoftwareCodec(const char *componentName) { 246 if (!strncmp("OMX.PV.", componentName, 7)) { 247 return true; 248 } 249 250 return false; 251} 252 253// A sort order in which non-OMX components are first, 254// followed by software codecs, i.e. OMX.PV.*, followed 255// by all the others. 256static int CompareSoftwareCodecsFirst( 257 const String8 *elem1, const String8 *elem2) { 258 bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4); 259 bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4); 260 261 if (isNotOMX1) { 262 if (isNotOMX2) { return 0; } 263 return -1; 264 } 265 if (isNotOMX2) { 266 return 1; 267 } 268 269 bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string()); 270 bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string()); 271 272 if (isSoftwareCodec1) { 273 if (isSoftwareCodec2) { return 0; } 274 return -1; 275 } 276 277 if (isSoftwareCodec2) { 278 return 1; 279 } 280 281 return 0; 282} 283 284// static 285uint32_t OMXCodec::getComponentQuirks(const char *componentName) { 286 uint32_t quirks = 0; 287 288 if (!strcmp(componentName, "OMX.PV.avcdec")) { 289 quirks |= kWantsNALFragments; 290 } 291 if (!strcmp(componentName, "OMX.TI.MP3.decode")) { 292 quirks |= kNeedsFlushBeforeDisable; 293 } 294 if (!strcmp(componentName, "OMX.TI.AAC.decode")) { 295 quirks |= kNeedsFlushBeforeDisable; 296 quirks |= kRequiresFlushCompleteEmulation; 297 } 298 if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) { 299 quirks |= kRequiresLoadedToIdleAfterAllocation; 300 quirks |= kRequiresAllocateBufferOnInputPorts; 301 quirks |= kRequiresAllocateBufferOnOutputPorts; 302 } 303 if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) { 304 // XXX Required on P....on only. 305 quirks |= kRequiresAllocateBufferOnOutputPorts; 306 } 307 308 if (!strncmp(componentName, "OMX.TI.", 7)) { 309 // Apparently I must not use OMX_UseBuffer on either input or 310 // output ports on any of the TI components or quote: 311 // "(I) may have unexpected problem (sic) which can be timing related 312 // and hard to reproduce." 313 314 quirks |= kRequiresAllocateBufferOnInputPorts; 315 quirks |= kRequiresAllocateBufferOnOutputPorts; 316 } 317 318 return quirks; 319} 320 321// static 322void OMXCodec::findMatchingCodecs( 323 const char *mime, 324 bool createEncoder, const char *matchComponentName, 325 uint32_t flags, 326 Vector<String8> *matchingCodecs) { 327 matchingCodecs->clear(); 328 329 for (int index = 0;; ++index) { 330 const char *componentName; 331 332 if (createEncoder) { 333 componentName = GetCodec( 334 kEncoderInfo, 335 sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 336 mime, index); 337 } else { 338 componentName = GetCodec( 339 kDecoderInfo, 340 sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 341 mime, index); 342 } 343 344 if (!componentName) { 345 break; 346 } 347 348 // If a specific codec is requested, skip the non-matching ones. 349 if (matchComponentName && strcmp(componentName, matchComponentName)) { 350 continue; 351 } 352 353 matchingCodecs->push(String8(componentName)); 354 } 355 356 if (flags & kPreferSoftwareCodecs) { 357 matchingCodecs->sort(CompareSoftwareCodecsFirst); 358 } 359} 360 361// static 362sp<MediaSource> OMXCodec::Create( 363 const sp<IOMX> &omx, 364 const sp<MetaData> &meta, bool createEncoder, 365 const sp<MediaSource> &source, 366 const char *matchComponentName, 367 uint32_t flags) { 368 const char *mime; 369 bool success = meta->findCString(kKeyMIMEType, &mime); 370 CHECK(success); 371 372 Vector<String8> matchingCodecs; 373 findMatchingCodecs( 374 mime, createEncoder, matchComponentName, flags, &matchingCodecs); 375 376 if (matchingCodecs.isEmpty()) { 377 return NULL; 378 } 379 380 sp<OMXCodecObserver> observer = new OMXCodecObserver; 381 IOMX::node_id node = 0; 382 success = false; 383 384 const char *componentName; 385 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 386 componentName = matchingCodecs[i].string(); 387 388#if BUILD_WITH_FULL_STAGEFRIGHT 389 sp<MediaSource> softwareCodec = 390 InstantiateSoftwareCodec(componentName, source); 391 392 if (softwareCodec != NULL) { 393 LOGV("Successfully allocated software codec '%s'", componentName); 394 395 return softwareCodec; 396 } 397#endif 398 399 LOGV("Attempting to allocate OMX node '%s'", componentName); 400 401 status_t err = omx->allocateNode(componentName, observer, &node); 402 if (err == OK) { 403 LOGV("Successfully allocated OMX node '%s'", componentName); 404 405 success = true; 406 break; 407 } 408 } 409 410 if (!success) { 411 return NULL; 412 } 413 414 sp<OMXCodec> codec = new OMXCodec( 415 omx, node, getComponentQuirks(componentName), 416 createEncoder, mime, componentName, 417 source); 418 419 observer->setCodec(codec); 420 421 uint32_t type; 422 const void *data; 423 size_t size; 424 if (meta->findData(kKeyESDS, &type, &data, &size)) { 425 ESDS esds((const char *)data, size); 426 CHECK_EQ(esds.InitCheck(), OK); 427 428 const void *codec_specific_data; 429 size_t codec_specific_data_size; 430 esds.getCodecSpecificInfo( 431 &codec_specific_data, &codec_specific_data_size); 432 433 codec->addCodecSpecificData( 434 codec_specific_data, codec_specific_data_size); 435 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 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 break; 1277 } 1278 1279 case omx_message::FILL_BUFFER_DONE: 1280 { 1281 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 1282 OMX_U32 flags = msg.u.extended_buffer_data.flags; 1283 1284 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 1285 buffer, 1286 msg.u.extended_buffer_data.range_length, 1287 flags, 1288 msg.u.extended_buffer_data.timestamp, 1289 msg.u.extended_buffer_data.timestamp / 1E6); 1290 1291 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1292 size_t i = 0; 1293 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 1294 ++i; 1295 } 1296 1297 CHECK(i < buffers->size()); 1298 BufferInfo *info = &buffers->editItemAt(i); 1299 1300 if (!info->mOwnedByComponent) { 1301 LOGW("We already own output buffer %p, yet received " 1302 "a FILL_BUFFER_DONE.", buffer); 1303 } 1304 1305 info->mOwnedByComponent = false; 1306 1307 if (mPortStatus[kPortIndexOutput] == DISABLING) { 1308 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 1309 1310 status_t err = 1311 mOMX->freeBuffer(mNode, kPortIndexOutput, buffer); 1312 CHECK_EQ(err, OK); 1313 1314 buffers->removeAt(i); 1315#if 0 1316 } else if (mPortStatus[kPortIndexOutput] == ENABLED 1317 && (flags & OMX_BUFFERFLAG_EOS)) { 1318 CODEC_LOGV("No more output data."); 1319 mNoMoreOutputData = true; 1320 mBufferFilled.signal(); 1321#endif 1322 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 1323 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1324 1325 MediaBuffer *buffer = info->mMediaBuffer; 1326 1327 buffer->set_range( 1328 msg.u.extended_buffer_data.range_offset, 1329 msg.u.extended_buffer_data.range_length); 1330 1331 buffer->meta_data()->clear(); 1332 1333 buffer->meta_data()->setInt64( 1334 kKeyTime, msg.u.extended_buffer_data.timestamp); 1335 1336 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 1337 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 1338 } 1339 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 1340 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 1341 } 1342 1343 buffer->meta_data()->setPointer( 1344 kKeyPlatformPrivate, 1345 msg.u.extended_buffer_data.platform_private); 1346 1347 buffer->meta_data()->setPointer( 1348 kKeyBufferID, 1349 msg.u.extended_buffer_data.buffer); 1350 1351 mFilledBuffers.push_back(i); 1352 mBufferFilled.signal(); 1353 1354 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 1355 CODEC_LOGV("No more output data."); 1356 mNoMoreOutputData = true; 1357 } 1358 } 1359 1360 break; 1361 } 1362 1363 default: 1364 { 1365 CHECK(!"should not be here."); 1366 break; 1367 } 1368 } 1369} 1370 1371void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1372 switch (event) { 1373 case OMX_EventCmdComplete: 1374 { 1375 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 1376 break; 1377 } 1378 1379 case OMX_EventError: 1380 { 1381 LOGE("ERROR(0x%08lx, %ld)", data1, data2); 1382 1383 setState(ERROR); 1384 break; 1385 } 1386 1387 case OMX_EventPortSettingsChanged: 1388 { 1389 onPortSettingsChanged(data1); 1390 break; 1391 } 1392 1393#if 0 1394 case OMX_EventBufferFlag: 1395 { 1396 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 1397 1398 if (data1 == kPortIndexOutput) { 1399 mNoMoreOutputData = true; 1400 } 1401 break; 1402 } 1403#endif 1404 1405 default: 1406 { 1407 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 1408 break; 1409 } 1410 } 1411} 1412 1413// Has the format changed in any way that the client would have to be aware of? 1414static bool formatHasNotablyChanged( 1415 const sp<MetaData> &from, const sp<MetaData> &to) { 1416 if (from.get() == NULL && to.get() == NULL) { 1417 return false; 1418 } 1419 1420 if ((from.get() == NULL && to.get() != NULL) 1421 || (from.get() != NULL && to.get() == NULL)) { 1422 return true; 1423 } 1424 1425 const char *mime_from, *mime_to; 1426 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 1427 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 1428 1429 if (strcasecmp(mime_from, mime_to)) { 1430 return true; 1431 } 1432 1433 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 1434 int32_t colorFormat_from, colorFormat_to; 1435 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 1436 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 1437 1438 if (colorFormat_from != colorFormat_to) { 1439 return true; 1440 } 1441 1442 int32_t width_from, width_to; 1443 CHECK(from->findInt32(kKeyWidth, &width_from)); 1444 CHECK(to->findInt32(kKeyWidth, &width_to)); 1445 1446 if (width_from != width_to) { 1447 return true; 1448 } 1449 1450 int32_t height_from, height_to; 1451 CHECK(from->findInt32(kKeyHeight, &height_from)); 1452 CHECK(to->findInt32(kKeyHeight, &height_to)); 1453 1454 if (height_from != height_to) { 1455 return true; 1456 } 1457 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 1458 int32_t numChannels_from, numChannels_to; 1459 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 1460 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 1461 1462 if (numChannels_from != numChannels_to) { 1463 return true; 1464 } 1465 1466 int32_t sampleRate_from, sampleRate_to; 1467 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 1468 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 1469 1470 if (sampleRate_from != sampleRate_to) { 1471 return true; 1472 } 1473 } 1474 1475 return false; 1476} 1477 1478void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 1479 switch (cmd) { 1480 case OMX_CommandStateSet: 1481 { 1482 onStateChange((OMX_STATETYPE)data); 1483 break; 1484 } 1485 1486 case OMX_CommandPortDisable: 1487 { 1488 OMX_U32 portIndex = data; 1489 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 1490 1491 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1492 CHECK_EQ(mPortStatus[portIndex], DISABLING); 1493 CHECK_EQ(mPortBuffers[portIndex].size(), 0); 1494 1495 mPortStatus[portIndex] = DISABLED; 1496 1497 if (mState == RECONFIGURING) { 1498 CHECK_EQ(portIndex, kPortIndexOutput); 1499 1500 sp<MetaData> oldOutputFormat = mOutputFormat; 1501 initOutputFormat(mSource->getFormat()); 1502 1503 // Don't notify clients if the output port settings change 1504 // wasn't of importance to them, i.e. it may be that just the 1505 // number of buffers has changed and nothing else. 1506 mOutputPortSettingsHaveChanged = 1507 formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 1508 1509 enablePortAsync(portIndex); 1510 1511 status_t err = allocateBuffersOnPort(portIndex); 1512 CHECK_EQ(err, OK); 1513 } 1514 break; 1515 } 1516 1517 case OMX_CommandPortEnable: 1518 { 1519 OMX_U32 portIndex = data; 1520 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 1521 1522 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1523 CHECK_EQ(mPortStatus[portIndex], ENABLING); 1524 1525 mPortStatus[portIndex] = ENABLED; 1526 1527 if (mState == RECONFIGURING) { 1528 CHECK_EQ(portIndex, kPortIndexOutput); 1529 1530 setState(EXECUTING); 1531 1532 fillOutputBuffers(); 1533 } 1534 break; 1535 } 1536 1537 case OMX_CommandFlush: 1538 { 1539 OMX_U32 portIndex = data; 1540 1541 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 1542 1543 CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); 1544 mPortStatus[portIndex] = ENABLED; 1545 1546 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 1547 mPortBuffers[portIndex].size()); 1548 1549 if (mState == RECONFIGURING) { 1550 CHECK_EQ(portIndex, kPortIndexOutput); 1551 1552 disablePortAsync(portIndex); 1553 } else if (mState == EXECUTING_TO_IDLE) { 1554 if (mPortStatus[kPortIndexInput] == ENABLED 1555 && mPortStatus[kPortIndexOutput] == ENABLED) { 1556 CODEC_LOGV("Finished flushing both ports, now completing " 1557 "transition from EXECUTING to IDLE."); 1558 1559 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1560 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1561 1562 status_t err = 1563 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1564 CHECK_EQ(err, OK); 1565 } 1566 } else { 1567 // We're flushing both ports in preparation for seeking. 1568 1569 if (mPortStatus[kPortIndexInput] == ENABLED 1570 && mPortStatus[kPortIndexOutput] == ENABLED) { 1571 CODEC_LOGV("Finished flushing both ports, now continuing from" 1572 " seek-time."); 1573 1574 drainInputBuffers(); 1575 fillOutputBuffers(); 1576 } 1577 } 1578 1579 break; 1580 } 1581 1582 default: 1583 { 1584 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1585 break; 1586 } 1587 } 1588} 1589 1590void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1591 switch (newState) { 1592 case OMX_StateIdle: 1593 { 1594 CODEC_LOGV("Now Idle."); 1595 if (mState == LOADED_TO_IDLE) { 1596 status_t err = mOMX->sendCommand( 1597 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1598 1599 CHECK_EQ(err, OK); 1600 1601 setState(IDLE_TO_EXECUTING); 1602 } else { 1603 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1604 1605 CHECK_EQ( 1606 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1607 mPortBuffers[kPortIndexInput].size()); 1608 1609 CHECK_EQ( 1610 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1611 mPortBuffers[kPortIndexOutput].size()); 1612 1613 status_t err = mOMX->sendCommand( 1614 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1615 1616 CHECK_EQ(err, OK); 1617 1618 err = freeBuffersOnPort(kPortIndexInput); 1619 CHECK_EQ(err, OK); 1620 1621 err = freeBuffersOnPort(kPortIndexOutput); 1622 CHECK_EQ(err, OK); 1623 1624 mPortStatus[kPortIndexInput] = ENABLED; 1625 mPortStatus[kPortIndexOutput] = ENABLED; 1626 1627 setState(IDLE_TO_LOADED); 1628 } 1629 break; 1630 } 1631 1632 case OMX_StateExecuting: 1633 { 1634 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1635 1636 CODEC_LOGV("Now Executing."); 1637 1638 setState(EXECUTING); 1639 1640 // Buffers will be submitted to the component in the first 1641 // call to OMXCodec::read as mInitialBufferSubmit is true at 1642 // this point. This ensures that this on_message call returns, 1643 // releases the lock and ::init can notice the state change and 1644 // itself return. 1645 break; 1646 } 1647 1648 case OMX_StateLoaded: 1649 { 1650 CHECK_EQ(mState, IDLE_TO_LOADED); 1651 1652 CODEC_LOGV("Now Loaded."); 1653 1654 setState(LOADED); 1655 break; 1656 } 1657 1658 default: 1659 { 1660 CHECK(!"should not be here."); 1661 break; 1662 } 1663 } 1664} 1665 1666// static 1667size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1668 size_t n = 0; 1669 for (size_t i = 0; i < buffers.size(); ++i) { 1670 if (!buffers[i].mOwnedByComponent) { 1671 ++n; 1672 } 1673 } 1674 1675 return n; 1676} 1677 1678status_t OMXCodec::freeBuffersOnPort( 1679 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1680 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1681 1682 status_t stickyErr = OK; 1683 1684 for (size_t i = buffers->size(); i-- > 0;) { 1685 BufferInfo *info = &buffers->editItemAt(i); 1686 1687 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1688 continue; 1689 } 1690 1691 CHECK_EQ(info->mOwnedByComponent, false); 1692 1693 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 1694 1695 status_t err = 1696 mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 1697 1698 if (err != OK) { 1699 stickyErr = err; 1700 } 1701 1702 if (info->mMediaBuffer != NULL) { 1703 info->mMediaBuffer->setObserver(NULL); 1704 1705 // Make sure nobody but us owns this buffer at this point. 1706 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1707 1708 info->mMediaBuffer->release(); 1709 } 1710 1711 buffers->removeAt(i); 1712 } 1713 1714 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1715 1716 return stickyErr; 1717} 1718 1719void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1720 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1721 1722 CHECK_EQ(mState, EXECUTING); 1723 CHECK_EQ(portIndex, kPortIndexOutput); 1724 setState(RECONFIGURING); 1725 1726 if (mQuirks & kNeedsFlushBeforeDisable) { 1727 if (!flushPortAsync(portIndex)) { 1728 onCmdComplete(OMX_CommandFlush, portIndex); 1729 } 1730 } else { 1731 disablePortAsync(portIndex); 1732 } 1733} 1734 1735bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1736 CHECK(mState == EXECUTING || mState == RECONFIGURING 1737 || mState == EXECUTING_TO_IDLE); 1738 1739 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1740 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1741 mPortBuffers[portIndex].size()); 1742 1743 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1744 mPortStatus[portIndex] = SHUTTING_DOWN; 1745 1746 if ((mQuirks & kRequiresFlushCompleteEmulation) 1747 && countBuffersWeOwn(mPortBuffers[portIndex]) 1748 == mPortBuffers[portIndex].size()) { 1749 // No flush is necessary and this component fails to send a 1750 // flush-complete event in this case. 1751 1752 return false; 1753 } 1754 1755 status_t err = 1756 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 1757 CHECK_EQ(err, OK); 1758 1759 return true; 1760} 1761 1762void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1763 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1764 1765 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1766 mPortStatus[portIndex] = DISABLING; 1767 1768 status_t err = 1769 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 1770 CHECK_EQ(err, OK); 1771 1772 freeBuffersOnPort(portIndex, true); 1773} 1774 1775void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1776 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1777 1778 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1779 mPortStatus[portIndex] = ENABLING; 1780 1781 status_t err = 1782 mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 1783 CHECK_EQ(err, OK); 1784} 1785 1786void OMXCodec::fillOutputBuffers() { 1787 CHECK_EQ(mState, EXECUTING); 1788 1789 // This is a workaround for some decoders not properly reporting 1790 // end-of-output-stream. If we own all input buffers and also own 1791 // all output buffers and we already signalled end-of-input-stream, 1792 // the end-of-output-stream is implied. 1793 if (mSignalledEOS 1794 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 1795 == mPortBuffers[kPortIndexInput].size() 1796 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 1797 == mPortBuffers[kPortIndexOutput].size()) { 1798 mNoMoreOutputData = true; 1799 mBufferFilled.signal(); 1800 1801 return; 1802 } 1803 1804 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1805 for (size_t i = 0; i < buffers->size(); ++i) { 1806 fillOutputBuffer(&buffers->editItemAt(i)); 1807 } 1808} 1809 1810void OMXCodec::drainInputBuffers() { 1811 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1812 1813 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1814 for (size_t i = 0; i < buffers->size(); ++i) { 1815 drainInputBuffer(&buffers->editItemAt(i)); 1816 } 1817} 1818 1819void OMXCodec::drainInputBuffer(BufferInfo *info) { 1820 CHECK_EQ(info->mOwnedByComponent, false); 1821 1822 if (mSignalledEOS) { 1823 return; 1824 } 1825 1826 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 1827 const CodecSpecificData *specific = 1828 mCodecSpecificData[mCodecSpecificDataIndex]; 1829 1830 size_t size = specific->mSize; 1831 1832 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 1833 && !(mQuirks & kWantsNALFragments)) { 1834 static const uint8_t kNALStartCode[4] = 1835 { 0x00, 0x00, 0x00, 0x01 }; 1836 1837 CHECK(info->mMem->size() >= specific->mSize + 4); 1838 1839 size += 4; 1840 1841 memcpy(info->mMem->pointer(), kNALStartCode, 4); 1842 memcpy((uint8_t *)info->mMem->pointer() + 4, 1843 specific->mData, specific->mSize); 1844 } else { 1845 CHECK(info->mMem->size() >= specific->mSize); 1846 memcpy(info->mMem->pointer(), specific->mData, specific->mSize); 1847 } 1848 1849 mNoMoreOutputData = false; 1850 1851 CODEC_LOGV("calling emptyBuffer with codec specific data"); 1852 1853 status_t err = mOMX->emptyBuffer( 1854 mNode, info->mBuffer, 0, size, 1855 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 1856 0); 1857 CHECK_EQ(err, OK); 1858 1859 info->mOwnedByComponent = true; 1860 1861 ++mCodecSpecificDataIndex; 1862 return; 1863 } 1864 1865 MediaBuffer *srcBuffer; 1866 status_t err; 1867 if (mSeekTimeUs >= 0) { 1868 MediaSource::ReadOptions options; 1869 options.setSeekTo(mSeekTimeUs); 1870 1871 mSeekTimeUs = -1; 1872 mBufferFilled.signal(); 1873 1874 err = mSource->read(&srcBuffer, &options); 1875 } else { 1876 err = mSource->read(&srcBuffer); 1877 } 1878 1879 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1880 OMX_TICKS timestampUs = 0; 1881 size_t srcLength = 0; 1882 1883 if (err != OK) { 1884 CODEC_LOGV("signalling end of input stream."); 1885 flags |= OMX_BUFFERFLAG_EOS; 1886 1887 mSignalledEOS = true; 1888 } else { 1889 mNoMoreOutputData = false; 1890 1891 srcLength = srcBuffer->range_length(); 1892 1893 if (info->mMem->size() < srcLength) { 1894 LOGE("info->mMem->size() = %d, srcLength = %d", 1895 info->mMem->size(), srcLength); 1896 } 1897 CHECK(info->mMem->size() >= srcLength); 1898 memcpy(info->mMem->pointer(), 1899 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1900 srcLength); 1901 1902 if (srcBuffer->meta_data()->findInt64(kKeyTime, ×tampUs)) { 1903 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 1904 "timestamp %lld us (%.2f secs)", 1905 info->mBuffer, srcLength, 1906 timestampUs, timestampUs / 1E6); 1907 } 1908 } 1909 1910 if (srcBuffer != NULL) { 1911 srcBuffer->release(); 1912 srcBuffer = NULL; 1913 } 1914 1915 err = mOMX->emptyBuffer( 1916 mNode, info->mBuffer, 0, srcLength, 1917 flags, timestampUs); 1918 1919 if (err != OK) { 1920 setState(ERROR); 1921 return; 1922 } 1923 1924 info->mOwnedByComponent = true; 1925 1926 // This component does not ever signal the EOS flag on output buffers, 1927 // Thanks for nothing. 1928 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 1929 mNoMoreOutputData = true; 1930 mBufferFilled.signal(); 1931 } 1932} 1933 1934void OMXCodec::fillOutputBuffer(BufferInfo *info) { 1935 CHECK_EQ(info->mOwnedByComponent, false); 1936 1937 if (mNoMoreOutputData) { 1938 CODEC_LOGV("There is no more output data available, not " 1939 "calling fillOutputBuffer"); 1940 return; 1941 } 1942 1943 CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 1944 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 1945 CHECK_EQ(err, OK); 1946 1947 info->mOwnedByComponent = true; 1948} 1949 1950void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 1951 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1952 for (size_t i = 0; i < buffers->size(); ++i) { 1953 if ((*buffers)[i].mBuffer == buffer) { 1954 drainInputBuffer(&buffers->editItemAt(i)); 1955 return; 1956 } 1957 } 1958 1959 CHECK(!"should not be here."); 1960} 1961 1962void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 1963 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1964 for (size_t i = 0; i < buffers->size(); ++i) { 1965 if ((*buffers)[i].mBuffer == buffer) { 1966 fillOutputBuffer(&buffers->editItemAt(i)); 1967 return; 1968 } 1969 } 1970 1971 CHECK(!"should not be here."); 1972} 1973 1974void OMXCodec::setState(State newState) { 1975 mState = newState; 1976 mAsyncCompletion.signal(); 1977 1978 // This may cause some spurious wakeups but is necessary to 1979 // unblock the reader if we enter ERROR state. 1980 mBufferFilled.signal(); 1981} 1982 1983void OMXCodec::setRawAudioFormat( 1984 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 1985 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 1986 InitOMXParams(&pcmParams); 1987 pcmParams.nPortIndex = portIndex; 1988 1989 status_t err = mOMX->getParameter( 1990 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1991 1992 CHECK_EQ(err, OK); 1993 1994 pcmParams.nChannels = numChannels; 1995 pcmParams.eNumData = OMX_NumericalDataSigned; 1996 pcmParams.bInterleaved = OMX_TRUE; 1997 pcmParams.nBitPerSample = 16; 1998 pcmParams.nSamplingRate = sampleRate; 1999 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2000 2001 if (numChannels == 1) { 2002 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 2003 } else { 2004 CHECK_EQ(numChannels, 2); 2005 2006 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 2007 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 2008 } 2009 2010 err = mOMX->setParameter( 2011 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2012 2013 CHECK_EQ(err, OK); 2014} 2015 2016void OMXCodec::setAMRFormat(bool isWAMR) { 2017 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 2018 2019 OMX_AUDIO_PARAM_AMRTYPE def; 2020 InitOMXParams(&def); 2021 def.nPortIndex = portIndex; 2022 2023 status_t err = 2024 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2025 2026 CHECK_EQ(err, OK); 2027 2028 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2029 def.eAMRBandMode = 2030 isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0; 2031 2032 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2033 CHECK_EQ(err, OK); 2034 2035 //////////////////////// 2036 2037 if (mIsEncoder) { 2038 sp<MetaData> format = mSource->getFormat(); 2039 int32_t sampleRate; 2040 int32_t numChannels; 2041 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 2042 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 2043 2044 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2045 } 2046} 2047 2048void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { 2049 if (mIsEncoder) { 2050 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 2051 } else { 2052 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2053 InitOMXParams(&profile); 2054 profile.nPortIndex = kPortIndexInput; 2055 2056 status_t err = mOMX->getParameter( 2057 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2058 CHECK_EQ(err, OK); 2059 2060 profile.nChannels = numChannels; 2061 profile.nSampleRate = sampleRate; 2062 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 2063 2064 err = mOMX->setParameter( 2065 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2066 CHECK_EQ(err, OK); 2067 } 2068} 2069 2070void OMXCodec::setImageOutputFormat( 2071 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 2072 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 2073 2074#if 0 2075 OMX_INDEXTYPE index; 2076 status_t err = mOMX->get_extension_index( 2077 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 2078 CHECK_EQ(err, OK); 2079 2080 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 2081 CHECK_EQ(err, OK); 2082#endif 2083 2084 OMX_PARAM_PORTDEFINITIONTYPE def; 2085 InitOMXParams(&def); 2086 def.nPortIndex = kPortIndexOutput; 2087 2088 status_t err = mOMX->getParameter( 2089 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2090 CHECK_EQ(err, OK); 2091 2092 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2093 2094 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2095 2096 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2097 imageDef->eColorFormat = format; 2098 imageDef->nFrameWidth = width; 2099 imageDef->nFrameHeight = height; 2100 2101 switch (format) { 2102 case OMX_COLOR_FormatYUV420PackedPlanar: 2103 case OMX_COLOR_FormatYUV411Planar: 2104 { 2105 def.nBufferSize = (width * height * 3) / 2; 2106 break; 2107 } 2108 2109 case OMX_COLOR_FormatCbYCrY: 2110 { 2111 def.nBufferSize = width * height * 2; 2112 break; 2113 } 2114 2115 case OMX_COLOR_Format32bitARGB8888: 2116 { 2117 def.nBufferSize = width * height * 4; 2118 break; 2119 } 2120 2121 case OMX_COLOR_Format16bitARGB4444: 2122 case OMX_COLOR_Format16bitARGB1555: 2123 case OMX_COLOR_Format16bitRGB565: 2124 case OMX_COLOR_Format16bitBGR565: 2125 { 2126 def.nBufferSize = width * height * 2; 2127 break; 2128 } 2129 2130 default: 2131 CHECK(!"Should not be here. Unknown color format."); 2132 break; 2133 } 2134 2135 def.nBufferCountActual = def.nBufferCountMin; 2136 2137 err = mOMX->setParameter( 2138 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2139 CHECK_EQ(err, OK); 2140} 2141 2142void OMXCodec::setJPEGInputFormat( 2143 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 2144 OMX_PARAM_PORTDEFINITIONTYPE def; 2145 InitOMXParams(&def); 2146 def.nPortIndex = kPortIndexInput; 2147 2148 status_t err = mOMX->getParameter( 2149 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2150 CHECK_EQ(err, OK); 2151 2152 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 2153 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2154 2155 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 2156 imageDef->nFrameWidth = width; 2157 imageDef->nFrameHeight = height; 2158 2159 def.nBufferSize = compressedSize; 2160 def.nBufferCountActual = def.nBufferCountMin; 2161 2162 err = mOMX->setParameter( 2163 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2164 CHECK_EQ(err, OK); 2165} 2166 2167void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 2168 CodecSpecificData *specific = 2169 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 2170 2171 specific->mSize = size; 2172 memcpy(specific->mData, data, size); 2173 2174 mCodecSpecificData.push(specific); 2175} 2176 2177void OMXCodec::clearCodecSpecificData() { 2178 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 2179 free(mCodecSpecificData.editItemAt(i)); 2180 } 2181 mCodecSpecificData.clear(); 2182 mCodecSpecificDataIndex = 0; 2183} 2184 2185status_t OMXCodec::start(MetaData *) { 2186 Mutex::Autolock autoLock(mLock); 2187 2188 if (mState != LOADED) { 2189 return UNKNOWN_ERROR; 2190 } 2191 2192 sp<MetaData> params = new MetaData; 2193 if (mQuirks & kWantsNALFragments) { 2194 params->setInt32(kKeyWantsNALFragments, true); 2195 } 2196 status_t err = mSource->start(params.get()); 2197 2198 if (err != OK) { 2199 return err; 2200 } 2201 2202 mCodecSpecificDataIndex = 0; 2203 mInitialBufferSubmit = true; 2204 mSignalledEOS = false; 2205 mNoMoreOutputData = false; 2206 mOutputPortSettingsHaveChanged = false; 2207 mSeekTimeUs = -1; 2208 mFilledBuffers.clear(); 2209 2210 return init(); 2211} 2212 2213status_t OMXCodec::stop() { 2214 CODEC_LOGV("stop"); 2215 2216 Mutex::Autolock autoLock(mLock); 2217 2218 while (isIntermediateState(mState)) { 2219 mAsyncCompletion.wait(mLock); 2220 } 2221 2222 switch (mState) { 2223 case LOADED: 2224 case ERROR: 2225 break; 2226 2227 case EXECUTING: 2228 { 2229 setState(EXECUTING_TO_IDLE); 2230 2231 if (mQuirks & kRequiresFlushBeforeShutdown) { 2232 CODEC_LOGV("This component requires a flush before transitioning " 2233 "from EXECUTING to IDLE..."); 2234 2235 bool emulateInputFlushCompletion = 2236 !flushPortAsync(kPortIndexInput); 2237 2238 bool emulateOutputFlushCompletion = 2239 !flushPortAsync(kPortIndexOutput); 2240 2241 if (emulateInputFlushCompletion) { 2242 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2243 } 2244 2245 if (emulateOutputFlushCompletion) { 2246 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2247 } 2248 } else { 2249 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2250 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2251 2252 status_t err = 2253 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2254 CHECK_EQ(err, OK); 2255 } 2256 2257 while (mState != LOADED && mState != ERROR) { 2258 mAsyncCompletion.wait(mLock); 2259 } 2260 2261 break; 2262 } 2263 2264 default: 2265 { 2266 CHECK(!"should not be here."); 2267 break; 2268 } 2269 } 2270 2271 mSource->stop(); 2272 2273 return OK; 2274} 2275 2276sp<MetaData> OMXCodec::getFormat() { 2277 Mutex::Autolock autoLock(mLock); 2278 2279 return mOutputFormat; 2280} 2281 2282status_t OMXCodec::read( 2283 MediaBuffer **buffer, const ReadOptions *options) { 2284 *buffer = NULL; 2285 2286 Mutex::Autolock autoLock(mLock); 2287 2288 if (mState != EXECUTING && mState != RECONFIGURING) { 2289 return UNKNOWN_ERROR; 2290 } 2291 2292 bool seeking = false; 2293 int64_t seekTimeUs; 2294 if (options && options->getSeekTo(&seekTimeUs)) { 2295 seeking = true; 2296 } 2297 2298 if (mInitialBufferSubmit) { 2299 mInitialBufferSubmit = false; 2300 2301 if (seeking) { 2302 CHECK(seekTimeUs >= 0); 2303 mSeekTimeUs = seekTimeUs; 2304 2305 // There's no reason to trigger the code below, there's 2306 // nothing to flush yet. 2307 seeking = false; 2308 } 2309 2310 drainInputBuffers(); 2311 2312 if (mState == EXECUTING) { 2313 // Otherwise mState == RECONFIGURING and this code will trigger 2314 // after the output port is reenabled. 2315 fillOutputBuffers(); 2316 } 2317 } 2318 2319 if (seeking) { 2320 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 2321 2322 mSignalledEOS = false; 2323 2324 CHECK(seekTimeUs >= 0); 2325 mSeekTimeUs = seekTimeUs; 2326 2327 mFilledBuffers.clear(); 2328 2329 CHECK_EQ(mState, EXECUTING); 2330 2331 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 2332 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 2333 2334 if (emulateInputFlushCompletion) { 2335 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 2336 } 2337 2338 if (emulateOutputFlushCompletion) { 2339 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 2340 } 2341 2342 while (mSeekTimeUs >= 0) { 2343 mBufferFilled.wait(mLock); 2344 } 2345 } 2346 2347 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 2348 mBufferFilled.wait(mLock); 2349 } 2350 2351 if (mState == ERROR) { 2352 return UNKNOWN_ERROR; 2353 } 2354 2355 if (mFilledBuffers.empty()) { 2356 return ERROR_END_OF_STREAM; 2357 } 2358 2359 if (mOutputPortSettingsHaveChanged) { 2360 mOutputPortSettingsHaveChanged = false; 2361 2362 return INFO_FORMAT_CHANGED; 2363 } 2364 2365 size_t index = *mFilledBuffers.begin(); 2366 mFilledBuffers.erase(mFilledBuffers.begin()); 2367 2368 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 2369 info->mMediaBuffer->add_ref(); 2370 *buffer = info->mMediaBuffer; 2371 2372 return OK; 2373} 2374 2375void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 2376 Mutex::Autolock autoLock(mLock); 2377 2378 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2379 for (size_t i = 0; i < buffers->size(); ++i) { 2380 BufferInfo *info = &buffers->editItemAt(i); 2381 2382 if (info->mMediaBuffer == buffer) { 2383 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 2384 fillOutputBuffer(info); 2385 return; 2386 } 2387 } 2388 2389 CHECK(!"should not be here."); 2390} 2391 2392static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 2393 static const char *kNames[] = { 2394 "OMX_IMAGE_CodingUnused", 2395 "OMX_IMAGE_CodingAutoDetect", 2396 "OMX_IMAGE_CodingJPEG", 2397 "OMX_IMAGE_CodingJPEG2K", 2398 "OMX_IMAGE_CodingEXIF", 2399 "OMX_IMAGE_CodingTIFF", 2400 "OMX_IMAGE_CodingGIF", 2401 "OMX_IMAGE_CodingPNG", 2402 "OMX_IMAGE_CodingLZW", 2403 "OMX_IMAGE_CodingBMP", 2404 }; 2405 2406 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2407 2408 if (type < 0 || (size_t)type >= numNames) { 2409 return "UNKNOWN"; 2410 } else { 2411 return kNames[type]; 2412 } 2413} 2414 2415static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 2416 static const char *kNames[] = { 2417 "OMX_COLOR_FormatUnused", 2418 "OMX_COLOR_FormatMonochrome", 2419 "OMX_COLOR_Format8bitRGB332", 2420 "OMX_COLOR_Format12bitRGB444", 2421 "OMX_COLOR_Format16bitARGB4444", 2422 "OMX_COLOR_Format16bitARGB1555", 2423 "OMX_COLOR_Format16bitRGB565", 2424 "OMX_COLOR_Format16bitBGR565", 2425 "OMX_COLOR_Format18bitRGB666", 2426 "OMX_COLOR_Format18bitARGB1665", 2427 "OMX_COLOR_Format19bitARGB1666", 2428 "OMX_COLOR_Format24bitRGB888", 2429 "OMX_COLOR_Format24bitBGR888", 2430 "OMX_COLOR_Format24bitARGB1887", 2431 "OMX_COLOR_Format25bitARGB1888", 2432 "OMX_COLOR_Format32bitBGRA8888", 2433 "OMX_COLOR_Format32bitARGB8888", 2434 "OMX_COLOR_FormatYUV411Planar", 2435 "OMX_COLOR_FormatYUV411PackedPlanar", 2436 "OMX_COLOR_FormatYUV420Planar", 2437 "OMX_COLOR_FormatYUV420PackedPlanar", 2438 "OMX_COLOR_FormatYUV420SemiPlanar", 2439 "OMX_COLOR_FormatYUV422Planar", 2440 "OMX_COLOR_FormatYUV422PackedPlanar", 2441 "OMX_COLOR_FormatYUV422SemiPlanar", 2442 "OMX_COLOR_FormatYCbYCr", 2443 "OMX_COLOR_FormatYCrYCb", 2444 "OMX_COLOR_FormatCbYCrY", 2445 "OMX_COLOR_FormatCrYCbY", 2446 "OMX_COLOR_FormatYUV444Interleaved", 2447 "OMX_COLOR_FormatRawBayer8bit", 2448 "OMX_COLOR_FormatRawBayer10bit", 2449 "OMX_COLOR_FormatRawBayer8bitcompressed", 2450 "OMX_COLOR_FormatL2", 2451 "OMX_COLOR_FormatL4", 2452 "OMX_COLOR_FormatL8", 2453 "OMX_COLOR_FormatL16", 2454 "OMX_COLOR_FormatL24", 2455 "OMX_COLOR_FormatL32", 2456 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 2457 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 2458 "OMX_COLOR_Format18BitBGR666", 2459 "OMX_COLOR_Format24BitARGB6666", 2460 "OMX_COLOR_Format24BitABGR6666", 2461 }; 2462 2463 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2464 2465 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 2466 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 2467 } else if (type < 0 || (size_t)type >= numNames) { 2468 return "UNKNOWN"; 2469 } else { 2470 return kNames[type]; 2471 } 2472} 2473 2474static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 2475 static const char *kNames[] = { 2476 "OMX_VIDEO_CodingUnused", 2477 "OMX_VIDEO_CodingAutoDetect", 2478 "OMX_VIDEO_CodingMPEG2", 2479 "OMX_VIDEO_CodingH263", 2480 "OMX_VIDEO_CodingMPEG4", 2481 "OMX_VIDEO_CodingWMV", 2482 "OMX_VIDEO_CodingRV", 2483 "OMX_VIDEO_CodingAVC", 2484 "OMX_VIDEO_CodingMJPEG", 2485 }; 2486 2487 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2488 2489 if (type < 0 || (size_t)type >= numNames) { 2490 return "UNKNOWN"; 2491 } else { 2492 return kNames[type]; 2493 } 2494} 2495 2496static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 2497 static const char *kNames[] = { 2498 "OMX_AUDIO_CodingUnused", 2499 "OMX_AUDIO_CodingAutoDetect", 2500 "OMX_AUDIO_CodingPCM", 2501 "OMX_AUDIO_CodingADPCM", 2502 "OMX_AUDIO_CodingAMR", 2503 "OMX_AUDIO_CodingGSMFR", 2504 "OMX_AUDIO_CodingGSMEFR", 2505 "OMX_AUDIO_CodingGSMHR", 2506 "OMX_AUDIO_CodingPDCFR", 2507 "OMX_AUDIO_CodingPDCEFR", 2508 "OMX_AUDIO_CodingPDCHR", 2509 "OMX_AUDIO_CodingTDMAFR", 2510 "OMX_AUDIO_CodingTDMAEFR", 2511 "OMX_AUDIO_CodingQCELP8", 2512 "OMX_AUDIO_CodingQCELP13", 2513 "OMX_AUDIO_CodingEVRC", 2514 "OMX_AUDIO_CodingSMV", 2515 "OMX_AUDIO_CodingG711", 2516 "OMX_AUDIO_CodingG723", 2517 "OMX_AUDIO_CodingG726", 2518 "OMX_AUDIO_CodingG729", 2519 "OMX_AUDIO_CodingAAC", 2520 "OMX_AUDIO_CodingMP3", 2521 "OMX_AUDIO_CodingSBC", 2522 "OMX_AUDIO_CodingVORBIS", 2523 "OMX_AUDIO_CodingWMA", 2524 "OMX_AUDIO_CodingRA", 2525 "OMX_AUDIO_CodingMIDI", 2526 }; 2527 2528 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2529 2530 if (type < 0 || (size_t)type >= numNames) { 2531 return "UNKNOWN"; 2532 } else { 2533 return kNames[type]; 2534 } 2535} 2536 2537static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 2538 static const char *kNames[] = { 2539 "OMX_AUDIO_PCMModeLinear", 2540 "OMX_AUDIO_PCMModeALaw", 2541 "OMX_AUDIO_PCMModeMULaw", 2542 }; 2543 2544 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2545 2546 if (type < 0 || (size_t)type >= numNames) { 2547 return "UNKNOWN"; 2548 } else { 2549 return kNames[type]; 2550 } 2551} 2552 2553static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 2554 static const char *kNames[] = { 2555 "OMX_AUDIO_AMRBandModeUnused", 2556 "OMX_AUDIO_AMRBandModeNB0", 2557 "OMX_AUDIO_AMRBandModeNB1", 2558 "OMX_AUDIO_AMRBandModeNB2", 2559 "OMX_AUDIO_AMRBandModeNB3", 2560 "OMX_AUDIO_AMRBandModeNB4", 2561 "OMX_AUDIO_AMRBandModeNB5", 2562 "OMX_AUDIO_AMRBandModeNB6", 2563 "OMX_AUDIO_AMRBandModeNB7", 2564 "OMX_AUDIO_AMRBandModeWB0", 2565 "OMX_AUDIO_AMRBandModeWB1", 2566 "OMX_AUDIO_AMRBandModeWB2", 2567 "OMX_AUDIO_AMRBandModeWB3", 2568 "OMX_AUDIO_AMRBandModeWB4", 2569 "OMX_AUDIO_AMRBandModeWB5", 2570 "OMX_AUDIO_AMRBandModeWB6", 2571 "OMX_AUDIO_AMRBandModeWB7", 2572 "OMX_AUDIO_AMRBandModeWB8", 2573 }; 2574 2575 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2576 2577 if (type < 0 || (size_t)type >= numNames) { 2578 return "UNKNOWN"; 2579 } else { 2580 return kNames[type]; 2581 } 2582} 2583 2584static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 2585 static const char *kNames[] = { 2586 "OMX_AUDIO_AMRFrameFormatConformance", 2587 "OMX_AUDIO_AMRFrameFormatIF1", 2588 "OMX_AUDIO_AMRFrameFormatIF2", 2589 "OMX_AUDIO_AMRFrameFormatFSF", 2590 "OMX_AUDIO_AMRFrameFormatRTPPayload", 2591 "OMX_AUDIO_AMRFrameFormatITU", 2592 }; 2593 2594 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2595 2596 if (type < 0 || (size_t)type >= numNames) { 2597 return "UNKNOWN"; 2598 } else { 2599 return kNames[type]; 2600 } 2601} 2602 2603void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 2604 OMX_PARAM_PORTDEFINITIONTYPE def; 2605 InitOMXParams(&def); 2606 def.nPortIndex = portIndex; 2607 2608 status_t err = mOMX->getParameter( 2609 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2610 CHECK_EQ(err, OK); 2611 2612 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 2613 2614 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 2615 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 2616 2617 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 2618 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 2619 printf(" nBufferSize = %ld\n", def.nBufferSize); 2620 2621 switch (def.eDomain) { 2622 case OMX_PortDomainImage: 2623 { 2624 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2625 2626 printf("\n"); 2627 printf(" // Image\n"); 2628 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 2629 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 2630 printf(" nStride = %ld\n", imageDef->nStride); 2631 2632 printf(" eCompressionFormat = %s\n", 2633 imageCompressionFormatString(imageDef->eCompressionFormat)); 2634 2635 printf(" eColorFormat = %s\n", 2636 colorFormatString(imageDef->eColorFormat)); 2637 2638 break; 2639 } 2640 2641 case OMX_PortDomainVideo: 2642 { 2643 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2644 2645 printf("\n"); 2646 printf(" // Video\n"); 2647 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 2648 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 2649 printf(" nStride = %ld\n", videoDef->nStride); 2650 2651 printf(" eCompressionFormat = %s\n", 2652 videoCompressionFormatString(videoDef->eCompressionFormat)); 2653 2654 printf(" eColorFormat = %s\n", 2655 colorFormatString(videoDef->eColorFormat)); 2656 2657 break; 2658 } 2659 2660 case OMX_PortDomainAudio: 2661 { 2662 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2663 2664 printf("\n"); 2665 printf(" // Audio\n"); 2666 printf(" eEncoding = %s\n", 2667 audioCodingTypeString(audioDef->eEncoding)); 2668 2669 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2670 OMX_AUDIO_PARAM_PCMMODETYPE params; 2671 InitOMXParams(¶ms); 2672 params.nPortIndex = portIndex; 2673 2674 err = mOMX->getParameter( 2675 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2676 CHECK_EQ(err, OK); 2677 2678 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2679 printf(" nChannels = %ld\n", params.nChannels); 2680 printf(" bInterleaved = %d\n", params.bInterleaved); 2681 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2682 2683 printf(" eNumData = %s\n", 2684 params.eNumData == OMX_NumericalDataSigned 2685 ? "signed" : "unsigned"); 2686 2687 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2688 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 2689 OMX_AUDIO_PARAM_AMRTYPE amr; 2690 InitOMXParams(&amr); 2691 amr.nPortIndex = portIndex; 2692 2693 err = mOMX->getParameter( 2694 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2695 CHECK_EQ(err, OK); 2696 2697 printf(" nChannels = %ld\n", amr.nChannels); 2698 printf(" eAMRBandMode = %s\n", 2699 amrBandModeString(amr.eAMRBandMode)); 2700 printf(" eAMRFrameFormat = %s\n", 2701 amrFrameFormatString(amr.eAMRFrameFormat)); 2702 } 2703 2704 break; 2705 } 2706 2707 default: 2708 { 2709 printf(" // Unknown\n"); 2710 break; 2711 } 2712 } 2713 2714 printf("}\n"); 2715} 2716 2717void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2718 mOutputFormat = new MetaData; 2719 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2720 2721 OMX_PARAM_PORTDEFINITIONTYPE def; 2722 InitOMXParams(&def); 2723 def.nPortIndex = kPortIndexOutput; 2724 2725 status_t err = mOMX->getParameter( 2726 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2727 CHECK_EQ(err, OK); 2728 2729 switch (def.eDomain) { 2730 case OMX_PortDomainImage: 2731 { 2732 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2733 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2734 2735 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2736 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2737 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2738 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2739 break; 2740 } 2741 2742 case OMX_PortDomainAudio: 2743 { 2744 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2745 2746 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 2747 OMX_AUDIO_PARAM_PCMMODETYPE params; 2748 InitOMXParams(¶ms); 2749 params.nPortIndex = kPortIndexOutput; 2750 2751 err = mOMX->getParameter( 2752 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2753 CHECK_EQ(err, OK); 2754 2755 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2756 CHECK_EQ(params.nBitPerSample, 16); 2757 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2758 2759 int32_t numChannels, sampleRate; 2760 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2761 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2762 2763 if ((OMX_U32)numChannels != params.nChannels) { 2764 LOGW("Codec outputs a different number of channels than " 2765 "the input stream contains."); 2766 } 2767 2768 mOutputFormat->setCString( 2769 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2770 2771 // Use the codec-advertised number of channels, as some 2772 // codecs appear to output stereo even if the input data is 2773 // mono. 2774 mOutputFormat->setInt32(kKeyChannelCount, params.nChannels); 2775 2776 // The codec-reported sampleRate is not reliable... 2777 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2778 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 2779 OMX_AUDIO_PARAM_AMRTYPE amr; 2780 InitOMXParams(&amr); 2781 amr.nPortIndex = kPortIndexOutput; 2782 2783 err = mOMX->getParameter( 2784 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2785 CHECK_EQ(err, OK); 2786 2787 CHECK_EQ(amr.nChannels, 1); 2788 mOutputFormat->setInt32(kKeyChannelCount, 1); 2789 2790 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 2791 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 2792 mOutputFormat->setCString( 2793 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 2794 mOutputFormat->setInt32(kKeySampleRate, 8000); 2795 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 2796 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 2797 mOutputFormat->setCString( 2798 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 2799 mOutputFormat->setInt32(kKeySampleRate, 16000); 2800 } else { 2801 CHECK(!"Unknown AMR band mode."); 2802 } 2803 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 2804 mOutputFormat->setCString( 2805 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 2806 } else { 2807 CHECK(!"Should not be here. Unknown audio encoding."); 2808 } 2809 break; 2810 } 2811 2812 case OMX_PortDomainVideo: 2813 { 2814 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2815 2816 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2817 mOutputFormat->setCString( 2818 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2819 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2820 mOutputFormat->setCString( 2821 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 2822 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2823 mOutputFormat->setCString( 2824 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 2825 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2826 mOutputFormat->setCString( 2827 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 2828 } else { 2829 CHECK(!"Unknown compression format."); 2830 } 2831 2832 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2833 // This component appears to be lying to me. 2834 mOutputFormat->setInt32( 2835 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2836 mOutputFormat->setInt32( 2837 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2838 } else { 2839 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2840 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2841 } 2842 2843 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2844 break; 2845 } 2846 2847 default: 2848 { 2849 CHECK(!"should not be here, neither audio nor video."); 2850 break; 2851 } 2852 } 2853} 2854 2855//////////////////////////////////////////////////////////////////////////////// 2856 2857status_t QueryCodecs( 2858 const sp<IOMX> &omx, 2859 const char *mime, bool queryDecoders, 2860 Vector<CodecCapabilities> *results) { 2861 results->clear(); 2862 2863 for (int index = 0;; ++index) { 2864 const char *componentName; 2865 2866 if (!queryDecoders) { 2867 componentName = GetCodec( 2868 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 2869 mime, index); 2870 } else { 2871 componentName = GetCodec( 2872 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 2873 mime, index); 2874 } 2875 2876 if (!componentName) { 2877 return OK; 2878 } 2879 2880 sp<OMXCodecObserver> observer = new OMXCodecObserver; 2881 IOMX::node_id node; 2882 status_t err = omx->allocateNode(componentName, observer, &node); 2883 2884 if (err != OK) { 2885 continue; 2886 } 2887 2888 OMXCodec::setComponentRole(omx, node, queryDecoders, mime); 2889 2890 results->push(); 2891 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 2892 caps->mComponentName = componentName; 2893 2894 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 2895 InitOMXParams(¶m); 2896 2897 param.nPortIndex = queryDecoders ? 0 : 1; 2898 2899 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 2900 err = omx->getParameter( 2901 node, OMX_IndexParamVideoProfileLevelQuerySupported, 2902 ¶m, sizeof(param)); 2903 2904 if (err != OK) { 2905 break; 2906 } 2907 2908 CodecProfileLevel profileLevel; 2909 profileLevel.mProfile = param.eProfile; 2910 profileLevel.mLevel = param.eLevel; 2911 2912 caps->mProfileLevels.push(profileLevel); 2913 } 2914 2915 CHECK_EQ(omx->freeNode(node), OK); 2916 } 2917} 2918 2919} // namespace android 2920