PreviewPlayer.cpp revision 2703f23af496c13cfa39cc7e157fa12d1cb4c169
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
46namespace android {
47
48
49struct PreviewPlayerEvent : public TimedEventQueue::Event {
50    PreviewPlayerEvent(
51            PreviewPlayer *player,
52            void (PreviewPlayer::*method)())
53        : mPlayer(player),
54          mMethod(method) {
55    }
56
57protected:
58    virtual ~PreviewPlayerEvent() {}
59
60    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
61        (mPlayer->*mMethod)();
62    }
63
64private:
65    PreviewPlayer *mPlayer;
66    void (PreviewPlayer::*mMethod)();
67
68    PreviewPlayerEvent(const PreviewPlayerEvent &);
69    PreviewPlayerEvent &operator=(const PreviewPlayerEvent &);
70};
71
72PreviewPlayer::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
119PreviewPlayer::~PreviewPlayer() {
120
121    if (mQueueStarted) {
122        mQueue.stop();
123    }
124
125    reset();
126
127    if (mVideoRenderer) {
128        mNativeWindowRenderer->destroyRenderInput(mVideoRenderer);
129    }
130}
131
132void 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
144status_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
150status_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
166status_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        ALOGV("PreviewPlayer: setDataSource_l Dummyaudiocreation started");
205
206        mAudioTrack = DummyAudioSource::Create(32000, 2, 20000,
207                                              ((mPlayEndTimeMsec)*1000LL));
208        ALOGV("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
222status_t PreviewPlayer::setDataSource_l_jpg() {
223    M4OSA_ERR err = M4NO_ERROR;
224    ALOGV("PreviewPlayer: setDataSource_l_jpg started");
225
226    mAudioSource = DummyAudioSource::Create(32000, 2, 20000,
227                                          ((mPlayEndTimeMsec)*1000LL));
228    ALOGV("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        ALOGV("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
256void PreviewPlayer::reset() {
257    Mutex::Autolock autoLock(mLock);
258    reset_l();
259}
260
261void 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
340status_t PreviewPlayer::play() {
341    Mutex::Autolock autoLock(mLock);
342
343    mFlags &= ~CACHE_UNDERRUN;
344    mFlags &= ~INFORMED_AV_EOS;
345    return play_l();
346}
347
348status_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
378status_t PreviewPlayer::setAudioPlayer(AudioPlayerBase *audioPlayer) {
379    Mutex::Autolock autoLock(mLock);
380    CHECK(!(mFlags & PLAYING));
381    mAudioPlayer = audioPlayer;
382
383    ALOGV("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        ALOGV("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                ALOGV(" 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                    ALOGV("setAudioPlayer: stop new audio source");
431                    mAudioSource->stop();
432                }
433            }
434        }
435    }
436
437    return OK;
438}
439
440void 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        ALOGV("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        ALOGV("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        ALOGV("onStreamDone end");
503        return;
504    }
505}
506
507
508status_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                ALOGV("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                ALOGV("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
657status_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
670status_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
681status_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
696status_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            ALOGV("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
741status_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
779void 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            ALOGV("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                    ALOGV("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                    ALOGV("video stream ended while seeking!");
856                }
857                finishSeekIfNecessary(-1);
858                ALOGV("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        ALOGV("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            ALOGV("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            ALOGV("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        ALOGV("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                ALOGV("Framing index = %d", mCurrFramingEffectIndex);
1061            } else {
1062                ALOGV("No framing effects found");
1063            }
1064        }
1065
1066    } else if (mOverlayUpdateEventPosted) {
1067        //Post the event when the overlay is no more valid
1068        ALOGV("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        ALOGV("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
1112status_t PreviewPlayer::prepare() {
1113    Mutex::Autolock autoLock(mLock);
1114    return prepare_l();
1115}
1116
1117status_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
1140status_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
1159status_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        ALOGV("PreviewPlayer::finishSetDataSource_l  extractor == NULL");
1182        return setDataSource_l_jpg();
1183    }
1184
1185    return setDataSource_l(extractor);
1186}
1187
1188
1189// static
1190bool PreviewPlayer::ContinuePreparation(void *cookie) {
1191    PreviewPlayer *me = static_cast<PreviewPlayer *>(cookie);
1192
1193    return (me->mFlags & PREPARE_CANCELLED) == 0;
1194}
1195
1196void PreviewPlayer::onPrepareAsyncEvent() {
1197    Mutex::Autolock autoLock(mLock);
1198    ALOGV("onPrepareAsyncEvent");
1199
1200    if (mFlags & PREPARE_CANCELLED) {
1201        ALOGV("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
1236void PreviewPlayer::finishAsyncPrepare_l() {
1237    if (mIsAsyncPrepare) {
1238        if (mVideoSource == NULL) {
1239            ALOGV("finishAsyncPrepare_l: MEDIA_SET_VIDEO_SIZE 0 0 ");
1240            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
1241        } else {
1242            ALOGV("finishAsyncPrepare_l: MEDIA_SET_VIDEO_SIZE");
1243            notifyVideoSize_l();
1244        }
1245        ALOGV("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
1256void PreviewPlayer::acquireLock() {
1257    ALOGV("acquireLock");
1258    mLockControl.lock();
1259}
1260
1261void PreviewPlayer::releaseLock() {
1262    ALOGV("releaseLock");
1263    mLockControl.unlock();
1264}
1265
1266status_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
1276status_t PreviewPlayer::loadAudioMixSettings(
1277                    M4xVSS_AudioMixingSettings* pAudioMixSettings) {
1278
1279    ALOGV("PreviewPlayer: loadAudioMixSettings: ");
1280    mPreviewPlayerAudioMixSettings = pAudioMixSettings;
1281    return OK;
1282}
1283
1284status_t PreviewPlayer::setAudioMixPCMFileHandle(
1285                    M4OSA_Context pAudioMixPCMFileHandle) {
1286
1287    ALOGV("PreviewPlayer: setAudioMixPCMFileHandle: ");
1288    mAudioMixPCMFileHandle = pAudioMixPCMFileHandle;
1289    return OK;
1290}
1291
1292status_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
1303status_t PreviewPlayer::setPlaybackBeginTime(uint32_t msec) {
1304
1305    mPlayBeginTimeMsec = msec;
1306    return OK;
1307}
1308
1309status_t PreviewPlayer::setPlaybackEndTime(uint32_t msec) {
1310
1311    mPlayEndTimeMsec = msec;
1312    return OK;
1313}
1314
1315status_t PreviewPlayer::setStoryboardStartTime(uint32_t msec) {
1316
1317    mStoryboardStartTimeMsec = msec;
1318    mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL;
1319    return OK;
1320}
1321
1322status_t PreviewPlayer::setProgressCallbackInterval(uint32_t cbInterval) {
1323
1324    mProgressCbInterval = cbInterval;
1325    return OK;
1326}
1327
1328
1329status_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
1343status_t PreviewPlayer::resetJniCallbackTimeStamp() {
1344
1345    mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL;
1346    return OK;
1347}
1348
1349void PreviewPlayer::postProgressCallbackEvent_l() {
1350    if (mProgressCbEventPending) {
1351        return;
1352    }
1353    mProgressCbEventPending = true;
1354
1355    mQueue.postEvent(mProgressCbEvent);
1356}
1357
1358
1359void 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
1376void PreviewPlayer::postOverlayUpdateEvent_l() {
1377    if (mOverlayUpdateEventPending) {
1378        return;
1379    }
1380    mOverlayUpdateEventPending = true;
1381    mQueue.postEvent(mOverlayUpdateEvent);
1382}
1383
1384void 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
1402void 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
1475status_t PreviewPlayer::setImageClipProperties(uint32_t width,uint32_t height) {
1476    mVideoWidth = width;
1477    mVideoHeight = height;
1478    return OK;
1479}
1480
1481status_t PreviewPlayer::readFirstVideoFrame() {
1482    ALOGV("PreviewPlayer::readFirstVideoFrame");
1483
1484    if (!mVideoBuffer) {
1485        MediaSource::ReadOptions options;
1486        if (mSeeking != NO_SEEK) {
1487            ALOGV("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                    ALOGV("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                ALOGV("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
1568status_t PreviewPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
1569    *lastRenderedTimeMs = (((mDecodedVideoTs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec);
1570    return OK;
1571}
1572
1573void PreviewPlayer::updateSizeToRender(sp<MetaData> meta) {
1574    if (mVideoRenderer) {
1575        mVideoRenderer->updateVideoSize(meta);
1576    }
1577}
1578
1579}  // namespace android
1580