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