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