Home | History | Annotate | Download | only in lvpp
      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