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