1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "OMXCodec" 19 #include <utils/Log.h> 20 21 #include "include/AACEncoder.h" 22 #include "include/AMRNBEncoder.h" 23 #include "include/AMRWBEncoder.h" 24 #include "include/AVCEncoder.h" 25 #include "include/M4vH263Encoder.h" 26 27 #include "include/ESDS.h" 28 29 #include <binder/IServiceManager.h> 30 #include <binder/MemoryDealer.h> 31 #include <binder/ProcessState.h> 32 #include <media/stagefright/foundation/ADebug.h> 33 #include <media/IMediaPlayerService.h> 34 #include <media/stagefright/HardwareAPI.h> 35 #include <media/stagefright/MediaBuffer.h> 36 #include <media/stagefright/MediaBufferGroup.h> 37 #include <media/stagefright/MediaDefs.h> 38 #include <media/stagefright/MediaExtractor.h> 39 #include <media/stagefright/MetaData.h> 40 #include <media/stagefright/OMXCodec.h> 41 #include <media/stagefright/Utils.h> 42 #include <utils/Vector.h> 43 44 #include <OMX_Audio.h> 45 #include <OMX_Component.h> 46 47 #include "include/avc_utils.h" 48 49 namespace android { 50 51 // Treat time out as an error if we have not received any output 52 // buffers after 3 seconds. 53 const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL; 54 55 // OMX Spec defines less than 50 color formats. If the query for 56 // color format is executed for more than kMaxColorFormatSupported, 57 // the query will fail to avoid looping forever. 58 // 1000 is more than enough for us to tell whether the omx 59 // component in question is buggy or not. 60 const static uint32_t kMaxColorFormatSupported = 1000; 61 62 struct CodecInfo { 63 const char *mime; 64 const char *codec; 65 }; 66 67 #define FACTORY_CREATE_ENCODER(name) \ 68 static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \ 69 return new name(source, meta); \ 70 } 71 72 #define FACTORY_REF(name) { #name, Make##name }, 73 74 FACTORY_CREATE_ENCODER(AMRNBEncoder) 75 FACTORY_CREATE_ENCODER(AMRWBEncoder) 76 FACTORY_CREATE_ENCODER(AACEncoder) 77 FACTORY_CREATE_ENCODER(AVCEncoder) 78 FACTORY_CREATE_ENCODER(M4vH263Encoder) 79 80 static sp<MediaSource> InstantiateSoftwareEncoder( 81 const char *name, const sp<MediaSource> &source, 82 const sp<MetaData> &meta) { 83 struct FactoryInfo { 84 const char *name; 85 sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &); 86 }; 87 88 static const FactoryInfo kFactoryInfo[] = { 89 FACTORY_REF(AMRNBEncoder) 90 FACTORY_REF(AMRWBEncoder) 91 FACTORY_REF(AACEncoder) 92 FACTORY_REF(AVCEncoder) 93 FACTORY_REF(M4vH263Encoder) 94 }; 95 for (size_t i = 0; 96 i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 97 if (!strcmp(name, kFactoryInfo[i].name)) { 98 return (*kFactoryInfo[i].CreateFunc)(source, meta); 99 } 100 } 101 102 return NULL; 103 } 104 105 #undef FACTORY_REF 106 #undef FACTORY_CREATE 107 108 static const CodecInfo kDecoderInfo[] = { 109 { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" }, 110 // { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, 111 { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.google.mp3.decoder" }, 112 // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" }, 113 // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" }, 114 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.google.amrnb.decoder" }, 115 // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" }, 116 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" }, 117 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.google.amrwb.decoder" }, 118 // { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" }, 119 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" }, 120 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.google.aac.decoder" }, 121 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "OMX.google.g711.alaw.decoder" }, 122 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "OMX.google.g711.mlaw.decoder" }, 123 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.DECODER" }, 124 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" }, 125 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" }, 126 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" }, 127 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, 128 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" }, 129 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.google.mpeg4.decoder" }, 130 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.DECODER" }, 131 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" }, 132 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" }, 133 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, 134 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" }, 135 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.google.h263.decoder" }, 136 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.DECODER" }, 137 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" }, 138 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" }, 139 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, 140 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, 141 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" }, 142 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.h264.decoder" }, 143 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.avc.decoder" }, 144 { MEDIA_MIMETYPE_AUDIO_VORBIS, "OMX.google.vorbis.decoder" }, 145 { MEDIA_MIMETYPE_VIDEO_VPX, "OMX.google.vpx.decoder" }, 146 { MEDIA_MIMETYPE_VIDEO_MPEG2, "OMX.Nvidia.mpeg2v.decode" }, 147 }; 148 149 static const CodecInfo kEncoderInfo[] = { 150 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" }, 151 { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" }, 152 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" }, 153 { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" }, 154 { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, 155 { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" }, 156 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.MPEG4E" }, 157 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" }, 158 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, 159 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, 160 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.encoder" }, 161 { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" }, 162 { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" }, 163 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.MPEG4E" }, 164 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" }, 165 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, 166 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, 167 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.encoder" }, 168 { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" }, 169 { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" }, 170 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.H264E" }, 171 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" }, 172 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" }, 173 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, 174 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" }, 175 { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" }, 176 { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" }, 177 }; 178 179 #undef OPTIONAL 180 181 #define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 182 #define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 183 #define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__) 184 185 struct OMXCodecObserver : public BnOMXObserver { 186 OMXCodecObserver() { 187 } 188 189 void setCodec(const sp<OMXCodec> &target) { 190 mTarget = target; 191 } 192 193 // from IOMXObserver 194 virtual void onMessage(const omx_message &msg) { 195 sp<OMXCodec> codec = mTarget.promote(); 196 197 if (codec.get() != NULL) { 198 Mutex::Autolock autoLock(codec->mLock); 199 codec->on_message(msg); 200 codec.clear(); 201 } 202 } 203 204 protected: 205 virtual ~OMXCodecObserver() {} 206 207 private: 208 wp<OMXCodec> mTarget; 209 210 OMXCodecObserver(const OMXCodecObserver &); 211 OMXCodecObserver &operator=(const OMXCodecObserver &); 212 }; 213 214 static const char *GetCodec(const CodecInfo *info, size_t numInfos, 215 const char *mime, int index) { 216 CHECK(index >= 0); 217 for(size_t i = 0; i < numInfos; ++i) { 218 if (!strcasecmp(mime, info[i].mime)) { 219 if (index == 0) { 220 return info[i].codec; 221 } 222 223 --index; 224 } 225 } 226 227 return NULL; 228 } 229 230 template<class T> 231 static void InitOMXParams(T *params) { 232 params->nSize = sizeof(T); 233 params->nVersion.s.nVersionMajor = 1; 234 params->nVersion.s.nVersionMinor = 0; 235 params->nVersion.s.nRevision = 0; 236 params->nVersion.s.nStep = 0; 237 } 238 239 static bool IsSoftwareCodec(const char *componentName) { 240 if (!strncmp("OMX.google.", componentName, 11)) { 241 return true; 242 } 243 244 if (!strncmp("OMX.", componentName, 4)) { 245 return false; 246 } 247 248 return true; 249 } 250 251 // A sort order in which OMX software codecs are first, followed 252 // by other (non-OMX) software codecs, followed by everything else. 253 static int CompareSoftwareCodecsFirst( 254 const String8 *elem1, const String8 *elem2) { 255 bool isOMX1 = !strncmp(elem1->string(), "OMX.", 4); 256 bool isOMX2 = !strncmp(elem2->string(), "OMX.", 4); 257 258 bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string()); 259 bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string()); 260 261 if (isSoftwareCodec1) { 262 if (!isSoftwareCodec2) { return -1; } 263 264 if (isOMX1) { 265 if (isOMX2) { return 0; } 266 267 return -1; 268 } else { 269 if (isOMX2) { return 0; } 270 271 return 1; 272 } 273 274 return -1; 275 } 276 277 if (isSoftwareCodec2) { 278 return 1; 279 } 280 281 return 0; 282 } 283 284 // static 285 uint32_t OMXCodec::getComponentQuirks( 286 const char *componentName, bool isEncoder) { 287 uint32_t quirks = 0; 288 289 if (!strcmp(componentName, "OMX.Nvidia.amr.decoder") || 290 !strcmp(componentName, "OMX.Nvidia.amrwb.decoder") || 291 !strcmp(componentName, "OMX.Nvidia.aac.decoder") || 292 !strcmp(componentName, "OMX.Nvidia.mp3.decoder")) { 293 quirks |= kDecoderLiesAboutNumberOfChannels; 294 } 295 296 if (!strcmp(componentName, "OMX.TI.MP3.decode")) { 297 quirks |= kNeedsFlushBeforeDisable; 298 quirks |= kDecoderLiesAboutNumberOfChannels; 299 } 300 if (!strcmp(componentName, "OMX.TI.AAC.decode")) { 301 quirks |= kNeedsFlushBeforeDisable; 302 quirks |= kRequiresFlushCompleteEmulation; 303 quirks |= kSupportsMultipleFramesPerInputBuffer; 304 } 305 if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) { 306 quirks |= kRequiresLoadedToIdleAfterAllocation; 307 quirks |= kRequiresAllocateBufferOnInputPorts; 308 quirks |= kRequiresAllocateBufferOnOutputPorts; 309 if (!strncmp(componentName, "OMX.qcom.video.encoder.avc", 26)) { 310 311 // The AVC encoder advertises the size of output buffers 312 // based on the input video resolution and assumes 313 // the worst/least compression ratio is 0.5. It is found that 314 // sometimes, the output buffer size is larger than 315 // size advertised by the encoder. 316 quirks |= kRequiresLargerEncoderOutputBuffer; 317 } 318 } 319 if (!strncmp(componentName, "OMX.qcom.7x30.video.encoder.", 28)) { 320 } 321 if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) { 322 quirks |= kRequiresAllocateBufferOnOutputPorts; 323 quirks |= kDefersOutputBufferAllocation; 324 } 325 if (!strncmp(componentName, "OMX.qcom.7x30.video.decoder.", 28)) { 326 quirks |= kRequiresAllocateBufferOnInputPorts; 327 quirks |= kRequiresAllocateBufferOnOutputPorts; 328 quirks |= kDefersOutputBufferAllocation; 329 } 330 331 if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.DECODER")) { 332 quirks |= kRequiresAllocateBufferOnInputPorts; 333 quirks |= kRequiresAllocateBufferOnOutputPorts; 334 } 335 336 // FIXME: 337 // Remove the quirks after the work is done. 338 else if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.MPEG4E") || 339 !strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.H264E")) { 340 341 quirks |= kRequiresAllocateBufferOnInputPorts; 342 quirks |= kRequiresAllocateBufferOnOutputPorts; 343 } 344 else if (!strncmp(componentName, "OMX.TI.", 7)) { 345 // Apparently I must not use OMX_UseBuffer on either input or 346 // output ports on any of the TI components or quote: 347 // "(I) may have unexpected problem (sic) which can be timing related 348 // and hard to reproduce." 349 350 quirks |= kRequiresAllocateBufferOnInputPorts; 351 quirks |= kRequiresAllocateBufferOnOutputPorts; 352 if (!strncmp(componentName, "OMX.TI.Video.encoder", 20)) { 353 quirks |= kAvoidMemcopyInputRecordingFrames; 354 } 355 } 356 357 if (!strcmp(componentName, "OMX.TI.Video.Decoder")) { 358 quirks |= kInputBufferSizesAreBogus; 359 } 360 361 if (!strncmp(componentName, "OMX.SEC.", 8) && !isEncoder) { 362 // These output buffers contain no video data, just some 363 // opaque information that allows the overlay to display their 364 // contents. 365 quirks |= kOutputBuffersAreUnreadable; 366 } 367 368 return quirks; 369 } 370 371 // static 372 void OMXCodec::findMatchingCodecs( 373 const char *mime, 374 bool createEncoder, const char *matchComponentName, 375 uint32_t flags, 376 Vector<String8> *matchingCodecs) { 377 matchingCodecs->clear(); 378 379 for (int index = 0;; ++index) { 380 const char *componentName; 381 382 if (createEncoder) { 383 componentName = GetCodec( 384 kEncoderInfo, 385 sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 386 mime, index); 387 } else { 388 componentName = GetCodec( 389 kDecoderInfo, 390 sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 391 mime, index); 392 } 393 394 if (!componentName) { 395 break; 396 } 397 398 // If a specific codec is requested, skip the non-matching ones. 399 if (matchComponentName && strcmp(componentName, matchComponentName)) { 400 continue; 401 } 402 403 // When requesting software-only codecs, only push software codecs 404 // When requesting hardware-only codecs, only push hardware codecs 405 // When there is request neither for software-only nor for 406 // hardware-only codecs, push all codecs 407 if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) || 408 ((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) || 409 (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) { 410 411 matchingCodecs->push(String8(componentName)); 412 } 413 } 414 415 if (flags & kPreferSoftwareCodecs) { 416 matchingCodecs->sort(CompareSoftwareCodecsFirst); 417 } 418 } 419 420 // static 421 sp<MediaSource> OMXCodec::Create( 422 const sp<IOMX> &omx, 423 const sp<MetaData> &meta, bool createEncoder, 424 const sp<MediaSource> &source, 425 const char *matchComponentName, 426 uint32_t flags, 427 const sp<ANativeWindow> &nativeWindow) { 428 int32_t requiresSecureBuffers; 429 if (source->getFormat()->findInt32( 430 kKeyRequiresSecureBuffers, 431 &requiresSecureBuffers) 432 && requiresSecureBuffers) { 433 flags |= kIgnoreCodecSpecificData; 434 flags |= kUseSecureInputBuffers; 435 } 436 437 const char *mime; 438 bool success = meta->findCString(kKeyMIMEType, &mime); 439 CHECK(success); 440 441 Vector<String8> matchingCodecs; 442 findMatchingCodecs( 443 mime, createEncoder, matchComponentName, flags, &matchingCodecs); 444 445 if (matchingCodecs.isEmpty()) { 446 return NULL; 447 } 448 449 sp<OMXCodecObserver> observer = new OMXCodecObserver; 450 IOMX::node_id node = 0; 451 452 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 453 const char *componentNameBase = matchingCodecs[i].string(); 454 const char *componentName = componentNameBase; 455 456 AString tmp; 457 if (flags & kUseSecureInputBuffers) { 458 tmp = componentNameBase; 459 tmp.append(".secure"); 460 461 componentName = tmp.c_str(); 462 } 463 464 if (createEncoder) { 465 sp<MediaSource> softwareCodec = 466 InstantiateSoftwareEncoder(componentName, source, meta); 467 468 if (softwareCodec != NULL) { 469 LOGV("Successfully allocated software codec '%s'", componentName); 470 471 return softwareCodec; 472 } 473 } 474 475 LOGV("Attempting to allocate OMX node '%s'", componentName); 476 477 uint32_t quirks = getComponentQuirks(componentNameBase, createEncoder); 478 479 if (!createEncoder 480 && (quirks & kOutputBuffersAreUnreadable) 481 && (flags & kClientNeedsFramebuffer)) { 482 if (strncmp(componentName, "OMX.SEC.", 8)) { 483 // For OMX.SEC.* decoders we can enable a special mode that 484 // gives the client access to the framebuffer contents. 485 486 LOGW("Component '%s' does not give the client access to " 487 "the framebuffer contents. Skipping.", 488 componentName); 489 490 continue; 491 } 492 } 493 494 status_t err = omx->allocateNode(componentName, observer, &node); 495 if (err == OK) { 496 LOGV("Successfully allocated OMX node '%s'", componentName); 497 498 sp<OMXCodec> codec = new OMXCodec( 499 omx, node, quirks, flags, 500 createEncoder, mime, componentName, 501 source, nativeWindow); 502 503 observer->setCodec(codec); 504 505 err = codec->configureCodec(meta); 506 507 if (err == OK) { 508 if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) { 509 codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime; 510 } 511 512 return codec; 513 } 514 515 LOGV("Failed to configure codec '%s'", componentName); 516 } 517 } 518 519 return NULL; 520 } 521 522 status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { 523 LOGV("configureCodec protected=%d", 524 (mFlags & kEnableGrallocUsageProtected) ? 1 : 0); 525 526 if (!(mFlags & kIgnoreCodecSpecificData)) { 527 uint32_t type; 528 const void *data; 529 size_t size; 530 if (meta->findData(kKeyESDS, &type, &data, &size)) { 531 ESDS esds((const char *)data, size); 532 CHECK_EQ(esds.InitCheck(), (status_t)OK); 533 534 const void *codec_specific_data; 535 size_t codec_specific_data_size; 536 esds.getCodecSpecificInfo( 537 &codec_specific_data, &codec_specific_data_size); 538 539 addCodecSpecificData( 540 codec_specific_data, codec_specific_data_size); 541 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 542 // Parse the AVCDecoderConfigurationRecord 543 544 const uint8_t *ptr = (const uint8_t *)data; 545 546 CHECK(size >= 7); 547 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 548 uint8_t profile = ptr[1]; 549 uint8_t level = ptr[3]; 550 551 // There is decodable content out there that fails the following 552 // assertion, let's be lenient for now... 553 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 554 555 size_t lengthSize = 1 + (ptr[4] & 3); 556 557 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 558 // violates it... 559 // CHECK((ptr[5] >> 5) == 7); // reserved 560 561 size_t numSeqParameterSets = ptr[5] & 31; 562 563 ptr += 6; 564 size -= 6; 565 566 for (size_t i = 0; i < numSeqParameterSets; ++i) { 567 CHECK(size >= 2); 568 size_t length = U16_AT(ptr); 569 570 ptr += 2; 571 size -= 2; 572 573 CHECK(size >= length); 574 575 addCodecSpecificData(ptr, length); 576 577 ptr += length; 578 size -= length; 579 } 580 581 CHECK(size >= 1); 582 size_t numPictureParameterSets = *ptr; 583 ++ptr; 584 --size; 585 586 for (size_t i = 0; i < numPictureParameterSets; ++i) { 587 CHECK(size >= 2); 588 size_t length = U16_AT(ptr); 589 590 ptr += 2; 591 size -= 2; 592 593 CHECK(size >= length); 594 595 addCodecSpecificData(ptr, length); 596 597 ptr += length; 598 size -= length; 599 } 600 601 CODEC_LOGI( 602 "AVC profile = %d (%s), level = %d", 603 (int)profile, AVCProfileToString(profile), level); 604 605 if (!strcmp(mComponentName, "OMX.TI.Video.Decoder") 606 && (profile != kAVCProfileBaseline || level > 30)) { 607 // This stream exceeds the decoder's capabilities. The decoder 608 // does not handle this gracefully and would clobber the heap 609 // and wreak havoc instead... 610 611 LOGE("Profile and/or level exceed the decoder's capabilities."); 612 return ERROR_UNSUPPORTED; 613 } 614 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 615 addCodecSpecificData(data, size); 616 617 CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 618 addCodecSpecificData(data, size); 619 } 620 } 621 622 int32_t bitRate = 0; 623 if (mIsEncoder) { 624 CHECK(meta->findInt32(kKeyBitRate, &bitRate)); 625 } 626 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) { 627 setAMRFormat(false /* isWAMR */, bitRate); 628 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) { 629 setAMRFormat(true /* isWAMR */, bitRate); 630 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) { 631 int32_t numChannels, sampleRate; 632 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 633 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 634 635 status_t err = setAACFormat(numChannels, sampleRate, bitRate); 636 if (err != OK) { 637 CODEC_LOGE("setAACFormat() failed (err = %d)", err); 638 return err; 639 } 640 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME) 641 || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) { 642 // These are PCM-like formats with a fixed sample rate but 643 // a variable number of channels. 644 645 int32_t numChannels; 646 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 647 648 setG711Format(numChannels); 649 } 650 651 if (!strncasecmp(mMIME, "video/", 6)) { 652 653 if (mIsEncoder) { 654 setVideoInputFormat(mMIME, meta); 655 } else { 656 int32_t width, height; 657 bool success = meta->findInt32(kKeyWidth, &width); 658 success = success && meta->findInt32(kKeyHeight, &height); 659 CHECK(success); 660 status_t err = setVideoOutputFormat( 661 mMIME, width, height); 662 663 if (err != OK) { 664 return err; 665 } 666 } 667 } 668 669 if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG) 670 && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) { 671 OMX_COLOR_FORMATTYPE format = 672 OMX_COLOR_Format32bitARGB8888; 673 // OMX_COLOR_FormatYUV420PackedPlanar; 674 // OMX_COLOR_FormatCbYCrY; 675 // OMX_COLOR_FormatYUV411Planar; 676 677 int32_t width, height; 678 bool success = meta->findInt32(kKeyWidth, &width); 679 success = success && meta->findInt32(kKeyHeight, &height); 680 681 int32_t compressedSize; 682 success = success && meta->findInt32( 683 kKeyMaxInputSize, &compressedSize); 684 685 CHECK(success); 686 CHECK(compressedSize > 0); 687 688 setImageOutputFormat(format, width, height); 689 setJPEGInputFormat(width, height, (OMX_U32)compressedSize); 690 } 691 692 int32_t maxInputSize; 693 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 694 setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize); 695 } 696 697 if (!strcmp(mComponentName, "OMX.TI.AMR.encode") 698 || !strcmp(mComponentName, "OMX.TI.WBAMR.encode") 699 || !strcmp(mComponentName, "OMX.TI.AAC.encode")) { 700 setMinBufferSize(kPortIndexOutput, 8192); // XXX 701 } 702 703 initOutputFormat(meta); 704 705 if ((mFlags & kClientNeedsFramebuffer) 706 && !strncmp(mComponentName, "OMX.SEC.", 8)) { 707 OMX_INDEXTYPE index; 708 709 status_t err = 710 mOMX->getExtensionIndex( 711 mNode, 712 "OMX.SEC.index.ThumbnailMode", 713 &index); 714 715 if (err != OK) { 716 return err; 717 } 718 719 OMX_BOOL enable = OMX_TRUE; 720 err = mOMX->setConfig(mNode, index, &enable, sizeof(enable)); 721 722 if (err != OK) { 723 CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') " 724 "returned error 0x%08x", err); 725 726 return err; 727 } 728 729 mQuirks &= ~kOutputBuffersAreUnreadable; 730 } 731 732 if (mNativeWindow != NULL 733 && !mIsEncoder 734 && !strncasecmp(mMIME, "video/", 6) 735 && !strncmp(mComponentName, "OMX.", 4)) { 736 status_t err = initNativeWindow(); 737 if (err != OK) { 738 return err; 739 } 740 } 741 742 return OK; 743 } 744 745 void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { 746 OMX_PARAM_PORTDEFINITIONTYPE def; 747 InitOMXParams(&def); 748 def.nPortIndex = portIndex; 749 750 status_t err = mOMX->getParameter( 751 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 752 CHECK_EQ(err, (status_t)OK); 753 754 if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus)) 755 || (def.nBufferSize < size)) { 756 def.nBufferSize = size; 757 } 758 759 err = mOMX->setParameter( 760 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 761 CHECK_EQ(err, (status_t)OK); 762 763 err = mOMX->getParameter( 764 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 765 CHECK_EQ(err, (status_t)OK); 766 767 // Make sure the setting actually stuck. 768 if (portIndex == kPortIndexInput 769 && (mQuirks & kInputBufferSizesAreBogus)) { 770 CHECK_EQ(def.nBufferSize, size); 771 } else { 772 CHECK(def.nBufferSize >= size); 773 } 774 } 775 776 status_t OMXCodec::setVideoPortFormatType( 777 OMX_U32 portIndex, 778 OMX_VIDEO_CODINGTYPE compressionFormat, 779 OMX_COLOR_FORMATTYPE colorFormat) { 780 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 781 InitOMXParams(&format); 782 format.nPortIndex = portIndex; 783 format.nIndex = 0; 784 bool found = false; 785 786 OMX_U32 index = 0; 787 for (;;) { 788 format.nIndex = index; 789 status_t err = mOMX->getParameter( 790 mNode, OMX_IndexParamVideoPortFormat, 791 &format, sizeof(format)); 792 793 if (err != OK) { 794 return err; 795 } 796 797 // The following assertion is violated by TI's video decoder. 798 // CHECK_EQ(format.nIndex, index); 799 800 #if 1 801 CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", 802 portIndex, 803 index, format.eCompressionFormat, format.eColorFormat); 804 #endif 805 806 if (!strcmp("OMX.TI.Video.encoder", mComponentName)) { 807 if (portIndex == kPortIndexInput 808 && colorFormat == format.eColorFormat) { 809 // eCompressionFormat does not seem right. 810 found = true; 811 break; 812 } 813 if (portIndex == kPortIndexOutput 814 && compressionFormat == format.eCompressionFormat) { 815 // eColorFormat does not seem right. 816 found = true; 817 break; 818 } 819 } 820 821 if (format.eCompressionFormat == compressionFormat 822 && format.eColorFormat == colorFormat) { 823 found = true; 824 break; 825 } 826 827 ++index; 828 if (index >= kMaxColorFormatSupported) { 829 CODEC_LOGE("color format %d or compression format %d is not supported", 830 colorFormat, compressionFormat); 831 return UNKNOWN_ERROR; 832 } 833 } 834 835 if (!found) { 836 return UNKNOWN_ERROR; 837 } 838 839 CODEC_LOGV("found a match."); 840 status_t err = mOMX->setParameter( 841 mNode, OMX_IndexParamVideoPortFormat, 842 &format, sizeof(format)); 843 844 return err; 845 } 846 847 static size_t getFrameSize( 848 OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) { 849 switch (colorFormat) { 850 case OMX_COLOR_FormatYCbYCr: 851 case OMX_COLOR_FormatCbYCrY: 852 return width * height * 2; 853 854 case OMX_COLOR_FormatYUV420Planar: 855 case OMX_COLOR_FormatYUV420SemiPlanar: 856 case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: 857 /* 858 * FIXME: For the Opaque color format, the frame size does not 859 * need to be (w*h*3)/2. It just needs to 860 * be larger than certain minimum buffer size. However, 861 * currently, this opaque foramt has been tested only on 862 * YUV420 formats. If that is changed, then we need to revisit 863 * this part in the future 864 */ 865 case OMX_COLOR_FormatAndroidOpaque: 866 return (width * height * 3) / 2; 867 868 default: 869 CHECK(!"Should not be here. Unsupported color format."); 870 break; 871 } 872 } 873 874 status_t OMXCodec::findTargetColorFormat( 875 const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) { 876 LOGV("findTargetColorFormat"); 877 CHECK(mIsEncoder); 878 879 *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 880 int32_t targetColorFormat; 881 if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) { 882 *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat; 883 } else { 884 if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) { 885 *colorFormat = OMX_COLOR_FormatYCbYCr; 886 } 887 } 888 889 890 // Check whether the target color format is supported. 891 return isColorFormatSupported(*colorFormat, kPortIndexInput); 892 } 893 894 status_t OMXCodec::isColorFormatSupported( 895 OMX_COLOR_FORMATTYPE colorFormat, int portIndex) { 896 LOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat)); 897 898 // Enumerate all the color formats supported by 899 // the omx component to see whether the given 900 // color format is supported. 901 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 902 InitOMXParams(&portFormat); 903 portFormat.nPortIndex = portIndex; 904 OMX_U32 index = 0; 905 portFormat.nIndex = index; 906 while (true) { 907 if (OMX_ErrorNone != mOMX->getParameter( 908 mNode, OMX_IndexParamVideoPortFormat, 909 &portFormat, sizeof(portFormat))) { 910 break; 911 } 912 // Make sure that omx component does not overwrite 913 // the incremented index (bug 2897413). 914 CHECK_EQ(index, portFormat.nIndex); 915 if (portFormat.eColorFormat == colorFormat) { 916 CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat); 917 return OK; // colorFormat is supported! 918 } 919 ++index; 920 portFormat.nIndex = index; 921 922 if (index >= kMaxColorFormatSupported) { 923 CODEC_LOGE("More than %ld color formats are supported???", index); 924 break; 925 } 926 } 927 928 CODEC_LOGE("color format %d is not supported", colorFormat); 929 return UNKNOWN_ERROR; 930 } 931 932 void OMXCodec::setVideoInputFormat( 933 const char *mime, const sp<MetaData>& meta) { 934 935 int32_t width, height, frameRate, bitRate, stride, sliceHeight; 936 bool success = meta->findInt32(kKeyWidth, &width); 937 success = success && meta->findInt32(kKeyHeight, &height); 938 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 939 success = success && meta->findInt32(kKeyBitRate, &bitRate); 940 success = success && meta->findInt32(kKeyStride, &stride); 941 success = success && meta->findInt32(kKeySliceHeight, &sliceHeight); 942 CHECK(success); 943 CHECK(stride != 0); 944 945 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 946 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 947 compressionFormat = OMX_VIDEO_CodingAVC; 948 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 949 compressionFormat = OMX_VIDEO_CodingMPEG4; 950 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 951 compressionFormat = OMX_VIDEO_CodingH263; 952 } else { 953 LOGE("Not a supported video mime type: %s", mime); 954 CHECK(!"Should not be here. Not a supported video mime type."); 955 } 956 957 OMX_COLOR_FORMATTYPE colorFormat; 958 CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat)); 959 960 status_t err; 961 OMX_PARAM_PORTDEFINITIONTYPE def; 962 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 963 964 //////////////////////// Input port ///////////////////////// 965 CHECK_EQ(setVideoPortFormatType( 966 kPortIndexInput, OMX_VIDEO_CodingUnused, 967 colorFormat), (status_t)OK); 968 969 InitOMXParams(&def); 970 def.nPortIndex = kPortIndexInput; 971 972 err = mOMX->getParameter( 973 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 974 CHECK_EQ(err, (status_t)OK); 975 976 def.nBufferSize = getFrameSize(colorFormat, 977 stride > 0? stride: -stride, sliceHeight); 978 979 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 980 981 video_def->nFrameWidth = width; 982 video_def->nFrameHeight = height; 983 video_def->nStride = stride; 984 video_def->nSliceHeight = sliceHeight; 985 video_def->xFramerate = (frameRate << 16); // Q16 format 986 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 987 video_def->eColorFormat = colorFormat; 988 989 err = mOMX->setParameter( 990 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 991 CHECK_EQ(err, (status_t)OK); 992 993 //////////////////////// Output port ///////////////////////// 994 CHECK_EQ(setVideoPortFormatType( 995 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused), 996 (status_t)OK); 997 InitOMXParams(&def); 998 def.nPortIndex = kPortIndexOutput; 999 1000 err = mOMX->getParameter( 1001 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1002 1003 CHECK_EQ(err, (status_t)OK); 1004 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1005 1006 video_def->nFrameWidth = width; 1007 video_def->nFrameHeight = height; 1008 video_def->xFramerate = 0; // No need for output port 1009 video_def->nBitrate = bitRate; // Q16 format 1010 video_def->eCompressionFormat = compressionFormat; 1011 video_def->eColorFormat = OMX_COLOR_FormatUnused; 1012 if (mQuirks & kRequiresLargerEncoderOutputBuffer) { 1013 // Increases the output buffer size 1014 def.nBufferSize = ((def.nBufferSize * 3) >> 1); 1015 } 1016 1017 err = mOMX->setParameter( 1018 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1019 CHECK_EQ(err, (status_t)OK); 1020 1021 /////////////////// Codec-specific //////////////////////// 1022 switch (compressionFormat) { 1023 case OMX_VIDEO_CodingMPEG4: 1024 { 1025 CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK); 1026 break; 1027 } 1028 1029 case OMX_VIDEO_CodingH263: 1030 CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK); 1031 break; 1032 1033 case OMX_VIDEO_CodingAVC: 1034 { 1035 CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK); 1036 break; 1037 } 1038 1039 default: 1040 CHECK(!"Support for this compressionFormat to be implemented."); 1041 break; 1042 } 1043 } 1044 1045 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 1046 if (iFramesInterval < 0) { 1047 return 0xFFFFFFFF; 1048 } else if (iFramesInterval == 0) { 1049 return 0; 1050 } 1051 OMX_U32 ret = frameRate * iFramesInterval; 1052 CHECK(ret > 1); 1053 return ret; 1054 } 1055 1056 status_t OMXCodec::setupErrorCorrectionParameters() { 1057 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 1058 InitOMXParams(&errorCorrectionType); 1059 errorCorrectionType.nPortIndex = kPortIndexOutput; 1060 1061 status_t err = mOMX->getParameter( 1062 mNode, OMX_IndexParamVideoErrorCorrection, 1063 &errorCorrectionType, sizeof(errorCorrectionType)); 1064 if (err != OK) { 1065 LOGW("Error correction param query is not supported"); 1066 return OK; // Optional feature. Ignore this failure 1067 } 1068 1069 errorCorrectionType.bEnableHEC = OMX_FALSE; 1070 errorCorrectionType.bEnableResync = OMX_TRUE; 1071 errorCorrectionType.nResynchMarkerSpacing = 256; 1072 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 1073 errorCorrectionType.bEnableRVLC = OMX_FALSE; 1074 1075 err = mOMX->setParameter( 1076 mNode, OMX_IndexParamVideoErrorCorrection, 1077 &errorCorrectionType, sizeof(errorCorrectionType)); 1078 if (err != OK) { 1079 LOGW("Error correction param configuration is not supported"); 1080 } 1081 1082 // Optional feature. Ignore the failure. 1083 return OK; 1084 } 1085 1086 status_t OMXCodec::setupBitRate(int32_t bitRate) { 1087 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 1088 InitOMXParams(&bitrateType); 1089 bitrateType.nPortIndex = kPortIndexOutput; 1090 1091 status_t err = mOMX->getParameter( 1092 mNode, OMX_IndexParamVideoBitrate, 1093 &bitrateType, sizeof(bitrateType)); 1094 CHECK_EQ(err, (status_t)OK); 1095 1096 bitrateType.eControlRate = OMX_Video_ControlRateVariable; 1097 bitrateType.nTargetBitrate = bitRate; 1098 1099 err = mOMX->setParameter( 1100 mNode, OMX_IndexParamVideoBitrate, 1101 &bitrateType, sizeof(bitrateType)); 1102 CHECK_EQ(err, (status_t)OK); 1103 return OK; 1104 } 1105 1106 status_t OMXCodec::getVideoProfileLevel( 1107 const sp<MetaData>& meta, 1108 const CodecProfileLevel& defaultProfileLevel, 1109 CodecProfileLevel &profileLevel) { 1110 CODEC_LOGV("Default profile: %ld, level %ld", 1111 defaultProfileLevel.mProfile, defaultProfileLevel.mLevel); 1112 1113 // Are the default profile and level overwriten? 1114 int32_t profile, level; 1115 if (!meta->findInt32(kKeyVideoProfile, &profile)) { 1116 profile = defaultProfileLevel.mProfile; 1117 } 1118 if (!meta->findInt32(kKeyVideoLevel, &level)) { 1119 level = defaultProfileLevel.mLevel; 1120 } 1121 CODEC_LOGV("Target profile: %d, level: %d", profile, level); 1122 1123 // Are the target profile and level supported by the encoder? 1124 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 1125 InitOMXParams(¶m); 1126 param.nPortIndex = kPortIndexOutput; 1127 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 1128 status_t err = mOMX->getParameter( 1129 mNode, OMX_IndexParamVideoProfileLevelQuerySupported, 1130 ¶m, sizeof(param)); 1131 1132 if (err != OK) break; 1133 1134 int32_t supportedProfile = static_cast<int32_t>(param.eProfile); 1135 int32_t supportedLevel = static_cast<int32_t>(param.eLevel); 1136 CODEC_LOGV("Supported profile: %d, level %d", 1137 supportedProfile, supportedLevel); 1138 1139 if (profile == supportedProfile && 1140 level <= supportedLevel) { 1141 // We can further check whether the level is a valid 1142 // value; but we will leave that to the omx encoder component 1143 // via OMX_SetParameter call. 1144 profileLevel.mProfile = profile; 1145 profileLevel.mLevel = level; 1146 return OK; 1147 } 1148 } 1149 1150 CODEC_LOGE("Target profile (%d) and level (%d) is not supported", 1151 profile, level); 1152 return BAD_VALUE; 1153 } 1154 1155 status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) { 1156 int32_t iFramesInterval, frameRate, bitRate; 1157 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1158 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1159 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1160 CHECK(success); 1161 OMX_VIDEO_PARAM_H263TYPE h263type; 1162 InitOMXParams(&h263type); 1163 h263type.nPortIndex = kPortIndexOutput; 1164 1165 status_t err = mOMX->getParameter( 1166 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1167 CHECK_EQ(err, (status_t)OK); 1168 1169 h263type.nAllowedPictureTypes = 1170 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1171 1172 h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1173 if (h263type.nPFrames == 0) { 1174 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1175 } 1176 h263type.nBFrames = 0; 1177 1178 // Check profile and level parameters 1179 CodecProfileLevel defaultProfileLevel, profileLevel; 1180 defaultProfileLevel.mProfile = h263type.eProfile; 1181 defaultProfileLevel.mLevel = h263type.eLevel; 1182 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1183 if (err != OK) return err; 1184 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile); 1185 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel); 1186 1187 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 1188 h263type.bForceRoundingTypeToZero = OMX_FALSE; 1189 h263type.nPictureHeaderRepetition = 0; 1190 h263type.nGOBHeaderInterval = 0; 1191 1192 err = mOMX->setParameter( 1193 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1194 CHECK_EQ(err, (status_t)OK); 1195 1196 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1197 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1198 1199 return OK; 1200 } 1201 1202 status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { 1203 int32_t iFramesInterval, frameRate, bitRate; 1204 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1205 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1206 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1207 CHECK(success); 1208 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 1209 InitOMXParams(&mpeg4type); 1210 mpeg4type.nPortIndex = kPortIndexOutput; 1211 1212 status_t err = mOMX->getParameter( 1213 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1214 CHECK_EQ(err, (status_t)OK); 1215 1216 mpeg4type.nSliceHeaderSpacing = 0; 1217 mpeg4type.bSVH = OMX_FALSE; 1218 mpeg4type.bGov = OMX_FALSE; 1219 1220 mpeg4type.nAllowedPictureTypes = 1221 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1222 1223 mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1224 if (mpeg4type.nPFrames == 0) { 1225 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1226 } 1227 mpeg4type.nBFrames = 0; 1228 mpeg4type.nIDCVLCThreshold = 0; 1229 mpeg4type.bACPred = OMX_TRUE; 1230 mpeg4type.nMaxPacketSize = 256; 1231 mpeg4type.nTimeIncRes = 1000; 1232 mpeg4type.nHeaderExtension = 0; 1233 mpeg4type.bReversibleVLC = OMX_FALSE; 1234 1235 // Check profile and level parameters 1236 CodecProfileLevel defaultProfileLevel, profileLevel; 1237 defaultProfileLevel.mProfile = mpeg4type.eProfile; 1238 defaultProfileLevel.mLevel = mpeg4type.eLevel; 1239 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1240 if (err != OK) return err; 1241 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile); 1242 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel); 1243 1244 err = mOMX->setParameter( 1245 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1246 CHECK_EQ(err, (status_t)OK); 1247 1248 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1249 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1250 1251 return OK; 1252 } 1253 1254 status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) { 1255 int32_t iFramesInterval, frameRate, bitRate; 1256 bool success = meta->findInt32(kKeyBitRate, &bitRate); 1257 success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1258 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1259 CHECK(success); 1260 1261 OMX_VIDEO_PARAM_AVCTYPE h264type; 1262 InitOMXParams(&h264type); 1263 h264type.nPortIndex = kPortIndexOutput; 1264 1265 status_t err = mOMX->getParameter( 1266 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1267 CHECK_EQ(err, (status_t)OK); 1268 1269 h264type.nAllowedPictureTypes = 1270 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1271 1272 // Check profile and level parameters 1273 CodecProfileLevel defaultProfileLevel, profileLevel; 1274 defaultProfileLevel.mProfile = h264type.eProfile; 1275 defaultProfileLevel.mLevel = h264type.eLevel; 1276 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1277 if (err != OK) return err; 1278 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile); 1279 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel); 1280 1281 // FIXME: 1282 // Remove the workaround after the work in done. 1283 if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) { 1284 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 1285 } 1286 1287 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 1288 h264type.nSliceHeaderSpacing = 0; 1289 h264type.bUseHadamard = OMX_TRUE; 1290 h264type.nRefFrames = 1; 1291 h264type.nBFrames = 0; 1292 h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1293 if (h264type.nPFrames == 0) { 1294 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1295 } 1296 h264type.nRefIdx10ActiveMinus1 = 0; 1297 h264type.nRefIdx11ActiveMinus1 = 0; 1298 h264type.bEntropyCodingCABAC = OMX_FALSE; 1299 h264type.bWeightedPPrediction = OMX_FALSE; 1300 h264type.bconstIpred = OMX_FALSE; 1301 h264type.bDirect8x8Inference = OMX_FALSE; 1302 h264type.bDirectSpatialTemporal = OMX_FALSE; 1303 h264type.nCabacInitIdc = 0; 1304 } 1305 1306 if (h264type.nBFrames != 0) { 1307 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 1308 } 1309 1310 h264type.bEnableUEP = OMX_FALSE; 1311 h264type.bEnableFMO = OMX_FALSE; 1312 h264type.bEnableASO = OMX_FALSE; 1313 h264type.bEnableRS = OMX_FALSE; 1314 h264type.bFrameMBsOnly = OMX_TRUE; 1315 h264type.bMBAFF = OMX_FALSE; 1316 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 1317 1318 if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName)) { 1319 h264type.eLevel = OMX_VIDEO_AVCLevelMax; 1320 } 1321 1322 err = mOMX->setParameter( 1323 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1324 CHECK_EQ(err, (status_t)OK); 1325 1326 CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1327 1328 return OK; 1329 } 1330 1331 status_t OMXCodec::setVideoOutputFormat( 1332 const char *mime, OMX_U32 width, OMX_U32 height) { 1333 CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); 1334 1335 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 1336 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1337 compressionFormat = OMX_VIDEO_CodingAVC; 1338 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1339 compressionFormat = OMX_VIDEO_CodingMPEG4; 1340 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1341 compressionFormat = OMX_VIDEO_CodingH263; 1342 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) { 1343 compressionFormat = OMX_VIDEO_CodingVPX; 1344 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) { 1345 compressionFormat = OMX_VIDEO_CodingMPEG2; 1346 } else { 1347 LOGE("Not a supported video mime type: %s", mime); 1348 CHECK(!"Should not be here. Not a supported video mime type."); 1349 } 1350 1351 status_t err = setVideoPortFormatType( 1352 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 1353 1354 if (err != OK) { 1355 return err; 1356 } 1357 1358 #if 1 1359 { 1360 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1361 InitOMXParams(&format); 1362 format.nPortIndex = kPortIndexOutput; 1363 format.nIndex = 0; 1364 1365 status_t err = mOMX->getParameter( 1366 mNode, OMX_IndexParamVideoPortFormat, 1367 &format, sizeof(format)); 1368 CHECK_EQ(err, (status_t)OK); 1369 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 1370 1371 CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 1372 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 1373 || format.eColorFormat == OMX_COLOR_FormatCbYCrY 1374 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar 1375 || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 1376 1377 err = mOMX->setParameter( 1378 mNode, OMX_IndexParamVideoPortFormat, 1379 &format, sizeof(format)); 1380 1381 if (err != OK) { 1382 return err; 1383 } 1384 } 1385 #endif 1386 1387 OMX_PARAM_PORTDEFINITIONTYPE def; 1388 InitOMXParams(&def); 1389 def.nPortIndex = kPortIndexInput; 1390 1391 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1392 1393 err = mOMX->getParameter( 1394 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1395 1396 CHECK_EQ(err, (status_t)OK); 1397 1398 #if 1 1399 // XXX Need a (much) better heuristic to compute input buffer sizes. 1400 const size_t X = 64 * 1024; 1401 if (def.nBufferSize < X) { 1402 def.nBufferSize = X; 1403 } 1404 #endif 1405 1406 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1407 1408 video_def->nFrameWidth = width; 1409 video_def->nFrameHeight = height; 1410 1411 video_def->eCompressionFormat = compressionFormat; 1412 video_def->eColorFormat = OMX_COLOR_FormatUnused; 1413 1414 err = mOMX->setParameter( 1415 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1416 1417 if (err != OK) { 1418 return err; 1419 } 1420 1421 //////////////////////////////////////////////////////////////////////////// 1422 1423 InitOMXParams(&def); 1424 def.nPortIndex = kPortIndexOutput; 1425 1426 err = mOMX->getParameter( 1427 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1428 CHECK_EQ(err, (status_t)OK); 1429 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1430 1431 #if 0 1432 def.nBufferSize = 1433 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 1434 #endif 1435 1436 video_def->nFrameWidth = width; 1437 video_def->nFrameHeight = height; 1438 1439 err = mOMX->setParameter( 1440 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1441 1442 return err; 1443 } 1444 1445 OMXCodec::OMXCodec( 1446 const sp<IOMX> &omx, IOMX::node_id node, 1447 uint32_t quirks, uint32_t flags, 1448 bool isEncoder, 1449 const char *mime, 1450 const char *componentName, 1451 const sp<MediaSource> &source, 1452 const sp<ANativeWindow> &nativeWindow) 1453 : mOMX(omx), 1454 mOMXLivesLocally(omx->livesLocally(getpid())), 1455 mNode(node), 1456 mQuirks(quirks), 1457 mFlags(flags), 1458 mIsEncoder(isEncoder), 1459 mMIME(strdup(mime)), 1460 mComponentName(strdup(componentName)), 1461 mSource(source), 1462 mCodecSpecificDataIndex(0), 1463 mState(LOADED), 1464 mInitialBufferSubmit(true), 1465 mSignalledEOS(false), 1466 mNoMoreOutputData(false), 1467 mOutputPortSettingsHaveChanged(false), 1468 mSeekTimeUs(-1), 1469 mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC), 1470 mTargetTimeUs(-1), 1471 mOutputPortSettingsChangedPending(false), 1472 mLeftOverBuffer(NULL), 1473 mPaused(false), 1474 mNativeWindow(!strncmp(componentName, "OMX.google.", 11) 1475 ? NULL : nativeWindow) { 1476 mPortStatus[kPortIndexInput] = ENABLED; 1477 mPortStatus[kPortIndexOutput] = ENABLED; 1478 1479 setComponentRole(); 1480 } 1481 1482 // static 1483 void OMXCodec::setComponentRole( 1484 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, 1485 const char *mime) { 1486 struct MimeToRole { 1487 const char *mime; 1488 const char *decoderRole; 1489 const char *encoderRole; 1490 }; 1491 1492 static const MimeToRole kMimeToRole[] = { 1493 { MEDIA_MIMETYPE_AUDIO_MPEG, 1494 "audio_decoder.mp3", "audio_encoder.mp3" }, 1495 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1496 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1497 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1498 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1499 { MEDIA_MIMETYPE_AUDIO_AAC, 1500 "audio_decoder.aac", "audio_encoder.aac" }, 1501 { MEDIA_MIMETYPE_AUDIO_VORBIS, 1502 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 1503 { MEDIA_MIMETYPE_VIDEO_AVC, 1504 "video_decoder.avc", "video_encoder.avc" }, 1505 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1506 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1507 { MEDIA_MIMETYPE_VIDEO_H263, 1508 "video_decoder.h263", "video_encoder.h263" }, 1509 }; 1510 1511 static const size_t kNumMimeToRole = 1512 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1513 1514 size_t i; 1515 for (i = 0; i < kNumMimeToRole; ++i) { 1516 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1517 break; 1518 } 1519 } 1520 1521 if (i == kNumMimeToRole) { 1522 return; 1523 } 1524 1525 const char *role = 1526 isEncoder ? kMimeToRole[i].encoderRole 1527 : kMimeToRole[i].decoderRole; 1528 1529 if (role != NULL) { 1530 OMX_PARAM_COMPONENTROLETYPE roleParams; 1531 InitOMXParams(&roleParams); 1532 1533 strncpy((char *)roleParams.cRole, 1534 role, OMX_MAX_STRINGNAME_SIZE - 1); 1535 1536 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1537 1538 status_t err = omx->setParameter( 1539 node, OMX_IndexParamStandardComponentRole, 1540 &roleParams, sizeof(roleParams)); 1541 1542 if (err != OK) { 1543 LOGW("Failed to set standard component role '%s'.", role); 1544 } 1545 } 1546 } 1547 1548 void OMXCodec::setComponentRole() { 1549 setComponentRole(mOMX, mNode, mIsEncoder, mMIME); 1550 } 1551 1552 OMXCodec::~OMXCodec() { 1553 mSource.clear(); 1554 1555 CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE); 1556 1557 status_t err = mOMX->freeNode(mNode); 1558 CHECK_EQ(err, (status_t)OK); 1559 1560 mNode = NULL; 1561 setState(DEAD); 1562 1563 clearCodecSpecificData(); 1564 1565 free(mComponentName); 1566 mComponentName = NULL; 1567 1568 free(mMIME); 1569 mMIME = NULL; 1570 } 1571 1572 status_t OMXCodec::init() { 1573 // mLock is held. 1574 1575 CHECK_EQ((int)mState, (int)LOADED); 1576 1577 status_t err; 1578 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 1579 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1580 CHECK_EQ(err, (status_t)OK); 1581 setState(LOADED_TO_IDLE); 1582 } 1583 1584 err = allocateBuffers(); 1585 if (err != (status_t)OK) { 1586 return err; 1587 } 1588 1589 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 1590 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1591 CHECK_EQ(err, (status_t)OK); 1592 1593 setState(LOADED_TO_IDLE); 1594 } 1595 1596 while (mState != EXECUTING && mState != ERROR) { 1597 mAsyncCompletion.wait(mLock); 1598 } 1599 1600 return mState == ERROR ? UNKNOWN_ERROR : OK; 1601 } 1602 1603 // static 1604 bool OMXCodec::isIntermediateState(State state) { 1605 return state == LOADED_TO_IDLE 1606 || state == IDLE_TO_EXECUTING 1607 || state == EXECUTING_TO_IDLE 1608 || state == IDLE_TO_LOADED 1609 || state == RECONFIGURING; 1610 } 1611 1612 status_t OMXCodec::allocateBuffers() { 1613 status_t err = allocateBuffersOnPort(kPortIndexInput); 1614 1615 if (err != OK) { 1616 return err; 1617 } 1618 1619 return allocateBuffersOnPort(kPortIndexOutput); 1620 } 1621 1622 status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 1623 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 1624 return allocateOutputBuffersFromNativeWindow(); 1625 } 1626 1627 if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) { 1628 LOGE("protected output buffers must be stent to an ANativeWindow"); 1629 return PERMISSION_DENIED; 1630 } 1631 1632 status_t err = OK; 1633 if ((mFlags & kStoreMetaDataInVideoBuffers) 1634 && portIndex == kPortIndexInput) { 1635 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 1636 if (err != OK) { 1637 LOGE("Storing meta data in video buffers is not supported"); 1638 return err; 1639 } 1640 } 1641 1642 OMX_PARAM_PORTDEFINITIONTYPE def; 1643 InitOMXParams(&def); 1644 def.nPortIndex = portIndex; 1645 1646 err = mOMX->getParameter( 1647 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1648 1649 if (err != OK) { 1650 return err; 1651 } 1652 1653 CODEC_LOGV("allocating %lu buffers of size %lu on %s port", 1654 def.nBufferCountActual, def.nBufferSize, 1655 portIndex == kPortIndexInput ? "input" : "output"); 1656 1657 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 1658 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 1659 1660 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 1661 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 1662 CHECK(mem.get() != NULL); 1663 1664 BufferInfo info; 1665 info.mData = NULL; 1666 info.mSize = def.nBufferSize; 1667 1668 IOMX::buffer_id buffer; 1669 if (portIndex == kPortIndexInput 1670 && ((mQuirks & kRequiresAllocateBufferOnInputPorts) 1671 || (mFlags & kUseSecureInputBuffers))) { 1672 if (mOMXLivesLocally) { 1673 mem.clear(); 1674 1675 err = mOMX->allocateBuffer( 1676 mNode, portIndex, def.nBufferSize, &buffer, 1677 &info.mData); 1678 } else { 1679 err = mOMX->allocateBufferWithBackup( 1680 mNode, portIndex, mem, &buffer); 1681 } 1682 } else if (portIndex == kPortIndexOutput 1683 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 1684 if (mOMXLivesLocally) { 1685 mem.clear(); 1686 1687 err = mOMX->allocateBuffer( 1688 mNode, portIndex, def.nBufferSize, &buffer, 1689 &info.mData); 1690 } else { 1691 err = mOMX->allocateBufferWithBackup( 1692 mNode, portIndex, mem, &buffer); 1693 } 1694 } else { 1695 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 1696 } 1697 1698 if (err != OK) { 1699 LOGE("allocate_buffer_with_backup failed"); 1700 return err; 1701 } 1702 1703 if (mem != NULL) { 1704 info.mData = mem->pointer(); 1705 } 1706 1707 info.mBuffer = buffer; 1708 info.mStatus = OWNED_BY_US; 1709 info.mMem = mem; 1710 info.mMediaBuffer = NULL; 1711 1712 if (portIndex == kPortIndexOutput) { 1713 if (!(mOMXLivesLocally 1714 && (mQuirks & kRequiresAllocateBufferOnOutputPorts) 1715 && (mQuirks & kDefersOutputBufferAllocation))) { 1716 // If the node does not fill in the buffer ptr at this time, 1717 // we will defer creating the MediaBuffer until receiving 1718 // the first FILL_BUFFER_DONE notification instead. 1719 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); 1720 info.mMediaBuffer->setObserver(this); 1721 } 1722 } 1723 1724 mPortBuffers[portIndex].push(info); 1725 1726 CODEC_LOGV("allocated buffer %p on %s port", buffer, 1727 portIndex == kPortIndexInput ? "input" : "output"); 1728 } 1729 1730 // dumpPortStatus(portIndex); 1731 1732 if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) { 1733 Vector<MediaBuffer *> buffers; 1734 for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1735 const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i); 1736 1737 MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize); 1738 buffers.push(mbuf); 1739 } 1740 1741 status_t err = mSource->setBuffers(buffers); 1742 1743 if (err != OK) { 1744 for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1745 buffers.editItemAt(i)->release(); 1746 } 1747 buffers.clear(); 1748 1749 CODEC_LOGE( 1750 "Codec requested to use secure input buffers but " 1751 "upstream source didn't support that."); 1752 1753 return err; 1754 } 1755 } 1756 1757 return OK; 1758 } 1759 1760 status_t OMXCodec::applyRotation() { 1761 sp<MetaData> meta = mSource->getFormat(); 1762 1763 int32_t rotationDegrees; 1764 if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { 1765 rotationDegrees = 0; 1766 } 1767 1768 uint32_t transform; 1769 switch (rotationDegrees) { 1770 case 0: transform = 0; break; 1771 case 90: transform = HAL_TRANSFORM_ROT_90; break; 1772 case 180: transform = HAL_TRANSFORM_ROT_180; break; 1773 case 270: transform = HAL_TRANSFORM_ROT_270; break; 1774 default: transform = 0; break; 1775 } 1776 1777 status_t err = OK; 1778 1779 if (transform) { 1780 err = native_window_set_buffers_transform( 1781 mNativeWindow.get(), transform); 1782 } 1783 1784 return err; 1785 } 1786 1787 status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { 1788 // Get the number of buffers needed. 1789 OMX_PARAM_PORTDEFINITIONTYPE def; 1790 InitOMXParams(&def); 1791 def.nPortIndex = kPortIndexOutput; 1792 1793 status_t err = mOMX->getParameter( 1794 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1795 if (err != OK) { 1796 return err; 1797 } 1798 1799 err = native_window_set_scaling_mode(mNativeWindow.get(), 1800 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 1801 1802 if (err != OK) { 1803 return err; 1804 } 1805 1806 err = native_window_set_buffers_geometry( 1807 mNativeWindow.get(), 1808 def.format.video.nFrameWidth, 1809 def.format.video.nFrameHeight, 1810 def.format.video.eColorFormat); 1811 1812 if (err != 0) { 1813 LOGE("native_window_set_buffers_geometry failed: %s (%d)", 1814 strerror(-err), -err); 1815 return err; 1816 } 1817 1818 err = applyRotation(); 1819 if (err != OK) { 1820 return err; 1821 } 1822 1823 // Set up the native window. 1824 OMX_U32 usage = 0; 1825 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 1826 if (err != 0) { 1827 LOGW("querying usage flags from OMX IL component failed: %d", err); 1828 // XXX: Currently this error is logged, but not fatal. 1829 usage = 0; 1830 } 1831 if (mFlags & kEnableGrallocUsageProtected) { 1832 usage |= GRALLOC_USAGE_PROTECTED; 1833 } 1834 1835 // Make sure to check whether either Stagefright or the video decoder 1836 // requested protected buffers. 1837 if (usage & GRALLOC_USAGE_PROTECTED) { 1838 // Verify that the ANativeWindow sends images directly to 1839 // SurfaceFlinger. 1840 int queuesToNativeWindow = 0; 1841 err = mNativeWindow->query( 1842 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 1843 &queuesToNativeWindow); 1844 if (err != 0) { 1845 LOGE("error authenticating native window: %d", err); 1846 return err; 1847 } 1848 if (queuesToNativeWindow != 1) { 1849 LOGE("native window could not be authenticated"); 1850 return PERMISSION_DENIED; 1851 } 1852 } 1853 1854 LOGV("native_window_set_usage usage=0x%lx", usage); 1855 err = native_window_set_usage( 1856 mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 1857 if (err != 0) { 1858 LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 1859 return err; 1860 } 1861 1862 int minUndequeuedBufs = 0; 1863 err = mNativeWindow->query(mNativeWindow.get(), 1864 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 1865 if (err != 0) { 1866 LOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 1867 strerror(-err), -err); 1868 return err; 1869 } 1870 1871 // XXX: Is this the right logic to use? It's not clear to me what the OMX 1872 // buffer counts refer to - how do they account for the renderer holding on 1873 // to buffers? 1874 if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { 1875 OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; 1876 def.nBufferCountActual = newBufferCount; 1877 err = mOMX->setParameter( 1878 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1879 if (err != OK) { 1880 CODEC_LOGE("setting nBufferCountActual to %lu failed: %d", 1881 newBufferCount, err); 1882 return err; 1883 } 1884 } 1885 1886 err = native_window_set_buffer_count( 1887 mNativeWindow.get(), def.nBufferCountActual); 1888 if (err != 0) { 1889 LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1890 -err); 1891 return err; 1892 } 1893 1894 CODEC_LOGV("allocating %lu buffers from a native window of size %lu on " 1895 "output port", def.nBufferCountActual, def.nBufferSize); 1896 1897 // Dequeue buffers and send them to OMX 1898 for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { 1899 ANativeWindowBuffer* buf; 1900 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); 1901 if (err != 0) { 1902 LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1903 break; 1904 } 1905 1906 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1907 BufferInfo info; 1908 info.mData = NULL; 1909 info.mSize = def.nBufferSize; 1910 info.mStatus = OWNED_BY_US; 1911 info.mMem = NULL; 1912 info.mMediaBuffer = new MediaBuffer(graphicBuffer); 1913 info.mMediaBuffer->setObserver(this); 1914 mPortBuffers[kPortIndexOutput].push(info); 1915 1916 IOMX::buffer_id bufferId; 1917 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 1918 &bufferId); 1919 if (err != 0) { 1920 CODEC_LOGE("registering GraphicBuffer with OMX IL component " 1921 "failed: %d", err); 1922 break; 1923 } 1924 1925 mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId; 1926 1927 CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)", 1928 bufferId, graphicBuffer.get()); 1929 } 1930 1931 OMX_U32 cancelStart; 1932 OMX_U32 cancelEnd; 1933 if (err != 0) { 1934 // If an error occurred while dequeuing we need to cancel any buffers 1935 // that were dequeued. 1936 cancelStart = 0; 1937 cancelEnd = mPortBuffers[kPortIndexOutput].size(); 1938 } else { 1939 // Return the last two buffers to the native window. 1940 cancelStart = def.nBufferCountActual - minUndequeuedBufs; 1941 cancelEnd = def.nBufferCountActual; 1942 } 1943 1944 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1945 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i); 1946 cancelBufferToNativeWindow(info); 1947 } 1948 1949 return err; 1950 } 1951 1952 status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) { 1953 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 1954 CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer); 1955 int err = mNativeWindow->cancelBuffer( 1956 mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get()); 1957 if (err != 0) { 1958 CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err); 1959 1960 setState(ERROR); 1961 return err; 1962 } 1963 info->mStatus = OWNED_BY_NATIVE_WINDOW; 1964 return OK; 1965 } 1966 1967 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() { 1968 // Dequeue the next buffer from the native window. 1969 ANativeWindowBuffer* buf; 1970 int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); 1971 if (err != 0) { 1972 CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err); 1973 1974 setState(ERROR); 1975 return 0; 1976 } 1977 1978 // Determine which buffer we just dequeued. 1979 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 1980 BufferInfo *bufInfo = 0; 1981 for (size_t i = 0; i < buffers->size(); i++) { 1982 sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i). 1983 mMediaBuffer->graphicBuffer(); 1984 if (graphicBuffer->handle == buf->handle) { 1985 bufInfo = &buffers->editItemAt(i); 1986 break; 1987 } 1988 } 1989 1990 if (bufInfo == 0) { 1991 CODEC_LOGE("dequeued unrecognized buffer: %p", buf); 1992 1993 setState(ERROR); 1994 return 0; 1995 } 1996 1997 // The native window no longer owns the buffer. 1998 CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW); 1999 bufInfo->mStatus = OWNED_BY_US; 2000 2001 return bufInfo; 2002 } 2003 2004 status_t OMXCodec::pushBlankBuffersToNativeWindow() { 2005 status_t err = NO_ERROR; 2006 ANativeWindowBuffer* anb = NULL; 2007 int numBufs = 0; 2008 int minUndequeuedBufs = 0; 2009 2010 // We need to reconnect to the ANativeWindow as a CPU client to ensure that 2011 // no frames get dropped by SurfaceFlinger assuming that these are video 2012 // frames. 2013 err = native_window_api_disconnect(mNativeWindow.get(), 2014 NATIVE_WINDOW_API_MEDIA); 2015 if (err != NO_ERROR) { 2016 LOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2017 strerror(-err), -err); 2018 return err; 2019 } 2020 2021 err = native_window_api_connect(mNativeWindow.get(), 2022 NATIVE_WINDOW_API_CPU); 2023 if (err != NO_ERROR) { 2024 LOGE("error pushing blank frames: api_connect failed: %s (%d)", 2025 strerror(-err), -err); 2026 return err; 2027 } 2028 2029 err = native_window_set_scaling_mode(mNativeWindow.get(), 2030 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 2031 if (err != NO_ERROR) { 2032 LOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)", 2033 strerror(-err), -err); 2034 goto error; 2035 } 2036 2037 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1, 2038 HAL_PIXEL_FORMAT_RGBX_8888); 2039 if (err != NO_ERROR) { 2040 LOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)", 2041 strerror(-err), -err); 2042 goto error; 2043 } 2044 2045 err = native_window_set_usage(mNativeWindow.get(), 2046 GRALLOC_USAGE_SW_WRITE_OFTEN); 2047 if (err != NO_ERROR) { 2048 LOGE("error pushing blank frames: set_usage failed: %s (%d)", 2049 strerror(-err), -err); 2050 goto error; 2051 } 2052 2053 err = mNativeWindow->query(mNativeWindow.get(), 2054 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 2055 if (err != NO_ERROR) { 2056 LOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 2057 "failed: %s (%d)", strerror(-err), -err); 2058 goto error; 2059 } 2060 2061 numBufs = minUndequeuedBufs + 1; 2062 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs); 2063 if (err != NO_ERROR) { 2064 LOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", 2065 strerror(-err), -err); 2066 goto error; 2067 } 2068 2069 // We push numBufs + 1 buffers to ensure that we've drawn into the same 2070 // buffer twice. This should guarantee that the buffer has been displayed 2071 // on the screen and then been replaced, so an previous video frames are 2072 // guaranteed NOT to be currently displayed. 2073 for (int i = 0; i < numBufs + 1; i++) { 2074 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb); 2075 if (err != NO_ERROR) { 2076 LOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 2077 strerror(-err), -err); 2078 goto error; 2079 } 2080 2081 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 2082 err = mNativeWindow->lockBuffer(mNativeWindow.get(), 2083 buf->getNativeBuffer()); 2084 if (err != NO_ERROR) { 2085 LOGE("error pushing blank frames: lockBuffer failed: %s (%d)", 2086 strerror(-err), -err); 2087 goto error; 2088 } 2089 2090 // Fill the buffer with the a 1x1 checkerboard pattern ;) 2091 uint32_t* img = NULL; 2092 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 2093 if (err != NO_ERROR) { 2094 LOGE("error pushing blank frames: lock failed: %s (%d)", 2095 strerror(-err), -err); 2096 goto error; 2097 } 2098 2099 *img = 0; 2100 2101 err = buf->unlock(); 2102 if (err != NO_ERROR) { 2103 LOGE("error pushing blank frames: unlock failed: %s (%d)", 2104 strerror(-err), -err); 2105 goto error; 2106 } 2107 2108 err = mNativeWindow->queueBuffer(mNativeWindow.get(), 2109 buf->getNativeBuffer()); 2110 if (err != NO_ERROR) { 2111 LOGE("error pushing blank frames: queueBuffer failed: %s (%d)", 2112 strerror(-err), -err); 2113 goto error; 2114 } 2115 2116 anb = NULL; 2117 } 2118 2119 error: 2120 2121 if (err != NO_ERROR) { 2122 // Clean up after an error. 2123 if (anb != NULL) { 2124 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb); 2125 } 2126 2127 native_window_api_disconnect(mNativeWindow.get(), 2128 NATIVE_WINDOW_API_CPU); 2129 native_window_api_connect(mNativeWindow.get(), 2130 NATIVE_WINDOW_API_MEDIA); 2131 2132 return err; 2133 } else { 2134 // Clean up after success. 2135 err = native_window_api_disconnect(mNativeWindow.get(), 2136 NATIVE_WINDOW_API_CPU); 2137 if (err != NO_ERROR) { 2138 LOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2139 strerror(-err), -err); 2140 return err; 2141 } 2142 2143 err = native_window_api_connect(mNativeWindow.get(), 2144 NATIVE_WINDOW_API_MEDIA); 2145 if (err != NO_ERROR) { 2146 LOGE("error pushing blank frames: api_connect failed: %s (%d)", 2147 strerror(-err), -err); 2148 return err; 2149 } 2150 2151 return NO_ERROR; 2152 } 2153 } 2154 2155 int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) { 2156 CHECK(mIsEncoder); 2157 2158 if (mDecodingTimeList.empty()) { 2159 CHECK(mSignalledEOS || mNoMoreOutputData); 2160 // No corresponding input frame available. 2161 // This could happen when EOS is reached. 2162 return 0; 2163 } 2164 2165 List<int64_t>::iterator it = mDecodingTimeList.begin(); 2166 int64_t timeUs = *it; 2167 2168 // If the output buffer is codec specific configuration, 2169 // do not remove the decoding time from the list. 2170 if (!isCodecSpecific) { 2171 mDecodingTimeList.erase(it); 2172 } 2173 return timeUs; 2174 } 2175 2176 void OMXCodec::on_message(const omx_message &msg) { 2177 if (mState == ERROR) { 2178 LOGW("Dropping OMX message - we're in ERROR state."); 2179 return; 2180 } 2181 2182 switch (msg.type) { 2183 case omx_message::EVENT: 2184 { 2185 onEvent( 2186 msg.u.event_data.event, msg.u.event_data.data1, 2187 msg.u.event_data.data2); 2188 2189 break; 2190 } 2191 2192 case omx_message::EMPTY_BUFFER_DONE: 2193 { 2194 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2195 2196 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 2197 2198 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2199 size_t i = 0; 2200 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2201 ++i; 2202 } 2203 2204 CHECK(i < buffers->size()); 2205 if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) { 2206 LOGW("We already own input buffer %p, yet received " 2207 "an EMPTY_BUFFER_DONE.", buffer); 2208 } 2209 2210 BufferInfo* info = &buffers->editItemAt(i); 2211 info->mStatus = OWNED_BY_US; 2212 2213 // Buffer could not be released until empty buffer done is called. 2214 if (info->mMediaBuffer != NULL) { 2215 if (mIsEncoder && 2216 (mQuirks & kAvoidMemcopyInputRecordingFrames)) { 2217 // If zero-copy mode is enabled this will send the 2218 // input buffer back to the upstream source. 2219 restorePatchedDataPointer(info); 2220 } 2221 2222 info->mMediaBuffer->release(); 2223 info->mMediaBuffer = NULL; 2224 } 2225 2226 if (mPortStatus[kPortIndexInput] == DISABLING) { 2227 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2228 2229 status_t err = freeBuffer(kPortIndexInput, i); 2230 CHECK_EQ(err, (status_t)OK); 2231 } else if (mState != ERROR 2232 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 2233 CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED); 2234 2235 if (mFlags & kUseSecureInputBuffers) { 2236 drainAnyInputBuffer(); 2237 } else { 2238 drainInputBuffer(&buffers->editItemAt(i)); 2239 } 2240 } 2241 break; 2242 } 2243 2244 case omx_message::FILL_BUFFER_DONE: 2245 { 2246 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2247 OMX_U32 flags = msg.u.extended_buffer_data.flags; 2248 2249 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 2250 buffer, 2251 msg.u.extended_buffer_data.range_length, 2252 flags, 2253 msg.u.extended_buffer_data.timestamp, 2254 msg.u.extended_buffer_data.timestamp / 1E6); 2255 2256 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2257 size_t i = 0; 2258 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2259 ++i; 2260 } 2261 2262 CHECK(i < buffers->size()); 2263 BufferInfo *info = &buffers->editItemAt(i); 2264 2265 if (info->mStatus != OWNED_BY_COMPONENT) { 2266 LOGW("We already own output buffer %p, yet received " 2267 "a FILL_BUFFER_DONE.", buffer); 2268 } 2269 2270 info->mStatus = OWNED_BY_US; 2271 2272 if (mPortStatus[kPortIndexOutput] == DISABLING) { 2273 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2274 2275 status_t err = freeBuffer(kPortIndexOutput, i); 2276 CHECK_EQ(err, (status_t)OK); 2277 2278 #if 0 2279 } else if (mPortStatus[kPortIndexOutput] == ENABLED 2280 && (flags & OMX_BUFFERFLAG_EOS)) { 2281 CODEC_LOGV("No more output data."); 2282 mNoMoreOutputData = true; 2283 mBufferFilled.signal(); 2284 #endif 2285 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 2286 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 2287 2288 if (info->mMediaBuffer == NULL) { 2289 CHECK(mOMXLivesLocally); 2290 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 2291 CHECK(mQuirks & kDefersOutputBufferAllocation); 2292 2293 // The qcom video decoders on Nexus don't actually allocate 2294 // output buffer memory on a call to OMX_AllocateBuffer 2295 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 2296 // structure is only filled in later. 2297 2298 info->mMediaBuffer = new MediaBuffer( 2299 msg.u.extended_buffer_data.data_ptr, 2300 info->mSize); 2301 info->mMediaBuffer->setObserver(this); 2302 } 2303 2304 MediaBuffer *buffer = info->mMediaBuffer; 2305 bool isGraphicBuffer = buffer->graphicBuffer() != NULL; 2306 2307 if (!isGraphicBuffer 2308 && msg.u.extended_buffer_data.range_offset 2309 + msg.u.extended_buffer_data.range_length 2310 > buffer->size()) { 2311 CODEC_LOGE( 2312 "Codec lied about its buffer size requirements, " 2313 "sending a buffer larger than the originally " 2314 "advertised size in FILL_BUFFER_DONE!"); 2315 } 2316 buffer->set_range( 2317 msg.u.extended_buffer_data.range_offset, 2318 msg.u.extended_buffer_data.range_length); 2319 2320 buffer->meta_data()->clear(); 2321 2322 buffer->meta_data()->setInt64( 2323 kKeyTime, msg.u.extended_buffer_data.timestamp); 2324 2325 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 2326 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 2327 } 2328 bool isCodecSpecific = false; 2329 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 2330 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 2331 isCodecSpecific = true; 2332 } 2333 2334 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) { 2335 buffer->meta_data()->setInt32(kKeyIsUnreadable, true); 2336 } 2337 2338 buffer->meta_data()->setPointer( 2339 kKeyPlatformPrivate, 2340 msg.u.extended_buffer_data.platform_private); 2341 2342 buffer->meta_data()->setPointer( 2343 kKeyBufferID, 2344 msg.u.extended_buffer_data.buffer); 2345 2346 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 2347 CODEC_LOGV("No more output data."); 2348 mNoMoreOutputData = true; 2349 } 2350 2351 if (mIsEncoder) { 2352 int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific); 2353 buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 2354 } 2355 2356 if (mTargetTimeUs >= 0) { 2357 CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs); 2358 2359 if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) { 2360 CODEC_LOGV( 2361 "skipping output buffer at timestamp %lld us", 2362 msg.u.extended_buffer_data.timestamp); 2363 2364 fillOutputBuffer(info); 2365 break; 2366 } 2367 2368 CODEC_LOGV( 2369 "returning output buffer at target timestamp " 2370 "%lld us", 2371 msg.u.extended_buffer_data.timestamp); 2372 2373 mTargetTimeUs = -1; 2374 } 2375 2376 mFilledBuffers.push_back(i); 2377 mBufferFilled.signal(); 2378 if (mIsEncoder) { 2379 sched_yield(); 2380 } 2381 } 2382 2383 break; 2384 } 2385 2386 default: 2387 { 2388 CHECK(!"should not be here."); 2389 break; 2390 } 2391 } 2392 } 2393 2394 // Has the format changed in any way that the client would have to be aware of? 2395 static bool formatHasNotablyChanged( 2396 const sp<MetaData> &from, const sp<MetaData> &to) { 2397 if (from.get() == NULL && to.get() == NULL) { 2398 return false; 2399 } 2400 2401 if ((from.get() == NULL && to.get() != NULL) 2402 || (from.get() != NULL && to.get() == NULL)) { 2403 return true; 2404 } 2405 2406 const char *mime_from, *mime_to; 2407 CHECK(from->findCString(kKeyMIMEType, &mime_from)); 2408 CHECK(to->findCString(kKeyMIMEType, &mime_to)); 2409 2410 if (strcasecmp(mime_from, mime_to)) { 2411 return true; 2412 } 2413 2414 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 2415 int32_t colorFormat_from, colorFormat_to; 2416 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 2417 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 2418 2419 if (colorFormat_from != colorFormat_to) { 2420 return true; 2421 } 2422 2423 int32_t width_from, width_to; 2424 CHECK(from->findInt32(kKeyWidth, &width_from)); 2425 CHECK(to->findInt32(kKeyWidth, &width_to)); 2426 2427 if (width_from != width_to) { 2428 return true; 2429 } 2430 2431 int32_t height_from, height_to; 2432 CHECK(from->findInt32(kKeyHeight, &height_from)); 2433 CHECK(to->findInt32(kKeyHeight, &height_to)); 2434 2435 if (height_from != height_to) { 2436 return true; 2437 } 2438 2439 int32_t left_from, top_from, right_from, bottom_from; 2440 CHECK(from->findRect( 2441 kKeyCropRect, 2442 &left_from, &top_from, &right_from, &bottom_from)); 2443 2444 int32_t left_to, top_to, right_to, bottom_to; 2445 CHECK(to->findRect( 2446 kKeyCropRect, 2447 &left_to, &top_to, &right_to, &bottom_to)); 2448 2449 if (left_to != left_from || top_to != top_from 2450 || right_to != right_from || bottom_to != bottom_from) { 2451 return true; 2452 } 2453 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 2454 int32_t numChannels_from, numChannels_to; 2455 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 2456 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 2457 2458 if (numChannels_from != numChannels_to) { 2459 return true; 2460 } 2461 2462 int32_t sampleRate_from, sampleRate_to; 2463 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 2464 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 2465 2466 if (sampleRate_from != sampleRate_to) { 2467 return true; 2468 } 2469 } 2470 2471 return false; 2472 } 2473 2474 void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2475 switch (event) { 2476 case OMX_EventCmdComplete: 2477 { 2478 onCmdComplete((OMX_COMMANDTYPE)data1, data2); 2479 break; 2480 } 2481 2482 case OMX_EventError: 2483 { 2484 CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); 2485 2486 setState(ERROR); 2487 break; 2488 } 2489 2490 case OMX_EventPortSettingsChanged: 2491 { 2492 CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", 2493 data1, data2); 2494 2495 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 2496 // There is no need to check whether mFilledBuffers is empty or not 2497 // when the OMX_EventPortSettingsChanged is not meant for reallocating 2498 // the output buffers. 2499 if (data1 == kPortIndexOutput) { 2500 CHECK(mFilledBuffers.empty()); 2501 } 2502 onPortSettingsChanged(data1); 2503 } else if (data1 == kPortIndexOutput && 2504 (data2 == OMX_IndexConfigCommonOutputCrop || 2505 data2 == OMX_IndexConfigCommonScale)) { 2506 2507 sp<MetaData> oldOutputFormat = mOutputFormat; 2508 initOutputFormat(mSource->getFormat()); 2509 2510 if (data2 == OMX_IndexConfigCommonOutputCrop && 2511 formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) { 2512 mOutputPortSettingsHaveChanged = true; 2513 2514 } else if (data2 == OMX_IndexConfigCommonScale) { 2515 OMX_CONFIG_SCALEFACTORTYPE scale; 2516 InitOMXParams(&scale); 2517 scale.nPortIndex = kPortIndexOutput; 2518 2519 // Change display dimension only when necessary. 2520 if (OK == mOMX->getConfig( 2521 mNode, 2522 OMX_IndexConfigCommonScale, 2523 &scale, sizeof(scale))) { 2524 int32_t left, top, right, bottom; 2525 CHECK(mOutputFormat->findRect(kKeyCropRect, 2526 &left, &top, 2527 &right, &bottom)); 2528 2529 // The scale is in 16.16 format. 2530 // scale 1.0 = 0x010000. When there is no 2531 // need to change the display, skip it. 2532 LOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx", 2533 scale.xWidth, scale.xHeight); 2534 2535 if (scale.xWidth != 0x010000) { 2536 mOutputFormat->setInt32(kKeyDisplayWidth, 2537 ((right - left + 1) * scale.xWidth) >> 16); 2538 mOutputPortSettingsHaveChanged = true; 2539 } 2540 2541 if (scale.xHeight != 0x010000) { 2542 mOutputFormat->setInt32(kKeyDisplayHeight, 2543 ((bottom - top + 1) * scale.xHeight) >> 16); 2544 mOutputPortSettingsHaveChanged = true; 2545 } 2546 } 2547 } 2548 } 2549 break; 2550 } 2551 2552 #if 0 2553 case OMX_EventBufferFlag: 2554 { 2555 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 2556 2557 if (data1 == kPortIndexOutput) { 2558 mNoMoreOutputData = true; 2559 } 2560 break; 2561 } 2562 #endif 2563 2564 default: 2565 { 2566 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 2567 break; 2568 } 2569 } 2570 } 2571 2572 void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 2573 switch (cmd) { 2574 case OMX_CommandStateSet: 2575 { 2576 onStateChange((OMX_STATETYPE)data); 2577 break; 2578 } 2579 2580 case OMX_CommandPortDisable: 2581 { 2582 OMX_U32 portIndex = data; 2583 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 2584 2585 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2586 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING); 2587 CHECK_EQ(mPortBuffers[portIndex].size(), 0u); 2588 2589 mPortStatus[portIndex] = DISABLED; 2590 2591 if (mState == RECONFIGURING) { 2592 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2593 2594 sp<MetaData> oldOutputFormat = mOutputFormat; 2595 initOutputFormat(mSource->getFormat()); 2596 2597 // Don't notify clients if the output port settings change 2598 // wasn't of importance to them, i.e. it may be that just the 2599 // number of buffers has changed and nothing else. 2600 bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 2601 if (!mOutputPortSettingsHaveChanged) { 2602 mOutputPortSettingsHaveChanged = formatChanged; 2603 } 2604 2605 status_t err = enablePortAsync(portIndex); 2606 if (err != OK) { 2607 CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err); 2608 setState(ERROR); 2609 } else { 2610 err = allocateBuffersOnPort(portIndex); 2611 if (err != OK) { 2612 CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err); 2613 setState(ERROR); 2614 } 2615 } 2616 } 2617 break; 2618 } 2619 2620 case OMX_CommandPortEnable: 2621 { 2622 OMX_U32 portIndex = data; 2623 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 2624 2625 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2626 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING); 2627 2628 mPortStatus[portIndex] = ENABLED; 2629 2630 if (mState == RECONFIGURING) { 2631 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2632 2633 setState(EXECUTING); 2634 2635 fillOutputBuffers(); 2636 } 2637 break; 2638 } 2639 2640 case OMX_CommandFlush: 2641 { 2642 OMX_U32 portIndex = data; 2643 2644 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 2645 2646 CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN); 2647 mPortStatus[portIndex] = ENABLED; 2648 2649 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 2650 mPortBuffers[portIndex].size()); 2651 2652 if (mState == RECONFIGURING) { 2653 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2654 2655 disablePortAsync(portIndex); 2656 } else if (mState == EXECUTING_TO_IDLE) { 2657 if (mPortStatus[kPortIndexInput] == ENABLED 2658 && mPortStatus[kPortIndexOutput] == ENABLED) { 2659 CODEC_LOGV("Finished flushing both ports, now completing " 2660 "transition from EXECUTING to IDLE."); 2661 2662 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2663 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2664 2665 status_t err = 2666 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2667 CHECK_EQ(err, (status_t)OK); 2668 } 2669 } else { 2670 // We're flushing both ports in preparation for seeking. 2671 2672 if (mPortStatus[kPortIndexInput] == ENABLED 2673 && mPortStatus[kPortIndexOutput] == ENABLED) { 2674 CODEC_LOGV("Finished flushing both ports, now continuing from" 2675 " seek-time."); 2676 2677 // We implicitly resume pulling on our upstream source. 2678 mPaused = false; 2679 2680 drainInputBuffers(); 2681 fillOutputBuffers(); 2682 } 2683 2684 if (mOutputPortSettingsChangedPending) { 2685 CODEC_LOGV( 2686 "Honoring deferred output port settings change."); 2687 2688 mOutputPortSettingsChangedPending = false; 2689 onPortSettingsChanged(kPortIndexOutput); 2690 } 2691 } 2692 2693 break; 2694 } 2695 2696 default: 2697 { 2698 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 2699 break; 2700 } 2701 } 2702 } 2703 2704 void OMXCodec::onStateChange(OMX_STATETYPE newState) { 2705 CODEC_LOGV("onStateChange %d", newState); 2706 2707 switch (newState) { 2708 case OMX_StateIdle: 2709 { 2710 CODEC_LOGV("Now Idle."); 2711 if (mState == LOADED_TO_IDLE) { 2712 status_t err = mOMX->sendCommand( 2713 mNode, OMX_CommandStateSet, OMX_StateExecuting); 2714 2715 CHECK_EQ(err, (status_t)OK); 2716 2717 setState(IDLE_TO_EXECUTING); 2718 } else { 2719 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE); 2720 2721 CHECK_EQ( 2722 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 2723 mPortBuffers[kPortIndexInput].size()); 2724 2725 CHECK_EQ( 2726 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 2727 mPortBuffers[kPortIndexOutput].size()); 2728 2729 status_t err = mOMX->sendCommand( 2730 mNode, OMX_CommandStateSet, OMX_StateLoaded); 2731 2732 CHECK_EQ(err, (status_t)OK); 2733 2734 err = freeBuffersOnPort(kPortIndexInput); 2735 CHECK_EQ(err, (status_t)OK); 2736 2737 err = freeBuffersOnPort(kPortIndexOutput); 2738 CHECK_EQ(err, (status_t)OK); 2739 2740 mPortStatus[kPortIndexInput] = ENABLED; 2741 mPortStatus[kPortIndexOutput] = ENABLED; 2742 2743 if ((mFlags & kEnableGrallocUsageProtected) && 2744 mNativeWindow != NULL) { 2745 // We push enough 1x1 blank buffers to ensure that one of 2746 // them has made it to the display. This allows the OMX 2747 // component teardown to zero out any protected buffers 2748 // without the risk of scanning out one of those buffers. 2749 pushBlankBuffersToNativeWindow(); 2750 } 2751 2752 setState(IDLE_TO_LOADED); 2753 } 2754 break; 2755 } 2756 2757 case OMX_StateExecuting: 2758 { 2759 CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING); 2760 2761 CODEC_LOGV("Now Executing."); 2762 2763 mOutputPortSettingsChangedPending = false; 2764 2765 setState(EXECUTING); 2766 2767 // Buffers will be submitted to the component in the first 2768 // call to OMXCodec::read as mInitialBufferSubmit is true at 2769 // this point. This ensures that this on_message call returns, 2770 // releases the lock and ::init can notice the state change and 2771 // itself return. 2772 break; 2773 } 2774 2775 case OMX_StateLoaded: 2776 { 2777 CHECK_EQ((int)mState, (int)IDLE_TO_LOADED); 2778 2779 CODEC_LOGV("Now Loaded."); 2780 2781 setState(LOADED); 2782 break; 2783 } 2784 2785 case OMX_StateInvalid: 2786 { 2787 setState(ERROR); 2788 break; 2789 } 2790 2791 default: 2792 { 2793 CHECK(!"should not be here."); 2794 break; 2795 } 2796 } 2797 } 2798 2799 // static 2800 size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 2801 size_t n = 0; 2802 for (size_t i = 0; i < buffers.size(); ++i) { 2803 if (buffers[i].mStatus != OWNED_BY_COMPONENT) { 2804 ++n; 2805 } 2806 } 2807 2808 return n; 2809 } 2810 2811 status_t OMXCodec::freeBuffersOnPort( 2812 OMX_U32 portIndex, bool onlyThoseWeOwn) { 2813 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2814 2815 status_t stickyErr = OK; 2816 2817 for (size_t i = buffers->size(); i-- > 0;) { 2818 BufferInfo *info = &buffers->editItemAt(i); 2819 2820 if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) { 2821 continue; 2822 } 2823 2824 CHECK(info->mStatus == OWNED_BY_US 2825 || info->mStatus == OWNED_BY_NATIVE_WINDOW); 2826 2827 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 2828 2829 status_t err = freeBuffer(portIndex, i); 2830 2831 if (err != OK) { 2832 stickyErr = err; 2833 } 2834 2835 } 2836 2837 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 2838 2839 return stickyErr; 2840 } 2841 2842 status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { 2843 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2844 2845 BufferInfo *info = &buffers->editItemAt(bufIndex); 2846 2847 status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 2848 2849 if (err == OK && info->mMediaBuffer != NULL) { 2850 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2851 info->mMediaBuffer->setObserver(NULL); 2852 2853 // Make sure nobody but us owns this buffer at this point. 2854 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 2855 2856 // Cancel the buffer if it belongs to an ANativeWindow. 2857 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer(); 2858 if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) { 2859 err = cancelBufferToNativeWindow(info); 2860 } 2861 2862 info->mMediaBuffer->release(); 2863 info->mMediaBuffer = NULL; 2864 } 2865 2866 if (err == OK) { 2867 buffers->removeAt(bufIndex); 2868 } 2869 2870 return err; 2871 } 2872 2873 void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 2874 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 2875 2876 CHECK_EQ((int)mState, (int)EXECUTING); 2877 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2878 CHECK(!mOutputPortSettingsChangedPending); 2879 2880 if (mPortStatus[kPortIndexOutput] != ENABLED) { 2881 CODEC_LOGV("Deferring output port settings change."); 2882 mOutputPortSettingsChangedPending = true; 2883 return; 2884 } 2885 2886 setState(RECONFIGURING); 2887 2888 if (mQuirks & kNeedsFlushBeforeDisable) { 2889 if (!flushPortAsync(portIndex)) { 2890 onCmdComplete(OMX_CommandFlush, portIndex); 2891 } 2892 } else { 2893 disablePortAsync(portIndex); 2894 } 2895 } 2896 2897 bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 2898 CHECK(mState == EXECUTING || mState == RECONFIGURING 2899 || mState == EXECUTING_TO_IDLE); 2900 2901 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 2902 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 2903 mPortBuffers[portIndex].size()); 2904 2905 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2906 mPortStatus[portIndex] = SHUTTING_DOWN; 2907 2908 if ((mQuirks & kRequiresFlushCompleteEmulation) 2909 && countBuffersWeOwn(mPortBuffers[portIndex]) 2910 == mPortBuffers[portIndex].size()) { 2911 // No flush is necessary and this component fails to send a 2912 // flush-complete event in this case. 2913 2914 return false; 2915 } 2916 2917 status_t err = 2918 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 2919 CHECK_EQ(err, (status_t)OK); 2920 2921 return true; 2922 } 2923 2924 void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 2925 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2926 2927 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2928 mPortStatus[portIndex] = DISABLING; 2929 2930 CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex); 2931 status_t err = 2932 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 2933 CHECK_EQ(err, (status_t)OK); 2934 2935 freeBuffersOnPort(portIndex, true); 2936 } 2937 2938 status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) { 2939 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2940 2941 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED); 2942 mPortStatus[portIndex] = ENABLING; 2943 2944 CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex); 2945 return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 2946 } 2947 2948 void OMXCodec::fillOutputBuffers() { 2949 CHECK_EQ((int)mState, (int)EXECUTING); 2950 2951 // This is a workaround for some decoders not properly reporting 2952 // end-of-output-stream. If we own all input buffers and also own 2953 // all output buffers and we already signalled end-of-input-stream, 2954 // the end-of-output-stream is implied. 2955 if (mSignalledEOS 2956 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 2957 == mPortBuffers[kPortIndexInput].size() 2958 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 2959 == mPortBuffers[kPortIndexOutput].size()) { 2960 mNoMoreOutputData = true; 2961 mBufferFilled.signal(); 2962 2963 return; 2964 } 2965 2966 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2967 for (size_t i = 0; i < buffers->size(); ++i) { 2968 BufferInfo *info = &buffers->editItemAt(i); 2969 if (info->mStatus == OWNED_BY_US) { 2970 fillOutputBuffer(&buffers->editItemAt(i)); 2971 } 2972 } 2973 } 2974 2975 void OMXCodec::drainInputBuffers() { 2976 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2977 2978 if (mFlags & kUseSecureInputBuffers) { 2979 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2980 for (size_t i = 0; i < buffers->size(); ++i) { 2981 if (!drainAnyInputBuffer() 2982 || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) { 2983 break; 2984 } 2985 } 2986 } else { 2987 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2988 for (size_t i = 0; i < buffers->size(); ++i) { 2989 BufferInfo *info = &buffers->editItemAt(i); 2990 2991 if (info->mStatus != OWNED_BY_US) { 2992 continue; 2993 } 2994 2995 if (!drainInputBuffer(info)) { 2996 break; 2997 } 2998 2999 if (mFlags & kOnlySubmitOneInputBufferAtOneTime) { 3000 break; 3001 } 3002 } 3003 } 3004 } 3005 3006 bool OMXCodec::drainAnyInputBuffer() { 3007 return drainInputBuffer((BufferInfo *)NULL); 3008 } 3009 3010 OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) { 3011 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 3012 for (size_t i = 0; i < infos->size(); ++i) { 3013 BufferInfo *info = &infos->editItemAt(i); 3014 3015 if (info->mData == ptr) { 3016 CODEC_LOGV( 3017 "input buffer data ptr = %p, buffer_id = %p", 3018 ptr, 3019 info->mBuffer); 3020 3021 return info; 3022 } 3023 } 3024 3025 TRESPASS(); 3026 } 3027 3028 OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() { 3029 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 3030 for (size_t i = 0; i < infos->size(); ++i) { 3031 BufferInfo *info = &infos->editItemAt(i); 3032 3033 if (info->mStatus == OWNED_BY_US) { 3034 return info; 3035 } 3036 } 3037 3038 TRESPASS(); 3039 } 3040 3041 bool OMXCodec::drainInputBuffer(BufferInfo *info) { 3042 if (info != NULL) { 3043 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3044 } 3045 3046 if (mSignalledEOS) { 3047 return false; 3048 } 3049 3050 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 3051 CHECK(!(mFlags & kUseSecureInputBuffers)); 3052 3053 const CodecSpecificData *specific = 3054 mCodecSpecificData[mCodecSpecificDataIndex]; 3055 3056 size_t size = specific->mSize; 3057 3058 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 3059 && !(mQuirks & kWantsNALFragments)) { 3060 static const uint8_t kNALStartCode[4] = 3061 { 0x00, 0x00, 0x00, 0x01 }; 3062 3063 CHECK(info->mSize >= specific->mSize + 4); 3064 3065 size += 4; 3066 3067 memcpy(info->mData, kNALStartCode, 4); 3068 memcpy((uint8_t *)info->mData + 4, 3069 specific->mData, specific->mSize); 3070 } else { 3071 CHECK(info->mSize >= specific->mSize); 3072 memcpy(info->mData, specific->mData, specific->mSize); 3073 } 3074 3075 mNoMoreOutputData = false; 3076 3077 CODEC_LOGV("calling emptyBuffer with codec specific data"); 3078 3079 status_t err = mOMX->emptyBuffer( 3080 mNode, info->mBuffer, 0, size, 3081 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 3082 0); 3083 CHECK_EQ(err, (status_t)OK); 3084 3085 info->mStatus = OWNED_BY_COMPONENT; 3086 3087 ++mCodecSpecificDataIndex; 3088 return true; 3089 } 3090 3091 if (mPaused) { 3092 return false; 3093 } 3094 3095 status_t err; 3096 3097 bool signalEOS = false; 3098 int64_t timestampUs = 0; 3099 3100 size_t offset = 0; 3101 int32_t n = 0; 3102 3103 3104 for (;;) { 3105 MediaBuffer *srcBuffer; 3106 if (mSeekTimeUs >= 0) { 3107 if (mLeftOverBuffer) { 3108 mLeftOverBuffer->release(); 3109 mLeftOverBuffer = NULL; 3110 } 3111 3112 MediaSource::ReadOptions options; 3113 options.setSeekTo(mSeekTimeUs, mSeekMode); 3114 3115 mSeekTimeUs = -1; 3116 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3117 mBufferFilled.signal(); 3118 3119 err = mSource->read(&srcBuffer, &options); 3120 3121 if (err == OK) { 3122 int64_t targetTimeUs; 3123 if (srcBuffer->meta_data()->findInt64( 3124 kKeyTargetTime, &targetTimeUs) 3125 && targetTimeUs >= 0) { 3126 CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs); 3127 mTargetTimeUs = targetTimeUs; 3128 } else { 3129 mTargetTimeUs = -1; 3130 } 3131 } 3132 } else if (mLeftOverBuffer) { 3133 srcBuffer = mLeftOverBuffer; 3134 mLeftOverBuffer = NULL; 3135 3136 err = OK; 3137 } else { 3138 err = mSource->read(&srcBuffer); 3139 } 3140 3141 if (err != OK) { 3142 signalEOS = true; 3143 mFinalStatus = err; 3144 mSignalledEOS = true; 3145 mBufferFilled.signal(); 3146 break; 3147 } 3148 3149 if (mFlags & kUseSecureInputBuffers) { 3150 info = findInputBufferByDataPointer(srcBuffer->data()); 3151 CHECK(info != NULL); 3152 } 3153 3154 size_t remainingBytes = info->mSize - offset; 3155 3156 if (srcBuffer->range_length() > remainingBytes) { 3157 if (offset == 0) { 3158 CODEC_LOGE( 3159 "Codec's input buffers are too small to accomodate " 3160 "buffer read from source (info->mSize = %d, srcLength = %d)", 3161 info->mSize, srcBuffer->range_length()); 3162 3163 srcBuffer->release(); 3164 srcBuffer = NULL; 3165 3166 setState(ERROR); 3167 return false; 3168 } 3169 3170 mLeftOverBuffer = srcBuffer; 3171 break; 3172 } 3173 3174 bool releaseBuffer = true; 3175 if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) { 3176 CHECK(mOMXLivesLocally && offset == 0); 3177 3178 OMX_BUFFERHEADERTYPE *header = 3179 (OMX_BUFFERHEADERTYPE *)info->mBuffer; 3180 3181 CHECK(header->pBuffer == info->mData); 3182 3183 header->pBuffer = 3184 (OMX_U8 *)srcBuffer->data() + srcBuffer->range_offset(); 3185 3186 releaseBuffer = false; 3187 info->mMediaBuffer = srcBuffer; 3188 } else { 3189 if (mFlags & kStoreMetaDataInVideoBuffers) { 3190 releaseBuffer = false; 3191 info->mMediaBuffer = srcBuffer; 3192 } 3193 3194 if (mFlags & kUseSecureInputBuffers) { 3195 // Data in "info" is already provided at this time. 3196 3197 releaseBuffer = false; 3198 3199 CHECK(info->mMediaBuffer == NULL); 3200 info->mMediaBuffer = srcBuffer; 3201 } else { 3202 CHECK(srcBuffer->data() != NULL) ; 3203 memcpy((uint8_t *)info->mData + offset, 3204 (const uint8_t *)srcBuffer->data() 3205 + srcBuffer->range_offset(), 3206 srcBuffer->range_length()); 3207 } 3208 } 3209 3210 int64_t lastBufferTimeUs; 3211 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); 3212 CHECK(lastBufferTimeUs >= 0); 3213 if (mIsEncoder) { 3214 mDecodingTimeList.push_back(lastBufferTimeUs); 3215 } 3216 3217 if (offset == 0) { 3218 timestampUs = lastBufferTimeUs; 3219 } 3220 3221 offset += srcBuffer->range_length(); 3222 3223 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) { 3224 CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer)); 3225 CHECK_GE(info->mSize, offset + sizeof(int32_t)); 3226 3227 int32_t numPageSamples; 3228 if (!srcBuffer->meta_data()->findInt32( 3229 kKeyValidSamples, &numPageSamples)) { 3230 numPageSamples = -1; 3231 } 3232 3233 memcpy((uint8_t *)info->mData + offset, 3234 &numPageSamples, 3235 sizeof(numPageSamples)); 3236 3237 offset += sizeof(numPageSamples); 3238 } 3239 3240 if (releaseBuffer) { 3241 srcBuffer->release(); 3242 srcBuffer = NULL; 3243 } 3244 3245 ++n; 3246 3247 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) { 3248 break; 3249 } 3250 3251 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs; 3252 3253 if (coalescedDurationUs > 250000ll) { 3254 // Don't coalesce more than 250ms worth of encoded data at once. 3255 break; 3256 } 3257 } 3258 3259 if (n > 1) { 3260 LOGV("coalesced %d frames into one input buffer", n); 3261 } 3262 3263 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 3264 3265 if (signalEOS) { 3266 flags |= OMX_BUFFERFLAG_EOS; 3267 } else { 3268 mNoMoreOutputData = false; 3269 } 3270 3271 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 3272 "timestamp %lld us (%.2f secs)", 3273 info->mBuffer, offset, 3274 timestampUs, timestampUs / 1E6); 3275 3276 if (info == NULL) { 3277 CHECK(mFlags & kUseSecureInputBuffers); 3278 CHECK(signalEOS); 3279 3280 // This is fishy, there's still a MediaBuffer corresponding to this 3281 // info available to the source at this point even though we're going 3282 // to use it to signal EOS to the codec. 3283 info = findEmptyInputBuffer(); 3284 } 3285 3286 err = mOMX->emptyBuffer( 3287 mNode, info->mBuffer, 0, offset, 3288 flags, timestampUs); 3289 3290 if (err != OK) { 3291 setState(ERROR); 3292 return false; 3293 } 3294 3295 info->mStatus = OWNED_BY_COMPONENT; 3296 3297 // This component does not ever signal the EOS flag on output buffers, 3298 // Thanks for nothing. 3299 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 3300 mNoMoreOutputData = true; 3301 mBufferFilled.signal(); 3302 } 3303 3304 return true; 3305 } 3306 3307 void OMXCodec::fillOutputBuffer(BufferInfo *info) { 3308 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3309 3310 if (mNoMoreOutputData) { 3311 CODEC_LOGV("There is no more output data available, not " 3312 "calling fillOutputBuffer"); 3313 return; 3314 } 3315 3316 if (info->mMediaBuffer != NULL) { 3317 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer(); 3318 if (graphicBuffer != 0) { 3319 // When using a native buffer we need to lock the buffer before 3320 // giving it to OMX. 3321 CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer); 3322 int err = mNativeWindow->lockBuffer(mNativeWindow.get(), 3323 graphicBuffer.get()); 3324 if (err != 0) { 3325 CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err); 3326 3327 setState(ERROR); 3328 return; 3329 } 3330 } 3331 } 3332 3333 CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer); 3334 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 3335 3336 if (err != OK) { 3337 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err); 3338 3339 setState(ERROR); 3340 return; 3341 } 3342 3343 info->mStatus = OWNED_BY_COMPONENT; 3344 } 3345 3346 bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 3347 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 3348 for (size_t i = 0; i < buffers->size(); ++i) { 3349 if ((*buffers)[i].mBuffer == buffer) { 3350 return drainInputBuffer(&buffers->editItemAt(i)); 3351 } 3352 } 3353 3354 CHECK(!"should not be here."); 3355 3356 return false; 3357 } 3358 3359 void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 3360 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3361 for (size_t i = 0; i < buffers->size(); ++i) { 3362 if ((*buffers)[i].mBuffer == buffer) { 3363 fillOutputBuffer(&buffers->editItemAt(i)); 3364 return; 3365 } 3366 } 3367 3368 CHECK(!"should not be here."); 3369 } 3370 3371 void OMXCodec::setState(State newState) { 3372 mState = newState; 3373 mAsyncCompletion.signal(); 3374 3375 // This may cause some spurious wakeups but is necessary to 3376 // unblock the reader if we enter ERROR state. 3377 mBufferFilled.signal(); 3378 } 3379 3380 status_t OMXCodec::waitForBufferFilled_l() { 3381 3382 if (mIsEncoder) { 3383 // For timelapse video recording, the timelapse video recording may 3384 // not send an input frame for a _long_ time. Do not use timeout 3385 // for video encoding. 3386 return mBufferFilled.wait(mLock); 3387 } 3388 status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs); 3389 if (err != OK) { 3390 CODEC_LOGE("Timed out waiting for output buffers: %d/%d", 3391 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 3392 countBuffersWeOwn(mPortBuffers[kPortIndexOutput])); 3393 } 3394 return err; 3395 } 3396 3397 void OMXCodec::setRawAudioFormat( 3398 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 3399 3400 // port definition 3401 OMX_PARAM_PORTDEFINITIONTYPE def; 3402 InitOMXParams(&def); 3403 def.nPortIndex = portIndex; 3404 status_t err = mOMX->getParameter( 3405 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3406 CHECK_EQ(err, (status_t)OK); 3407 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 3408 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3409 &def, sizeof(def)), (status_t)OK); 3410 3411 // pcm param 3412 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 3413 InitOMXParams(&pcmParams); 3414 pcmParams.nPortIndex = portIndex; 3415 3416 err = mOMX->getParameter( 3417 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3418 3419 CHECK_EQ(err, (status_t)OK); 3420 3421 pcmParams.nChannels = numChannels; 3422 pcmParams.eNumData = OMX_NumericalDataSigned; 3423 pcmParams.bInterleaved = OMX_TRUE; 3424 pcmParams.nBitPerSample = 16; 3425 pcmParams.nSamplingRate = sampleRate; 3426 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 3427 3428 if (numChannels == 1) { 3429 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 3430 } else { 3431 CHECK_EQ(numChannels, 2); 3432 3433 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 3434 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 3435 } 3436 3437 err = mOMX->setParameter( 3438 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3439 3440 CHECK_EQ(err, (status_t)OK); 3441 } 3442 3443 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) { 3444 if (isAMRWB) { 3445 if (bps <= 6600) { 3446 return OMX_AUDIO_AMRBandModeWB0; 3447 } else if (bps <= 8850) { 3448 return OMX_AUDIO_AMRBandModeWB1; 3449 } else if (bps <= 12650) { 3450 return OMX_AUDIO_AMRBandModeWB2; 3451 } else if (bps <= 14250) { 3452 return OMX_AUDIO_AMRBandModeWB3; 3453 } else if (bps <= 15850) { 3454 return OMX_AUDIO_AMRBandModeWB4; 3455 } else if (bps <= 18250) { 3456 return OMX_AUDIO_AMRBandModeWB5; 3457 } else if (bps <= 19850) { 3458 return OMX_AUDIO_AMRBandModeWB6; 3459 } else if (bps <= 23050) { 3460 return OMX_AUDIO_AMRBandModeWB7; 3461 } 3462 3463 // 23850 bps 3464 return OMX_AUDIO_AMRBandModeWB8; 3465 } else { // AMRNB 3466 if (bps <= 4750) { 3467 return OMX_AUDIO_AMRBandModeNB0; 3468 } else if (bps <= 5150) { 3469 return OMX_AUDIO_AMRBandModeNB1; 3470 } else if (bps <= 5900) { 3471 return OMX_AUDIO_AMRBandModeNB2; 3472 } else if (bps <= 6700) { 3473 return OMX_AUDIO_AMRBandModeNB3; 3474 } else if (bps <= 7400) { 3475 return OMX_AUDIO_AMRBandModeNB4; 3476 } else if (bps <= 7950) { 3477 return OMX_AUDIO_AMRBandModeNB5; 3478 } else if (bps <= 10200) { 3479 return OMX_AUDIO_AMRBandModeNB6; 3480 } 3481 3482 // 12200 bps 3483 return OMX_AUDIO_AMRBandModeNB7; 3484 } 3485 } 3486 3487 void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) { 3488 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 3489 3490 OMX_AUDIO_PARAM_AMRTYPE def; 3491 InitOMXParams(&def); 3492 def.nPortIndex = portIndex; 3493 3494 status_t err = 3495 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3496 3497 CHECK_EQ(err, (status_t)OK); 3498 3499 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 3500 3501 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate); 3502 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3503 CHECK_EQ(err, (status_t)OK); 3504 3505 //////////////////////// 3506 3507 if (mIsEncoder) { 3508 sp<MetaData> format = mSource->getFormat(); 3509 int32_t sampleRate; 3510 int32_t numChannels; 3511 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 3512 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 3513 3514 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3515 } 3516 } 3517 3518 status_t OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) { 3519 if (numChannels > 2) 3520 LOGW("Number of channels: (%d) \n", numChannels); 3521 3522 if (mIsEncoder) { 3523 //////////////// input port //////////////////// 3524 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3525 3526 //////////////// output port //////////////////// 3527 // format 3528 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 3529 format.nPortIndex = kPortIndexOutput; 3530 format.nIndex = 0; 3531 status_t err = OMX_ErrorNone; 3532 while (OMX_ErrorNone == err) { 3533 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, 3534 &format, sizeof(format)), (status_t)OK); 3535 if (format.eEncoding == OMX_AUDIO_CodingAAC) { 3536 break; 3537 } 3538 format.nIndex++; 3539 } 3540 CHECK_EQ((status_t)OK, err); 3541 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, 3542 &format, sizeof(format)), (status_t)OK); 3543 3544 // port definition 3545 OMX_PARAM_PORTDEFINITIONTYPE def; 3546 InitOMXParams(&def); 3547 def.nPortIndex = kPortIndexOutput; 3548 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, 3549 &def, sizeof(def)), (status_t)OK); 3550 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 3551 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 3552 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3553 &def, sizeof(def)), (status_t)OK); 3554 3555 // profile 3556 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3557 InitOMXParams(&profile); 3558 profile.nPortIndex = kPortIndexOutput; 3559 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, 3560 &profile, sizeof(profile)), (status_t)OK); 3561 profile.nChannels = numChannels; 3562 profile.eChannelMode = (numChannels == 1? 3563 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); 3564 profile.nSampleRate = sampleRate; 3565 profile.nBitRate = bitRate; 3566 profile.nAudioBandWidth = 0; 3567 profile.nFrameLength = 0; 3568 profile.nAACtools = OMX_AUDIO_AACToolAll; 3569 profile.nAACERtools = OMX_AUDIO_AACERNone; 3570 profile.eAACProfile = OMX_AUDIO_AACObjectLC; 3571 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 3572 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, 3573 &profile, sizeof(profile)); 3574 3575 if (err != OK) { 3576 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err); 3577 return err; 3578 } 3579 } else { 3580 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3581 InitOMXParams(&profile); 3582 profile.nPortIndex = kPortIndexInput; 3583 3584 status_t err = mOMX->getParameter( 3585 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3586 CHECK_EQ(err, (status_t)OK); 3587 3588 profile.nChannels = numChannels; 3589 profile.nSampleRate = sampleRate; 3590 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 3591 3592 err = mOMX->setParameter( 3593 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3594 3595 if (err != OK) { 3596 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err); 3597 return err; 3598 } 3599 } 3600 3601 return OK; 3602 } 3603 3604 void OMXCodec::setG711Format(int32_t numChannels) { 3605 CHECK(!mIsEncoder); 3606 setRawAudioFormat(kPortIndexInput, 8000, numChannels); 3607 } 3608 3609 void OMXCodec::setImageOutputFormat( 3610 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 3611 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 3612 3613 #if 0 3614 OMX_INDEXTYPE index; 3615 status_t err = mOMX->get_extension_index( 3616 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 3617 CHECK_EQ(err, (status_t)OK); 3618 3619 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 3620 CHECK_EQ(err, (status_t)OK); 3621 #endif 3622 3623 OMX_PARAM_PORTDEFINITIONTYPE def; 3624 InitOMXParams(&def); 3625 def.nPortIndex = kPortIndexOutput; 3626 3627 status_t err = mOMX->getParameter( 3628 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3629 CHECK_EQ(err, (status_t)OK); 3630 3631 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3632 3633 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3634 3635 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused); 3636 imageDef->eColorFormat = format; 3637 imageDef->nFrameWidth = width; 3638 imageDef->nFrameHeight = height; 3639 3640 switch (format) { 3641 case OMX_COLOR_FormatYUV420PackedPlanar: 3642 case OMX_COLOR_FormatYUV411Planar: 3643 { 3644 def.nBufferSize = (width * height * 3) / 2; 3645 break; 3646 } 3647 3648 case OMX_COLOR_FormatCbYCrY: 3649 { 3650 def.nBufferSize = width * height * 2; 3651 break; 3652 } 3653 3654 case OMX_COLOR_Format32bitARGB8888: 3655 { 3656 def.nBufferSize = width * height * 4; 3657 break; 3658 } 3659 3660 case OMX_COLOR_Format16bitARGB4444: 3661 case OMX_COLOR_Format16bitARGB1555: 3662 case OMX_COLOR_Format16bitRGB565: 3663 case OMX_COLOR_Format16bitBGR565: 3664 { 3665 def.nBufferSize = width * height * 2; 3666 break; 3667 } 3668 3669 default: 3670 CHECK(!"Should not be here. Unknown color format."); 3671 break; 3672 } 3673 3674 def.nBufferCountActual = def.nBufferCountMin; 3675 3676 err = mOMX->setParameter( 3677 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3678 CHECK_EQ(err, (status_t)OK); 3679 } 3680 3681 void OMXCodec::setJPEGInputFormat( 3682 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 3683 OMX_PARAM_PORTDEFINITIONTYPE def; 3684 InitOMXParams(&def); 3685 def.nPortIndex = kPortIndexInput; 3686 3687 status_t err = mOMX->getParameter( 3688 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3689 CHECK_EQ(err, (status_t)OK); 3690 3691 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3692 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3693 3694 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG); 3695 imageDef->nFrameWidth = width; 3696 imageDef->nFrameHeight = height; 3697 3698 def.nBufferSize = compressedSize; 3699 def.nBufferCountActual = def.nBufferCountMin; 3700 3701 err = mOMX->setParameter( 3702 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3703 CHECK_EQ(err, (status_t)OK); 3704 } 3705 3706 void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 3707 CodecSpecificData *specific = 3708 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 3709 3710 specific->mSize = size; 3711 memcpy(specific->mData, data, size); 3712 3713 mCodecSpecificData.push(specific); 3714 } 3715 3716 void OMXCodec::clearCodecSpecificData() { 3717 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 3718 free(mCodecSpecificData.editItemAt(i)); 3719 } 3720 mCodecSpecificData.clear(); 3721 mCodecSpecificDataIndex = 0; 3722 } 3723 3724 status_t OMXCodec::start(MetaData *meta) { 3725 Mutex::Autolock autoLock(mLock); 3726 3727 if (mState != LOADED) { 3728 return UNKNOWN_ERROR; 3729 } 3730 3731 sp<MetaData> params = new MetaData; 3732 if (mQuirks & kWantsNALFragments) { 3733 params->setInt32(kKeyWantsNALFragments, true); 3734 } 3735 if (meta) { 3736 int64_t startTimeUs = 0; 3737 int64_t timeUs; 3738 if (meta->findInt64(kKeyTime, &timeUs)) { 3739 startTimeUs = timeUs; 3740 } 3741 params->setInt64(kKeyTime, startTimeUs); 3742 } 3743 status_t err = mSource->start(params.get()); 3744 3745 if (err != OK) { 3746 return err; 3747 } 3748 3749 mCodecSpecificDataIndex = 0; 3750 mInitialBufferSubmit = true; 3751 mSignalledEOS = false; 3752 mNoMoreOutputData = false; 3753 mOutputPortSettingsHaveChanged = false; 3754 mSeekTimeUs = -1; 3755 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3756 mTargetTimeUs = -1; 3757 mFilledBuffers.clear(); 3758 mPaused = false; 3759 3760 return init(); 3761 } 3762 3763 status_t OMXCodec::stop() { 3764 CODEC_LOGV("stop mState=%d", mState); 3765 3766 Mutex::Autolock autoLock(mLock); 3767 3768 while (isIntermediateState(mState)) { 3769 mAsyncCompletion.wait(mLock); 3770 } 3771 3772 bool isError = false; 3773 switch (mState) { 3774 case LOADED: 3775 break; 3776 3777 case ERROR: 3778 { 3779 OMX_STATETYPE state = OMX_StateInvalid; 3780 status_t err = mOMX->getState(mNode, &state); 3781 CHECK_EQ(err, (status_t)OK); 3782 3783 if (state != OMX_StateExecuting) { 3784 break; 3785 } 3786 // else fall through to the idling code 3787 isError = true; 3788 } 3789 3790 case EXECUTING: 3791 { 3792 setState(EXECUTING_TO_IDLE); 3793 3794 if (mQuirks & kRequiresFlushBeforeShutdown) { 3795 CODEC_LOGV("This component requires a flush before transitioning " 3796 "from EXECUTING to IDLE..."); 3797 3798 bool emulateInputFlushCompletion = 3799 !flushPortAsync(kPortIndexInput); 3800 3801 bool emulateOutputFlushCompletion = 3802 !flushPortAsync(kPortIndexOutput); 3803 3804 if (emulateInputFlushCompletion) { 3805 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3806 } 3807 3808 if (emulateOutputFlushCompletion) { 3809 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3810 } 3811 } else { 3812 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 3813 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 3814 3815 status_t err = 3816 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 3817 CHECK_EQ(err, (status_t)OK); 3818 } 3819 3820 while (mState != LOADED && mState != ERROR) { 3821 mAsyncCompletion.wait(mLock); 3822 } 3823 3824 if (isError) { 3825 // We were in the ERROR state coming in, so restore that now 3826 // that we've idled the OMX component. 3827 setState(ERROR); 3828 } 3829 3830 break; 3831 } 3832 3833 default: 3834 { 3835 CHECK(!"should not be here."); 3836 break; 3837 } 3838 } 3839 3840 if (mLeftOverBuffer) { 3841 mLeftOverBuffer->release(); 3842 mLeftOverBuffer = NULL; 3843 } 3844 3845 mSource->stop(); 3846 3847 CODEC_LOGV("stopped in state %d", mState); 3848 3849 return OK; 3850 } 3851 3852 sp<MetaData> OMXCodec::getFormat() { 3853 Mutex::Autolock autoLock(mLock); 3854 3855 return mOutputFormat; 3856 } 3857 3858 status_t OMXCodec::read( 3859 MediaBuffer **buffer, const ReadOptions *options) { 3860 status_t err = OK; 3861 *buffer = NULL; 3862 3863 Mutex::Autolock autoLock(mLock); 3864 3865 if (mState != EXECUTING && mState != RECONFIGURING) { 3866 return UNKNOWN_ERROR; 3867 } 3868 3869 bool seeking = false; 3870 int64_t seekTimeUs; 3871 ReadOptions::SeekMode seekMode; 3872 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 3873 seeking = true; 3874 } 3875 3876 if (mInitialBufferSubmit) { 3877 mInitialBufferSubmit = false; 3878 3879 if (seeking) { 3880 CHECK(seekTimeUs >= 0); 3881 mSeekTimeUs = seekTimeUs; 3882 mSeekMode = seekMode; 3883 3884 // There's no reason to trigger the code below, there's 3885 // nothing to flush yet. 3886 seeking = false; 3887 mPaused = false; 3888 } 3889 3890 drainInputBuffers(); 3891 3892 if (mState == EXECUTING) { 3893 // Otherwise mState == RECONFIGURING and this code will trigger 3894 // after the output port is reenabled. 3895 fillOutputBuffers(); 3896 } 3897 } 3898 3899 if (seeking) { 3900 while (mState == RECONFIGURING) { 3901 if ((err = waitForBufferFilled_l()) != OK) { 3902 return err; 3903 } 3904 } 3905 3906 if (mState != EXECUTING) { 3907 return UNKNOWN_ERROR; 3908 } 3909 3910 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 3911 3912 mSignalledEOS = false; 3913 3914 CHECK(seekTimeUs >= 0); 3915 mSeekTimeUs = seekTimeUs; 3916 mSeekMode = seekMode; 3917 3918 mFilledBuffers.clear(); 3919 3920 CHECK_EQ((int)mState, (int)EXECUTING); 3921 3922 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 3923 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 3924 3925 if (emulateInputFlushCompletion) { 3926 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3927 } 3928 3929 if (emulateOutputFlushCompletion) { 3930 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3931 } 3932 3933 while (mSeekTimeUs >= 0) { 3934 if ((err = waitForBufferFilled_l()) != OK) { 3935 return err; 3936 } 3937 } 3938 } 3939 3940 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 3941 if ((err = waitForBufferFilled_l()) != OK) { 3942 return err; 3943 } 3944 } 3945 3946 if (mState == ERROR) { 3947 return UNKNOWN_ERROR; 3948 } 3949 3950 if (mFilledBuffers.empty()) { 3951 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 3952 } 3953 3954 if (mOutputPortSettingsHaveChanged) { 3955 mOutputPortSettingsHaveChanged = false; 3956 3957 return INFO_FORMAT_CHANGED; 3958 } 3959 3960 size_t index = *mFilledBuffers.begin(); 3961 mFilledBuffers.erase(mFilledBuffers.begin()); 3962 3963 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 3964 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3965 info->mStatus = OWNED_BY_CLIENT; 3966 3967 info->mMediaBuffer->add_ref(); 3968 *buffer = info->mMediaBuffer; 3969 3970 return OK; 3971 } 3972 3973 void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 3974 Mutex::Autolock autoLock(mLock); 3975 3976 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3977 for (size_t i = 0; i < buffers->size(); ++i) { 3978 BufferInfo *info = &buffers->editItemAt(i); 3979 3980 if (info->mMediaBuffer == buffer) { 3981 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 3982 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT); 3983 3984 info->mStatus = OWNED_BY_US; 3985 3986 if (buffer->graphicBuffer() == 0) { 3987 fillOutputBuffer(info); 3988 } else { 3989 sp<MetaData> metaData = info->mMediaBuffer->meta_data(); 3990 int32_t rendered = 0; 3991 if (!metaData->findInt32(kKeyRendered, &rendered)) { 3992 rendered = 0; 3993 } 3994 if (!rendered) { 3995 status_t err = cancelBufferToNativeWindow(info); 3996 if (err < 0) { 3997 return; 3998 } 3999 } 4000 4001 info->mStatus = OWNED_BY_NATIVE_WINDOW; 4002 4003 // Dequeue the next buffer from the native window. 4004 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow(); 4005 if (nextBufInfo == 0) { 4006 return; 4007 } 4008 4009 // Give the buffer to the OMX node to fill. 4010 fillOutputBuffer(nextBufInfo); 4011 } 4012 return; 4013 } 4014 } 4015 4016 CHECK(!"should not be here."); 4017 } 4018 4019 static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 4020 static const char *kNames[] = { 4021 "OMX_IMAGE_CodingUnused", 4022 "OMX_IMAGE_CodingAutoDetect", 4023 "OMX_IMAGE_CodingJPEG", 4024 "OMX_IMAGE_CodingJPEG2K", 4025 "OMX_IMAGE_CodingEXIF", 4026 "OMX_IMAGE_CodingTIFF", 4027 "OMX_IMAGE_CodingGIF", 4028 "OMX_IMAGE_CodingPNG", 4029 "OMX_IMAGE_CodingLZW", 4030 "OMX_IMAGE_CodingBMP", 4031 }; 4032 4033 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4034 4035 if (type < 0 || (size_t)type >= numNames) { 4036 return "UNKNOWN"; 4037 } else { 4038 return kNames[type]; 4039 } 4040 } 4041 4042 static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 4043 static const char *kNames[] = { 4044 "OMX_COLOR_FormatUnused", 4045 "OMX_COLOR_FormatMonochrome", 4046 "OMX_COLOR_Format8bitRGB332", 4047 "OMX_COLOR_Format12bitRGB444", 4048 "OMX_COLOR_Format16bitARGB4444", 4049 "OMX_COLOR_Format16bitARGB1555", 4050 "OMX_COLOR_Format16bitRGB565", 4051 "OMX_COLOR_Format16bitBGR565", 4052 "OMX_COLOR_Format18bitRGB666", 4053 "OMX_COLOR_Format18bitARGB1665", 4054 "OMX_COLOR_Format19bitARGB1666", 4055 "OMX_COLOR_Format24bitRGB888", 4056 "OMX_COLOR_Format24bitBGR888", 4057 "OMX_COLOR_Format24bitARGB1887", 4058 "OMX_COLOR_Format25bitARGB1888", 4059 "OMX_COLOR_Format32bitBGRA8888", 4060 "OMX_COLOR_Format32bitARGB8888", 4061 "OMX_COLOR_FormatYUV411Planar", 4062 "OMX_COLOR_FormatYUV411PackedPlanar", 4063 "OMX_COLOR_FormatYUV420Planar", 4064 "OMX_COLOR_FormatYUV420PackedPlanar", 4065 "OMX_COLOR_FormatYUV420SemiPlanar", 4066 "OMX_COLOR_FormatYUV422Planar", 4067 "OMX_COLOR_FormatYUV422PackedPlanar", 4068 "OMX_COLOR_FormatYUV422SemiPlanar", 4069 "OMX_COLOR_FormatYCbYCr", 4070 "OMX_COLOR_FormatYCrYCb", 4071 "OMX_COLOR_FormatCbYCrY", 4072 "OMX_COLOR_FormatCrYCbY", 4073 "OMX_COLOR_FormatYUV444Interleaved", 4074 "OMX_COLOR_FormatRawBayer8bit", 4075 "OMX_COLOR_FormatRawBayer10bit", 4076 "OMX_COLOR_FormatRawBayer8bitcompressed", 4077 "OMX_COLOR_FormatL2", 4078 "OMX_COLOR_FormatL4", 4079 "OMX_COLOR_FormatL8", 4080 "OMX_COLOR_FormatL16", 4081 "OMX_COLOR_FormatL24", 4082 "OMX_COLOR_FormatL32", 4083 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 4084 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 4085 "OMX_COLOR_Format18BitBGR666", 4086 "OMX_COLOR_Format24BitARGB6666", 4087 "OMX_COLOR_Format24BitABGR6666", 4088 }; 4089 4090 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4091 4092 if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 4093 return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; 4094 } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 4095 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 4096 } else if (type < 0 || (size_t)type >= numNames) { 4097 return "UNKNOWN"; 4098 } else { 4099 return kNames[type]; 4100 } 4101 } 4102 4103 static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 4104 static const char *kNames[] = { 4105 "OMX_VIDEO_CodingUnused", 4106 "OMX_VIDEO_CodingAutoDetect", 4107 "OMX_VIDEO_CodingMPEG2", 4108 "OMX_VIDEO_CodingH263", 4109 "OMX_VIDEO_CodingMPEG4", 4110 "OMX_VIDEO_CodingWMV", 4111 "OMX_VIDEO_CodingRV", 4112 "OMX_VIDEO_CodingAVC", 4113 "OMX_VIDEO_CodingMJPEG", 4114 }; 4115 4116 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4117 4118 if (type < 0 || (size_t)type >= numNames) { 4119 return "UNKNOWN"; 4120 } else { 4121 return kNames[type]; 4122 } 4123 } 4124 4125 static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 4126 static const char *kNames[] = { 4127 "OMX_AUDIO_CodingUnused", 4128 "OMX_AUDIO_CodingAutoDetect", 4129 "OMX_AUDIO_CodingPCM", 4130 "OMX_AUDIO_CodingADPCM", 4131 "OMX_AUDIO_CodingAMR", 4132 "OMX_AUDIO_CodingGSMFR", 4133 "OMX_AUDIO_CodingGSMEFR", 4134 "OMX_AUDIO_CodingGSMHR", 4135 "OMX_AUDIO_CodingPDCFR", 4136 "OMX_AUDIO_CodingPDCEFR", 4137 "OMX_AUDIO_CodingPDCHR", 4138 "OMX_AUDIO_CodingTDMAFR", 4139 "OMX_AUDIO_CodingTDMAEFR", 4140 "OMX_AUDIO_CodingQCELP8", 4141 "OMX_AUDIO_CodingQCELP13", 4142 "OMX_AUDIO_CodingEVRC", 4143 "OMX_AUDIO_CodingSMV", 4144 "OMX_AUDIO_CodingG711", 4145 "OMX_AUDIO_CodingG723", 4146 "OMX_AUDIO_CodingG726", 4147 "OMX_AUDIO_CodingG729", 4148 "OMX_AUDIO_CodingAAC", 4149 "OMX_AUDIO_CodingMP3", 4150 "OMX_AUDIO_CodingSBC", 4151 "OMX_AUDIO_CodingVORBIS", 4152 "OMX_AUDIO_CodingWMA", 4153 "OMX_AUDIO_CodingRA", 4154 "OMX_AUDIO_CodingMIDI", 4155 }; 4156 4157 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4158 4159 if (type < 0 || (size_t)type >= numNames) { 4160 return "UNKNOWN"; 4161 } else { 4162 return kNames[type]; 4163 } 4164 } 4165 4166 static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 4167 static const char *kNames[] = { 4168 "OMX_AUDIO_PCMModeLinear", 4169 "OMX_AUDIO_PCMModeALaw", 4170 "OMX_AUDIO_PCMModeMULaw", 4171 }; 4172 4173 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4174 4175 if (type < 0 || (size_t)type >= numNames) { 4176 return "UNKNOWN"; 4177 } else { 4178 return kNames[type]; 4179 } 4180 } 4181 4182 static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 4183 static const char *kNames[] = { 4184 "OMX_AUDIO_AMRBandModeUnused", 4185 "OMX_AUDIO_AMRBandModeNB0", 4186 "OMX_AUDIO_AMRBandModeNB1", 4187 "OMX_AUDIO_AMRBandModeNB2", 4188 "OMX_AUDIO_AMRBandModeNB3", 4189 "OMX_AUDIO_AMRBandModeNB4", 4190 "OMX_AUDIO_AMRBandModeNB5", 4191 "OMX_AUDIO_AMRBandModeNB6", 4192 "OMX_AUDIO_AMRBandModeNB7", 4193 "OMX_AUDIO_AMRBandModeWB0", 4194 "OMX_AUDIO_AMRBandModeWB1", 4195 "OMX_AUDIO_AMRBandModeWB2", 4196 "OMX_AUDIO_AMRBandModeWB3", 4197 "OMX_AUDIO_AMRBandModeWB4", 4198 "OMX_AUDIO_AMRBandModeWB5", 4199 "OMX_AUDIO_AMRBandModeWB6", 4200 "OMX_AUDIO_AMRBandModeWB7", 4201 "OMX_AUDIO_AMRBandModeWB8", 4202 }; 4203 4204 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4205 4206 if (type < 0 || (size_t)type >= numNames) { 4207 return "UNKNOWN"; 4208 } else { 4209 return kNames[type]; 4210 } 4211 } 4212 4213 static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 4214 static const char *kNames[] = { 4215 "OMX_AUDIO_AMRFrameFormatConformance", 4216 "OMX_AUDIO_AMRFrameFormatIF1", 4217 "OMX_AUDIO_AMRFrameFormatIF2", 4218 "OMX_AUDIO_AMRFrameFormatFSF", 4219 "OMX_AUDIO_AMRFrameFormatRTPPayload", 4220 "OMX_AUDIO_AMRFrameFormatITU", 4221 }; 4222 4223 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4224 4225 if (type < 0 || (size_t)type >= numNames) { 4226 return "UNKNOWN"; 4227 } else { 4228 return kNames[type]; 4229 } 4230 } 4231 4232 void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 4233 OMX_PARAM_PORTDEFINITIONTYPE def; 4234 InitOMXParams(&def); 4235 def.nPortIndex = portIndex; 4236 4237 status_t err = mOMX->getParameter( 4238 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4239 CHECK_EQ(err, (status_t)OK); 4240 4241 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 4242 4243 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 4244 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 4245 4246 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 4247 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 4248 printf(" nBufferSize = %ld\n", def.nBufferSize); 4249 4250 switch (def.eDomain) { 4251 case OMX_PortDomainImage: 4252 { 4253 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4254 4255 printf("\n"); 4256 printf(" // Image\n"); 4257 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 4258 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 4259 printf(" nStride = %ld\n", imageDef->nStride); 4260 4261 printf(" eCompressionFormat = %s\n", 4262 imageCompressionFormatString(imageDef->eCompressionFormat)); 4263 4264 printf(" eColorFormat = %s\n", 4265 colorFormatString(imageDef->eColorFormat)); 4266 4267 break; 4268 } 4269 4270 case OMX_PortDomainVideo: 4271 { 4272 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4273 4274 printf("\n"); 4275 printf(" // Video\n"); 4276 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 4277 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 4278 printf(" nStride = %ld\n", videoDef->nStride); 4279 4280 printf(" eCompressionFormat = %s\n", 4281 videoCompressionFormatString(videoDef->eCompressionFormat)); 4282 4283 printf(" eColorFormat = %s\n", 4284 colorFormatString(videoDef->eColorFormat)); 4285 4286 break; 4287 } 4288 4289 case OMX_PortDomainAudio: 4290 { 4291 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4292 4293 printf("\n"); 4294 printf(" // Audio\n"); 4295 printf(" eEncoding = %s\n", 4296 audioCodingTypeString(audioDef->eEncoding)); 4297 4298 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 4299 OMX_AUDIO_PARAM_PCMMODETYPE params; 4300 InitOMXParams(¶ms); 4301 params.nPortIndex = portIndex; 4302 4303 err = mOMX->getParameter( 4304 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4305 CHECK_EQ(err, (status_t)OK); 4306 4307 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 4308 printf(" nChannels = %ld\n", params.nChannels); 4309 printf(" bInterleaved = %d\n", params.bInterleaved); 4310 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 4311 4312 printf(" eNumData = %s\n", 4313 params.eNumData == OMX_NumericalDataSigned 4314 ? "signed" : "unsigned"); 4315 4316 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 4317 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 4318 OMX_AUDIO_PARAM_AMRTYPE amr; 4319 InitOMXParams(&amr); 4320 amr.nPortIndex = portIndex; 4321 4322 err = mOMX->getParameter( 4323 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4324 CHECK_EQ(err, (status_t)OK); 4325 4326 printf(" nChannels = %ld\n", amr.nChannels); 4327 printf(" eAMRBandMode = %s\n", 4328 amrBandModeString(amr.eAMRBandMode)); 4329 printf(" eAMRFrameFormat = %s\n", 4330 amrFrameFormatString(amr.eAMRFrameFormat)); 4331 } 4332 4333 break; 4334 } 4335 4336 default: 4337 { 4338 printf(" // Unknown\n"); 4339 break; 4340 } 4341 } 4342 4343 printf("}\n"); 4344 } 4345 4346 status_t OMXCodec::initNativeWindow() { 4347 // Enable use of a GraphicBuffer as the output for this node. This must 4348 // happen before getting the IndexParamPortDefinition parameter because it 4349 // will affect the pixel format that the node reports. 4350 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 4351 if (err != 0) { 4352 return err; 4353 } 4354 4355 return OK; 4356 } 4357 4358 void OMXCodec::initNativeWindowCrop() { 4359 int32_t left, top, right, bottom; 4360 4361 CHECK(mOutputFormat->findRect( 4362 kKeyCropRect, 4363 &left, &top, &right, &bottom)); 4364 4365 android_native_rect_t crop; 4366 crop.left = left; 4367 crop.top = top; 4368 crop.right = right + 1; 4369 crop.bottom = bottom + 1; 4370 4371 // We'll ignore any errors here, if the surface is 4372 // already invalid, we'll know soon enough. 4373 native_window_set_crop(mNativeWindow.get(), &crop); 4374 } 4375 4376 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 4377 mOutputFormat = new MetaData; 4378 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 4379 if (mIsEncoder) { 4380 int32_t timeScale; 4381 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) { 4382 mOutputFormat->setInt32(kKeyTimeScale, timeScale); 4383 } 4384 } 4385 4386 OMX_PARAM_PORTDEFINITIONTYPE def; 4387 InitOMXParams(&def); 4388 def.nPortIndex = kPortIndexOutput; 4389 4390 status_t err = mOMX->getParameter( 4391 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4392 CHECK_EQ(err, (status_t)OK); 4393 4394 switch (def.eDomain) { 4395 case OMX_PortDomainImage: 4396 { 4397 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4398 CHECK_EQ((int)imageDef->eCompressionFormat, 4399 (int)OMX_IMAGE_CodingUnused); 4400 4401 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4402 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 4403 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 4404 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 4405 break; 4406 } 4407 4408 case OMX_PortDomainAudio: 4409 { 4410 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 4411 4412 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 4413 OMX_AUDIO_PARAM_PCMMODETYPE params; 4414 InitOMXParams(¶ms); 4415 params.nPortIndex = kPortIndexOutput; 4416 4417 err = mOMX->getParameter( 4418 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4419 CHECK_EQ(err, (status_t)OK); 4420 4421 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 4422 CHECK_EQ(params.nBitPerSample, 16u); 4423 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 4424 4425 int32_t numChannels, sampleRate; 4426 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4427 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4428 4429 if ((OMX_U32)numChannels != params.nChannels) { 4430 LOGV("Codec outputs a different number of channels than " 4431 "the input stream contains (contains %d channels, " 4432 "codec outputs %ld channels).", 4433 numChannels, params.nChannels); 4434 } 4435 4436 if (sampleRate != (int32_t)params.nSamplingRate) { 4437 LOGV("Codec outputs at different sampling rate than " 4438 "what the input stream contains (contains data at " 4439 "%d Hz, codec outputs %lu Hz)", 4440 sampleRate, params.nSamplingRate); 4441 } 4442 4443 mOutputFormat->setCString( 4444 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 4445 4446 // Use the codec-advertised number of channels, as some 4447 // codecs appear to output stereo even if the input data is 4448 // mono. If we know the codec lies about this information, 4449 // use the actual number of channels instead. 4450 mOutputFormat->setInt32( 4451 kKeyChannelCount, 4452 (mQuirks & kDecoderLiesAboutNumberOfChannels) 4453 ? numChannels : params.nChannels); 4454 4455 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate); 4456 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 4457 OMX_AUDIO_PARAM_AMRTYPE amr; 4458 InitOMXParams(&amr); 4459 amr.nPortIndex = kPortIndexOutput; 4460 4461 err = mOMX->getParameter( 4462 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4463 CHECK_EQ(err, (status_t)OK); 4464 4465 CHECK_EQ(amr.nChannels, 1u); 4466 mOutputFormat->setInt32(kKeyChannelCount, 1); 4467 4468 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 4469 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 4470 mOutputFormat->setCString( 4471 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 4472 mOutputFormat->setInt32(kKeySampleRate, 8000); 4473 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 4474 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 4475 mOutputFormat->setCString( 4476 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 4477 mOutputFormat->setInt32(kKeySampleRate, 16000); 4478 } else { 4479 CHECK(!"Unknown AMR band mode."); 4480 } 4481 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 4482 mOutputFormat->setCString( 4483 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 4484 int32_t numChannels, sampleRate, bitRate; 4485 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4486 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4487 inputFormat->findInt32(kKeyBitRate, &bitRate); 4488 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 4489 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 4490 mOutputFormat->setInt32(kKeyBitRate, bitRate); 4491 } else { 4492 CHECK(!"Should not be here. Unknown audio encoding."); 4493 } 4494 break; 4495 } 4496 4497 case OMX_PortDomainVideo: 4498 { 4499 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4500 4501 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 4502 mOutputFormat->setCString( 4503 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4504 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4505 mOutputFormat->setCString( 4506 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 4507 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 4508 mOutputFormat->setCString( 4509 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 4510 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 4511 mOutputFormat->setCString( 4512 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 4513 } else { 4514 CHECK(!"Unknown compression format."); 4515 } 4516 4517 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 4518 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 4519 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 4520 4521 if (!mIsEncoder) { 4522 OMX_CONFIG_RECTTYPE rect; 4523 InitOMXParams(&rect); 4524 rect.nPortIndex = kPortIndexOutput; 4525 status_t err = 4526 mOMX->getConfig( 4527 mNode, OMX_IndexConfigCommonOutputCrop, 4528 &rect, sizeof(rect)); 4529 4530 CODEC_LOGI( 4531 "video dimensions are %ld x %ld", 4532 video_def->nFrameWidth, video_def->nFrameHeight); 4533 4534 if (err == OK) { 4535 CHECK_GE(rect.nLeft, 0); 4536 CHECK_GE(rect.nTop, 0); 4537 CHECK_GE(rect.nWidth, 0u); 4538 CHECK_GE(rect.nHeight, 0u); 4539 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth); 4540 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight); 4541 4542 mOutputFormat->setRect( 4543 kKeyCropRect, 4544 rect.nLeft, 4545 rect.nTop, 4546 rect.nLeft + rect.nWidth - 1, 4547 rect.nTop + rect.nHeight - 1); 4548 4549 CODEC_LOGI( 4550 "Crop rect is %ld x %ld @ (%ld, %ld)", 4551 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop); 4552 } else { 4553 mOutputFormat->setRect( 4554 kKeyCropRect, 4555 0, 0, 4556 video_def->nFrameWidth - 1, 4557 video_def->nFrameHeight - 1); 4558 } 4559 4560 if (mNativeWindow != NULL) { 4561 initNativeWindowCrop(); 4562 } 4563 } 4564 break; 4565 } 4566 4567 default: 4568 { 4569 CHECK(!"should not be here, neither audio nor video."); 4570 break; 4571 } 4572 } 4573 4574 // If the input format contains rotation information, flag the output 4575 // format accordingly. 4576 4577 int32_t rotationDegrees; 4578 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) { 4579 mOutputFormat->setInt32(kKeyRotation, rotationDegrees); 4580 } 4581 } 4582 4583 status_t OMXCodec::pause() { 4584 Mutex::Autolock autoLock(mLock); 4585 4586 mPaused = true; 4587 4588 return OK; 4589 } 4590 4591 //////////////////////////////////////////////////////////////////////////////// 4592 4593 status_t QueryCodecs( 4594 const sp<IOMX> &omx, 4595 const char *mime, bool queryDecoders, bool hwCodecOnly, 4596 Vector<CodecCapabilities> *results) { 4597 Vector<String8> matchingCodecs; 4598 results->clear(); 4599 4600 OMXCodec::findMatchingCodecs(mime, 4601 !queryDecoders /*createEncoder*/, 4602 NULL /*matchComponentName*/, 4603 hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/, 4604 &matchingCodecs); 4605 4606 for (size_t c = 0; c < matchingCodecs.size(); c++) { 4607 const char *componentName = matchingCodecs.itemAt(c).string(); 4608 4609 if (strncmp(componentName, "OMX.", 4)) { 4610 // Not an OpenMax component but a software codec. 4611 4612 results->push(); 4613 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4614 caps->mComponentName = componentName; 4615 continue; 4616 } 4617 4618 sp<OMXCodecObserver> observer = new OMXCodecObserver; 4619 IOMX::node_id node; 4620 status_t err = omx->allocateNode(componentName, observer, &node); 4621 4622 if (err != OK) { 4623 continue; 4624 } 4625 4626 OMXCodec::setComponentRole(omx, node, !queryDecoders, mime); 4627 4628 results->push(); 4629 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4630 caps->mComponentName = componentName; 4631 4632 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 4633 InitOMXParams(¶m); 4634 4635 param.nPortIndex = queryDecoders ? 0 : 1; 4636 4637 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 4638 err = omx->getParameter( 4639 node, OMX_IndexParamVideoProfileLevelQuerySupported, 4640 ¶m, sizeof(param)); 4641 4642 if (err != OK) { 4643 break; 4644 } 4645 4646 CodecProfileLevel profileLevel; 4647 profileLevel.mProfile = param.eProfile; 4648 profileLevel.mLevel = param.eLevel; 4649 4650 caps->mProfileLevels.push(profileLevel); 4651 } 4652 4653 // Color format query 4654 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 4655 InitOMXParams(&portFormat); 4656 portFormat.nPortIndex = queryDecoders ? 1 : 0; 4657 for (portFormat.nIndex = 0;; ++portFormat.nIndex) { 4658 err = omx->getParameter( 4659 node, OMX_IndexParamVideoPortFormat, 4660 &portFormat, sizeof(portFormat)); 4661 if (err != OK) { 4662 break; 4663 } 4664 caps->mColorFormats.push(portFormat.eColorFormat); 4665 } 4666 4667 CHECK_EQ(omx->freeNode(node), (status_t)OK); 4668 } 4669 4670 return OK; 4671 } 4672 4673 status_t QueryCodecs( 4674 const sp<IOMX> &omx, 4675 const char *mimeType, bool queryDecoders, 4676 Vector<CodecCapabilities> *results) { 4677 return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results); 4678 } 4679 4680 void OMXCodec::restorePatchedDataPointer(BufferInfo *info) { 4681 CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)); 4682 CHECK(mOMXLivesLocally); 4683 4684 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer; 4685 header->pBuffer = (OMX_U8 *)info->mData; 4686 } 4687 4688 } // namespace android 4689