From 9be07ef6a1d4dc591a25b3364a6ca0ad6f524ab9 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Fri, 1 Feb 2013 18:49:00 -0800 Subject: libstagefright: Squashed commit of LPA/tunnel updates from CAF libstagefright: Exceptions in using Tunnel mode decode - Accumulate all known exceptions to a separate function Change-Id: I61bbc288c9a087559db210e76141b8c57e67fff0 CRs-Fixed: 432080 libstagefright : Stability fixes for Tunnel Player (part 2) - Synchronize b/w reset() and onPauseTimeout - Synchronize b/w seekTo() and onPauseTimeout Change-Id: Ia5cfc6b4dcc326ead440fba35d809d4f3f1b5a81 CRs-Fixed: 449122 Revert "Revert "libstagefright: Convert mono to stereo for LPA clips"" This reverts commit 0db8a19fb3216a8a83d5d6cbd5f1ccbf997a20d8. libstagefright: Port Tunnel mode fixes to LPA - Miscellaneous fixes for seek, pause/resume, EOS handling - Miscellaneous fixes for synchronization between the decoder thread, TimedEventQueue and the player thread. - This change is a port of a similar set of changes made for TunnelPlayer Change-Id: I82c2904f7aedfb9c4f03200419fcba8b038e3d54 libstagefright: Avoid use of extra bytes to signal seek processed - A few bytes were reserved in the buffer sent by Tunnel/LPA player to audio HAL to indicate a seek has been processed and there is no need to skip it. - We won't need this method anymore as this can be fixed instead by synchronizing seekTo() and the extractor/decoder threads. Change-Id: Ic02ae1699bb59e2f6b8d9fb599d0fa43fd3f19e3 libstagefright: LPAPlayer synchronization fixes - synchronize b/w seekTo() and onPauseTimeout() - synchronize b/w reset() and onPauseTimeout() Change-Id: I29a4ccf02e28fe7b7c00e35a679ff2b5271ffb6f libstagefright: TunnelPlayer performance tweaks Some tweaks when TunnelPlayer is used for audio/video playback - Keep the extractor thread at ANDROID_PRIORITY_NORMAL - sched_yield() after reading a frame to give the video thread(s) (CallbackDispatcher and/or TimedEventQueue) to be scheduled Change-Id: If0d86d629fd0e15aff917af8589472578cd28bf4 CRs-Fixed: 444041 --- media/libstagefright/TunnelPlayer.cpp | 59 ++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'media/libstagefright/TunnelPlayer.cpp') diff --git a/media/libstagefright/TunnelPlayer.cpp b/media/libstagefright/TunnelPlayer.cpp index c5f8066..3b45db4 100644 --- a/media/libstagefright/TunnelPlayer.cpp +++ b/media/libstagefright/TunnelPlayer.cpp @@ -51,6 +51,13 @@ static const char mName[] = "TunnelPlayer"; #define MEM_METADATA_SIZE 64 #define MEM_PADDING 64 +/* + * We need to reserve some space in the + * ion buffer (used in HAL) to save the + * metadata. so read from the extractor + * a somewhat smaller number of bytes. + * ideally this number should be bufer_size - sizeof(struct output_metadata_t) + */ #define MEM_BUFFER_SIZE (240*1024 - MEM_METADATA_SIZE) #define MEM_BUFFER_COUNT 4 #define TUNNEL_BUFFER_TIME 1500000 @@ -374,7 +381,9 @@ status_t TunnelPlayer::start(bool sourceAlreadyStarted) { status_t TunnelPlayer::seekTo(int64_t time_us) { - ALOGV("seekTo: time_us %lld", time_us); + ALOGD("seekTo: time_us %lld", time_us); + + Mutex::Autolock _l(mLock); //to sync w/ onpausetimeout //This can happen if the client calls seek //without ever calling getPosition @@ -385,19 +394,26 @@ status_t TunnelPlayer::seekTo(int64_t time_us) { if (mPositionTimeRealUs > 0) { //check for return conditions only if seektime // is set + bool postSeekComplete = false; + if (time_us > mPositionTimeRealUs){ - if((time_us - mPositionTimeRealUs) < TUNNEL_BUFFER_TIME){ + if ((time_us - mPositionTimeRealUs) < TUNNEL_BUFFER_TIME){ ALOGV("In seekTo(), ignoring time_us %lld mSeekTimeUs %lld", time_us, mSeekTimeUs); - mObserver->postAudioSeekComplete(); - return OK; + postSeekComplete = true; } } else { - if((mPositionTimeRealUs - time_us) < TUNNEL_BUFFER_TIME){ + if ((mPositionTimeRealUs - time_us) < TUNNEL_BUFFER_TIME){ ALOGV("In seekTo(), ignoring time_us %lld mSeekTimeUs %lld", time_us, mSeekTimeUs); - mObserver->postAudioSeekComplete(); - return OK; + postSeekComplete = true; } } + + if (postSeekComplete) { + mLock.unlock(); //unlock and post + mObserver->postAudioSeekComplete(); + mLock.lock(); + return OK; + } } mSeeking = true; @@ -502,6 +518,13 @@ size_t TunnelPlayer::AudioSinkCallback( void TunnelPlayer::reset() { ALOGV("Reset"); + Mutex::Autolock _l(mLock); //to sync w/ onpausetimeout + + //cancel any pending onpause timeout events + //doesnt matter if the event is really present or not + mPauseEventPending = false; + mQueue.cancelEvent(mPauseEvent->eventID()); + mReachedEOS = true; // make sure Decoder thread has exited @@ -568,7 +591,8 @@ void TunnelPlayer::extractorThreadEntry() { uint32_t BufferSizeToUse = MEM_BUFFER_SIZE; pid_t tid = gettid(); - androidSetThreadPriority(tid, ANDROID_PRIORITY_AUDIO); + androidSetThreadPriority(tid, mHasVideo ? ANDROID_PRIORITY_NORMAL : + ANDROID_PRIORITY_AUDIO); prctl(PR_SET_NAME, (unsigned long)"Extractor Thread", 0, 0, 0); ALOGV("extractorThreadEntry wait for signal \n"); @@ -585,7 +609,7 @@ void TunnelPlayer::extractorThreadEntry() { const char *mime; bool success = format->findCString(kKeyMIMEType, &mime); } - void* local_buf = malloc(BufferSizeToUse + MEM_PADDING); + void* local_buf = malloc(BufferSizeToUse); int *lptr = ((int*)local_buf); int bytesWritten = 0; bool lSeeking = false; @@ -632,8 +656,7 @@ void TunnelPlayer::extractorThreadEntry() { if(lSeeking == false && (killExtractorThread == false)){ //if we are seeking, ignore write, otherwise write - ALOGV("Fillbuffer before write %d and seek flag %d", mSeeking, - lptr[MEM_BUFFER_SIZE/sizeof(int)]); + ALOGV("Fillbuffer before seek flag %d", mSeeking); int lWrittenBytes = mAudioSink->write(local_buf, bytesWritten); ALOGV("Fillbuffer after write, written bytes %d and seek flag %d", lWrittenBytes, mSeeking); if(lWrittenBytes > 0) { @@ -660,6 +683,7 @@ void TunnelPlayer::extractorThreadEntry() { } } } + } free(local_buf); @@ -696,11 +720,11 @@ size_t TunnelPlayer::fillBuffer(void *data, size_t size) { size_t size_done = 0; size_t size_remaining = size; - int *ldataptr = (int*) data; //clear the flag since we dont know whether we are seeking or not, yet - ldataptr[(MEM_BUFFER_SIZE/sizeof(int))] = 0; ALOGV("fillBuffer: Clearing seek flag in fill buffer"); + bool yield = !mIsFirstBuffer; + while (size_remaining > 0) { MediaSource::ReadOptions options; { @@ -738,7 +762,6 @@ size_t TunnelPlayer::fillBuffer(void *data, size_t size) { mInternalSeeking = false; ALOGV("fillBuffer: Setting seek flag in fill buffer"); //set the flag since we know that this buffer is the new positions buffer - ldataptr[(MEM_BUFFER_SIZE/sizeof(int))] = 1; } } if (mInputBuffer == NULL) { @@ -787,6 +810,10 @@ size_t TunnelPlayer::fillBuffer(void *data, size_t size) { size_done += copy; size_remaining -= copy; + + if (mHasVideo && yield) { + sched_yield(); + } } if(mReachedEOS) memset((char *)data + size_done, 0x0, size_remaining); @@ -841,7 +868,9 @@ bool TunnelPlayer::getMediaTimeMapping( return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; } +//lock has been taken in reset() to sync with onpausetimeout void TunnelPlayer::requestAndWaitForExtractorThreadExit() { + ALOGV("requestAndWaitForExtractorThreadExit -1"); if (!extractorThreadAlive) return; @@ -856,7 +885,9 @@ void TunnelPlayer::requestAndWaitForExtractorThreadExit() { ALOGV("requestAndWaitForExtractorThreadExit +1"); pthread_cond_signal(&extractor_cv); ALOGV("requestAndWaitForExtractorThreadExit +2"); + mLock.unlock(); pthread_join(extractorThread,NULL); + mLock.lock(); ALOGV("requestAndWaitForExtractorThreadExit +3"); ALOGV("Extractor thread killed"); -- cgit v1.1