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