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