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