am 7ed7668b: Merge "Calculate audio media drift time from AudioSource" into gingerbread

Merge commit '7ed7668b30e70ca8e3f0f183364433326ed29f39' into gingerbread-plus-aosp

* commit '7ed7668b30e70ca8e3f0f183364433326ed29f39':
  Calculate audio media drift time from AudioSource
This commit is contained in:
James Dong
2010-09-02 18:41:49 -07:00
committed by Android Git Automerger
8 changed files with 63 additions and 32 deletions

View File

@@ -72,6 +72,7 @@ private:
int64_t mPrevSampleTimeUs;
int64_t mTotalLostFrames;
int64_t mPrevLostBytes;
int64_t mInitialReadTimeUs;
MediaBufferGroup *mGroup;

View File

@@ -132,7 +132,7 @@ private:
// Adjust other track media clock (presumably wall clock)
// based on audio track media clock with the drift time.
int64_t mDriftTimeUs;
void addDriftTimeUs(int64_t driftTimeUs);
void setDriftTimeUs(int64_t driftTimeUs);
int64_t getDriftTimeUs();
void lock();

View File

@@ -48,6 +48,7 @@ enum {
kKeyTime = 'time', // int64_t (usecs)
kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp)
kKeyTargetTime = 'tarT', // int64_t (usecs)
kKeyDriftTime = 'dftT', // int64_t (usecs)
kKeyDuration = 'dura', // int64_t (usecs)
kKeyColorFormat = 'colf',
kKeyPlatformPrivate = 'priv', // pointer

View File

@@ -84,6 +84,7 @@ status_t AudioSource::start(MetaData *params) {
mTrackMaxAmplitude = false;
mMaxAmplitude = 0;
mInitialReadTimeUs = 0;
mStartTimeUs = 0;
int64_t startTimeUs;
if (params && params->findInt64(kKeyTime, &startTimeUs)) {
@@ -210,6 +211,7 @@ status_t AudioSource::read(
return NO_INIT;
}
int64_t readTimeUs = systemTime() / 1000;
*out = NULL;
MediaBuffer *buffer;
@@ -223,9 +225,10 @@ status_t AudioSource::read(
if (numFramesRecorded == 0 && mPrevSampleTimeUs == 0) {
mInitialReadTimeUs = readTimeUs;
// Initial delay
if (mStartTimeUs > 0) {
mStartTimeUs = systemTime() / 1000 - mStartTimeUs;
mStartTimeUs = readTimeUs - mStartTimeUs;
} else {
// Assume latency is constant.
mStartTimeUs += mRecord->latency() * 1000;
@@ -271,7 +274,10 @@ status_t AudioSource::read(
}
memset(buffer->data(), 0, numLostBytes);
buffer->set_range(0, numLostBytes);
buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
if (numFramesRecorded == 0) {
buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs);
}
buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
mPrevSampleTimeUs = timestampUs;
*out = buffer;
return OK;
@@ -309,7 +315,10 @@ status_t AudioSource::read(
trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
}
buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
if (numFramesRecorded == 0) {
buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs);
}
buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
CHECK(timestampUs > mPrevSampleTimeUs);
mPrevSampleTimeUs = timestampUs;
LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",

View File

@@ -1430,9 +1430,6 @@ status_t MPEG4Writer::Track::threadEntry() {
int64_t previousPausedDurationUs = 0;
int64_t timestampUs;
int64_t wallClockTimeUs = 0;
int64_t lastWallClockTimeUs = 0;
sp<MetaData> meta_data;
bool collectStats = collectStatisticalData();
@@ -1542,14 +1539,15 @@ status_t MPEG4Writer::Track::threadEntry() {
// of neighboring samples. This in turn helps reduce the track header size,
// especially, the number of entries in the "stts" box.
if (mNumSamples > 1) {
int64_t durationUs = timestampUs + mOwner->getDriftTimeUs() - lastTimestampUs;
int64_t currDriftTimeUs = mOwner->getDriftTimeUs();
int64_t durationUs = timestampUs + currDriftTimeUs - lastTimestampUs;
int64_t diffUs = (durationUs > lastDurationUs)
? durationUs - lastDurationUs
: lastDurationUs - durationUs;
if (diffUs <= 5000) { // XXX: Magic number 5ms
timestampUs = lastTimestampUs + lastDurationUs;
} else {
timestampUs += mOwner->getDriftTimeUs();
timestampUs += currDriftTimeUs;
}
}
}
@@ -1557,12 +1555,6 @@ status_t MPEG4Writer::Track::threadEntry() {
if (mNumSamples > 1) {
if (timestampUs <= lastTimestampUs) {
LOGW("Frame arrives too late!");
#if 0
// Drop the late frame.
copy->release();
copy = NULL;
continue;
#else
// Don't drop the late frame, since dropping a frame may cause
// problems later during playback
@@ -1573,7 +1565,6 @@ status_t MPEG4Writer::Track::threadEntry() {
} else {
timestampUs = lastTimestampUs + (1000000LL + (mTimeScale >> 1)) / mTimeScale;
}
#endif
}
}
@@ -1613,12 +1604,10 @@ status_t MPEG4Writer::Track::threadEntry() {
lastDurationTicks = currDurationTicks;
lastTimestampUs = timestampUs;
if (mIsRealTimeRecording && mIsAudio) {
wallClockTimeUs = systemTime() / 1000;
int64_t wallClockDurationUs = wallClockTimeUs - lastWallClockTimeUs;
if (mNumSamples > 2) {
mOwner->addDriftTimeUs(lastDurationUs - wallClockDurationUs);
int64_t driftTimeUs = 0;
if (meta_data->findInt64(kKeyDriftTime, &driftTimeUs)) {
mOwner->setDriftTimeUs(driftTimeUs);
}
lastWallClockTimeUs = wallClockTimeUs;
}
if (isSync != 0) {
@@ -1851,10 +1840,10 @@ void MPEG4Writer::Track::logStatisticalData(bool isAudio) {
}
}
void MPEG4Writer::addDriftTimeUs(int64_t driftTimeUs) {
LOGV("addDriftTimeUs: %lld us", driftTimeUs);
void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) {
LOGV("setDriftTimeUs: %lld us", driftTimeUs);
Mutex::Autolock autolock(mLock);
mDriftTimeUs += driftTimeUs;
mDriftTimeUs = driftTimeUs;
}
int64_t MPEG4Writer::getDriftTimeUs() {

View File

@@ -208,6 +208,8 @@ status_t AACEncoder::read(
MediaBuffer *buffer;
CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
uint8_t *outPtr = (uint8_t *)buffer->data();
bool readFromSource = false;
int64_t wallClockTimeUs = 0;
if (mFrameCount == 0) {
memcpy(outPtr, mAudioSpecificConfigData, 2);
@@ -238,9 +240,14 @@ status_t AACEncoder::read(
CHECK_EQ(align, 0);
int64_t timeUs;
CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
wallClockTimeUs = timeUs;
if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
mAnchorTimeUs = timeUs;
}
readFromSource = true;
} else {
readFromSource = false;
}
size_t copy =
(kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t);
@@ -288,9 +295,13 @@ status_t AACEncoder::read(
CHECK(outputData.Length != 0);
buffer->set_range(0, outputData.Length);
int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
int64_t mediaTimeUs =
((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
if (readFromSource) {
buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
}
++mFrameCount;
buffer->meta_data()->setInt64(kKeyTime, timestampUs);
*out = buffer;
return OK;

View File

@@ -147,6 +147,8 @@ status_t AMRNBEncoder::read(
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
bool readFromSource = false;
int64_t wallClockTimeUs = 0;
while (mNumInputSamples < kNumSamplesPerFrame) {
if (mInputBuffer == NULL) {
@@ -166,12 +168,16 @@ status_t AMRNBEncoder::read(
size_t align = mInputBuffer->range_length() % sizeof(int16_t);
CHECK_EQ(align, 0);
readFromSource = true;
int64_t timeUs;
CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
wallClockTimeUs = timeUs;
if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
mAnchorTimeUs = timeUs;
mNumFramesOutput = 0;
}
} else {
readFromSource = false;
}
size_t copy =
@@ -217,8 +223,14 @@ status_t AMRNBEncoder::read(
buffer->set_range(0, res);
// Each frame of 160 samples is 20ms long.
int64_t mediaTimeUs = mNumFramesOutput * 20000LL;
buffer->meta_data()->setInt64(
kKeyTime, mAnchorTimeUs + mNumFramesOutput * 20000);
kKeyTime, mAnchorTimeUs + mediaTimeUs);
if (readFromSource) {
buffer->meta_data()->setInt64(kKeyDriftTime,
mediaTimeUs - wallClockTimeUs);
}
++mNumFramesOutput;

View File

@@ -198,6 +198,8 @@ status_t AMRWBEncoder::read(
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
bool readFromSource = false;
int64_t wallClockTimeUs = 0;
while (mNumInputSamples < kNumSamplesPerFrame) {
if (mInputBuffer == NULL) {
@@ -219,9 +221,14 @@ status_t AMRWBEncoder::read(
CHECK_EQ(align, 0);
int64_t timeUs;
CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
wallClockTimeUs = timeUs;
if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
mAnchorTimeUs = timeUs;
}
readFromSource = true;
} else {
readFromSource = false;
}
size_t copy =
@@ -276,10 +283,11 @@ status_t AMRWBEncoder::read(
buffer->set_range(0, outputData.Length);
++mNumFramesOutput;
// XXX: fix timestamp calculation
int64_t timestampUs = mNumFramesOutput * 20000LL;
buffer->meta_data()->setInt64(kKeyTime, timestampUs);
int64_t mediaTimeUs = mNumFramesOutput * 20000LL;
buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
if (readFromSource) {
buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
}
*out = buffer;
return OK;