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