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