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