PreviewPlayer.cpp revision 00f742c087d92e5452d29be1fb668022b5f8a6c7
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 0
19#define LOG_TAG "PreviewPlayer"
20#include <utils/Log.h>
21
22#include <binder/IPCThreadState.h>
23#include <binder/IServiceManager.h>
24#include <media/IMediaPlayerService.h>
25#include <media/stagefright/DataSource.h>
26#include <media/stagefright/MediaBuffer.h>
27#include <media/stagefright/MediaDefs.h>
28#include <media/stagefright/MediaExtractor.h>
29#include <media/stagefright/MediaSource.h>
30#include <media/stagefright/MetaData.h>
31#include <media/stagefright/OMXCodec.h>
32#include <media/stagefright/foundation/ADebug.h>
33#include <surfaceflinger/Surface.h>
34#include <gui/ISurfaceTexture.h>
35#include <gui/SurfaceTextureClient.h>
36#include <surfaceflinger/ISurfaceComposer.h>
37
38#include "VideoEditorPreviewController.h"
39#include "AudioPlayerBase.h"
40#include "DummyAudioSource.h"
41#include "DummyVideoSource.h"
42#include "VideoEditorSRC.h"
43#include "PreviewPlayer.h"
44
45namespace android {
46
47
48void addBatteryData(uint32_t params) {
49    sp<IBinder> binder =
50        defaultServiceManager()->getService(String16("media.player"));
51    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
52    CHECK(service.get() != NULL);
53
54    service->addBatteryData(params);
55}
56
57struct PreviewPlayerEvent : public TimedEventQueue::Event {
58    PreviewPlayerEvent(
59            PreviewPlayer *player,
60            void (PreviewPlayer::*method)())
61        : mPlayer(player),
62          mMethod(method) {
63    }
64
65protected:
66    virtual ~PreviewPlayerEvent() {}
67
68    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
69        (mPlayer->*mMethod)();
70    }
71
72private:
73    PreviewPlayer *mPlayer;
74    void (PreviewPlayer::*mMethod)();
75
76    PreviewPlayerEvent(const PreviewPlayerEvent &);
77    PreviewPlayerEvent &operator=(const PreviewPlayerEvent &);
78};
79
80PreviewPlayer::PreviewPlayer(NativeWindowRenderer* renderer)
81    : mQueueStarted(false),
82      mTimeSource(NULL),
83      mVideoRendererIsPreview(false),
84      mAudioPlayer(NULL),
85      mDisplayWidth(0),
86      mDisplayHeight(0),
87      mFlags(0),
88      mExtractorFlags(0),
89      mVideoBuffer(NULL),
90      mLastVideoTimeUs(-1),
91      mNativeWindowRenderer(renderer),
92      mCurrFramingEffectIndex(0),
93      mFrameRGBBuffer(NULL),
94      mFrameYUVBuffer(NULL) {
95
96    CHECK_EQ(mClient.connect(), (status_t)OK);
97    DataSource::RegisterDefaultSniffers();
98
99
100    mVideoRenderer = NULL;
101    mEffectsSettings = NULL;
102    mVeAudioPlayer = NULL;
103    mAudioMixStoryBoardTS = 0;
104    mCurrentMediaBeginCutTime = 0;
105    mCurrentMediaVolumeValue = 0;
106    mNumberEffects = 0;
107    mDecodedVideoTs = 0;
108    mDecVideoTsStoryBoard = 0;
109    mCurrentVideoEffect = VIDEO_EFFECT_NONE;
110    mProgressCbInterval = 0;
111    mNumberDecVideoFrames = 0;
112    mOverlayUpdateEventPosted = false;
113    mIsChangeSourceRequired = true;
114
115    mVideoEvent = new PreviewPlayerEvent(this, &PreviewPlayer::onVideoEvent);
116    mVideoEventPending = false;
117    mVideoLagEvent = new PreviewPlayerEvent(this, &PreviewPlayer::onVideoLagUpdate);
118    mVideoEventPending = false;
119    mCheckAudioStatusEvent = new PreviewPlayerEvent(
120            this, &PreviewPlayer::onCheckAudioStatus);
121    mAudioStatusEventPending = false;
122    mStreamDoneEvent = new PreviewPlayerEvent(
123            this, &PreviewPlayer::onStreamDone);
124    mStreamDoneEventPending = false;
125    mProgressCbEvent = new PreviewPlayerEvent(this,
126         &PreviewPlayer::onProgressCbEvent);
127
128    mOverlayUpdateEvent = new PreviewPlayerEvent(this,
129        &PreviewPlayer::onUpdateOverlayEvent);
130    mProgressCbEventPending = false;
131
132    mOverlayUpdateEventPending = false;
133    mRenderingMode = (M4xVSS_MediaRendering)MEDIA_RENDERING_INVALID;
134    mIsFiftiesEffectStarted = false;
135    reset();
136}
137
138PreviewPlayer::~PreviewPlayer() {
139
140    if (mQueueStarted) {
141        mQueue.stop();
142    }
143
144    reset();
145
146    if (mVideoRenderer) {
147        mNativeWindowRenderer->destroyRenderInput(mVideoRenderer);
148    }
149
150    Mutex::Autolock lock(mLock);
151    clear_l();
152    mClient.disconnect();
153}
154
155void PreviewPlayer::cancelPlayerEvents_l(bool updateProgressCb) {
156    mQueue.cancelEvent(mVideoEvent->eventID());
157    mVideoEventPending = false;
158    mQueue.cancelEvent(mStreamDoneEvent->eventID());
159    mStreamDoneEventPending = false;
160    mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
161    mAudioStatusEventPending = false;
162    mQueue.cancelEvent(mVideoLagEvent->eventID());
163    mVideoLagEventPending = false;
164    if (updateProgressCb) {
165        mQueue.cancelEvent(mProgressCbEvent->eventID());
166        mProgressCbEventPending = false;
167    }
168}
169
170status_t PreviewPlayer::setDataSource(const char *path) {
171    Mutex::Autolock autoLock(mLock);
172    return setDataSource_l(path);
173}
174
175status_t PreviewPlayer::setDataSource_l(const char *path) {
176    reset_l();
177
178    mUri = path;
179
180    // The actual work will be done during preparation in the call to
181    // ::finishSetDataSource_l to avoid blocking the calling thread in
182    // setDataSource for any significant time.
183    return OK;
184}
185
186status_t PreviewPlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
187    bool haveAudio = false;
188    bool haveVideo = false;
189    for (size_t i = 0; i < extractor->countTracks(); ++i) {
190        sp<MetaData> meta = extractor->getTrackMetaData(i);
191
192        const char *mime;
193        CHECK(meta->findCString(kKeyMIMEType, &mime));
194
195        if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
196            setVideoSource(extractor->getTrack(i));
197            haveVideo = true;
198        } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
199            setAudioSource(extractor->getTrack(i));
200            haveAudio = true;
201
202            if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
203                // Only do this for vorbis audio, none of the other audio
204                // formats even support this ringtone specific hack and
205                // retrieving the metadata on some extractors may turn out
206                // to be very expensive.
207                sp<MetaData> fileMeta = extractor->getMetaData();
208                int32_t loop;
209                if (fileMeta != NULL
210                        && fileMeta->findInt32(kKeyAutoLoop, &loop)
211                         && loop != 0) {
212                    mFlags |= AUTO_LOOPING;
213                }
214            }
215        }
216
217        if (haveAudio && haveVideo) {
218            break;
219        }
220    }
221
222    /* Add the support for Dummy audio*/
223    if( !haveAudio ){
224        mAudioTrack = DummyAudioSource::Create(32000, 2, 20000,
225                                              ((mPlayEndTimeMsec)*1000LL));
226        if(mAudioTrack != NULL) {
227            haveAudio = true;
228        }
229    }
230
231    if (!haveAudio && !haveVideo) {
232        return UNKNOWN_ERROR;
233    }
234
235    mExtractorFlags = extractor->flags();
236    return OK;
237}
238
239status_t PreviewPlayer::setDataSource_l_jpg() {
240    ALOGV("setDataSource_l_jpg");
241
242    M4OSA_ERR err = M4NO_ERROR;
243
244    mAudioSource = DummyAudioSource::Create(32000, 2, 20000,
245                                          ((mPlayEndTimeMsec)*1000LL));
246    if(mAudioSource != NULL) {
247        setAudioSource(mAudioSource);
248    }
249    status_t error = mAudioSource->start();
250    if (error != OK) {
251        ALOGE("Error starting dummy audio source");
252        mAudioSource.clear();
253        return err;
254    }
255
256    mDurationUs = (mPlayEndTimeMsec - mPlayBeginTimeMsec)*1000LL;
257
258    mVideoSource = DummyVideoSource::Create(mVideoWidth, mVideoHeight,
259                                            mDurationUs, mUri);
260
261    updateSizeToRender(mVideoSource->getFormat());
262    setVideoSource(mVideoSource);
263    status_t err1 = mVideoSource->start();
264    if (err1 != OK) {
265        mVideoSource.clear();
266        return err;
267    }
268
269    mIsVideoSourceJpg = true;
270    return OK;
271}
272
273void PreviewPlayer::reset_l() {
274
275    if (mFlags & PREPARING) {
276        mFlags |= PREPARE_CANCELLED;
277    }
278
279    while (mFlags & PREPARING) {
280        mPreparedCondition.wait(mLock);
281    }
282
283    cancelPlayerEvents_l();
284    mAudioTrack.clear();
285    mVideoTrack.clear();
286
287    // Shutdown audio first, so that the respone to the reset request
288    // appears to happen instantaneously as far as the user is concerned
289    // If we did this later, audio would continue playing while we
290    // shutdown the video-related resources and the player appear to
291    // not be as responsive to a reset request.
292    if (mAudioPlayer == NULL && mAudioSource != NULL) {
293        // If we had an audio player, it would have effectively
294        // taken possession of the audio source and stopped it when
295        // _it_ is stopped. Otherwise this is still our responsibility.
296        mAudioSource->stop();
297    }
298    mAudioSource.clear();
299
300    mTimeSource = NULL;
301
302    //Single audio player instance used
303    //So donot delete it here
304    //It is deleted from PreviewController class
305    //delete mAudioPlayer;
306    mAudioPlayer = NULL;
307
308    if (mVideoBuffer) {
309        mVideoBuffer->release();
310        mVideoBuffer = NULL;
311    }
312
313    if (mVideoSource != NULL) {
314        mVideoSource->stop();
315
316        // The following hack is necessary to ensure that the OMX
317        // component is completely released by the time we may try
318        // to instantiate it again.
319        wp<MediaSource> tmp = mVideoSource;
320        mVideoSource.clear();
321        while (tmp.promote() != NULL) {
322            usleep(1000);
323        }
324        IPCThreadState::self()->flushCommands();
325    }
326
327    mDurationUs = -1;
328    mFlags = 0;
329    mExtractorFlags = 0;
330    mVideoWidth = mVideoHeight = -1;
331    mTimeSourceDeltaUs = 0;
332    mVideoTimeUs = 0;
333
334    mSeeking = NO_SEEK;
335    mSeekNotificationSent = false;
336    mSeekTimeUs = 0;
337
338    mUri.setTo("");
339
340    mCurrentVideoEffect = VIDEO_EFFECT_NONE;
341    mIsVideoSourceJpg = false;
342    mFrameRGBBuffer = NULL;
343    if(mFrameYUVBuffer != NULL) {
344        free(mFrameYUVBuffer);
345        mFrameYUVBuffer = NULL;
346    }
347}
348
349status_t PreviewPlayer::play() {
350    ALOGV("play");
351    Mutex::Autolock autoLock(mLock);
352
353    mFlags &= ~CACHE_UNDERRUN;
354    mFlags &= ~INFORMED_AV_EOS;
355    return play_l();
356}
357
358status_t PreviewPlayer::startAudioPlayer_l() {
359    ALOGV("startAudioPlayer_l");
360    CHECK(!(mFlags & AUDIO_RUNNING));
361
362    if (mAudioSource == NULL || mAudioPlayer == NULL) {
363        return OK;
364    }
365
366    if (!(mFlags & AUDIOPLAYER_STARTED)) {
367        mFlags |= AUDIOPLAYER_STARTED;
368
369        // We've already started the MediaSource in order to enable
370        // the prefetcher to read its data.
371        status_t err = mVeAudioPlayer->start(
372                true /* sourceAlreadyStarted */);
373
374        if (err != OK) {
375            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
376            return err;
377        }
378    } else {
379        mVeAudioPlayer->resume();
380    }
381
382    mFlags |= AUDIO_RUNNING;
383
384    mWatchForAudioEOS = true;
385
386    return OK;
387}
388
389status_t PreviewPlayer::setAudioPlayer(AudioPlayerBase *audioPlayer) {
390    ALOGV("setAudioPlayer");
391    Mutex::Autolock autoLock(mLock);
392    CHECK(!(mFlags & PLAYING));
393    mAudioPlayer = audioPlayer;
394
395    ALOGV("SetAudioPlayer");
396    mIsChangeSourceRequired = true;
397    mVeAudioPlayer =
398            (VideoEditorAudioPlayer*)mAudioPlayer;
399
400    // check if the new and old source are dummy
401    sp<MediaSource> anAudioSource = mVeAudioPlayer->getSource();
402    if (anAudioSource == NULL) {
403        // Audio player does not have any source set.
404        ALOGV("setAudioPlayer: Audio player does not have any source set");
405        return OK;
406    }
407
408    // If new video source is not dummy, then always change source
409    // Else audio player continues using old audio source and there are
410    // frame drops to maintain AV sync
411    sp<MetaData> meta;
412    if (mVideoSource != NULL) {
413        meta = mVideoSource->getFormat();
414        const char *pVidSrcType;
415        if (meta->findCString(kKeyDecoderComponent, &pVidSrcType)) {
416            if (strcmp(pVidSrcType, "DummyVideoSource") != 0) {
417                ALOGV(" Video clip with silent audio; need to change source");
418                return OK;
419            }
420        }
421    }
422
423    const char *pSrcType1;
424    const char *pSrcType2;
425    meta = anAudioSource->getFormat();
426
427    if (meta->findCString(kKeyDecoderComponent, &pSrcType1)) {
428        if (strcmp(pSrcType1, "DummyAudioSource") == 0) {
429            meta = mAudioSource->getFormat();
430            if (meta->findCString(kKeyDecoderComponent, &pSrcType2)) {
431                if (strcmp(pSrcType2, "DummyAudioSource") == 0) {
432                    mIsChangeSourceRequired = false;
433                    // Just set the new play duration for the existing source
434                    MediaSource *pMediaSrc = anAudioSource.get();
435                    DummyAudioSource *pDummyAudioSource = (DummyAudioSource*)pMediaSrc;
436                    //Increment the duration of audio source
437                    pDummyAudioSource->setDuration(
438                        (int64_t)((mPlayEndTimeMsec)*1000LL));
439
440                    // Stop the new audio source
441                    // since we continue using old source
442                    ALOGV("setAudioPlayer: stop new audio source");
443                    mAudioSource->stop();
444                }
445            }
446        }
447    }
448
449    return OK;
450}
451
452void PreviewPlayer::onStreamDone() {
453    ALOGV("onStreamDone");
454    // Posted whenever any stream finishes playing.
455
456    Mutex::Autolock autoLock(mLock);
457    if (!mStreamDoneEventPending) {
458        return;
459    }
460    mStreamDoneEventPending = false;
461
462    if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
463        ALOGV("MEDIA_ERROR %d", mStreamDoneStatus);
464
465        notifyListener_l(
466                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
467
468        pause_l(true /* at eos */);
469
470        mFlags |= AT_EOS;
471        return;
472    }
473
474    const bool allDone =
475        (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
476            && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
477
478    if (!allDone) {
479        return;
480    }
481
482    if (mFlags & (LOOPING | AUTO_LOOPING)) {
483        seekTo_l(0);
484
485        if (mVideoSource != NULL) {
486            postVideoEvent_l();
487        }
488    } else {
489        ALOGV("MEDIA_PLAYBACK_COMPLETE");
490        //pause before sending event
491        pause_l(true /* at eos */);
492
493        //This lock is used to syncronize onStreamDone() in PreviewPlayer and
494        //stopPreview() in PreviewController
495        Mutex::Autolock autoLock(mLockControl);
496        /* Make sure PreviewPlayer only notifies MEDIA_PLAYBACK_COMPLETE once for each clip!
497         * It happens twice in following scenario.
498         * To make the clips in preview storyboard are played and switched smoothly,
499         * PreviewController uses two PreviewPlayer instances and one AudioPlayer.
500         * The two PreviewPlayer use the same AudioPlayer to play the audio,
501         * and change the audio source of the AudioPlayer.
502         * If the audio source of current playing clip and next clip are dummy
503         * audio source(image or video without audio), it will not change the audio source
504         * to avoid the "audio glitch", and keep using the current audio source.
505         * When the video of current clip reached the EOS, PreviewPlayer will set EOS flag
506         * for video and audio, and it will notify MEDIA_PLAYBACK_COMPLETE.
507         * But the audio(dummy audio source) is still playing(for next clip),
508         * and when it reached the EOS, and video reached EOS,
509         * PreviewPlayer will notify MEDIA_PLAYBACK_COMPLETE again. */
510        if (!(mFlags & INFORMED_AV_EOS)) {
511            notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
512            mFlags |= INFORMED_AV_EOS;
513        }
514        mFlags |= AT_EOS;
515        ALOGV("onStreamDone end");
516        return;
517    }
518}
519
520
521status_t PreviewPlayer::play_l() {
522    ALOGV("play_l");
523
524    mFlags &= ~SEEK_PREVIEW;
525
526    if (mFlags & PLAYING) {
527        return OK;
528    }
529    mStartNextPlayer = false;
530
531    if (!(mFlags & PREPARED)) {
532        status_t err = prepare_l();
533
534        if (err != OK) {
535            return err;
536        }
537    }
538
539    mFlags |= PLAYING;
540    mFlags |= FIRST_FRAME;
541
542    bool deferredAudioSeek = false;
543
544    if (mAudioSource != NULL) {
545        if (mAudioPlayer == NULL) {
546            if (mAudioSink != NULL) {
547
548                mAudioPlayer = new VideoEditorAudioPlayer(mAudioSink, this);
549                mVeAudioPlayer =
550                          (VideoEditorAudioPlayer*)mAudioPlayer;
551
552                mAudioPlayer->setSource(mAudioSource);
553
554                mVeAudioPlayer->setAudioMixSettings(
555                 mPreviewPlayerAudioMixSettings);
556
557                mVeAudioPlayer->setAudioMixPCMFileHandle(
558                 mAudioMixPCMFileHandle);
559
560                mVeAudioPlayer->setAudioMixStoryBoardSkimTimeStamp(
561                 mAudioMixStoryBoardTS, mCurrentMediaBeginCutTime,
562                 mCurrentMediaVolumeValue);
563
564                 mFlags |= AUDIOPLAYER_STARTED;
565                // We've already started the MediaSource in order to enable
566                // the prefetcher to read its data.
567                status_t err = mVeAudioPlayer->start(
568                        true /* sourceAlreadyStarted */);
569
570                if (err != OK) {
571                    //delete mAudioPlayer;
572                    mAudioPlayer = NULL;
573
574                    mFlags &= ~(PLAYING | FIRST_FRAME);
575                    return err;
576                }
577
578                mTimeSource = mVeAudioPlayer;
579                mFlags |= AUDIO_RUNNING;
580                deferredAudioSeek = true;
581                mWatchForAudioSeekComplete = false;
582                mWatchForAudioEOS = true;
583            }
584        } else {
585            mVeAudioPlayer = (VideoEditorAudioPlayer*)mAudioPlayer;
586            bool isAudioPlayerStarted = mVeAudioPlayer->isStarted();
587
588            if (mIsChangeSourceRequired == true) {
589                ALOGV("play_l: Change audio source required");
590
591                if (isAudioPlayerStarted == true) {
592                    mVeAudioPlayer->pause();
593                }
594
595                mVeAudioPlayer->setSource(mAudioSource);
596                mVeAudioPlayer->setObserver(this);
597
598                mVeAudioPlayer->setAudioMixSettings(
599                 mPreviewPlayerAudioMixSettings);
600
601                mVeAudioPlayer->setAudioMixStoryBoardSkimTimeStamp(
602                    mAudioMixStoryBoardTS, mCurrentMediaBeginCutTime,
603                    mCurrentMediaVolumeValue);
604
605                if (isAudioPlayerStarted == true) {
606                    mVeAudioPlayer->resume();
607                } else {
608                    status_t err = OK;
609                    err = mVeAudioPlayer->start(true);
610                    if (err != OK) {
611                        mAudioPlayer = NULL;
612                        mVeAudioPlayer = NULL;
613
614                        mFlags &= ~(PLAYING | FIRST_FRAME);
615                        return err;
616                    }
617                }
618            } else {
619                ALOGV("play_l: No Source change required");
620                mVeAudioPlayer->setAudioMixStoryBoardSkimTimeStamp(
621                    mAudioMixStoryBoardTS, mCurrentMediaBeginCutTime,
622                    mCurrentMediaVolumeValue);
623
624                mVeAudioPlayer->resume();
625            }
626
627            mFlags |= AUDIOPLAYER_STARTED;
628            mFlags |= AUDIO_RUNNING;
629            mTimeSource = mVeAudioPlayer;
630            deferredAudioSeek = true;
631            mWatchForAudioSeekComplete = false;
632            mWatchForAudioEOS = true;
633        }
634    }
635
636    if (mTimeSource == NULL && mAudioPlayer == NULL) {
637        mTimeSource = &mSystemTimeSource;
638    }
639
640    // Set the seek option for Image source files and read.
641    // This resets the timestamping for image play
642    if (mIsVideoSourceJpg) {
643        MediaSource::ReadOptions options;
644        MediaBuffer *aLocalBuffer;
645        options.setSeekTo(mSeekTimeUs);
646        mVideoSource->read(&aLocalBuffer, &options);
647        aLocalBuffer->release();
648    }
649
650    if (mVideoSource != NULL) {
651        // Kick off video playback
652        postVideoEvent_l();
653    }
654
655    if (deferredAudioSeek) {
656        // If there was a seek request while we were paused
657        // and we're just starting up again, honor the request now.
658        seekAudioIfNecessary_l();
659    }
660
661    if (mFlags & AT_EOS) {
662        // Legacy behaviour, if a stream finishes playing and then
663        // is started again, we play from the start...
664        seekTo_l(0);
665    }
666
667    return OK;
668}
669
670
671status_t PreviewPlayer::initRenderer_l() {
672    if (mSurface != NULL) {
673        if(mVideoRenderer == NULL) {
674            mVideoRenderer = mNativeWindowRenderer->createRenderInput();
675            if (mVideoSource != NULL) {
676                updateSizeToRender(mVideoSource->getFormat());
677            }
678        }
679    }
680    return OK;
681}
682
683
684status_t PreviewPlayer::seekTo(int64_t timeUs) {
685    Mutex::Autolock autoLock(mLock);
686    if ((mExtractorFlags & MediaExtractor::CAN_SEEK) || (mIsVideoSourceJpg)) {
687        return seekTo_l(timeUs);
688    }
689
690    return OK;
691}
692
693
694status_t PreviewPlayer::getVideoDimensions(
695        int32_t *width, int32_t *height) const {
696    Mutex::Autolock autoLock(mLock);
697
698    if (mVideoWidth < 0 || mVideoHeight < 0) {
699        return UNKNOWN_ERROR;
700    }
701
702    *width = mVideoWidth;
703    *height = mVideoHeight;
704
705    return OK;
706}
707
708
709status_t PreviewPlayer::initAudioDecoder_l() {
710    sp<MetaData> meta = mAudioTrack->getFormat();
711    const char *mime;
712    CHECK(meta->findCString(kKeyMIMEType, &mime));
713
714    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
715        mAudioSource = mAudioTrack;
716    } else {
717        sp<MediaSource> aRawSource;
718        aRawSource = OMXCodec::Create(
719                mClient.interface(), mAudioTrack->getFormat(),
720                false, // createEncoder
721                mAudioTrack);
722
723        if(aRawSource != NULL) {
724            mAudioSource = new VideoEditorSRC(aRawSource);
725        }
726    }
727
728    if (mAudioSource != NULL) {
729        int64_t durationUs;
730        if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
731            setDuration_l(durationUs);
732        }
733        status_t err = mAudioSource->start();
734
735        if (err != OK) {
736            mAudioSource.clear();
737            return err;
738        }
739    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
740        // For legacy reasons we're simply going to ignore the absence
741        // of an audio decoder for QCELP instead of aborting playback
742        // altogether.
743        return OK;
744    }
745
746    return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
747}
748
749status_t PreviewPlayer::initVideoDecoder_l(uint32_t flags) {
750    initRenderer_l();
751
752    if (mVideoRenderer == NULL) {
753        ALOGE("Cannot create renderer");
754        return UNKNOWN_ERROR;
755    }
756
757    mVideoSource = OMXCodec::Create(
758            mClient.interface(), mVideoTrack->getFormat(),
759            false,
760            mVideoTrack,
761            NULL, flags, mVideoRenderer->getTargetWindow());
762
763    if (mVideoSource != NULL) {
764        int64_t durationUs;
765        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
766            setDuration_l(durationUs);
767        }
768
769        updateSizeToRender(mVideoTrack->getFormat());
770
771        status_t err = mVideoSource->start();
772
773        if (err != OK) {
774            mVideoSource.clear();
775            return err;
776        }
777    }
778
779    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
780}
781
782
783void PreviewPlayer::onVideoEvent() {
784    uint32_t i=0;
785    M4OSA_ERR err1 = M4NO_ERROR;
786    int64_t imageFrameTimeUs = 0;
787
788    Mutex::Autolock autoLock(mLock);
789    if (!mVideoEventPending) {
790        // The event has been cancelled in reset_l() but had already
791        // been scheduled for execution at that time.
792        return;
793    }
794    mVideoEventPending = false;
795
796    if (mFlags & SEEK_PREVIEW) {
797        mFlags &= ~SEEK_PREVIEW;
798        return;
799    }
800
801    TimeSource *ts_st =  &mSystemTimeSource;
802    int64_t timeStartUs = ts_st->getRealTimeUs();
803
804    if (mSeeking != NO_SEEK) {
805
806        if(mAudioSource != NULL) {
807
808            // We're going to seek the video source first, followed by
809            // the audio source.
810            // In order to avoid jumps in the DataSource offset caused by
811            // the audio codec prefetching data from the old locations
812            // while the video codec is already reading data from the new
813            // locations, we'll "pause" the audio source, causing it to
814            // stop reading input data until a subsequent seek.
815
816            if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
817                mAudioPlayer->pause();
818                mFlags &= ~AUDIO_RUNNING;
819            }
820            mAudioSource->pause();
821        }
822    }
823
824    if (!mVideoBuffer) {
825        MediaSource::ReadOptions options;
826        if (mSeeking != NO_SEEK) {
827            ALOGV("LV PLAYER seeking to %lld us (%.2f secs)", mSeekTimeUs,
828                                                      mSeekTimeUs / 1E6);
829
830            options.setSeekTo(
831                    mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST);
832        }
833        for (;;) {
834            status_t err = mVideoSource->read(&mVideoBuffer, &options);
835            options.clearSeekTo();
836
837            if (err != OK) {
838                CHECK(!mVideoBuffer);
839
840                if (err == INFO_FORMAT_CHANGED) {
841                    ALOGV("LV PLAYER VideoSource signalled format change");
842                    notifyVideoSize_l();
843
844                    if (mVideoRenderer != NULL) {
845                        mVideoRendererIsPreview = false;
846                        err = initRenderer_l();
847                        if (err != OK) {
848                            postStreamDoneEvent_l(err);
849                        }
850
851                    }
852
853                    updateSizeToRender(mVideoSource->getFormat());
854                    continue;
855                }
856                // So video playback is complete, but we may still have
857                // a seek request pending that needs to be applied to the audio track
858                if (mSeeking != NO_SEEK) {
859                    ALOGV("video stream ended while seeking!");
860                }
861                finishSeekIfNecessary(-1);
862                ALOGV("PreviewPlayer: onVideoEvent EOS reached.");
863                mFlags |= VIDEO_AT_EOS;
864                mFlags |= AUDIO_AT_EOS;
865                mOverlayUpdateEventPosted = false;
866                postStreamDoneEvent_l(err);
867                // Set the last decoded timestamp to duration
868                mDecodedVideoTs = (mPlayEndTimeMsec*1000LL);
869                return;
870            }
871
872            if (mVideoBuffer->range_length() == 0) {
873                // Some decoders, notably the PV AVC software decoder
874                // return spurious empty buffers that we just want to ignore.
875
876                mVideoBuffer->release();
877                mVideoBuffer = NULL;
878                continue;
879            }
880
881            int64_t videoTimeUs;
882            CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &videoTimeUs));
883
884            if (mSeeking != NO_SEEK) {
885                if (videoTimeUs < mSeekTimeUs) {
886                    // buffers are before seek time
887                    // ignore them
888                    mVideoBuffer->release();
889                    mVideoBuffer = NULL;
890                    continue;
891                }
892            } else {
893                if((videoTimeUs/1000) < mPlayBeginTimeMsec) {
894                    // Frames are before begin cut time
895                    // Donot render
896                    mVideoBuffer->release();
897                    mVideoBuffer = NULL;
898                    continue;
899                }
900            }
901            break;
902        }
903    }
904
905    mNumberDecVideoFrames++;
906
907    int64_t timeUs;
908    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
909    setPosition_l(timeUs);
910
911    if (!mStartNextPlayer) {
912        int64_t playbackTimeRemaining = (mPlayEndTimeMsec * 1000LL) - timeUs;
913        if (playbackTimeRemaining <= 1500000) {
914            //When less than 1.5 sec of playback left
915            // send notification to start next player
916
917            mStartNextPlayer = true;
918            notifyListener_l(0xAAAAAAAA);
919        }
920    }
921
922    SeekType wasSeeking = mSeeking;
923    finishSeekIfNecessary(timeUs);
924    if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING))) {
925        status_t err = startAudioPlayer_l();
926        if (err != OK) {
927            ALOGE("Starting the audio player failed w/ err %d", err);
928            return;
929        }
930    }
931
932    TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
933
934    if(ts == NULL) {
935        mVideoBuffer->release();
936        mVideoBuffer = NULL;
937        return;
938    }
939
940    if(!mIsVideoSourceJpg) {
941        if (mFlags & FIRST_FRAME) {
942            mFlags &= ~FIRST_FRAME;
943
944            mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
945        }
946
947        int64_t realTimeUs, mediaTimeUs;
948        if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
949            && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
950            mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
951        }
952
953        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
954
955        int64_t latenessUs = nowUs - timeUs;
956
957        if (wasSeeking != NO_SEEK) {
958            // Let's display the first frame after seeking right away.
959            latenessUs = 0;
960        }
961        ALOGV("Audio time stamp = %lld and video time stamp = %lld",
962                                            ts->getRealTimeUs(),timeUs);
963        if (latenessUs > 40000) {
964            // We're more than 40ms late.
965
966            ALOGV("LV PLAYER we're late by %lld us (%.2f secs)",
967                                           latenessUs, latenessUs / 1E6);
968
969            mVideoBuffer->release();
970            mVideoBuffer = NULL;
971            postVideoEvent_l(0);
972            return;
973        }
974
975        if (latenessUs < -25000) {
976            // We're more than 25ms early.
977            ALOGV("We're more than 25ms early, lateness %lld", latenessUs);
978
979            postVideoEvent_l(25000);
980            return;
981        }
982    }
983
984    if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
985        mVideoRendererIsPreview = false;
986
987        status_t err = initRenderer_l();
988        if (err != OK) {
989            postStreamDoneEvent_l(err);
990        }
991    }
992
993    // If timestamp exceeds endCutTime of clip, donot render
994    if((timeUs/1000) > mPlayEndTimeMsec) {
995        mVideoBuffer->release();
996        mVideoBuffer = NULL;
997        mFlags |= VIDEO_AT_EOS;
998        mFlags |= AUDIO_AT_EOS;
999        ALOGV("PreviewPlayer: onVideoEvent timeUs > mPlayEndTime; send EOS..");
1000        mOverlayUpdateEventPosted = false;
1001        // Set the last decoded timestamp to duration
1002        mDecodedVideoTs = (mPlayEndTimeMsec*1000LL);
1003        postStreamDoneEvent_l(ERROR_END_OF_STREAM);
1004        return;
1005    }
1006    // Capture the frame timestamp to be rendered
1007    mDecodedVideoTs = timeUs;
1008
1009    // Post processing to apply video effects
1010    for(i=0;i<mNumberEffects;i++) {
1011        // First check if effect starttime matches the clip being previewed
1012        if((mEffectsSettings[i].uiStartTime < (mDecVideoTsStoryBoard/1000)) ||
1013        (mEffectsSettings[i].uiStartTime >=
1014         ((mDecVideoTsStoryBoard/1000) + mPlayEndTimeMsec - mPlayBeginTimeMsec)))
1015        {
1016            // This effect doesn't belong to this clip, check next one
1017            continue;
1018        }
1019        // Check if effect applies to this particular frame timestamp
1020        if((mEffectsSettings[i].uiStartTime <=
1021         (((timeUs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec)) &&
1022            ((mEffectsSettings[i].uiStartTime+mEffectsSettings[i].uiDuration) >=
1023             (((timeUs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec))
1024              && (mEffectsSettings[i].uiDuration != 0)) {
1025            setVideoPostProcessingNode(
1026             mEffectsSettings[i].VideoEffectType, TRUE);
1027        }
1028        else {
1029            setVideoPostProcessingNode(
1030             mEffectsSettings[i].VideoEffectType, FALSE);
1031        }
1032    }
1033
1034    //Provide the overlay Update indication when there is an overlay effect
1035    if (mCurrentVideoEffect & VIDEO_EFFECT_FRAMING) {
1036        mCurrentVideoEffect &= ~VIDEO_EFFECT_FRAMING; //never apply framing here.
1037        if (!mOverlayUpdateEventPosted) {
1038            // Find the effect in effectSettings array
1039            M4OSA_UInt32 index;
1040            for (index = 0; index < mNumberEffects; index++) {
1041                M4OSA_UInt32 timeMs = mDecodedVideoTs/1000;
1042                M4OSA_UInt32 timeOffset = mDecVideoTsStoryBoard/1000;
1043                if(mEffectsSettings[index].VideoEffectType ==
1044                    (M4VSS3GPP_VideoEffectType)M4xVSS_kVideoEffectType_Framing) {
1045                    if (((mEffectsSettings[index].uiStartTime + 1) <=
1046                        timeMs + timeOffset - mPlayBeginTimeMsec) &&
1047                        ((mEffectsSettings[index].uiStartTime - 1 +
1048                        mEffectsSettings[index].uiDuration) >=
1049                        timeMs + timeOffset - mPlayBeginTimeMsec))
1050                    {
1051                        break;
1052                    }
1053                }
1054            }
1055            if (index < mNumberEffects) {
1056                mCurrFramingEffectIndex = index;
1057                mOverlayUpdateEventPosted = true;
1058                postOverlayUpdateEvent_l();
1059                ALOGV("Framing index = %ld", mCurrFramingEffectIndex);
1060            } else {
1061                ALOGV("No framing effects found");
1062            }
1063        }
1064
1065    } else if (mOverlayUpdateEventPosted) {
1066        //Post the event when the overlay is no more valid
1067        ALOGV("Overlay is Done");
1068        mOverlayUpdateEventPosted = false;
1069        postOverlayUpdateEvent_l();
1070    }
1071
1072    if (mVideoRenderer != NULL) {
1073        mVideoRenderer->render(mVideoBuffer, mCurrentVideoEffect,
1074                mRenderingMode, mIsVideoSourceJpg);
1075    }
1076
1077    mVideoBuffer->release();
1078    mVideoBuffer = NULL;
1079
1080    // Post progress callback based on callback interval set
1081    if(mNumberDecVideoFrames >= mProgressCbInterval) {
1082        postProgressCallbackEvent_l();
1083        mNumberDecVideoFrames = 0;  // reset counter
1084    }
1085
1086    // if reached EndCutTime of clip, post EOS event
1087    if((timeUs/1000) >= mPlayEndTimeMsec) {
1088        ALOGV("PreviewPlayer: onVideoEvent EOS.");
1089        mFlags |= VIDEO_AT_EOS;
1090        mFlags |= AUDIO_AT_EOS;
1091        mOverlayUpdateEventPosted = false;
1092        // Set the last decoded timestamp to duration
1093        mDecodedVideoTs = (mPlayEndTimeMsec*1000LL);
1094        postStreamDoneEvent_l(ERROR_END_OF_STREAM);
1095    }
1096    else {
1097        if ((wasSeeking != NO_SEEK) && (mFlags & SEEK_PREVIEW)) {
1098            mFlags &= ~SEEK_PREVIEW;
1099            return;
1100        }
1101
1102        if(!mIsVideoSourceJpg) {
1103            postVideoEvent_l(0);
1104        }
1105        else {
1106            postVideoEvent_l(33000);
1107        }
1108    }
1109}
1110
1111status_t PreviewPlayer::prepare() {
1112    ALOGV("prepare");
1113    Mutex::Autolock autoLock(mLock);
1114    return prepare_l();
1115}
1116
1117status_t PreviewPlayer::prepare_l() {
1118    ALOGV("prepare_l");
1119    if (mFlags & PREPARED) {
1120        return OK;
1121    }
1122
1123    if (mFlags & PREPARING) {
1124        return UNKNOWN_ERROR;
1125    }
1126
1127    mIsAsyncPrepare = false;
1128    status_t err = prepareAsync_l();
1129
1130    if (err != OK) {
1131        return err;
1132    }
1133
1134    while (mFlags & PREPARING) {
1135        mPreparedCondition.wait(mLock);
1136    }
1137
1138    return mPrepareResult;
1139}
1140
1141status_t PreviewPlayer::prepareAsync() {
1142    ALOGV("prepareAsync");
1143    Mutex::Autolock autoLock(mLock);
1144    return prepareAsync_l();
1145}
1146
1147status_t PreviewPlayer::prepareAsync_l() {
1148    ALOGV("prepareAsync_l");
1149    if (mFlags & PREPARING) {
1150        return UNKNOWN_ERROR;  // async prepare already pending
1151    }
1152
1153    if (!mQueueStarted) {
1154        mQueue.start();
1155        mQueueStarted = true;
1156    }
1157
1158    mFlags |= PREPARING;
1159    mAsyncPrepareEvent = new PreviewPlayerEvent(
1160            this, &PreviewPlayer::onPrepareAsyncEvent);
1161
1162    mQueue.postEvent(mAsyncPrepareEvent);
1163
1164    return OK;
1165}
1166
1167status_t PreviewPlayer::finishSetDataSource_l() {
1168    sp<DataSource> dataSource;
1169    sp<MediaExtractor> extractor;
1170
1171    dataSource = DataSource::CreateFromURI(mUri.string(), NULL);
1172
1173    if (dataSource == NULL) {
1174        return UNKNOWN_ERROR;
1175    }
1176
1177    //If file type is .rgb, then no need to check for Extractor
1178    int uriLen = strlen(mUri);
1179    int startOffset = uriLen - 4;
1180    if(!strncasecmp(mUri+startOffset, ".rgb", 4)) {
1181        extractor = NULL;
1182    }
1183    else {
1184        extractor = MediaExtractor::Create(dataSource,
1185                                        MEDIA_MIMETYPE_CONTAINER_MPEG4);
1186    }
1187
1188    if (extractor == NULL) {
1189        ALOGV("finishSetDataSource_l: failed to create extractor");
1190        return setDataSource_l_jpg();
1191    }
1192
1193    return setDataSource_l(extractor);
1194}
1195
1196void PreviewPlayer::onPrepareAsyncEvent() {
1197    Mutex::Autolock autoLock(mLock);
1198    ALOGV("onPrepareAsyncEvent");
1199
1200    if (mFlags & PREPARE_CANCELLED) {
1201        ALOGV("prepare was cancelled before doing anything");
1202        abortPrepare(UNKNOWN_ERROR);
1203        return;
1204    }
1205
1206    if (mUri.size() > 0) {
1207        status_t err = finishSetDataSource_l();
1208
1209        if (err != OK) {
1210            abortPrepare(err);
1211            return;
1212        }
1213    }
1214
1215    if (mVideoTrack != NULL && mVideoSource == NULL) {
1216        status_t err = initVideoDecoder_l(OMXCodec::kHardwareCodecsOnly);
1217
1218        if (err != OK) {
1219            abortPrepare(err);
1220            return;
1221        }
1222    }
1223
1224    if (mAudioTrack != NULL && mAudioSource == NULL) {
1225        status_t err = initAudioDecoder_l();
1226
1227        if (err != OK) {
1228            abortPrepare(err);
1229            return;
1230        }
1231    }
1232    finishAsyncPrepare_l();
1233
1234}
1235
1236void PreviewPlayer::finishAsyncPrepare_l() {
1237    ALOGV("finishAsyncPrepare_l");
1238    if (mIsAsyncPrepare) {
1239        if (mVideoSource == NULL) {
1240            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
1241        } else {
1242            notifyVideoSize_l();
1243        }
1244        notifyListener_l(MEDIA_PREPARED);
1245    }
1246
1247    mPrepareResult = OK;
1248    mFlags &= ~(PREPARING|PREPARE_CANCELLED);
1249    mFlags |= PREPARED;
1250    mAsyncPrepareEvent = NULL;
1251    mPreparedCondition.broadcast();
1252}
1253
1254void PreviewPlayer::acquireLock() {
1255    ALOGV("acquireLock");
1256    mLockControl.lock();
1257}
1258
1259void PreviewPlayer::releaseLock() {
1260    ALOGV("releaseLock");
1261    mLockControl.unlock();
1262}
1263
1264status_t PreviewPlayer::loadEffectsSettings(
1265        M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
1266
1267    ALOGV("loadEffectsSettings");
1268    mNumberEffects = nEffects;
1269    mEffectsSettings = pEffectSettings;
1270    return OK;
1271}
1272
1273status_t PreviewPlayer::loadAudioMixSettings(
1274        M4xVSS_AudioMixingSettings* pAudioMixSettings) {
1275
1276    ALOGV("loadAudioMixSettings");
1277    mPreviewPlayerAudioMixSettings = pAudioMixSettings;
1278    return OK;
1279}
1280
1281status_t PreviewPlayer::setAudioMixPCMFileHandle(
1282        M4OSA_Context pAudioMixPCMFileHandle) {
1283
1284    ALOGV("setAudioMixPCMFileHandle");
1285    mAudioMixPCMFileHandle = pAudioMixPCMFileHandle;
1286    return OK;
1287}
1288
1289status_t PreviewPlayer::setAudioMixStoryBoardParam(
1290        M4OSA_UInt32 audioMixStoryBoardTS,
1291        M4OSA_UInt32 currentMediaBeginCutTime,
1292        M4OSA_UInt32 primaryTrackVolValue ) {
1293
1294    ALOGV("setAudioMixStoryBoardParam");
1295    mAudioMixStoryBoardTS = audioMixStoryBoardTS;
1296    mCurrentMediaBeginCutTime = currentMediaBeginCutTime;
1297    mCurrentMediaVolumeValue = primaryTrackVolValue;
1298    return OK;
1299}
1300
1301status_t PreviewPlayer::setPlaybackBeginTime(uint32_t msec) {
1302
1303    mPlayBeginTimeMsec = msec;
1304    return OK;
1305}
1306
1307status_t PreviewPlayer::setPlaybackEndTime(uint32_t msec) {
1308
1309    mPlayEndTimeMsec = msec;
1310    return OK;
1311}
1312
1313status_t PreviewPlayer::setStoryboardStartTime(uint32_t msec) {
1314
1315    mStoryboardStartTimeMsec = msec;
1316    mDecVideoTsStoryBoard = mStoryboardStartTimeMsec * 1000LL;
1317    return OK;
1318}
1319
1320status_t PreviewPlayer::setProgressCallbackInterval(uint32_t cbInterval) {
1321
1322    mProgressCbInterval = cbInterval;
1323    return OK;
1324}
1325
1326
1327status_t PreviewPlayer::setMediaRenderingMode(
1328        M4xVSS_MediaRendering mode,
1329        M4VIDEOEDITING_VideoFrameSize outputVideoSize) {
1330
1331    mRenderingMode = mode;
1332
1333    /* get the video width and height by resolution */
1334    return getVideoSizeByResolution(
1335                outputVideoSize,
1336                    &mOutputVideoWidth, &mOutputVideoHeight);
1337
1338}
1339
1340status_t PreviewPlayer::resetJniCallbackTimeStamp() {
1341
1342    mDecVideoTsStoryBoard = mStoryboardStartTimeMsec * 1000LL;
1343    return OK;
1344}
1345
1346void PreviewPlayer::postProgressCallbackEvent_l() {
1347    if (mProgressCbEventPending) {
1348        return;
1349    }
1350    mProgressCbEventPending = true;
1351
1352    mQueue.postEvent(mProgressCbEvent);
1353}
1354
1355
1356void PreviewPlayer::onProgressCbEvent() {
1357    Mutex::Autolock autoLock(mLock);
1358    if (!mProgressCbEventPending) {
1359        return;
1360    }
1361    mProgressCbEventPending = false;
1362    // If playback starts from previous I-frame,
1363    // then send frame storyboard duration
1364    if ((mDecodedVideoTs/1000) < mPlayBeginTimeMsec) {
1365        notifyListener_l(MEDIA_INFO, 0, mDecVideoTsStoryBoard/1000);
1366    } else {
1367        notifyListener_l(MEDIA_INFO, 0,
1368        (((mDecodedVideoTs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec));
1369    }
1370}
1371
1372void PreviewPlayer::postOverlayUpdateEvent_l() {
1373    if (mOverlayUpdateEventPending) {
1374        return;
1375    }
1376    mOverlayUpdateEventPending = true;
1377    mQueue.postEvent(mOverlayUpdateEvent);
1378}
1379
1380void PreviewPlayer::onUpdateOverlayEvent() {
1381    Mutex::Autolock autoLock(mLock);
1382
1383    if (!mOverlayUpdateEventPending) {
1384        return;
1385    }
1386    mOverlayUpdateEventPending = false;
1387
1388    int updateState = mOverlayUpdateEventPosted? 1: 0;
1389    notifyListener_l(0xBBBBBBBB, updateState, mCurrFramingEffectIndex);
1390}
1391
1392
1393void PreviewPlayer::setVideoPostProcessingNode(
1394        M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) {
1395
1396    uint32_t effect = VIDEO_EFFECT_NONE;
1397
1398    //Map M4VSS3GPP_VideoEffectType to local enum
1399    switch(type) {
1400        case M4VSS3GPP_kVideoEffectType_FadeFromBlack:
1401            effect = VIDEO_EFFECT_FADEFROMBLACK;
1402            break;
1403
1404        case M4VSS3GPP_kVideoEffectType_FadeToBlack:
1405            effect = VIDEO_EFFECT_FADETOBLACK;
1406            break;
1407
1408        case M4xVSS_kVideoEffectType_BlackAndWhite:
1409            effect = VIDEO_EFFECT_BLACKANDWHITE;
1410            break;
1411
1412        case M4xVSS_kVideoEffectType_Pink:
1413            effect = VIDEO_EFFECT_PINK;
1414            break;
1415
1416        case M4xVSS_kVideoEffectType_Green:
1417            effect = VIDEO_EFFECT_GREEN;
1418            break;
1419
1420        case M4xVSS_kVideoEffectType_Sepia:
1421            effect = VIDEO_EFFECT_SEPIA;
1422            break;
1423
1424        case M4xVSS_kVideoEffectType_Negative:
1425            effect = VIDEO_EFFECT_NEGATIVE;
1426            break;
1427
1428        case M4xVSS_kVideoEffectType_Framing:
1429            effect = VIDEO_EFFECT_FRAMING;
1430            break;
1431
1432        case M4xVSS_kVideoEffectType_Fifties:
1433            effect = VIDEO_EFFECT_FIFTIES;
1434            break;
1435
1436        case M4xVSS_kVideoEffectType_ColorRGB16:
1437            effect = VIDEO_EFFECT_COLOR_RGB16;
1438            break;
1439
1440        case M4xVSS_kVideoEffectType_Gradient:
1441            effect = VIDEO_EFFECT_GRADIENT;
1442            break;
1443
1444        default:
1445            effect = VIDEO_EFFECT_NONE;
1446            break;
1447    }
1448
1449    if (enable == M4OSA_TRUE) {
1450        //If already set, then no need to set again
1451        if (!(mCurrentVideoEffect & effect)) {
1452            mCurrentVideoEffect |= effect;
1453            if (effect == VIDEO_EFFECT_FIFTIES) {
1454                mIsFiftiesEffectStarted = true;
1455            }
1456        }
1457    } else  {
1458        //Reset only if already set
1459        if (mCurrentVideoEffect & effect) {
1460            mCurrentVideoEffect &= ~effect;
1461        }
1462    }
1463}
1464
1465status_t PreviewPlayer::setImageClipProperties(uint32_t width,uint32_t height) {
1466    mVideoWidth = width;
1467    mVideoHeight = height;
1468    return OK;
1469}
1470
1471status_t PreviewPlayer::readFirstVideoFrame() {
1472    ALOGV("readFirstVideoFrame");
1473
1474    if (!mVideoBuffer) {
1475        MediaSource::ReadOptions options;
1476        if (mSeeking != NO_SEEK) {
1477            ALOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs,
1478                    mSeekTimeUs / 1E6);
1479
1480            options.setSeekTo(
1481                    mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST);
1482        }
1483        for (;;) {
1484            status_t err = mVideoSource->read(&mVideoBuffer, &options);
1485            options.clearSeekTo();
1486
1487            if (err != OK) {
1488                CHECK(!mVideoBuffer);
1489
1490                if (err == INFO_FORMAT_CHANGED) {
1491                    ALOGV("VideoSource signalled format change");
1492                    notifyVideoSize_l();
1493
1494                    if (mVideoRenderer != NULL) {
1495                        mVideoRendererIsPreview = false;
1496                        err = initRenderer_l();
1497                        if (err != OK) {
1498                            postStreamDoneEvent_l(err);
1499                        }
1500                    }
1501
1502                    updateSizeToRender(mVideoSource->getFormat());
1503                    continue;
1504                }
1505                ALOGV("EOS reached.");
1506                mFlags |= VIDEO_AT_EOS;
1507                mFlags |= AUDIO_AT_EOS;
1508                postStreamDoneEvent_l(err);
1509                return OK;
1510            }
1511
1512            if (mVideoBuffer->range_length() == 0) {
1513                // Some decoders, notably the PV AVC software decoder
1514                // return spurious empty buffers that we just want to ignore.
1515
1516                mVideoBuffer->release();
1517                mVideoBuffer = NULL;
1518                continue;
1519            }
1520
1521            int64_t videoTimeUs;
1522            CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &videoTimeUs));
1523            if (mSeeking != NO_SEEK) {
1524                if (videoTimeUs < mSeekTimeUs) {
1525                    // buffers are before seek time
1526                    // ignore them
1527                    mVideoBuffer->release();
1528                    mVideoBuffer = NULL;
1529                    continue;
1530                }
1531            } else {
1532                if ((videoTimeUs/1000) < mPlayBeginTimeMsec) {
1533                    // buffers are before begin cut time
1534                    // ignore them
1535                    mVideoBuffer->release();
1536                    mVideoBuffer = NULL;
1537                    continue;
1538                }
1539            }
1540            break;
1541        }
1542    }
1543
1544    int64_t timeUs;
1545    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1546    setPosition_l(timeUs);
1547
1548    mDecodedVideoTs = timeUs;
1549
1550    return OK;
1551
1552}
1553
1554status_t PreviewPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
1555    *lastRenderedTimeMs = (((mDecodedVideoTs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec);
1556    return OK;
1557}
1558
1559void PreviewPlayer::updateSizeToRender(sp<MetaData> meta) {
1560    if (mVideoRenderer) {
1561        mVideoRenderer->updateVideoSize(meta);
1562    }
1563}
1564
1565void PreviewPlayer::setListener(const wp<MediaPlayerBase> &listener) {
1566    Mutex::Autolock autoLock(mLock);
1567    mListener = listener;
1568}
1569
1570status_t PreviewPlayer::setDataSource(const sp<IStreamSource> &source) {
1571    return INVALID_OPERATION;
1572}
1573
1574void PreviewPlayer::reset() {
1575    Mutex::Autolock autoLock(mLock);
1576    reset_l();
1577}
1578
1579void PreviewPlayer::clear_l() {
1580    mDisplayWidth = 0;
1581    mDisplayHeight = 0;
1582
1583    if (mFlags & PLAYING) {
1584        updateBatteryUsage_l();
1585    }
1586
1587    if (mFlags & PREPARING) {
1588        mFlags |= PREPARE_CANCELLED;
1589
1590        if (mFlags & PREPARING_CONNECTED) {
1591            // We are basically done preparing, we're just buffering
1592            // enough data to start playback, we can safely interrupt that.
1593            finishAsyncPrepare_l();
1594        }
1595    }
1596
1597    while (mFlags & PREPARING) {
1598        mPreparedCondition.wait(mLock);
1599    }
1600
1601    cancelPlayerEvents_l(true);
1602
1603    mAudioTrack.clear();
1604    mVideoTrack.clear();
1605
1606    // Shutdown audio first, so that the respone to the reset request
1607    // appears to happen instantaneously as far as the user is concerned
1608    // If we did this later, audio would continue playing while we
1609    // shutdown the video-related resources and the player appear to
1610    // not be as responsive to a reset request.
1611    if (mAudioPlayer == NULL && mAudioSource != NULL) {
1612        // If we had an audio player, it would have effectively
1613        // taken possession of the audio source and stopped it when
1614        // _it_ is stopped. Otherwise this is still our responsibility.
1615        mAudioSource->stop();
1616    }
1617    mAudioSource.clear();
1618
1619    mTimeSource = NULL;
1620
1621    delete mAudioPlayer;
1622    mAudioPlayer = NULL;
1623
1624    if (mVideoSource != NULL) {
1625        shutdownVideoDecoder_l();
1626    }
1627
1628    mDurationUs = -1;
1629    mFlags = 0;
1630    mExtractorFlags = 0;
1631    mTimeSourceDeltaUs = 0;
1632    mVideoTimeUs = 0;
1633
1634    mSeeking = NO_SEEK;
1635    mSeekNotificationSent = false;
1636    mSeekTimeUs = 0;
1637
1638    mUri.setTo("");
1639
1640    mBitrate = -1;
1641    mLastVideoTimeUs = -1;
1642}
1643
1644void PreviewPlayer::notifyListener_l(int msg, int ext1, int ext2) {
1645    if (mListener != NULL) {
1646        sp<MediaPlayerBase> listener = mListener.promote();
1647
1648        if (listener != NULL) {
1649            listener->sendEvent(msg, ext1, ext2);
1650        }
1651    }
1652}
1653
1654void PreviewPlayer::onVideoLagUpdate() {
1655    Mutex::Autolock autoLock(mLock);
1656    if (!mVideoLagEventPending) {
1657        return;
1658    }
1659    mVideoLagEventPending = false;
1660
1661    int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
1662    int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
1663
1664    if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
1665        ALOGV("video late by %lld ms.", videoLateByUs / 1000ll);
1666
1667        notifyListener_l(
1668                MEDIA_INFO,
1669                MEDIA_INFO_VIDEO_TRACK_LAGGING,
1670                videoLateByUs / 1000ll);
1671    }
1672
1673    postVideoLagEvent_l();
1674}
1675
1676void PreviewPlayer::notifyVideoSize_l() {
1677    sp<MetaData> meta = mVideoSource->getFormat();
1678
1679    int32_t vWidth, vHeight;
1680    int32_t cropLeft, cropTop, cropRight, cropBottom;
1681
1682    CHECK(meta->findInt32(kKeyWidth, &vWidth));
1683    CHECK(meta->findInt32(kKeyHeight, &vHeight));
1684
1685    mGivenWidth = vWidth;
1686    mGivenHeight = vHeight;
1687
1688    if (!meta->findRect(
1689                kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
1690
1691        cropLeft = cropTop = 0;
1692        cropRight = vWidth - 1;
1693        cropBottom = vHeight - 1;
1694
1695        ALOGD("got dimensions only %d x %d", vWidth, vHeight);
1696    } else {
1697        ALOGD("got crop rect %d, %d, %d, %d",
1698             cropLeft, cropTop, cropRight, cropBottom);
1699    }
1700
1701    mCropRect.left = cropLeft;
1702    mCropRect.right = cropRight;
1703    mCropRect.top = cropTop;
1704    mCropRect.bottom = cropBottom;
1705
1706    int32_t displayWidth;
1707    if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
1708        ALOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
1709        mDisplayWidth = displayWidth;
1710    }
1711    int32_t displayHeight;
1712    if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
1713        ALOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
1714        mDisplayHeight = displayHeight;
1715    }
1716
1717    int32_t usableWidth = cropRight - cropLeft + 1;
1718    int32_t usableHeight = cropBottom - cropTop + 1;
1719    if (mDisplayWidth != 0) {
1720        usableWidth = mDisplayWidth;
1721    }
1722    if (mDisplayHeight != 0) {
1723        usableHeight = mDisplayHeight;
1724    }
1725
1726    int32_t rotationDegrees;
1727    if (!mVideoTrack->getFormat()->findInt32(
1728                kKeyRotation, &rotationDegrees)) {
1729        rotationDegrees = 0;
1730    }
1731
1732    if (rotationDegrees == 90 || rotationDegrees == 270) {
1733        notifyListener_l(
1734                MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
1735    } else {
1736        notifyListener_l(
1737                MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
1738    }
1739}
1740
1741status_t PreviewPlayer::pause() {
1742    Mutex::Autolock autoLock(mLock);
1743
1744    mFlags &= ~CACHE_UNDERRUN;
1745
1746    return pause_l();
1747}
1748
1749status_t PreviewPlayer::pause_l(bool at_eos) {
1750    if (!(mFlags & PLAYING)) {
1751        return OK;
1752    }
1753
1754    cancelPlayerEvents_l();
1755
1756    if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1757        if (at_eos) {
1758            // If we played the audio stream to completion we
1759            // want to make sure that all samples remaining in the audio
1760            // track's queue are played out.
1761            mAudioPlayer->pause(true /* playPendingSamples */);
1762        } else {
1763            mAudioPlayer->pause();
1764        }
1765
1766        mFlags &= ~AUDIO_RUNNING;
1767    }
1768
1769    mFlags &= ~PLAYING;
1770    updateBatteryUsage_l();
1771
1772    return OK;
1773}
1774
1775bool PreviewPlayer::isPlaying() const {
1776    return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
1777}
1778
1779void PreviewPlayer::setSurface(const sp<Surface> &surface) {
1780    Mutex::Autolock autoLock(mLock);
1781
1782    mSurface = surface;
1783    setNativeWindow_l(surface);
1784}
1785
1786void PreviewPlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1787    Mutex::Autolock autoLock(mLock);
1788
1789    mSurface.clear();
1790    if (surfaceTexture != NULL) {
1791        setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
1792    }
1793}
1794
1795void PreviewPlayer::shutdownVideoDecoder_l() {
1796    if (mVideoBuffer) {
1797        mVideoBuffer->release();
1798        mVideoBuffer = NULL;
1799    }
1800
1801    mVideoSource->stop();
1802
1803    // The following hack is necessary to ensure that the OMX
1804    // component is completely released by the time we may try
1805    // to instantiate it again.
1806    wp<MediaSource> tmp = mVideoSource;
1807    mVideoSource.clear();
1808    while (tmp.promote() != NULL) {
1809        usleep(1000);
1810    }
1811    IPCThreadState::self()->flushCommands();
1812}
1813
1814void PreviewPlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
1815    mNativeWindow = native;
1816
1817    if (mVideoSource == NULL) {
1818        return;
1819    }
1820
1821    ALOGI("attempting to reconfigure to use new surface");
1822
1823    bool wasPlaying = (mFlags & PLAYING) != 0;
1824
1825    pause_l();
1826
1827    shutdownVideoDecoder_l();
1828
1829    CHECK_EQ(initVideoDecoder_l(), (status_t)OK);
1830
1831    if (mLastVideoTimeUs >= 0) {
1832        mSeeking = SEEK;
1833        mSeekNotificationSent = true;
1834        mSeekTimeUs = mLastVideoTimeUs;
1835        mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
1836    }
1837
1838    if (wasPlaying) {
1839        play_l();
1840    }
1841}
1842
1843void PreviewPlayer::setAudioSink(
1844        const sp<MediaPlayerBase::AudioSink> &audioSink) {
1845    Mutex::Autolock autoLock(mLock);
1846
1847    mAudioSink = audioSink;
1848}
1849
1850status_t PreviewPlayer::setLooping(bool shouldLoop) {
1851    Mutex::Autolock autoLock(mLock);
1852
1853    mFlags = mFlags & ~LOOPING;
1854
1855    if (shouldLoop) {
1856        mFlags |= LOOPING;
1857    }
1858
1859    return OK;
1860}
1861
1862void PreviewPlayer::setDuration_l(int64_t durationUs) {
1863    if (mDurationUs < 0 || durationUs > mDurationUs) {
1864        mDurationUs = durationUs;
1865    }
1866}
1867
1868status_t PreviewPlayer::getDuration(int64_t *durationUs) {
1869    Mutex::Autolock autoLock(mLock);
1870    if (mDurationUs < 0) {
1871        return UNKNOWN_ERROR;
1872    }
1873
1874    *durationUs = mDurationUs;
1875    return OK;
1876}
1877
1878status_t PreviewPlayer::getPosition(int64_t *positionUs) {
1879    Mutex::Autolock autoLock(mLock);
1880
1881    if (mSeeking != NO_SEEK) {
1882        *positionUs = mSeekTimeUs;
1883    } else if (mVideoSource != NULL
1884            && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
1885        *positionUs = mVideoTimeUs;
1886    } else if (mAudioPlayer != NULL) {
1887        *positionUs = mAudioPlayer->getMediaTimeUs();
1888    } else {
1889        *positionUs = 0;
1890    }
1891
1892    return OK;
1893}
1894
1895void PreviewPlayer::setPosition_l(int64_t timeUs) {
1896    mVideoTimeUs = timeUs;
1897}
1898
1899status_t PreviewPlayer::seekTo_l(int64_t timeUs) {
1900    ALOGV("seekTo_l");
1901    if (mFlags & CACHE_UNDERRUN) {
1902        mFlags &= ~CACHE_UNDERRUN;
1903        play_l();
1904    }
1905
1906    if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
1907        // Video playback completed before, there's no pending
1908        // video event right now. In order for this new seek
1909        // to be honored, we need to post one.
1910
1911        postVideoEvent_l();
1912    }
1913
1914    mSeeking = SEEK;
1915    mSeekNotificationSent = false;
1916    mSeekTimeUs = timeUs;
1917    mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
1918
1919    seekAudioIfNecessary_l();
1920
1921    if (!(mFlags & PLAYING)) {
1922        ALOGV("seeking while paused, sending SEEK_COMPLETE notification"
1923             " immediately.");
1924
1925        notifyListener_l(MEDIA_SEEK_COMPLETE);
1926        mSeekNotificationSent = true;
1927
1928        if ((mFlags & PREPARED) && mVideoSource != NULL) {
1929            mFlags |= SEEK_PREVIEW;
1930            postVideoEvent_l();
1931        }
1932    }
1933
1934    return OK;
1935}
1936
1937void PreviewPlayer::seekAudioIfNecessary_l() {
1938    if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
1939        mAudioPlayer->seekTo(mSeekTimeUs);
1940
1941        mWatchForAudioSeekComplete = true;
1942        mWatchForAudioEOS = true;
1943    }
1944}
1945
1946void PreviewPlayer::setAudioSource(const sp<MediaSource>& source) {
1947    CHECK(source != NULL);
1948    mAudioTrack = source;
1949}
1950
1951void PreviewPlayer::setVideoSource(const sp<MediaSource>& source) {
1952    CHECK(source != NULL);
1953    mVideoTrack = source;
1954}
1955
1956void PreviewPlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
1957    if (mSeeking == SEEK_VIDEO_ONLY) {
1958        mSeeking = NO_SEEK;
1959        return;
1960    }
1961
1962    if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
1963        return;
1964    }
1965
1966    if (mAudioPlayer != NULL) {
1967        ALOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
1968
1969        // If we don't have a video time, seek audio to the originally
1970        // requested seek time instead.
1971
1972        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
1973        mWatchForAudioSeekComplete = true;
1974        mWatchForAudioEOS = true;
1975    } else if (!mSeekNotificationSent) {
1976        // If we're playing video only, report seek complete now,
1977        // otherwise audio player will notify us later.
1978        notifyListener_l(MEDIA_SEEK_COMPLETE);
1979        mSeekNotificationSent = true;
1980    }
1981
1982    mFlags |= FIRST_FRAME;
1983    mSeeking = NO_SEEK;
1984}
1985
1986void PreviewPlayer::onCheckAudioStatus() {
1987    Mutex::Autolock autoLock(mLock);
1988    if (!mAudioStatusEventPending) {
1989        // Event was dispatched and while we were blocking on the mutex,
1990        // has already been cancelled.
1991        return;
1992    }
1993
1994    mAudioStatusEventPending = false;
1995
1996    if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
1997        mWatchForAudioSeekComplete = false;
1998
1999        if (!mSeekNotificationSent) {
2000            notifyListener_l(MEDIA_SEEK_COMPLETE);
2001            mSeekNotificationSent = true;
2002        }
2003
2004        mSeeking = NO_SEEK;
2005    }
2006
2007    status_t finalStatus;
2008    if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
2009        mWatchForAudioEOS = false;
2010        mFlags |= AUDIO_AT_EOS;
2011        mFlags |= FIRST_FRAME;
2012        postStreamDoneEvent_l(finalStatus);
2013    }
2014}
2015
2016void PreviewPlayer::postVideoEvent_l(int64_t delayUs) {
2017    if (mVideoEventPending) {
2018        return;
2019    }
2020
2021    mVideoEventPending = true;
2022    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
2023}
2024
2025void PreviewPlayer::postStreamDoneEvent_l(status_t status) {
2026    if (mStreamDoneEventPending) {
2027        return;
2028    }
2029    mStreamDoneEventPending = true;
2030
2031    mStreamDoneStatus = status;
2032    mQueue.postEvent(mStreamDoneEvent);
2033}
2034
2035void PreviewPlayer::postVideoLagEvent_l() {
2036    if (mVideoLagEventPending) {
2037        return;
2038    }
2039    mVideoLagEventPending = true;
2040    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
2041}
2042
2043void PreviewPlayer::postCheckAudioStatusEvent_l(int64_t delayUs) {
2044    if (mAudioStatusEventPending) {
2045        return;
2046    }
2047    mAudioStatusEventPending = true;
2048    mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
2049}
2050
2051void PreviewPlayer::abortPrepare(status_t err) {
2052    CHECK(err != OK);
2053
2054    if (mIsAsyncPrepare) {
2055        notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
2056    }
2057
2058    mPrepareResult = err;
2059    mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
2060    mAsyncPrepareEvent = NULL;
2061    mPreparedCondition.broadcast();
2062}
2063
2064uint32_t PreviewPlayer::getSourceSeekFlags() const {
2065    Mutex::Autolock lock(mLock);
2066    return mExtractorFlags;
2067}
2068
2069void PreviewPlayer::postAudioEOS(int64_t delayUs) {
2070    Mutex::Autolock autoLock(mLock);
2071    postCheckAudioStatusEvent_l(delayUs);
2072}
2073
2074void PreviewPlayer::postAudioSeekComplete() {
2075    Mutex::Autolock autoLock(mLock);
2076    postCheckAudioStatusEvent_l(0 /* delayUs */);
2077}
2078
2079void PreviewPlayer::updateBatteryUsage_l() {
2080    uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
2081    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
2082        params |= IMediaPlayerService::kBatteryDataTrackAudio;
2083    }
2084    if (mVideoSource != NULL) {
2085        params |= IMediaPlayerService::kBatteryDataTrackVideo;
2086    }
2087    addBatteryData(params);
2088}
2089
2090}  // namespace android
2091