summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/TunnelPlayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/TunnelPlayer.cpp')
-rw-r--r--media/libstagefright/TunnelPlayer.cpp59
1 files changed, 45 insertions, 14 deletions
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");