summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/AudioSource.cpp
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-07-21 14:51:35 -0700
committerJames Dong <jdong@google.com>2010-07-22 14:51:53 -0700
commit53d4e0d58e2d5c18f6e026c705af833b9bdd7aba (patch)
tree70bafe068da199dcd0206802d0f673e5dc80d918 /media/libstagefright/AudioSource.cpp
parentdb3eb3553502d142c85d47ec4fb847b7fa3b06fa (diff)
downloadframeworks_base-53d4e0d58e2d5c18f6e026c705af833b9bdd7aba.zip
frameworks_base-53d4e0d58e2d5c18f6e026c705af833b9bdd7aba.tar.gz
frameworks_base-53d4e0d58e2d5c18f6e026c705af833b9bdd7aba.tar.bz2
Allows the authoring engine to skip frame.
This is 1st part of the work to allow audio and video resync if we found out that audio and video are out of sync during authoring - also fixed a problem in AACEncoder::read() where the buffer acquired from the buffer group does not release when error out at reading from source. Change-Id: I8a2740097fcfdf85e6178869afeb9f3687a99118
Diffstat (limited to 'media/libstagefright/AudioSource.cpp')
-rw-r--r--media/libstagefright/AudioSource.cpp95
1 files changed, 59 insertions, 36 deletions
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 6031797..50c0edc 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -137,52 +137,75 @@ status_t AudioSource::read(
MediaBuffer *buffer;
CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
- uint32_t numFramesRecorded;
- mRecord->getPosition(&numFramesRecorded);
- int64_t latency = mRecord->latency() * 1000;
-
- int64_t readTime = systemTime() / 1000;
- if (numFramesRecorded == 0) {
- // Initial delay
- if (mStartTimeUs > 0) {
- mStartTimeUs = readTime - mStartTimeUs;
+ while (mStarted) {
+ uint32_t numFramesRecorded;
+ mRecord->getPosition(&numFramesRecorded);
+ int64_t latency = mRecord->latency() * 1000;
+
+ int64_t readTime = systemTime() / 1000;
+
+ if (numFramesRecorded == 0) {
+ // Initial delay
+ if (mStartTimeUs > 0) {
+ mStartTimeUs = readTime - mStartTimeUs;
+ } else {
+ mStartTimeUs += latency;
+ }
+ }
+
+ ssize_t n = 0;
+ if (mCollectStats) {
+ n = mRecord->read(buffer->data(), buffer->size());
+ int64_t endTime = systemTime() / 1000;
+ mTotalReadTimeUs += (endTime - readTime);
+ if (n >= 0) {
+ mTotalReadBytes += n;
+ }
} else {
- mStartTimeUs += latency;
+ n = mRecord->read(buffer->data(), buffer->size());
}
- }
- ssize_t n = 0;
- if (mCollectStats) {
- n = mRecord->read(buffer->data(), buffer->size());
- int64_t endTime = systemTime() / 1000;
- mTotalReadTimeUs += (endTime - readTime);
- if (n >= 0) {
- mTotalReadBytes += n;
+ if (n < 0) {
+ buffer->release();
+ buffer = NULL;
+
+ return (status_t)n;
}
- } else {
- n = mRecord->read(buffer->data(), buffer->size());
- }
- if (n < 0) {
- buffer->release();
- buffer = NULL;
+ uint32_t sampleRate = mRecord->getSampleRate();
+ int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate +
+ mStartTimeUs;
+ int64_t skipFrameUs;
+ if (!options || !options->getSkipFrame(&skipFrameUs)) {
+ skipFrameUs = timestampUs; // Don't skip frame
+ }
- return (status_t)n;
- }
+ if (skipFrameUs > timestampUs) {
+ // Safe guard against the abuse of the kSkipFrame_Option.
+ if (skipFrameUs - timestampUs >= 1E6) {
+ LOGE("Frame skipping requested is way too long: %lld us",
+ skipFrameUs - timestampUs);
+ buffer->release();
+ return UNKNOWN_ERROR;
+ }
+ LOGV("skipFrame: %lld us > timestamp: %lld us, samples %d",
+ skipFrameUs, timestampUs, numFramesRecorded);
+ continue;
+ }
- if (mTrackMaxAmplitude) {
- trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
- }
+ if (mTrackMaxAmplitude) {
+ trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
+ }
- uint32_t sampleRate = mRecord->getSampleRate();
- int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate + mStartTimeUs;
- buffer->meta_data()->setInt64(kKeyTime, timestampUs);
- LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
- mStartTimeUs, sampleRate, timestampUs);
+ buffer->meta_data()->setInt64(kKeyTime, timestampUs);
+ LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
+ mStartTimeUs, sampleRate, timestampUs);
- buffer->set_range(0, n);
+ buffer->set_range(0, n);
- *out = buffer;
+ *out = buffer;
+ return OK;
+ }
return OK;
}