1 /* 2 * Copyright (C) 2011 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 18 #define LOG_NDEBUG 1 19 #define LOG_TAG "PreviewPlayer" 20 #include <utils/Log.h> 21 22 #include <dlfcn.h> 23 24 #include "PreviewPlayer.h" 25 #include "DummyAudioSource.h" 26 #include "DummyVideoSource.h" 27 #include "VideoEditorSRC.h" 28 #include "include/NuCachedSource2.h" 29 #include "include/ThrottledSource.h" 30 31 32 #include <binder/IPCThreadState.h> 33 #include <media/stagefright/DataSource.h> 34 #include <media/stagefright/FileSource.h> 35 #include <media/stagefright/MediaBuffer.h> 36 #include <media/stagefright/MediaDefs.h> 37 #include <media/stagefright/MediaExtractor.h> 38 #include <media/stagefright/MediaDebug.h> 39 #include <media/stagefright/MediaSource.h> 40 #include <media/stagefright/MetaData.h> 41 #include <media/stagefright/OMXCodec.h> 42 43 #include <surfaceflinger/Surface.h> 44 #include <media/stagefright/foundation/ALooper.h> 45 46 namespace android { 47 48 49 struct PreviewPlayerEvent : public TimedEventQueue::Event { 50 PreviewPlayerEvent( 51 PreviewPlayer *player, 52 void (PreviewPlayer::*method)()) 53 : mPlayer(player), 54 mMethod(method) { 55 } 56 57 protected: 58 virtual ~PreviewPlayerEvent() {} 59 60 virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) { 61 (mPlayer->*mMethod)(); 62 } 63 64 private: 65 PreviewPlayer *mPlayer; 66 void (PreviewPlayer::*mMethod)(); 67 68 PreviewPlayerEvent(const PreviewPlayerEvent &); 69 PreviewPlayerEvent &operator=(const PreviewPlayerEvent &); 70 }; 71 72 PreviewPlayer::PreviewPlayer(NativeWindowRenderer* renderer) 73 : PreviewPlayerBase(), 74 mNativeWindowRenderer(renderer), 75 mCurrFramingEffectIndex(0), 76 mFrameRGBBuffer(NULL), 77 mFrameYUVBuffer(NULL) { 78 79 mVideoRenderer = NULL; 80 mEffectsSettings = NULL; 81 mVeAudioPlayer = NULL; 82 mAudioMixStoryBoardTS = 0; 83 mCurrentMediaBeginCutTime = 0; 84 mCurrentMediaVolumeValue = 0; 85 mNumberEffects = 0; 86 mDecodedVideoTs = 0; 87 mDecVideoTsStoryBoard = 0; 88 mCurrentVideoEffect = VIDEO_EFFECT_NONE; 89 mProgressCbInterval = 0; 90 mNumberDecVideoFrames = 0; 91 mOverlayUpdateEventPosted = false; 92 mIsChangeSourceRequired = true; 93 94 mVideoEvent = new PreviewPlayerEvent(this, &PreviewPlayer::onVideoEvent); 95 mVideoEventPending = false; 96 mStreamDoneEvent = new PreviewPlayerEvent(this, 97 &PreviewPlayer::onStreamDone); 98 99 mStreamDoneEventPending = false; 100 101 mCheckAudioStatusEvent = new PreviewPlayerEvent( 102 this, &PreviewPlayerBase::onCheckAudioStatus); 103 104 mAudioStatusEventPending = false; 105 106 mProgressCbEvent = new PreviewPlayerEvent(this, 107 &PreviewPlayer::onProgressCbEvent); 108 109 mOverlayUpdateEvent = new PreviewPlayerEvent(this, 110 &PreviewPlayer::onUpdateOverlayEvent); 111 mProgressCbEventPending = false; 112 113 mOverlayUpdateEventPending = false; 114 mRenderingMode = (M4xVSS_MediaRendering)MEDIA_RENDERING_INVALID; 115 mIsFiftiesEffectStarted = false; 116 reset(); 117 } 118 119 PreviewPlayer::~PreviewPlayer() { 120 121 if (mQueueStarted) { 122 mQueue.stop(); 123 } 124 125 reset(); 126 127 if (mVideoRenderer) { 128 mNativeWindowRenderer->destroyRenderInput(mVideoRenderer); 129 } 130 } 131 132 void PreviewPlayer::cancelPlayerEvents(bool keepBufferingGoing) { 133 mQueue.cancelEvent(mVideoEvent->eventID()); 134 mVideoEventPending = false; 135 mQueue.cancelEvent(mStreamDoneEvent->eventID()); 136 mStreamDoneEventPending = false; 137 mQueue.cancelEvent(mCheckAudioStatusEvent->eventID()); 138 mAudioStatusEventPending = false; 139 140 mQueue.cancelEvent(mProgressCbEvent->eventID()); 141 mProgressCbEventPending = false; 142 } 143 144 status_t PreviewPlayer::setDataSource( 145 const char *uri, const KeyedVector<String8, String8> *headers) { 146 Mutex::Autolock autoLock(mLock); 147 return setDataSource_l(uri, headers); 148 } 149 150 status_t PreviewPlayer::setDataSource_l( 151 const char *uri, const KeyedVector<String8, String8> *headers) { 152 reset_l(); 153 154 mUri = uri; 155 156 if (headers) { 157 mUriHeaders = *headers; 158 } 159 160 // The actual work will be done during preparation in the call to 161 // ::finishSetDataSource_l to avoid blocking the calling thread in 162 // setDataSource for any significant time. 163 return OK; 164 } 165 166 status_t PreviewPlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { 167 bool haveAudio = false; 168 bool haveVideo = false; 169 for (size_t i = 0; i < extractor->countTracks(); ++i) { 170 sp<MetaData> meta = extractor->getTrackMetaData(i); 171 172 const char *mime; 173 CHECK(meta->findCString(kKeyMIMEType, &mime)); 174 175 if (!haveVideo && !strncasecmp(mime, "video/", 6)) { 176 setVideoSource(extractor->getTrack(i)); 177 haveVideo = true; 178 } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) { 179 setAudioSource(extractor->getTrack(i)); 180 haveAudio = true; 181 182 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 183 // Only do this for vorbis audio, none of the other audio 184 // formats even support this ringtone specific hack and 185 // retrieving the metadata on some extractors may turn out 186 // to be very expensive. 187 sp<MetaData> fileMeta = extractor->getMetaData(); 188 int32_t loop; 189 if (fileMeta != NULL 190 && fileMeta->findInt32(kKeyAutoLoop, &loop) 191 && loop != 0) { 192 mFlags |= AUTO_LOOPING; 193 } 194 } 195 } 196 197 if (haveAudio && haveVideo) { 198 break; 199 } 200 } 201 202 /* Add the support for Dummy audio*/ 203 if( !haveAudio ){ 204 LOGV("PreviewPlayer: setDataSource_l Dummyaudiocreation started"); 205 206 mAudioTrack = DummyAudioSource::Create(32000, 2, 20000, 207 ((mPlayEndTimeMsec)*1000LL)); 208 LOGV("PreviewPlayer: setDataSource_l Dummyauiosource created"); 209 if(mAudioTrack != NULL) { 210 haveAudio = true; 211 } 212 } 213 214 if (!haveAudio && !haveVideo) { 215 return UNKNOWN_ERROR; 216 } 217 218 mExtractorFlags = extractor->flags(); 219 return OK; 220 } 221 222 status_t PreviewPlayer::setDataSource_l_jpg() { 223 M4OSA_ERR err = M4NO_ERROR; 224 LOGV("PreviewPlayer: setDataSource_l_jpg started"); 225 226 mAudioSource = DummyAudioSource::Create(32000, 2, 20000, 227 ((mPlayEndTimeMsec)*1000LL)); 228 LOGV("PreviewPlayer: setDataSource_l_jpg Dummyaudiosource created"); 229 if(mAudioSource != NULL) { 230 setAudioSource(mAudioSource); 231 } 232 status_t error = mAudioSource->start(); 233 if (error != OK) { 234 LOGV("Error starting dummy audio source"); 235 mAudioSource.clear(); 236 return err; 237 } 238 239 mDurationUs = (mPlayEndTimeMsec - mPlayBeginTimeMsec)*1000LL; 240 241 mVideoSource = DummyVideoSource::Create(mVideoWidth, mVideoHeight, 242 mDurationUs, mUri); 243 244 updateSizeToRender(mVideoSource->getFormat()); 245 setVideoSource(mVideoSource); 246 status_t err1 = mVideoSource->start(); 247 if (err1 != OK) { 248 mVideoSource.clear(); 249 return err; 250 } 251 252 mIsVideoSourceJpg = true; 253 return OK; 254 } 255 256 void PreviewPlayer::reset() { 257 Mutex::Autolock autoLock(mLock); 258 reset_l(); 259 } 260 261 void PreviewPlayer::reset_l() { 262 263 if (mFlags & PREPARING) { 264 mFlags |= PREPARE_CANCELLED; 265 } 266 267 while (mFlags & PREPARING) { 268 mPreparedCondition.wait(mLock); 269 } 270 271 cancelPlayerEvents(); 272 mAudioTrack.clear(); 273 mVideoTrack.clear(); 274 275 // Shutdown audio first, so that the respone to the reset request 276 // appears to happen instantaneously as far as the user is concerned 277 // If we did this later, audio would continue playing while we 278 // shutdown the video-related resources and the player appear to 279 // not be as responsive to a reset request. 280 if (mAudioPlayer == NULL && mAudioSource != NULL) { 281 // If we had an audio player, it would have effectively 282 // taken possession of the audio source and stopped it when 283 // _it_ is stopped. Otherwise this is still our responsibility. 284 mAudioSource->stop(); 285 } 286 mAudioSource.clear(); 287 288 mTimeSource = NULL; 289 290 //Single audio player instance used 291 //So donot delete it here 292 //It is deleted from PreviewController class 293 //delete mAudioPlayer; 294 mAudioPlayer = NULL; 295 296 if (mVideoBuffer) { 297 mVideoBuffer->release(); 298 mVideoBuffer = NULL; 299 } 300 301 if (mVideoSource != NULL) { 302 mVideoSource->stop(); 303 304 // The following hack is necessary to ensure that the OMX 305 // component is completely released by the time we may try 306 // to instantiate it again. 307 wp<MediaSource> tmp = mVideoSource; 308 mVideoSource.clear(); 309 while (tmp.promote() != NULL) { 310 usleep(1000); 311 } 312 IPCThreadState::self()->flushCommands(); 313 } 314 315 mDurationUs = -1; 316 mFlags = 0; 317 mExtractorFlags = 0; 318 mVideoWidth = mVideoHeight = -1; 319 mTimeSourceDeltaUs = 0; 320 mVideoTimeUs = 0; 321 322 mSeeking = NO_SEEK; 323 mSeekNotificationSent = false; 324 mSeekTimeUs = 0; 325 326 mUri.setTo(""); 327 mUriHeaders.clear(); 328 329 mFileSource.clear(); 330 331 mCurrentVideoEffect = VIDEO_EFFECT_NONE; 332 mIsVideoSourceJpg = false; 333 mFrameRGBBuffer = NULL; 334 if(mFrameYUVBuffer != NULL) { 335 free(mFrameYUVBuffer); 336 mFrameYUVBuffer = NULL; 337 } 338 } 339 340 status_t PreviewPlayer::play() { 341 Mutex::Autolock autoLock(mLock); 342 343 mFlags &= ~CACHE_UNDERRUN; 344 mFlags &= ~INFORMED_AV_EOS; 345 return play_l(); 346 } 347 348 status_t PreviewPlayer::startAudioPlayer_l() { 349 CHECK(!(mFlags & AUDIO_RUNNING)); 350 351 if (mAudioSource == NULL || mAudioPlayer == NULL) { 352 return OK; 353 } 354 355 if (!(mFlags & AUDIOPLAYER_STARTED)) { 356 mFlags |= AUDIOPLAYER_STARTED; 357 358 // We've already started the MediaSource in order to enable 359 // the prefetcher to read its data. 360 status_t err = mVeAudioPlayer->start( 361 true /* sourceAlreadyStarted */); 362 363 if (err != OK) { 364 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 365 return err; 366 } 367 } else { 368 mVeAudioPlayer->resume(); 369 } 370 371 mFlags |= AUDIO_RUNNING; 372 373 mWatchForAudioEOS = true; 374 375 return OK; 376 } 377 378 status_t PreviewPlayer::setAudioPlayer(AudioPlayerBase *audioPlayer) { 379 Mutex::Autolock autoLock(mLock); 380 CHECK(!(mFlags & PLAYING)); 381 mAudioPlayer = audioPlayer; 382 383 LOGV("SetAudioPlayer"); 384 mIsChangeSourceRequired = true; 385 mVeAudioPlayer = 386 (VideoEditorAudioPlayer*)mAudioPlayer; 387 388 // check if the new and old source are dummy 389 sp<MediaSource> anAudioSource = mVeAudioPlayer->getSource(); 390 if (anAudioSource == NULL) { 391 // Audio player does not have any source set. 392 LOGV("setAudioPlayer: Audio player does not have any source set"); 393 return OK; 394 } 395 396 // If new video source is not dummy, then always change source 397 // Else audio player continues using old audio source and there are 398 // frame drops to maintain AV sync 399 sp<MetaData> meta; 400 if (mVideoSource != NULL) { 401 meta = mVideoSource->getFormat(); 402 const char *pVidSrcType; 403 if (meta->findCString(kKeyDecoderComponent, &pVidSrcType)) { 404 if (strcmp(pVidSrcType, "DummyVideoSource") != 0) { 405 LOGV(" Video clip with silent audio; need to change source"); 406 return OK; 407 } 408 } 409 } 410 411 const char *pSrcType1; 412 const char *pSrcType2; 413 meta = anAudioSource->getFormat(); 414 415 if (meta->findCString(kKeyDecoderComponent, &pSrcType1)) { 416 if (strcmp(pSrcType1, "DummyAudioSource") == 0) { 417 meta = mAudioSource->getFormat(); 418 if (meta->findCString(kKeyDecoderComponent, &pSrcType2)) { 419 if (strcmp(pSrcType2, "DummyAudioSource") == 0) { 420 mIsChangeSourceRequired = false; 421 // Just set the new play duration for the existing source 422 MediaSource *pMediaSrc = anAudioSource.get(); 423 DummyAudioSource *pDummyAudioSource = (DummyAudioSource*)pMediaSrc; 424 //Increment the duration of audio source 425 pDummyAudioSource->setDuration( 426 (int64_t)((mPlayEndTimeMsec)*1000LL)); 427 428 // Stop the new audio source 429 // since we continue using old source 430 LOGV("setAudioPlayer: stop new audio source"); 431 mAudioSource->stop(); 432 } 433 } 434 } 435 } 436 437 return OK; 438 } 439 440 void PreviewPlayer::onStreamDone() { 441 // Posted whenever any stream finishes playing. 442 443 Mutex::Autolock autoLock(mLock); 444 if (!mStreamDoneEventPending) { 445 return; 446 } 447 mStreamDoneEventPending = false; 448 449 if (mStreamDoneStatus != ERROR_END_OF_STREAM) { 450 LOGV("MEDIA_ERROR %d", mStreamDoneStatus); 451 452 notifyListener_l( 453 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus); 454 455 pause_l(true /* at eos */); 456 457 mFlags |= AT_EOS; 458 return; 459 } 460 461 const bool allDone = 462 (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS)) 463 && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS)); 464 465 if (!allDone) { 466 return; 467 } 468 469 if (mFlags & (LOOPING | AUTO_LOOPING)) { 470 seekTo_l(0); 471 472 if (mVideoSource != NULL) { 473 postVideoEvent_l(); 474 } 475 } else { 476 LOGV("MEDIA_PLAYBACK_COMPLETE"); 477 //pause before sending event 478 pause_l(true /* at eos */); 479 480 //This lock is used to syncronize onStreamDone() in PreviewPlayer and 481 //stopPreview() in PreviewController 482 Mutex::Autolock autoLock(mLockControl); 483 /* Make sure PreviewPlayer only notifies MEDIA_PLAYBACK_COMPLETE once for each clip! 484 * It happens twice in following scenario. 485 * To make the clips in preview storyboard are played and switched smoothly, 486 * PreviewController uses two PreviewPlayer instances and one AudioPlayer. 487 * The two PreviewPlayer use the same AudioPlayer to play the audio, 488 * and change the audio source of the AudioPlayer. 489 * If the audio source of current playing clip and next clip are dummy 490 * audio source(image or video without audio), it will not change the audio source 491 * to avoid the "audio glitch", and keep using the current audio source. 492 * When the video of current clip reached the EOS, PreviewPlayer will set EOS flag 493 * for video and audio, and it will notify MEDIA_PLAYBACK_COMPLETE. 494 * But the audio(dummy audio source) is still playing(for next clip), 495 * and when it reached the EOS, and video reached EOS, 496 * PreviewPlayer will notify MEDIA_PLAYBACK_COMPLETE again. */ 497 if (!(mFlags & INFORMED_AV_EOS)) { 498 notifyListener_l(MEDIA_PLAYBACK_COMPLETE); 499 mFlags |= INFORMED_AV_EOS; 500 } 501 mFlags |= AT_EOS; 502 LOGV("onStreamDone end"); 503 return; 504 } 505 } 506 507 508 status_t PreviewPlayer::play_l() { 509 510 mFlags &= ~SEEK_PREVIEW; 511 512 if (mFlags & PLAYING) { 513 return OK; 514 } 515 mStartNextPlayer = false; 516 517 if (!(mFlags & PREPARED)) { 518 status_t err = prepare_l(); 519 520 if (err != OK) { 521 return err; 522 } 523 } 524 525 mFlags |= PLAYING; 526 mFlags |= FIRST_FRAME; 527 528 bool deferredAudioSeek = false; 529 530 if (mAudioSource != NULL) { 531 if (mAudioPlayer == NULL) { 532 if (mAudioSink != NULL) { 533 534 mAudioPlayer = new VideoEditorAudioPlayer(mAudioSink, this); 535 mVeAudioPlayer = 536 (VideoEditorAudioPlayer*)mAudioPlayer; 537 538 mAudioPlayer->setSource(mAudioSource); 539 540 mVeAudioPlayer->setAudioMixSettings( 541 mPreviewPlayerAudioMixSettings); 542 543 mVeAudioPlayer->setAudioMixPCMFileHandle( 544 mAudioMixPCMFileHandle); 545 546 mVeAudioPlayer->setAudioMixStoryBoardSkimTimeStamp( 547 mAudioMixStoryBoardTS, mCurrentMediaBeginCutTime, 548 mCurrentMediaVolumeValue); 549 550 mFlags |= AUDIOPLAYER_STARTED; 551 // We've already started the MediaSource in order to enable 552 // the prefetcher to read its data. 553 status_t err = mVeAudioPlayer->start( 554 true /* sourceAlreadyStarted */); 555 556 if (err != OK) { 557 //delete mAudioPlayer; 558 mAudioPlayer = NULL; 559 560 mFlags &= ~(PLAYING | FIRST_FRAME); 561 return err; 562 } 563 564 mTimeSource = mVeAudioPlayer; 565 mFlags |= AUDIO_RUNNING; 566 deferredAudioSeek = true; 567 mWatchForAudioSeekComplete = false; 568 mWatchForAudioEOS = true; 569 } 570 } else { 571 mVeAudioPlayer = (VideoEditorAudioPlayer*)mAudioPlayer; 572 bool isAudioPlayerStarted = mVeAudioPlayer->isStarted(); 573 574 if (mIsChangeSourceRequired == true) { 575 LOGV("play_l: Change audio source required"); 576 577 if (isAudioPlayerStarted == true) { 578 mVeAudioPlayer->pause(); 579 } 580 581 mVeAudioPlayer->setSource(mAudioSource); 582 mVeAudioPlayer->setObserver(this); 583 584 mVeAudioPlayer->setAudioMixSettings( 585 mPreviewPlayerAudioMixSettings); 586 587 mVeAudioPlayer->setAudioMixStoryBoardSkimTimeStamp( 588 mAudioMixStoryBoardTS, mCurrentMediaBeginCutTime, 589 mCurrentMediaVolumeValue); 590 591 if (isAudioPlayerStarted == true) { 592 mVeAudioPlayer->resume(); 593 } else { 594 status_t err = OK; 595 err = mVeAudioPlayer->start(true); 596 if (err != OK) { 597 mAudioPlayer = NULL; 598 mVeAudioPlayer = NULL; 599 600 mFlags &= ~(PLAYING | FIRST_FRAME); 601 return err; 602 } 603 } 604 } else { 605 LOGV("play_l: No Source change required"); 606 mVeAudioPlayer->setAudioMixStoryBoardSkimTimeStamp( 607 mAudioMixStoryBoardTS, mCurrentMediaBeginCutTime, 608 mCurrentMediaVolumeValue); 609 610 mVeAudioPlayer->resume(); 611 } 612 613 mFlags |= AUDIOPLAYER_STARTED; 614 mFlags |= AUDIO_RUNNING; 615 mTimeSource = mVeAudioPlayer; 616 deferredAudioSeek = true; 617 mWatchForAudioSeekComplete = false; 618 mWatchForAudioEOS = true; 619 } 620 } 621 622 if (mTimeSource == NULL && mAudioPlayer == NULL) { 623 mTimeSource = &mSystemTimeSource; 624 } 625 626 // Set the seek option for Image source files and read. 627 // This resets the timestamping for image play 628 if (mIsVideoSourceJpg) { 629 MediaSource::ReadOptions options; 630 MediaBuffer *aLocalBuffer; 631 options.setSeekTo(mSeekTimeUs); 632 mVideoSource->read(&aLocalBuffer, &options); 633 aLocalBuffer->release(); 634 } 635 636 if (mVideoSource != NULL) { 637 // Kick off video playback 638 postVideoEvent_l(); 639 } 640 641 if (deferredAudioSeek) { 642 // If there was a seek request while we were paused 643 // and we're just starting up again, honor the request now. 644 seekAudioIfNecessary_l(); 645 } 646 647 if (mFlags & AT_EOS) { 648 // Legacy behaviour, if a stream finishes playing and then 649 // is started again, we play from the start... 650 seekTo_l(0); 651 } 652 653 return OK; 654 } 655 656 657 status_t PreviewPlayer::initRenderer_l() { 658 if (mSurface != NULL) { 659 if(mVideoRenderer == NULL) { 660 mVideoRenderer = mNativeWindowRenderer->createRenderInput(); 661 if (mVideoSource != NULL) { 662 updateSizeToRender(mVideoSource->getFormat()); 663 } 664 } 665 } 666 return OK; 667 } 668 669 670 status_t PreviewPlayer::seekTo(int64_t timeUs) { 671 672 if ((mExtractorFlags & MediaExtractor::CAN_SEEK) || (mIsVideoSourceJpg)) { 673 Mutex::Autolock autoLock(mLock); 674 return seekTo_l(timeUs); 675 } 676 677 return OK; 678 } 679 680 681 status_t PreviewPlayer::getVideoDimensions( 682 int32_t *width, int32_t *height) const { 683 Mutex::Autolock autoLock(mLock); 684 685 if (mVideoWidth < 0 || mVideoHeight < 0) { 686 return UNKNOWN_ERROR; 687 } 688 689 *width = mVideoWidth; 690 *height = mVideoHeight; 691 692 return OK; 693 } 694 695 696 status_t PreviewPlayer::initAudioDecoder() { 697 sp<MetaData> meta = mAudioTrack->getFormat(); 698 const char *mime; 699 CHECK(meta->findCString(kKeyMIMEType, &mime)); 700 701 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 702 mAudioSource = mAudioTrack; 703 } else { 704 sp<MediaSource> aRawSource; 705 aRawSource = OMXCodec::Create( 706 mClient.interface(), mAudioTrack->getFormat(), 707 false, // createEncoder 708 mAudioTrack); 709 710 if(aRawSource != NULL) { 711 LOGV("initAudioDecoder: new VideoEditorSRC"); 712 mAudioSource = new VideoEditorSRC(aRawSource); 713 } 714 } 715 716 if (mAudioSource != NULL) { 717 int64_t durationUs; 718 if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) { 719 Mutex::Autolock autoLock(mMiscStateLock); 720 if (mDurationUs < 0 || durationUs > mDurationUs) { 721 mDurationUs = durationUs; 722 } 723 } 724 status_t err = mAudioSource->start(); 725 726 if (err != OK) { 727 mAudioSource.clear(); 728 return err; 729 } 730 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) { 731 // For legacy reasons we're simply going to ignore the absence 732 // of an audio decoder for QCELP instead of aborting playback 733 // altogether. 734 return OK; 735 } 736 737 return mAudioSource != NULL ? OK : UNKNOWN_ERROR; 738 } 739 740 741 status_t PreviewPlayer::initVideoDecoder(uint32_t flags) { 742 743 initRenderer_l(); 744 745 if (mVideoRenderer == NULL) { 746 LOGE("Cannot create renderer"); 747 return UNKNOWN_ERROR; 748 } 749 750 mVideoSource = OMXCodec::Create( 751 mClient.interface(), mVideoTrack->getFormat(), 752 false, 753 mVideoTrack, 754 NULL, flags, mVideoRenderer->getTargetWindow()); 755 756 if (mVideoSource != NULL) { 757 int64_t durationUs; 758 if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) { 759 Mutex::Autolock autoLock(mMiscStateLock); 760 if (mDurationUs < 0 || durationUs > mDurationUs) { 761 mDurationUs = durationUs; 762 } 763 } 764 765 updateSizeToRender(mVideoTrack->getFormat()); 766 767 status_t err = mVideoSource->start(); 768 769 if (err != OK) { 770 mVideoSource.clear(); 771 return err; 772 } 773 } 774 775 return mVideoSource != NULL ? OK : UNKNOWN_ERROR; 776 } 777 778 779 void PreviewPlayer::onVideoEvent() { 780 uint32_t i=0; 781 M4OSA_ERR err1 = M4NO_ERROR; 782 int64_t imageFrameTimeUs = 0; 783 784 Mutex::Autolock autoLock(mLock); 785 if (!mVideoEventPending) { 786 // The event has been cancelled in reset_l() but had already 787 // been scheduled for execution at that time. 788 return; 789 } 790 mVideoEventPending = false; 791 792 if (mFlags & SEEK_PREVIEW) { 793 mFlags &= ~SEEK_PREVIEW; 794 return; 795 } 796 797 TimeSource *ts_st = &mSystemTimeSource; 798 int64_t timeStartUs = ts_st->getRealTimeUs(); 799 800 if (mSeeking != NO_SEEK) { 801 802 if(mAudioSource != NULL) { 803 804 // We're going to seek the video source first, followed by 805 // the audio source. 806 // In order to avoid jumps in the DataSource offset caused by 807 // the audio codec prefetching data from the old locations 808 // while the video codec is already reading data from the new 809 // locations, we'll "pause" the audio source, causing it to 810 // stop reading input data until a subsequent seek. 811 812 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) { 813 mAudioPlayer->pause(); 814 mFlags &= ~AUDIO_RUNNING; 815 } 816 mAudioSource->pause(); 817 } 818 } 819 820 if (!mVideoBuffer) { 821 MediaSource::ReadOptions options; 822 if (mSeeking != NO_SEEK) { 823 LOGV("LV PLAYER seeking to %lld us (%.2f secs)", mSeekTimeUs, 824 mSeekTimeUs / 1E6); 825 826 options.setSeekTo( 827 mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST); 828 } 829 for (;;) { 830 status_t err = mVideoSource->read(&mVideoBuffer, &options); 831 options.clearSeekTo(); 832 833 if (err != OK) { 834 CHECK_EQ(mVideoBuffer, NULL); 835 836 if (err == INFO_FORMAT_CHANGED) { 837 LOGV("LV PLAYER VideoSource signalled format change"); 838 notifyVideoSize_l(); 839 840 if (mVideoRenderer != NULL) { 841 mVideoRendererIsPreview = false; 842 err = initRenderer_l(); 843 if (err != OK) { 844 postStreamDoneEvent_l(err); 845 } 846 847 } 848 849 updateSizeToRender(mVideoSource->getFormat()); 850 continue; 851 } 852 // So video playback is complete, but we may still have 853 // a seek request pending that needs to be applied to the audio track 854 if (mSeeking != NO_SEEK) { 855 LOGV("video stream ended while seeking!"); 856 } 857 finishSeekIfNecessary(-1); 858 LOGV("PreviewPlayer: onVideoEvent EOS reached."); 859 mFlags |= VIDEO_AT_EOS; 860 mFlags |= AUDIO_AT_EOS; 861 mOverlayUpdateEventPosted = false; 862 postStreamDoneEvent_l(err); 863 // Set the last decoded timestamp to duration 864 mDecodedVideoTs = (mPlayEndTimeMsec*1000LL); 865 return; 866 } 867 868 if (mVideoBuffer->range_length() == 0) { 869 // Some decoders, notably the PV AVC software decoder 870 // return spurious empty buffers that we just want to ignore. 871 872 mVideoBuffer->release(); 873 mVideoBuffer = NULL; 874 continue; 875 } 876 877 int64_t videoTimeUs; 878 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &videoTimeUs)); 879 880 if (mSeeking != NO_SEEK) { 881 if (videoTimeUs < mSeekTimeUs) { 882 // buffers are before seek time 883 // ignore them 884 mVideoBuffer->release(); 885 mVideoBuffer = NULL; 886 continue; 887 } 888 } else { 889 if((videoTimeUs/1000) < mPlayBeginTimeMsec) { 890 // Frames are before begin cut time 891 // Donot render 892 mVideoBuffer->release(); 893 mVideoBuffer = NULL; 894 continue; 895 } 896 } 897 break; 898 } 899 } 900 901 mNumberDecVideoFrames++; 902 903 int64_t timeUs; 904 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 905 906 { 907 Mutex::Autolock autoLock(mMiscStateLock); 908 mVideoTimeUs = timeUs; 909 } 910 911 912 if(!mStartNextPlayer) { 913 int64_t playbackTimeRemaining = (mPlayEndTimeMsec*1000LL) - timeUs; 914 if(playbackTimeRemaining <= 1500000) { 915 //When less than 1.5 sec of playback left 916 // send notification to start next player 917 918 mStartNextPlayer = true; 919 notifyListener_l(0xAAAAAAAA); 920 } 921 } 922 923 SeekType wasSeeking = mSeeking; 924 finishSeekIfNecessary(timeUs); 925 if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING))) { 926 status_t err = startAudioPlayer_l(); 927 if (err != OK) { 928 LOGE("Starting the audio player failed w/ err %d", err); 929 return; 930 } 931 } 932 933 TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource; 934 935 if(ts == NULL) { 936 mVideoBuffer->release(); 937 mVideoBuffer = NULL; 938 return; 939 } 940 941 if(!mIsVideoSourceJpg) { 942 if (mFlags & FIRST_FRAME) { 943 mFlags &= ~FIRST_FRAME; 944 945 mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs; 946 } 947 948 int64_t realTimeUs, mediaTimeUs; 949 if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL 950 && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) { 951 mTimeSourceDeltaUs = realTimeUs - mediaTimeUs; 952 } 953 954 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs; 955 956 int64_t latenessUs = nowUs - timeUs; 957 958 if (wasSeeking != NO_SEEK) { 959 // Let's display the first frame after seeking right away. 960 latenessUs = 0; 961 } 962 LOGV("Audio time stamp = %lld and video time stamp = %lld", 963 ts->getRealTimeUs(),timeUs); 964 if (latenessUs > 40000) { 965 // We're more than 40ms late. 966 967 LOGV("LV PLAYER we're late by %lld us (%.2f secs)", 968 latenessUs, latenessUs / 1E6); 969 970 mVideoBuffer->release(); 971 mVideoBuffer = NULL; 972 postVideoEvent_l(0); 973 return; 974 } 975 976 if (latenessUs < -25000) { 977 // We're more than 25ms early. 978 LOGV("We're more than 25ms early, lateness %lld", latenessUs); 979 980 postVideoEvent_l(25000); 981 return; 982 } 983 } 984 985 if (mVideoRendererIsPreview || mVideoRenderer == NULL) { 986 mVideoRendererIsPreview = false; 987 988 status_t err = initRenderer_l(); 989 if (err != OK) { 990 postStreamDoneEvent_l(err); 991 } 992 } 993 994 // If timestamp exceeds endCutTime of clip, donot render 995 if((timeUs/1000) > mPlayEndTimeMsec) { 996 mVideoBuffer->release(); 997 mVideoBuffer = NULL; 998 mFlags |= VIDEO_AT_EOS; 999 mFlags |= AUDIO_AT_EOS; 1000 LOGV("PreviewPlayer: onVideoEvent timeUs > mPlayEndTime; send EOS.."); 1001 mOverlayUpdateEventPosted = false; 1002 // Set the last decoded timestamp to duration 1003 mDecodedVideoTs = (mPlayEndTimeMsec*1000LL); 1004 postStreamDoneEvent_l(ERROR_END_OF_STREAM); 1005 return; 1006 } 1007 // Capture the frame timestamp to be rendered 1008 mDecodedVideoTs = timeUs; 1009 1010 // Post processing to apply video effects 1011 for(i=0;i<mNumberEffects;i++) { 1012 // First check if effect starttime matches the clip being previewed 1013 if((mEffectsSettings[i].uiStartTime < (mDecVideoTsStoryBoard/1000)) || 1014 (mEffectsSettings[i].uiStartTime >= 1015 ((mDecVideoTsStoryBoard/1000) + mPlayEndTimeMsec - mPlayBeginTimeMsec))) 1016 { 1017 // This effect doesn't belong to this clip, check next one 1018 continue; 1019 } 1020 // Check if effect applies to this particular frame timestamp 1021 if((mEffectsSettings[i].uiStartTime <= 1022 (((timeUs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec)) && 1023 ((mEffectsSettings[i].uiStartTime+mEffectsSettings[i].uiDuration) >= 1024 (((timeUs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec)) 1025 && (mEffectsSettings[i].uiDuration != 0)) { 1026 setVideoPostProcessingNode( 1027 mEffectsSettings[i].VideoEffectType, TRUE); 1028 } 1029 else { 1030 setVideoPostProcessingNode( 1031 mEffectsSettings[i].VideoEffectType, FALSE); 1032 } 1033 } 1034 1035 //Provide the overlay Update indication when there is an overlay effect 1036 if (mCurrentVideoEffect & VIDEO_EFFECT_FRAMING) { 1037 mCurrentVideoEffect &= ~VIDEO_EFFECT_FRAMING; //never apply framing here. 1038 if (!mOverlayUpdateEventPosted) { 1039 // Find the effect in effectSettings array 1040 M4OSA_UInt32 index; 1041 for (index = 0; index < mNumberEffects; index++) { 1042 M4OSA_UInt32 timeMs = mDecodedVideoTs/1000; 1043 M4OSA_UInt32 timeOffset = mDecVideoTsStoryBoard/1000; 1044 if(mEffectsSettings[index].VideoEffectType == 1045 (M4VSS3GPP_VideoEffectType)M4xVSS_kVideoEffectType_Framing) { 1046 if (((mEffectsSettings[index].uiStartTime + 1) <= 1047 timeMs + timeOffset - mPlayBeginTimeMsec) && 1048 ((mEffectsSettings[index].uiStartTime - 1 + 1049 mEffectsSettings[index].uiDuration) >= 1050 timeMs + timeOffset - mPlayBeginTimeMsec)) 1051 { 1052 break; 1053 } 1054 } 1055 } 1056 if (index < mNumberEffects) { 1057 mCurrFramingEffectIndex = index; 1058 mOverlayUpdateEventPosted = true; 1059 postOverlayUpdateEvent_l(); 1060 LOGV("Framing index = %d", mCurrFramingEffectIndex); 1061 } else { 1062 LOGV("No framing effects found"); 1063 } 1064 } 1065 1066 } else if (mOverlayUpdateEventPosted) { 1067 //Post the event when the overlay is no more valid 1068 LOGV("Overlay is Done"); 1069 mOverlayUpdateEventPosted = false; 1070 postOverlayUpdateEvent_l(); 1071 } 1072 1073 if (mVideoRenderer != NULL) { 1074 mVideoRenderer->render(mVideoBuffer, mCurrentVideoEffect, 1075 mRenderingMode, mIsVideoSourceJpg); 1076 } 1077 1078 mVideoBuffer->release(); 1079 mVideoBuffer = NULL; 1080 1081 // Post progress callback based on callback interval set 1082 if(mNumberDecVideoFrames >= mProgressCbInterval) { 1083 postProgressCallbackEvent_l(); 1084 mNumberDecVideoFrames = 0; // reset counter 1085 } 1086 1087 // if reached EndCutTime of clip, post EOS event 1088 if((timeUs/1000) >= mPlayEndTimeMsec) { 1089 LOGV("PreviewPlayer: onVideoEvent EOS."); 1090 mFlags |= VIDEO_AT_EOS; 1091 mFlags |= AUDIO_AT_EOS; 1092 mOverlayUpdateEventPosted = false; 1093 // Set the last decoded timestamp to duration 1094 mDecodedVideoTs = (mPlayEndTimeMsec*1000LL); 1095 postStreamDoneEvent_l(ERROR_END_OF_STREAM); 1096 } 1097 else { 1098 if ((wasSeeking != NO_SEEK) && (mFlags & SEEK_PREVIEW)) { 1099 mFlags &= ~SEEK_PREVIEW; 1100 return; 1101 } 1102 1103 if(!mIsVideoSourceJpg) { 1104 postVideoEvent_l(0); 1105 } 1106 else { 1107 postVideoEvent_l(33000); 1108 } 1109 } 1110 } 1111 1112 status_t PreviewPlayer::prepare() { 1113 Mutex::Autolock autoLock(mLock); 1114 return prepare_l(); 1115 } 1116 1117 status_t PreviewPlayer::prepare_l() { 1118 if (mFlags & PREPARED) { 1119 return OK; 1120 } 1121 1122 if (mFlags & PREPARING) { 1123 return UNKNOWN_ERROR; 1124 } 1125 1126 mIsAsyncPrepare = false; 1127 status_t err = prepareAsync_l(); 1128 1129 if (err != OK) { 1130 return err; 1131 } 1132 1133 while (mFlags & PREPARING) { 1134 mPreparedCondition.wait(mLock); 1135 } 1136 1137 return mPrepareResult; 1138 } 1139 1140 status_t PreviewPlayer::prepareAsync_l() { 1141 if (mFlags & PREPARING) { 1142 return UNKNOWN_ERROR; // async prepare already pending 1143 } 1144 1145 if (!mQueueStarted) { 1146 mQueue.start(); 1147 mQueueStarted = true; 1148 } 1149 1150 mFlags |= PREPARING; 1151 mAsyncPrepareEvent = new PreviewPlayerEvent( 1152 this, &PreviewPlayer::onPrepareAsyncEvent); 1153 1154 mQueue.postEvent(mAsyncPrepareEvent); 1155 1156 return OK; 1157 } 1158 1159 status_t PreviewPlayer::finishSetDataSource_l() { 1160 sp<DataSource> dataSource; 1161 sp<MediaExtractor> extractor; 1162 1163 dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders); 1164 1165 if (dataSource == NULL) { 1166 return UNKNOWN_ERROR; 1167 } 1168 1169 //If file type is .rgb, then no need to check for Extractor 1170 int uriLen = strlen(mUri); 1171 int startOffset = uriLen - 4; 1172 if(!strncasecmp(mUri+startOffset, ".rgb", 4)) { 1173 extractor = NULL; 1174 } 1175 else { 1176 extractor = MediaExtractor::Create(dataSource, 1177 MEDIA_MIMETYPE_CONTAINER_MPEG4); 1178 } 1179 1180 if (extractor == NULL) { 1181 LOGV("PreviewPlayer::finishSetDataSource_l extractor == NULL"); 1182 return setDataSource_l_jpg(); 1183 } 1184 1185 return setDataSource_l(extractor); 1186 } 1187 1188 1189 // static 1190 bool PreviewPlayer::ContinuePreparation(void *cookie) { 1191 PreviewPlayer *me = static_cast<PreviewPlayer *>(cookie); 1192 1193 return (me->mFlags & PREPARE_CANCELLED) == 0; 1194 } 1195 1196 void PreviewPlayer::onPrepareAsyncEvent() { 1197 Mutex::Autolock autoLock(mLock); 1198 LOGV("onPrepareAsyncEvent"); 1199 1200 if (mFlags & PREPARE_CANCELLED) { 1201 LOGV("LV PLAYER prepare was cancelled before doing anything"); 1202 abortPrepare(UNKNOWN_ERROR); 1203 return; 1204 } 1205 1206 if (mUri.size() > 0) { 1207 status_t err = finishSetDataSource_l(); 1208 1209 if (err != OK) { 1210 abortPrepare(err); 1211 return; 1212 } 1213 } 1214 1215 if (mVideoTrack != NULL && mVideoSource == NULL) { 1216 status_t err = initVideoDecoder(OMXCodec::kHardwareCodecsOnly); 1217 1218 if (err != OK) { 1219 abortPrepare(err); 1220 return; 1221 } 1222 } 1223 1224 if (mAudioTrack != NULL && mAudioSource == NULL) { 1225 status_t err = initAudioDecoder(); 1226 1227 if (err != OK) { 1228 abortPrepare(err); 1229 return; 1230 } 1231 } 1232 finishAsyncPrepare_l(); 1233 1234 } 1235 1236 void PreviewPlayer::finishAsyncPrepare_l() { 1237 if (mIsAsyncPrepare) { 1238 if (mVideoSource == NULL) { 1239 LOGV("finishAsyncPrepare_l: MEDIA_SET_VIDEO_SIZE 0 0 "); 1240 notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0); 1241 } else { 1242 LOGV("finishAsyncPrepare_l: MEDIA_SET_VIDEO_SIZE"); 1243 notifyVideoSize_l(); 1244 } 1245 LOGV("finishAsyncPrepare_l: MEDIA_PREPARED"); 1246 notifyListener_l(MEDIA_PREPARED); 1247 } 1248 1249 mPrepareResult = OK; 1250 mFlags &= ~(PREPARING|PREPARE_CANCELLED); 1251 mFlags |= PREPARED; 1252 mAsyncPrepareEvent = NULL; 1253 mPreparedCondition.broadcast(); 1254 } 1255 1256 void PreviewPlayer::acquireLock() { 1257 LOGV("acquireLock"); 1258 mLockControl.lock(); 1259 } 1260 1261 void PreviewPlayer::releaseLock() { 1262 LOGV("releaseLock"); 1263 mLockControl.unlock(); 1264 } 1265 1266 status_t PreviewPlayer::loadEffectsSettings( 1267 M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) { 1268 M4OSA_UInt32 i = 0, rgbSize = 0; 1269 M4VIFI_UInt8 *tmp = M4OSA_NULL; 1270 1271 mNumberEffects = nEffects; 1272 mEffectsSettings = pEffectSettings; 1273 return OK; 1274 } 1275 1276 status_t PreviewPlayer::loadAudioMixSettings( 1277 M4xVSS_AudioMixingSettings* pAudioMixSettings) { 1278 1279 LOGV("PreviewPlayer: loadAudioMixSettings: "); 1280 mPreviewPlayerAudioMixSettings = pAudioMixSettings; 1281 return OK; 1282 } 1283 1284 status_t PreviewPlayer::setAudioMixPCMFileHandle( 1285 M4OSA_Context pAudioMixPCMFileHandle) { 1286 1287 LOGV("PreviewPlayer: setAudioMixPCMFileHandle: "); 1288 mAudioMixPCMFileHandle = pAudioMixPCMFileHandle; 1289 return OK; 1290 } 1291 1292 status_t PreviewPlayer::setAudioMixStoryBoardParam( 1293 M4OSA_UInt32 audioMixStoryBoardTS, 1294 M4OSA_UInt32 currentMediaBeginCutTime, 1295 M4OSA_UInt32 primaryTrackVolValue ) { 1296 1297 mAudioMixStoryBoardTS = audioMixStoryBoardTS; 1298 mCurrentMediaBeginCutTime = currentMediaBeginCutTime; 1299 mCurrentMediaVolumeValue = primaryTrackVolValue; 1300 return OK; 1301 } 1302 1303 status_t PreviewPlayer::setPlaybackBeginTime(uint32_t msec) { 1304 1305 mPlayBeginTimeMsec = msec; 1306 return OK; 1307 } 1308 1309 status_t PreviewPlayer::setPlaybackEndTime(uint32_t msec) { 1310 1311 mPlayEndTimeMsec = msec; 1312 return OK; 1313 } 1314 1315 status_t PreviewPlayer::setStoryboardStartTime(uint32_t msec) { 1316 1317 mStoryboardStartTimeMsec = msec; 1318 mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL; 1319 return OK; 1320 } 1321 1322 status_t PreviewPlayer::setProgressCallbackInterval(uint32_t cbInterval) { 1323 1324 mProgressCbInterval = cbInterval; 1325 return OK; 1326 } 1327 1328 1329 status_t PreviewPlayer::setMediaRenderingMode( 1330 M4xVSS_MediaRendering mode, 1331 M4VIDEOEDITING_VideoFrameSize outputVideoSize) { 1332 1333 mRenderingMode = mode; 1334 1335 status_t err = OK; 1336 /* get the video width and height by resolution */ 1337 err = getVideoSizeByResolution(outputVideoSize, 1338 &mOutputVideoWidth, &mOutputVideoHeight); 1339 1340 return err; 1341 } 1342 1343 status_t PreviewPlayer::resetJniCallbackTimeStamp() { 1344 1345 mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL; 1346 return OK; 1347 } 1348 1349 void PreviewPlayer::postProgressCallbackEvent_l() { 1350 if (mProgressCbEventPending) { 1351 return; 1352 } 1353 mProgressCbEventPending = true; 1354 1355 mQueue.postEvent(mProgressCbEvent); 1356 } 1357 1358 1359 void PreviewPlayer::onProgressCbEvent() { 1360 Mutex::Autolock autoLock(mLock); 1361 if (!mProgressCbEventPending) { 1362 return; 1363 } 1364 mProgressCbEventPending = false; 1365 // If playback starts from previous I-frame, 1366 // then send frame storyboard duration 1367 if((mDecodedVideoTs/1000) < mPlayBeginTimeMsec) { 1368 notifyListener_l(MEDIA_INFO, 0, mDecVideoTsStoryBoard/1000); 1369 } 1370 else { 1371 notifyListener_l(MEDIA_INFO, 0, 1372 (((mDecodedVideoTs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec)); 1373 } 1374 } 1375 1376 void PreviewPlayer::postOverlayUpdateEvent_l() { 1377 if (mOverlayUpdateEventPending) { 1378 return; 1379 } 1380 mOverlayUpdateEventPending = true; 1381 mQueue.postEvent(mOverlayUpdateEvent); 1382 } 1383 1384 void PreviewPlayer::onUpdateOverlayEvent() { 1385 Mutex::Autolock autoLock(mLock); 1386 1387 if (!mOverlayUpdateEventPending) { 1388 return; 1389 } 1390 mOverlayUpdateEventPending = false; 1391 1392 int updateState; 1393 if (mOverlayUpdateEventPosted) { 1394 updateState = 1; 1395 } else { 1396 updateState = 0; 1397 } 1398 notifyListener_l(0xBBBBBBBB, updateState, mCurrFramingEffectIndex); 1399 } 1400 1401 1402 void PreviewPlayer::setVideoPostProcessingNode( 1403 M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) { 1404 1405 uint32_t effect = VIDEO_EFFECT_NONE; 1406 1407 //Map M4VSS3GPP_VideoEffectType to local enum 1408 switch(type) { 1409 case M4VSS3GPP_kVideoEffectType_FadeFromBlack: 1410 effect = VIDEO_EFFECT_FADEFROMBLACK; 1411 break; 1412 1413 case M4VSS3GPP_kVideoEffectType_FadeToBlack: 1414 effect = VIDEO_EFFECT_FADETOBLACK; 1415 break; 1416 1417 case M4xVSS_kVideoEffectType_BlackAndWhite: 1418 effect = VIDEO_EFFECT_BLACKANDWHITE; 1419 break; 1420 1421 case M4xVSS_kVideoEffectType_Pink: 1422 effect = VIDEO_EFFECT_PINK; 1423 break; 1424 1425 case M4xVSS_kVideoEffectType_Green: 1426 effect = VIDEO_EFFECT_GREEN; 1427 break; 1428 1429 case M4xVSS_kVideoEffectType_Sepia: 1430 effect = VIDEO_EFFECT_SEPIA; 1431 break; 1432 1433 case M4xVSS_kVideoEffectType_Negative: 1434 effect = VIDEO_EFFECT_NEGATIVE; 1435 break; 1436 1437 case M4xVSS_kVideoEffectType_Framing: 1438 effect = VIDEO_EFFECT_FRAMING; 1439 break; 1440 1441 case M4xVSS_kVideoEffectType_Fifties: 1442 effect = VIDEO_EFFECT_FIFTIES; 1443 break; 1444 1445 case M4xVSS_kVideoEffectType_ColorRGB16: 1446 effect = VIDEO_EFFECT_COLOR_RGB16; 1447 break; 1448 1449 case M4xVSS_kVideoEffectType_Gradient: 1450 effect = VIDEO_EFFECT_GRADIENT; 1451 break; 1452 1453 default: 1454 effect = VIDEO_EFFECT_NONE; 1455 break; 1456 } 1457 1458 if(enable == M4OSA_TRUE) { 1459 //If already set, then no need to set again 1460 if(!(mCurrentVideoEffect & effect)) { 1461 mCurrentVideoEffect |= effect; 1462 if(effect == VIDEO_EFFECT_FIFTIES) { 1463 mIsFiftiesEffectStarted = true; 1464 } 1465 } 1466 } 1467 else { 1468 //Reset only if already set 1469 if(mCurrentVideoEffect & effect) { 1470 mCurrentVideoEffect &= ~effect; 1471 } 1472 } 1473 } 1474 1475 status_t PreviewPlayer::setImageClipProperties(uint32_t width,uint32_t height) { 1476 mVideoWidth = width; 1477 mVideoHeight = height; 1478 return OK; 1479 } 1480 1481 status_t PreviewPlayer::readFirstVideoFrame() { 1482 LOGV("PreviewPlayer::readFirstVideoFrame"); 1483 1484 if (!mVideoBuffer) { 1485 MediaSource::ReadOptions options; 1486 if (mSeeking != NO_SEEK) { 1487 LOGV("LV PLAYER seeking to %lld us (%.2f secs)", mSeekTimeUs, 1488 mSeekTimeUs / 1E6); 1489 1490 options.setSeekTo( 1491 mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST); 1492 } 1493 for (;;) { 1494 status_t err = mVideoSource->read(&mVideoBuffer, &options); 1495 options.clearSeekTo(); 1496 1497 if (err != OK) { 1498 CHECK_EQ(mVideoBuffer, NULL); 1499 1500 if (err == INFO_FORMAT_CHANGED) { 1501 LOGV("LV PLAYER VideoSource signalled format change"); 1502 notifyVideoSize_l(); 1503 1504 if (mVideoRenderer != NULL) { 1505 mVideoRendererIsPreview = false; 1506 err = initRenderer_l(); 1507 if (err != OK) { 1508 postStreamDoneEvent_l(err); 1509 } 1510 } 1511 1512 updateSizeToRender(mVideoSource->getFormat()); 1513 continue; 1514 } 1515 LOGV("PreviewPlayer: onVideoEvent EOS reached."); 1516 mFlags |= VIDEO_AT_EOS; 1517 mFlags |= AUDIO_AT_EOS; 1518 postStreamDoneEvent_l(err); 1519 return OK; 1520 } 1521 1522 if (mVideoBuffer->range_length() == 0) { 1523 // Some decoders, notably the PV AVC software decoder 1524 // return spurious empty buffers that we just want to ignore. 1525 1526 mVideoBuffer->release(); 1527 mVideoBuffer = NULL; 1528 continue; 1529 } 1530 1531 int64_t videoTimeUs; 1532 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &videoTimeUs)); 1533 if (mSeeking != NO_SEEK) { 1534 if (videoTimeUs < mSeekTimeUs) { 1535 // buffers are before seek time 1536 // ignore them 1537 mVideoBuffer->release(); 1538 mVideoBuffer = NULL; 1539 continue; 1540 } 1541 } else { 1542 if((videoTimeUs/1000) < mPlayBeginTimeMsec) { 1543 // buffers are before begin cut time 1544 // ignore them 1545 mVideoBuffer->release(); 1546 mVideoBuffer = NULL; 1547 continue; 1548 } 1549 } 1550 break; 1551 } 1552 } 1553 1554 int64_t timeUs; 1555 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 1556 1557 { 1558 Mutex::Autolock autoLock(mMiscStateLock); 1559 mVideoTimeUs = timeUs; 1560 } 1561 1562 mDecodedVideoTs = timeUs; 1563 1564 return OK; 1565 1566 } 1567 1568 status_t PreviewPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) { 1569 *lastRenderedTimeMs = (((mDecodedVideoTs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec); 1570 return OK; 1571 } 1572 1573 void PreviewPlayer::updateSizeToRender(sp<MetaData> meta) { 1574 if (mVideoRenderer) { 1575 mVideoRenderer->updateVideoSize(meta); 1576 } 1577 } 1578 1579 } // namespace android 1580