diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 26 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 16 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h | 4 | ||||
-rw-r--r-- | media/libstagefright/AVIExtractor.cpp | 59 | ||||
-rw-r--r-- | media/libstagefright/include/AVIExtractor.h | 11 |
5 files changed, 87 insertions, 29 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index c2c6715..8ebb652 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -262,7 +262,7 @@ status_t AudioTrack::set( mFlushed = false; mFlags = flags; AudioSystem::acquireAudioSessionId(mSessionId); - + mRestoreStatus = NO_ERROR; return NO_ERROR; } @@ -1161,8 +1161,8 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) status_t result; if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { - LOGW("dead IAudioTrack, creating a new one from %s", - fromStart ? "start()" : "obtainBuffer()"); + LOGW("dead IAudioTrack, creating a new one from %s TID %d", + fromStart ? "start()" : "obtainBuffer()", gettid()); // signal old cblk condition so that other threads waiting for available buffers stop // waiting now @@ -1217,33 +1217,35 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) } if (mActive) { result = mAudioTrack->start(); + LOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result); } if (fromStart && result == NO_ERROR) { mNewPosition = mCblk->server + mUpdatePeriod; } } if (result != NO_ERROR) { - mActive = false; + android_atomic_and(~CBLK_RESTORING_ON, &cblk->flags); + LOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result); } - + mRestoreStatus = result; // signal old cblk condition for other threads waiting for restore completion android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); cblk->cv.broadcast(); } else { if (!(cblk->flags & CBLK_RESTORED_MSK)) { - LOGW("dead IAudioTrack, waiting for a new one"); + LOGW("dead IAudioTrack, waiting for a new one TID %d", gettid()); mLock.unlock(); result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); + if (result == NO_ERROR) { + result = mRestoreStatus; + } cblk->lock.unlock(); mLock.lock(); } else { - LOGW("dead IAudioTrack, already restored"); - result = NO_ERROR; + LOGW("dead IAudioTrack, already restored TID %d", gettid()); + result = mRestoreStatus; cblk->lock.unlock(); } - if (result != NO_ERROR || mActive == 0) { - result = status_t(STOPPED); - } } LOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); @@ -1254,7 +1256,7 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) } cblk->lock.lock(); - LOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d", result); + LOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d TID %d", result, gettid()); return result; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 8f213da..bf83849 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -26,6 +26,9 @@ namespace android { +// static +const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; + NuPlayer::Renderer::Renderer( const sp<MediaPlayerBase::AudioSink> &sink, const sp<AMessage> ¬ify) @@ -43,7 +46,8 @@ NuPlayer::Renderer::Renderer( mHasAudio(false), mHasVideo(false), mSyncQueues(false), - mPaused(false) { + mPaused(false), + mLastPositionUpdateUs(-1ll) { } NuPlayer::Renderer::~Renderer() { @@ -190,7 +194,7 @@ void NuPlayer::Renderer::postDrainAudioQueue() { mDrainAudioQueuePending = true; sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id()); msg->setInt32("generation", mAudioQueueGeneration); - msg->post(10000); + msg->post(); } void NuPlayer::Renderer::signalAudioSinkChanged() { @@ -198,7 +202,6 @@ void NuPlayer::Renderer::signalAudioSinkChanged() { } void NuPlayer::Renderer::onDrainAudioQueue() { - for (;;) { if (mAudioQueue.empty()) { break; @@ -562,6 +565,13 @@ void NuPlayer::Renderer::notifyPosition() { } int64_t nowUs = ALooper::GetNowUs(); + + if (mLastPositionUpdateUs >= 0 + && nowUs < mLastPositionUpdateUs + kMinPositionUpdateDelayUs) { + return; + } + mLastPositionUpdateUs = nowUs; + int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs; sp<AMessage> notify = mNotify->dup(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 2713031..3a641a2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -74,6 +74,8 @@ private: status_t mFinalResult; }; + static const int64_t kMinPositionUpdateDelayUs; + sp<MediaPlayerBase::AudioSink> mAudioSink; sp<AMessage> mNotify; List<QueueEntry> mAudioQueue; @@ -98,6 +100,8 @@ private: bool mPaused; + int64_t mLastPositionUpdateUs; + void onDrainAudioQueue(); void postDrainAudioQueue(); diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp index 62d17da..4e46414 100644 --- a/media/libstagefright/AVIExtractor.cpp +++ b/media/libstagefright/AVIExtractor.cpp @@ -117,14 +117,12 @@ status_t AVIExtractor::AVISource::read( } } - int64_t timeUs = - (mSampleIndex * 1000000ll * mTrack.mRate) / mTrack.mScale; - off64_t offset; size_t size; bool isKey; + int64_t timeUs; status_t err = mExtractor->getSampleInfo( - mTrackIndex, mSampleIndex, &offset, &size, &isKey); + mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs); ++mSampleIndex; @@ -396,6 +394,8 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { uint32_t rate = U32LE_AT(&data[20]); uint32_t scale = U32LE_AT(&data[24]); + uint32_t sampleSize = U32LE_AT(&data[44]); + const char *mime = NULL; Track::Kind kind = Track::OTHER; @@ -427,6 +427,7 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { track->mMeta = meta; track->mRate = rate; track->mScale = scale; + track->mBytesPerSample = sampleSize; track->mKind = kind; track->mNumSyncSamples = 0; track->mThumbnailSampleSize = 0; @@ -612,11 +613,12 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) { off64_t offset; size_t size; bool isKey; - status_t err = getSampleInfo(0, 0, &offset, &size, &isKey); + int64_t timeUs; + status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); if (err != OK) { mOffsetsAreAbsolute = !mOffsetsAreAbsolute; - err = getSampleInfo(0, 0, &offset, &size, &isKey); + err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); if (err != OK) { return err; @@ -630,8 +632,9 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) { for (size_t i = 0; i < mTracks.size(); ++i) { Track *track = &mTracks.editItemAt(i); - int64_t durationUs = - (track->mSamples.size() * 1000000ll * track->mRate) / track->mScale; + int64_t durationUs; + CHECK_EQ((status_t)OK, + getSampleTime(i, track->mSamples.size() - 1, &durationUs)); LOGV("track %d duration = %.2f secs", i, durationUs / 1E6); @@ -645,9 +648,10 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) { if (!strncasecmp("video/", mime.c_str(), 6) && track->mThumbnailSampleIndex >= 0) { - int64_t thumbnailTimeUs = - (track->mThumbnailSampleIndex * 1000000ll * track->mRate) - / track->mScale; + int64_t thumbnailTimeUs; + CHECK_EQ((status_t)OK, + getSampleTime(i, track->mThumbnailSampleIndex, + &thumbnailTimeUs)); track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); @@ -659,6 +663,21 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) { } } } + + if (track->mBytesPerSample != 0) { + // Assume all chunks are the same size for now. + + off64_t offset; + size_t size; + bool isKey; + int64_t sampleTimeUs; + CHECK_EQ((status_t)OK, + getSampleInfo( + i, 0, + &offset, &size, &isKey, &sampleTimeUs)); + + track->mRate *= size / track->mBytesPerSample; + } } mFoundIndex = true; @@ -720,7 +739,9 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { off64_t offset; size_t size; bool isKey; - status_t err = getSampleInfo(trackIndex, 0, &offset, &size, &isKey); + int64_t timeUs; + status_t err = + getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs); if (err != OK) { return err; @@ -762,7 +783,8 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { status_t AVIExtractor::getSampleInfo( size_t trackIndex, size_t sampleIndex, - off64_t *offset, size_t *size, bool *isKey) { + off64_t *offset, size_t *size, bool *isKey, + int64_t *sampleTimeUs) { if (trackIndex >= mTracks.size()) { return -ERANGE; } @@ -801,9 +823,20 @@ status_t AVIExtractor::getSampleInfo( *isKey = info.mIsKey; + *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale; + return OK; } +status_t AVIExtractor::getSampleTime( + size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) { + off64_t offset; + size_t size; + bool isKey; + return getSampleInfo( + trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs); +} + status_t AVIExtractor::getSampleIndexAtTime( size_t trackIndex, int64_t timeUs, MediaSource::ReadOptions::SeekMode mode, diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h index 375a94d..b575347 100644 --- a/media/libstagefright/include/AVIExtractor.h +++ b/media/libstagefright/include/AVIExtractor.h @@ -54,6 +54,11 @@ private: uint32_t mRate; uint32_t mScale; + // If bytes per sample == 0, each chunk represents a single sample, + // otherwise each chunk should me a multiple of bytes-per-sample in + // size. + uint32_t mBytesPerSample; + enum Kind { AUDIO, VIDEO, @@ -84,7 +89,11 @@ private: status_t getSampleInfo( size_t trackIndex, size_t sampleIndex, - off64_t *offset, size_t *size, bool *isKey); + off64_t *offset, size_t *size, bool *isKey, + int64_t *sampleTimeUs); + + status_t getSampleTime( + size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs); status_t getSampleIndexAtTime( size_t trackIndex, |