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