OMXCodec.cpp revision 269091da58951736dc2f4c8b74886b6a9aa12be1
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 drainInputBuffers(); 1152 fillOutputBuffers(); 1153 } 1154 } 1155 1156 break; 1157 } 1158 1159 default: 1160 { 1161 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 1162 break; 1163 } 1164 } 1165} 1166 1167void OMXCodec::onStateChange(OMX_STATETYPE newState) { 1168 switch (newState) { 1169 case OMX_StateIdle: 1170 { 1171 CODEC_LOGV("Now Idle."); 1172 if (mState == LOADED_TO_IDLE) { 1173 status_t err = mOMX->send_command( 1174 mNode, OMX_CommandStateSet, OMX_StateExecuting); 1175 1176 CHECK_EQ(err, OK); 1177 1178 setState(IDLE_TO_EXECUTING); 1179 } else { 1180 CHECK_EQ(mState, EXECUTING_TO_IDLE); 1181 1182 CHECK_EQ( 1183 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 1184 mPortBuffers[kPortIndexInput].size()); 1185 1186 CHECK_EQ( 1187 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 1188 mPortBuffers[kPortIndexOutput].size()); 1189 1190 status_t err = mOMX->send_command( 1191 mNode, OMX_CommandStateSet, OMX_StateLoaded); 1192 1193 CHECK_EQ(err, OK); 1194 1195 err = freeBuffersOnPort(kPortIndexInput); 1196 CHECK_EQ(err, OK); 1197 1198 err = freeBuffersOnPort(kPortIndexOutput); 1199 CHECK_EQ(err, OK); 1200 1201 mPortStatus[kPortIndexInput] = ENABLED; 1202 mPortStatus[kPortIndexOutput] = ENABLED; 1203 1204 setState(IDLE_TO_LOADED); 1205 } 1206 break; 1207 } 1208 1209 case OMX_StateExecuting: 1210 { 1211 CHECK_EQ(mState, IDLE_TO_EXECUTING); 1212 1213 CODEC_LOGV("Now Executing."); 1214 1215 setState(EXECUTING); 1216 1217 // Buffers will be submitted to the component in the first 1218 // call to OMXCodec::read as mInitialBufferSubmit is true at 1219 // this point. This ensures that this on_message call returns, 1220 // releases the lock and ::init can notice the state change and 1221 // itself return. 1222 break; 1223 } 1224 1225 case OMX_StateLoaded: 1226 { 1227 CHECK_EQ(mState, IDLE_TO_LOADED); 1228 1229 CODEC_LOGV("Now Loaded."); 1230 1231 setState(LOADED); 1232 break; 1233 } 1234 1235 default: 1236 { 1237 CHECK(!"should not be here."); 1238 break; 1239 } 1240 } 1241} 1242 1243// static 1244size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 1245 size_t n = 0; 1246 for (size_t i = 0; i < buffers.size(); ++i) { 1247 if (!buffers[i].mOwnedByComponent) { 1248 ++n; 1249 } 1250 } 1251 1252 return n; 1253} 1254 1255status_t OMXCodec::freeBuffersOnPort( 1256 OMX_U32 portIndex, bool onlyThoseWeOwn) { 1257 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1258 1259 status_t stickyErr = OK; 1260 1261 for (size_t i = buffers->size(); i-- > 0;) { 1262 BufferInfo *info = &buffers->editItemAt(i); 1263 1264 if (onlyThoseWeOwn && info->mOwnedByComponent) { 1265 continue; 1266 } 1267 1268 CHECK_EQ(info->mOwnedByComponent, false); 1269 1270 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 1271 1272 status_t err = 1273 mOMX->free_buffer(mNode, portIndex, info->mBuffer); 1274 1275 if (err != OK) { 1276 stickyErr = err; 1277 } 1278 1279 if (info->mMediaBuffer != NULL) { 1280 info->mMediaBuffer->setObserver(NULL); 1281 1282 // Make sure nobody but us owns this buffer at this point. 1283 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 1284 1285 info->mMediaBuffer->release(); 1286 } 1287 1288 buffers->removeAt(i); 1289 } 1290 1291 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 1292 1293 return stickyErr; 1294} 1295 1296void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 1297 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 1298 1299 CHECK_EQ(mState, EXECUTING); 1300 CHECK_EQ(portIndex, kPortIndexOutput); 1301 setState(RECONFIGURING); 1302 1303 if (mQuirks & kNeedsFlushBeforeDisable) { 1304 if (!flushPortAsync(portIndex)) { 1305 onCmdComplete(OMX_CommandFlush, portIndex); 1306 } 1307 } else { 1308 disablePortAsync(portIndex); 1309 } 1310} 1311 1312bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 1313 CHECK(mState == EXECUTING || mState == RECONFIGURING 1314 || mState == EXECUTING_TO_IDLE); 1315 1316 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 1317 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 1318 mPortBuffers[portIndex].size()); 1319 1320 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1321 mPortStatus[portIndex] = SHUTTING_DOWN; 1322 1323 if ((mQuirks & kRequiresFlushCompleteEmulation) 1324 && countBuffersWeOwn(mPortBuffers[portIndex]) 1325 == mPortBuffers[portIndex].size()) { 1326 // No flush is necessary and this component fails to send a 1327 // flush-complete event in this case. 1328 1329 return false; 1330 } 1331 1332 status_t err = 1333 mOMX->send_command(mNode, OMX_CommandFlush, portIndex); 1334 CHECK_EQ(err, OK); 1335 1336 return true; 1337} 1338 1339void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 1340 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1341 1342 CHECK_EQ(mPortStatus[portIndex], ENABLED); 1343 mPortStatus[portIndex] = DISABLING; 1344 1345 status_t err = 1346 mOMX->send_command(mNode, OMX_CommandPortDisable, portIndex); 1347 CHECK_EQ(err, OK); 1348 1349 freeBuffersOnPort(portIndex, true); 1350} 1351 1352void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 1353 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1354 1355 CHECK_EQ(mPortStatus[portIndex], DISABLED); 1356 mPortStatus[portIndex] = ENABLING; 1357 1358 status_t err = 1359 mOMX->send_command(mNode, OMX_CommandPortEnable, portIndex); 1360 CHECK_EQ(err, OK); 1361} 1362 1363void OMXCodec::fillOutputBuffers() { 1364 CHECK_EQ(mState, EXECUTING); 1365 1366 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1367 for (size_t i = 0; i < buffers->size(); ++i) { 1368 fillOutputBuffer(&buffers->editItemAt(i)); 1369 } 1370} 1371 1372void OMXCodec::drainInputBuffers() { 1373 CHECK(mState == EXECUTING || mState == RECONFIGURING); 1374 1375 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1376 for (size_t i = 0; i < buffers->size(); ++i) { 1377 drainInputBuffer(&buffers->editItemAt(i)); 1378 } 1379} 1380 1381void OMXCodec::drainInputBuffer(BufferInfo *info) { 1382 CHECK_EQ(info->mOwnedByComponent, false); 1383 1384 if (mSignalledEOS) { 1385 return; 1386 } 1387 1388 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 1389 const CodecSpecificData *specific = 1390 mCodecSpecificData[mCodecSpecificDataIndex]; 1391 1392 size_t size = specific->mSize; 1393 1394 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 1395 && !(mQuirks & kWantsNALFragments)) { 1396 static const uint8_t kNALStartCode[4] = 1397 { 0x00, 0x00, 0x00, 0x01 }; 1398 1399 CHECK(info->mMem->size() >= specific->mSize + 4); 1400 1401 size += 4; 1402 1403 memcpy(info->mMem->pointer(), kNALStartCode, 4); 1404 memcpy((uint8_t *)info->mMem->pointer() + 4, 1405 specific->mData, specific->mSize); 1406 } else { 1407 CHECK(info->mMem->size() >= specific->mSize); 1408 memcpy(info->mMem->pointer(), specific->mData, specific->mSize); 1409 } 1410 1411 mOMX->empty_buffer( 1412 mNode, info->mBuffer, 0, size, 1413 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 1414 0); 1415 1416 info->mOwnedByComponent = true; 1417 1418 ++mCodecSpecificDataIndex; 1419 return; 1420 } 1421 1422 MediaBuffer *srcBuffer; 1423 status_t err; 1424 if (mSeekTimeUs >= 0) { 1425 MediaSource::ReadOptions options; 1426 options.setSeekTo(mSeekTimeUs); 1427 mSeekTimeUs = -1; 1428 1429 err = mSource->read(&srcBuffer, &options); 1430 } else { 1431 err = mSource->read(&srcBuffer); 1432 } 1433 1434 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1435 OMX_TICKS timestamp = 0; 1436 size_t srcLength = 0; 1437 1438 if (err != OK) { 1439 CODEC_LOGV("signalling end of input stream."); 1440 flags |= OMX_BUFFERFLAG_EOS; 1441 1442 mSignalledEOS = true; 1443 } else { 1444 srcLength = srcBuffer->range_length(); 1445 1446 if (info->mMem->size() < srcLength) { 1447 LOGE("info->mMem->size() = %d, srcLength = %d", 1448 info->mMem->size(), srcLength); 1449 } 1450 CHECK(info->mMem->size() >= srcLength); 1451 memcpy(info->mMem->pointer(), 1452 (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), 1453 srcLength); 1454 1455 int32_t units, scale; 1456 if (srcBuffer->meta_data()->findInt32(kKeyTimeUnits, &units) 1457 && srcBuffer->meta_data()->findInt32(kKeyTimeScale, &scale)) { 1458 timestamp = ((OMX_TICKS)units * 1000000) / scale; 1459 1460 CODEC_LOGV("Calling empty_buffer on buffer %p (length %d)", 1461 info->mBuffer, srcLength); 1462 CODEC_LOGV("Calling empty_buffer with timestamp %lld us (%.2f secs)", 1463 timestamp, timestamp / 1E6); 1464 } 1465 } 1466 1467 mOMX->empty_buffer( 1468 mNode, info->mBuffer, 0, srcLength, 1469 flags, timestamp); 1470 1471 info->mOwnedByComponent = true; 1472 1473 if (srcBuffer != NULL) { 1474 srcBuffer->release(); 1475 srcBuffer = NULL; 1476 } 1477} 1478 1479void OMXCodec::fillOutputBuffer(BufferInfo *info) { 1480 CHECK_EQ(info->mOwnedByComponent, false); 1481 1482 if (mNoMoreOutputData) { 1483 CODEC_LOGV("There is no more output data available, not " 1484 "calling fillOutputBuffer"); 1485 return; 1486 } 1487 1488 CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer); 1489 mOMX->fill_buffer(mNode, info->mBuffer); 1490 1491 info->mOwnedByComponent = true; 1492} 1493 1494void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 1495 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 1496 for (size_t i = 0; i < buffers->size(); ++i) { 1497 if ((*buffers)[i].mBuffer == buffer) { 1498 drainInputBuffer(&buffers->editItemAt(i)); 1499 return; 1500 } 1501 } 1502 1503 CHECK(!"should not be here."); 1504} 1505 1506void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 1507 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1508 for (size_t i = 0; i < buffers->size(); ++i) { 1509 if ((*buffers)[i].mBuffer == buffer) { 1510 fillOutputBuffer(&buffers->editItemAt(i)); 1511 return; 1512 } 1513 } 1514 1515 CHECK(!"should not be here."); 1516} 1517 1518void OMXCodec::setState(State newState) { 1519 mState = newState; 1520 mAsyncCompletion.signal(); 1521 1522 // This may cause some spurious wakeups but is necessary to 1523 // unblock the reader if we enter ERROR state. 1524 mBufferFilled.signal(); 1525} 1526 1527void OMXCodec::setRawAudioFormat( 1528 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 1529 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 1530 InitOMXParams(&pcmParams); 1531 pcmParams.nPortIndex = portIndex; 1532 1533 status_t err = mOMX->get_parameter( 1534 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1535 1536 CHECK_EQ(err, OK); 1537 1538 pcmParams.nChannels = numChannels; 1539 pcmParams.eNumData = OMX_NumericalDataSigned; 1540 pcmParams.bInterleaved = OMX_TRUE; 1541 pcmParams.nBitPerSample = 16; 1542 pcmParams.nSamplingRate = sampleRate; 1543 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 1544 1545 if (numChannels == 1) { 1546 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 1547 } else { 1548 CHECK_EQ(numChannels, 2); 1549 1550 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 1551 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 1552 } 1553 1554 err = mOMX->set_parameter( 1555 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1556 1557 CHECK_EQ(err, OK); 1558} 1559 1560void OMXCodec::setAMRFormat() { 1561 if (!mIsEncoder) { 1562 OMX_AUDIO_PARAM_AMRTYPE def; 1563 InitOMXParams(&def); 1564 def.nPortIndex = kPortIndexInput; 1565 1566 status_t err = 1567 mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1568 1569 CHECK_EQ(err, OK); 1570 1571 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 1572 def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; 1573 1574 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1575 CHECK_EQ(err, OK); 1576 } 1577 1578 //////////////////////// 1579 1580 if (mIsEncoder) { 1581 sp<MetaData> format = mSource->getFormat(); 1582 int32_t sampleRate; 1583 int32_t numChannels; 1584 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 1585 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 1586 1587 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 1588 } 1589} 1590 1591void OMXCodec::setAMRWBFormat() { 1592 if (!mIsEncoder) { 1593 OMX_AUDIO_PARAM_AMRTYPE def; 1594 InitOMXParams(&def); 1595 def.nPortIndex = kPortIndexInput; 1596 1597 status_t err = 1598 mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1599 1600 CHECK_EQ(err, OK); 1601 1602 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 1603 def.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0; 1604 1605 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1606 CHECK_EQ(err, OK); 1607 } 1608 1609 //////////////////////// 1610 1611 if (mIsEncoder) { 1612 sp<MetaData> format = mSource->getFormat(); 1613 int32_t sampleRate; 1614 int32_t numChannels; 1615 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 1616 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 1617 1618 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 1619 } 1620} 1621 1622void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { 1623 if (mIsEncoder) { 1624 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 1625 } else { 1626 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1627 InitOMXParams(&profile); 1628 profile.nPortIndex = kPortIndexInput; 1629 1630 status_t err = mOMX->get_parameter( 1631 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1632 CHECK_EQ(err, OK); 1633 1634 profile.nChannels = numChannels; 1635 profile.nSampleRate = sampleRate; 1636 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 1637 1638 err = mOMX->set_parameter( 1639 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1640 CHECK_EQ(err, OK); 1641 } 1642} 1643 1644void OMXCodec::setImageOutputFormat( 1645 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 1646 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 1647 1648#if 0 1649 OMX_INDEXTYPE index; 1650 status_t err = mOMX->get_extension_index( 1651 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 1652 CHECK_EQ(err, OK); 1653 1654 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 1655 CHECK_EQ(err, OK); 1656#endif 1657 1658 OMX_PARAM_PORTDEFINITIONTYPE def; 1659 InitOMXParams(&def); 1660 def.nPortIndex = kPortIndexOutput; 1661 1662 status_t err = mOMX->get_parameter( 1663 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1664 CHECK_EQ(err, OK); 1665 1666 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 1667 1668 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1669 1670 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 1671 imageDef->eColorFormat = format; 1672 imageDef->nFrameWidth = width; 1673 imageDef->nFrameHeight = height; 1674 1675 switch (format) { 1676 case OMX_COLOR_FormatYUV420PackedPlanar: 1677 case OMX_COLOR_FormatYUV411Planar: 1678 { 1679 def.nBufferSize = (width * height * 3) / 2; 1680 break; 1681 } 1682 1683 case OMX_COLOR_FormatCbYCrY: 1684 { 1685 def.nBufferSize = width * height * 2; 1686 break; 1687 } 1688 1689 case OMX_COLOR_Format32bitARGB8888: 1690 { 1691 def.nBufferSize = width * height * 4; 1692 break; 1693 } 1694 1695 case OMX_COLOR_Format16bitARGB4444: 1696 case OMX_COLOR_Format16bitARGB1555: 1697 case OMX_COLOR_Format16bitRGB565: 1698 case OMX_COLOR_Format16bitBGR565: 1699 { 1700 def.nBufferSize = width * height * 2; 1701 break; 1702 } 1703 1704 default: 1705 CHECK(!"Should not be here. Unknown color format."); 1706 break; 1707 } 1708 1709 def.nBufferCountActual = def.nBufferCountMin; 1710 1711 err = mOMX->set_parameter( 1712 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1713 CHECK_EQ(err, OK); 1714} 1715 1716void OMXCodec::setJPEGInputFormat( 1717 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 1718 OMX_PARAM_PORTDEFINITIONTYPE def; 1719 InitOMXParams(&def); 1720 def.nPortIndex = kPortIndexInput; 1721 1722 status_t err = mOMX->get_parameter( 1723 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1724 CHECK_EQ(err, OK); 1725 1726 CHECK_EQ(def.eDomain, OMX_PortDomainImage); 1727 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 1728 1729 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); 1730 imageDef->nFrameWidth = width; 1731 imageDef->nFrameHeight = height; 1732 1733 def.nBufferSize = compressedSize; 1734 def.nBufferCountActual = def.nBufferCountMin; 1735 1736 err = mOMX->set_parameter( 1737 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1738 CHECK_EQ(err, OK); 1739} 1740 1741void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 1742 CodecSpecificData *specific = 1743 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 1744 1745 specific->mSize = size; 1746 memcpy(specific->mData, data, size); 1747 1748 mCodecSpecificData.push(specific); 1749} 1750 1751void OMXCodec::clearCodecSpecificData() { 1752 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 1753 free(mCodecSpecificData.editItemAt(i)); 1754 } 1755 mCodecSpecificData.clear(); 1756 mCodecSpecificDataIndex = 0; 1757} 1758 1759status_t OMXCodec::start(MetaData *) { 1760 Mutex::Autolock autoLock(mLock); 1761 1762 if (mState != LOADED) { 1763 return UNKNOWN_ERROR; 1764 } 1765 1766 sp<MetaData> params = new MetaData; 1767 if (mQuirks & kWantsNALFragments) { 1768 params->setInt32(kKeyWantsNALFragments, true); 1769 } 1770 status_t err = mSource->start(params.get()); 1771 1772 if (err != OK) { 1773 return err; 1774 } 1775 1776 mCodecSpecificDataIndex = 0; 1777 mInitialBufferSubmit = true; 1778 mSignalledEOS = false; 1779 mNoMoreOutputData = false; 1780 mSeekTimeUs = -1; 1781 mFilledBuffers.clear(); 1782 1783 return init(); 1784} 1785 1786status_t OMXCodec::stop() { 1787 CODEC_LOGV("stop"); 1788 1789 Mutex::Autolock autoLock(mLock); 1790 1791 while (isIntermediateState(mState)) { 1792 mAsyncCompletion.wait(mLock); 1793 } 1794 1795 switch (mState) { 1796 case LOADED: 1797 case ERROR: 1798 break; 1799 1800 case EXECUTING: 1801 { 1802 setState(EXECUTING_TO_IDLE); 1803 1804 if (mQuirks & kRequiresFlushBeforeShutdown) { 1805 CODEC_LOGV("This component requires a flush before transitioning " 1806 "from EXECUTING to IDLE..."); 1807 1808 bool emulateInputFlushCompletion = 1809 !flushPortAsync(kPortIndexInput); 1810 1811 bool emulateOutputFlushCompletion = 1812 !flushPortAsync(kPortIndexOutput); 1813 1814 if (emulateInputFlushCompletion) { 1815 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 1816 } 1817 1818 if (emulateOutputFlushCompletion) { 1819 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 1820 } 1821 } else { 1822 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 1823 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 1824 1825 status_t err = 1826 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle); 1827 CHECK_EQ(err, OK); 1828 } 1829 1830 while (mState != LOADED && mState != ERROR) { 1831 mAsyncCompletion.wait(mLock); 1832 } 1833 1834 break; 1835 } 1836 1837 default: 1838 { 1839 CHECK(!"should not be here."); 1840 break; 1841 } 1842 } 1843 1844 mSource->stop(); 1845 1846 return OK; 1847} 1848 1849sp<MetaData> OMXCodec::getFormat() { 1850 return mOutputFormat; 1851} 1852 1853status_t OMXCodec::read( 1854 MediaBuffer **buffer, const ReadOptions *options) { 1855 *buffer = NULL; 1856 1857 Mutex::Autolock autoLock(mLock); 1858 1859 if (mState != EXECUTING && mState != RECONFIGURING) { 1860 return UNKNOWN_ERROR; 1861 } 1862 1863 if (mInitialBufferSubmit) { 1864 mInitialBufferSubmit = false; 1865 1866 drainInputBuffers(); 1867 1868 if (mState == EXECUTING) { 1869 // Otherwise mState == RECONFIGURING and this code will trigger 1870 // after the output port is reenabled. 1871 fillOutputBuffers(); 1872 } 1873 } 1874 1875 int64_t seekTimeUs; 1876 if (options && options->getSeekTo(&seekTimeUs)) { 1877 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 1878 1879 mSignalledEOS = false; 1880 mNoMoreOutputData = false; 1881 1882 CHECK(seekTimeUs >= 0); 1883 mSeekTimeUs = seekTimeUs; 1884 1885 mFilledBuffers.clear(); 1886 1887 CHECK_EQ(mState, EXECUTING); 1888 1889 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 1890 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 1891 1892 if (emulateInputFlushCompletion) { 1893 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 1894 } 1895 1896 if (emulateOutputFlushCompletion) { 1897 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 1898 } 1899 } 1900 1901 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 1902 mBufferFilled.wait(mLock); 1903 } 1904 1905 if (mState == ERROR) { 1906 return UNKNOWN_ERROR; 1907 } 1908 1909 if (mFilledBuffers.empty()) { 1910 return ERROR_END_OF_STREAM; 1911 } 1912 1913 size_t index = *mFilledBuffers.begin(); 1914 mFilledBuffers.erase(mFilledBuffers.begin()); 1915 1916 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1917 info->mMediaBuffer->add_ref(); 1918 *buffer = info->mMediaBuffer; 1919 1920 return OK; 1921} 1922 1923void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 1924 Mutex::Autolock autoLock(mLock); 1925 1926 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1927 for (size_t i = 0; i < buffers->size(); ++i) { 1928 BufferInfo *info = &buffers->editItemAt(i); 1929 1930 if (info->mMediaBuffer == buffer) { 1931 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); 1932 fillOutputBuffer(info); 1933 return; 1934 } 1935 } 1936 1937 CHECK(!"should not be here."); 1938} 1939 1940static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 1941 static const char *kNames[] = { 1942 "OMX_IMAGE_CodingUnused", 1943 "OMX_IMAGE_CodingAutoDetect", 1944 "OMX_IMAGE_CodingJPEG", 1945 "OMX_IMAGE_CodingJPEG2K", 1946 "OMX_IMAGE_CodingEXIF", 1947 "OMX_IMAGE_CodingTIFF", 1948 "OMX_IMAGE_CodingGIF", 1949 "OMX_IMAGE_CodingPNG", 1950 "OMX_IMAGE_CodingLZW", 1951 "OMX_IMAGE_CodingBMP", 1952 }; 1953 1954 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 1955 1956 if (type < 0 || (size_t)type >= numNames) { 1957 return "UNKNOWN"; 1958 } else { 1959 return kNames[type]; 1960 } 1961} 1962 1963static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 1964 static const char *kNames[] = { 1965 "OMX_COLOR_FormatUnused", 1966 "OMX_COLOR_FormatMonochrome", 1967 "OMX_COLOR_Format8bitRGB332", 1968 "OMX_COLOR_Format12bitRGB444", 1969 "OMX_COLOR_Format16bitARGB4444", 1970 "OMX_COLOR_Format16bitARGB1555", 1971 "OMX_COLOR_Format16bitRGB565", 1972 "OMX_COLOR_Format16bitBGR565", 1973 "OMX_COLOR_Format18bitRGB666", 1974 "OMX_COLOR_Format18bitARGB1665", 1975 "OMX_COLOR_Format19bitARGB1666", 1976 "OMX_COLOR_Format24bitRGB888", 1977 "OMX_COLOR_Format24bitBGR888", 1978 "OMX_COLOR_Format24bitARGB1887", 1979 "OMX_COLOR_Format25bitARGB1888", 1980 "OMX_COLOR_Format32bitBGRA8888", 1981 "OMX_COLOR_Format32bitARGB8888", 1982 "OMX_COLOR_FormatYUV411Planar", 1983 "OMX_COLOR_FormatYUV411PackedPlanar", 1984 "OMX_COLOR_FormatYUV420Planar", 1985 "OMX_COLOR_FormatYUV420PackedPlanar", 1986 "OMX_COLOR_FormatYUV420SemiPlanar", 1987 "OMX_COLOR_FormatYUV422Planar", 1988 "OMX_COLOR_FormatYUV422PackedPlanar", 1989 "OMX_COLOR_FormatYUV422SemiPlanar", 1990 "OMX_COLOR_FormatYCbYCr", 1991 "OMX_COLOR_FormatYCrYCb", 1992 "OMX_COLOR_FormatCbYCrY", 1993 "OMX_COLOR_FormatCrYCbY", 1994 "OMX_COLOR_FormatYUV444Interleaved", 1995 "OMX_COLOR_FormatRawBayer8bit", 1996 "OMX_COLOR_FormatRawBayer10bit", 1997 "OMX_COLOR_FormatRawBayer8bitcompressed", 1998 "OMX_COLOR_FormatL2", 1999 "OMX_COLOR_FormatL4", 2000 "OMX_COLOR_FormatL8", 2001 "OMX_COLOR_FormatL16", 2002 "OMX_COLOR_FormatL24", 2003 "OMX_COLOR_FormatL32", 2004 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 2005 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 2006 "OMX_COLOR_Format18BitBGR666", 2007 "OMX_COLOR_Format24BitARGB6666", 2008 "OMX_COLOR_Format24BitABGR6666", 2009 }; 2010 2011 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2012 2013 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 2014 2015 if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 2016 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 2017 } else if (type < 0 || (size_t)type >= numNames) { 2018 return "UNKNOWN"; 2019 } else { 2020 return kNames[type]; 2021 } 2022} 2023 2024static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 2025 static const char *kNames[] = { 2026 "OMX_VIDEO_CodingUnused", 2027 "OMX_VIDEO_CodingAutoDetect", 2028 "OMX_VIDEO_CodingMPEG2", 2029 "OMX_VIDEO_CodingH263", 2030 "OMX_VIDEO_CodingMPEG4", 2031 "OMX_VIDEO_CodingWMV", 2032 "OMX_VIDEO_CodingRV", 2033 "OMX_VIDEO_CodingAVC", 2034 "OMX_VIDEO_CodingMJPEG", 2035 }; 2036 2037 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2038 2039 if (type < 0 || (size_t)type >= numNames) { 2040 return "UNKNOWN"; 2041 } else { 2042 return kNames[type]; 2043 } 2044} 2045 2046static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 2047 static const char *kNames[] = { 2048 "OMX_AUDIO_CodingUnused", 2049 "OMX_AUDIO_CodingAutoDetect", 2050 "OMX_AUDIO_CodingPCM", 2051 "OMX_AUDIO_CodingADPCM", 2052 "OMX_AUDIO_CodingAMR", 2053 "OMX_AUDIO_CodingGSMFR", 2054 "OMX_AUDIO_CodingGSMEFR", 2055 "OMX_AUDIO_CodingGSMHR", 2056 "OMX_AUDIO_CodingPDCFR", 2057 "OMX_AUDIO_CodingPDCEFR", 2058 "OMX_AUDIO_CodingPDCHR", 2059 "OMX_AUDIO_CodingTDMAFR", 2060 "OMX_AUDIO_CodingTDMAEFR", 2061 "OMX_AUDIO_CodingQCELP8", 2062 "OMX_AUDIO_CodingQCELP13", 2063 "OMX_AUDIO_CodingEVRC", 2064 "OMX_AUDIO_CodingSMV", 2065 "OMX_AUDIO_CodingG711", 2066 "OMX_AUDIO_CodingG723", 2067 "OMX_AUDIO_CodingG726", 2068 "OMX_AUDIO_CodingG729", 2069 "OMX_AUDIO_CodingAAC", 2070 "OMX_AUDIO_CodingMP3", 2071 "OMX_AUDIO_CodingSBC", 2072 "OMX_AUDIO_CodingVORBIS", 2073 "OMX_AUDIO_CodingWMA", 2074 "OMX_AUDIO_CodingRA", 2075 "OMX_AUDIO_CodingMIDI", 2076 }; 2077 2078 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2079 2080 if (type < 0 || (size_t)type >= numNames) { 2081 return "UNKNOWN"; 2082 } else { 2083 return kNames[type]; 2084 } 2085} 2086 2087static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 2088 static const char *kNames[] = { 2089 "OMX_AUDIO_PCMModeLinear", 2090 "OMX_AUDIO_PCMModeALaw", 2091 "OMX_AUDIO_PCMModeMULaw", 2092 }; 2093 2094 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2095 2096 if (type < 0 || (size_t)type >= numNames) { 2097 return "UNKNOWN"; 2098 } else { 2099 return kNames[type]; 2100 } 2101} 2102 2103static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 2104 static const char *kNames[] = { 2105 "OMX_AUDIO_AMRBandModeUnused", 2106 "OMX_AUDIO_AMRBandModeNB0", 2107 "OMX_AUDIO_AMRBandModeNB1", 2108 "OMX_AUDIO_AMRBandModeNB2", 2109 "OMX_AUDIO_AMRBandModeNB3", 2110 "OMX_AUDIO_AMRBandModeNB4", 2111 "OMX_AUDIO_AMRBandModeNB5", 2112 "OMX_AUDIO_AMRBandModeNB6", 2113 "OMX_AUDIO_AMRBandModeNB7", 2114 "OMX_AUDIO_AMRBandModeWB0", 2115 "OMX_AUDIO_AMRBandModeWB1", 2116 "OMX_AUDIO_AMRBandModeWB2", 2117 "OMX_AUDIO_AMRBandModeWB3", 2118 "OMX_AUDIO_AMRBandModeWB4", 2119 "OMX_AUDIO_AMRBandModeWB5", 2120 "OMX_AUDIO_AMRBandModeWB6", 2121 "OMX_AUDIO_AMRBandModeWB7", 2122 "OMX_AUDIO_AMRBandModeWB8", 2123 }; 2124 2125 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2126 2127 if (type < 0 || (size_t)type >= numNames) { 2128 return "UNKNOWN"; 2129 } else { 2130 return kNames[type]; 2131 } 2132} 2133 2134static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 2135 static const char *kNames[] = { 2136 "OMX_AUDIO_AMRFrameFormatConformance", 2137 "OMX_AUDIO_AMRFrameFormatIF1", 2138 "OMX_AUDIO_AMRFrameFormatIF2", 2139 "OMX_AUDIO_AMRFrameFormatFSF", 2140 "OMX_AUDIO_AMRFrameFormatRTPPayload", 2141 "OMX_AUDIO_AMRFrameFormatITU", 2142 }; 2143 2144 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 2145 2146 if (type < 0 || (size_t)type >= numNames) { 2147 return "UNKNOWN"; 2148 } else { 2149 return kNames[type]; 2150 } 2151} 2152 2153void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 2154 OMX_PARAM_PORTDEFINITIONTYPE def; 2155 InitOMXParams(&def); 2156 def.nPortIndex = portIndex; 2157 2158 status_t err = mOMX->get_parameter( 2159 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2160 CHECK_EQ(err, OK); 2161 2162 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 2163 2164 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 2165 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 2166 2167 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 2168 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 2169 printf(" nBufferSize = %ld\n", def.nBufferSize); 2170 2171 switch (def.eDomain) { 2172 case OMX_PortDomainImage: 2173 { 2174 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2175 2176 printf("\n"); 2177 printf(" // Image\n"); 2178 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 2179 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 2180 printf(" nStride = %ld\n", imageDef->nStride); 2181 2182 printf(" eCompressionFormat = %s\n", 2183 imageCompressionFormatString(imageDef->eCompressionFormat)); 2184 2185 printf(" eColorFormat = %s\n", 2186 colorFormatString(imageDef->eColorFormat)); 2187 2188 break; 2189 } 2190 2191 case OMX_PortDomainVideo: 2192 { 2193 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2194 2195 printf("\n"); 2196 printf(" // Video\n"); 2197 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 2198 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 2199 printf(" nStride = %ld\n", videoDef->nStride); 2200 2201 printf(" eCompressionFormat = %s\n", 2202 videoCompressionFormatString(videoDef->eCompressionFormat)); 2203 2204 printf(" eColorFormat = %s\n", 2205 colorFormatString(videoDef->eColorFormat)); 2206 2207 break; 2208 } 2209 2210 case OMX_PortDomainAudio: 2211 { 2212 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2213 2214 printf("\n"); 2215 printf(" // Audio\n"); 2216 printf(" eEncoding = %s\n", 2217 audioCodingTypeString(audioDef->eEncoding)); 2218 2219 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 2220 OMX_AUDIO_PARAM_PCMMODETYPE params; 2221 InitOMXParams(¶ms); 2222 params.nPortIndex = portIndex; 2223 2224 err = mOMX->get_parameter( 2225 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2226 CHECK_EQ(err, OK); 2227 2228 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 2229 printf(" nChannels = %ld\n", params.nChannels); 2230 printf(" bInterleaved = %d\n", params.bInterleaved); 2231 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 2232 2233 printf(" eNumData = %s\n", 2234 params.eNumData == OMX_NumericalDataSigned 2235 ? "signed" : "unsigned"); 2236 2237 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 2238 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 2239 OMX_AUDIO_PARAM_AMRTYPE amr; 2240 InitOMXParams(&amr); 2241 amr.nPortIndex = portIndex; 2242 2243 err = mOMX->get_parameter( 2244 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2245 CHECK_EQ(err, OK); 2246 2247 printf(" nChannels = %ld\n", amr.nChannels); 2248 printf(" eAMRBandMode = %s\n", 2249 amrBandModeString(amr.eAMRBandMode)); 2250 printf(" eAMRFrameFormat = %s\n", 2251 amrFrameFormatString(amr.eAMRFrameFormat)); 2252 } 2253 2254 break; 2255 } 2256 2257 default: 2258 { 2259 printf(" // Unknown\n"); 2260 break; 2261 } 2262 } 2263 2264 printf("}\n"); 2265} 2266 2267void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 2268 mOutputFormat = new MetaData; 2269 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 2270 2271 OMX_PARAM_PORTDEFINITIONTYPE def; 2272 InitOMXParams(&def); 2273 def.nPortIndex = kPortIndexOutput; 2274 2275 status_t err = mOMX->get_parameter( 2276 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2277 CHECK_EQ(err, OK); 2278 2279 switch (def.eDomain) { 2280 case OMX_PortDomainImage: 2281 { 2282 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 2283 CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); 2284 2285 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2286 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 2287 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 2288 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 2289 break; 2290 } 2291 2292 case OMX_PortDomainAudio: 2293 { 2294 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 2295 2296 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 2297 OMX_AUDIO_PARAM_PCMMODETYPE params; 2298 InitOMXParams(¶ms); 2299 params.nPortIndex = kPortIndexOutput; 2300 2301 err = mOMX->get_parameter( 2302 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 2303 CHECK_EQ(err, OK); 2304 2305 CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); 2306 CHECK_EQ(params.nBitPerSample, 16); 2307 CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); 2308 2309 int32_t numChannels, sampleRate; 2310 inputFormat->findInt32(kKeyChannelCount, &numChannels); 2311 inputFormat->findInt32(kKeySampleRate, &sampleRate); 2312 2313 if ((OMX_U32)numChannels != params.nChannels) { 2314 LOGW("Codec outputs a different number of channels than " 2315 "the input stream contains."); 2316 } 2317 2318 mOutputFormat->setCString( 2319 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2320 2321 // Use the codec-advertised number of channels, as some 2322 // codecs appear to output stereo even if the input data is 2323 // mono. 2324 mOutputFormat->setInt32(kKeyChannelCount, params.nChannels); 2325 2326 // The codec-reported sampleRate is not reliable... 2327 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 2328 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 2329 OMX_AUDIO_PARAM_AMRTYPE amr; 2330 InitOMXParams(&amr); 2331 amr.nPortIndex = kPortIndexOutput; 2332 2333 err = mOMX->get_parameter( 2334 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 2335 CHECK_EQ(err, OK); 2336 2337 CHECK_EQ(amr.nChannels, 1); 2338 mOutputFormat->setInt32(kKeyChannelCount, 1); 2339 2340 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 2341 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 2342 mOutputFormat->setCString( 2343 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 2344 mOutputFormat->setInt32(kKeySampleRate, 8000); 2345 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 2346 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 2347 mOutputFormat->setCString( 2348 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 2349 mOutputFormat->setInt32(kKeySampleRate, 16000); 2350 } else { 2351 CHECK(!"Unknown AMR band mode."); 2352 } 2353 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 2354 mOutputFormat->setCString( 2355 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 2356 } else { 2357 CHECK(!"Should not be here. Unknown audio encoding."); 2358 } 2359 break; 2360 } 2361 2362 case OMX_PortDomainVideo: 2363 { 2364 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2365 2366 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 2367 mOutputFormat->setCString( 2368 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 2369 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 2370 mOutputFormat->setCString( 2371 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 2372 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 2373 mOutputFormat->setCString( 2374 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 2375 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 2376 mOutputFormat->setCString( 2377 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 2378 } else { 2379 CHECK(!"Unknown compression format."); 2380 } 2381 2382 if (!strcmp(mComponentName, "OMX.PV.avcdec")) { 2383 // This component appears to be lying to me. 2384 mOutputFormat->setInt32( 2385 kKeyWidth, (video_def->nFrameWidth + 15) & -16); 2386 mOutputFormat->setInt32( 2387 kKeyHeight, (video_def->nFrameHeight + 15) & -16); 2388 } else { 2389 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 2390 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 2391 } 2392 2393 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 2394 break; 2395 } 2396 2397 default: 2398 { 2399 CHECK(!"should not be here, neither audio nor video."); 2400 break; 2401 } 2402 } 2403} 2404 2405//////////////////////////////////////////////////////////////////////////////// 2406 2407status_t QueryCodecs( 2408 const sp<IOMX> &omx, 2409 const char *mime, bool queryDecoders, 2410 Vector<CodecCapabilities> *results) { 2411 results->clear(); 2412 2413 for (int index = 0;; ++index) { 2414 const char *componentName; 2415 2416 if (!queryDecoders) { 2417 componentName = GetCodec( 2418 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 2419 mime, index); 2420 } else { 2421 componentName = GetCodec( 2422 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 2423 mime, index); 2424 } 2425 2426 if (!componentName) { 2427 return OK; 2428 } 2429 2430 IOMX::node_id node; 2431 status_t err = omx->allocate_node(componentName, &node); 2432 2433 if (err != OK) { 2434 continue; 2435 } 2436 2437 OMXCodec::setComponentRole(omx, node, queryDecoders, mime); 2438 2439 results->push(); 2440 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 2441 caps->mComponentName = componentName; 2442 2443 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 2444 InitOMXParams(¶m); 2445 2446 param.nPortIndex = queryDecoders ? 0 : 1; 2447 2448 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 2449 err = omx->get_parameter( 2450 node, OMX_IndexParamVideoProfileLevelQuerySupported, 2451 ¶m, sizeof(param)); 2452 2453 if (err != OK) { 2454 break; 2455 } 2456 2457 CodecProfileLevel profileLevel; 2458 profileLevel.mProfile = param.eProfile; 2459 profileLevel.mLevel = param.eLevel; 2460 2461 caps->mProfileLevels.push(profileLevel); 2462 } 2463 2464 CHECK_EQ(omx->free_node(node), OK); 2465 } 2466} 2467 2468} // namespace android 2469