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:
@@ -72,6 +72,7 @@ private:
|
||||
int64_t mPrevSampleTimeUs;
|
||||
int64_t mTotalLostFrames;
|
||||
int64_t mPrevLostBytes;
|
||||
int64_t mInitialReadTimeUs;
|
||||
|
||||
MediaBufferGroup *mGroup;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user