Merge "Initial checkin for pause and resume control" into kraken
This commit is contained in:
@@ -37,6 +37,7 @@ struct AMRWriter : public MediaWriter {
|
|||||||
virtual bool reachedEOS();
|
virtual bool reachedEOS();
|
||||||
virtual status_t start();
|
virtual status_t start();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
virtual void pause();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~AMRWriter();
|
virtual ~AMRWriter();
|
||||||
@@ -46,6 +47,8 @@ private:
|
|||||||
status_t mInitCheck;
|
status_t mInitCheck;
|
||||||
sp<MediaSource> mSource;
|
sp<MediaSource> mSource;
|
||||||
bool mStarted;
|
bool mStarted;
|
||||||
|
volatile bool mPaused;
|
||||||
|
volatile bool mResumed;
|
||||||
volatile bool mDone;
|
volatile bool mDone;
|
||||||
volatile bool mReachedEOS;
|
volatile bool mReachedEOS;
|
||||||
pthread_t mThread;
|
pthread_t mThread;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public:
|
|||||||
virtual status_t start();
|
virtual status_t start();
|
||||||
virtual bool reachedEOS();
|
virtual bool reachedEOS();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
virtual void pause();
|
||||||
|
|
||||||
void beginBox(const char *fourcc);
|
void beginBox(const char *fourcc);
|
||||||
void writeInt8(int8_t x);
|
void writeInt8(int8_t x);
|
||||||
@@ -59,6 +60,8 @@ private:
|
|||||||
class Track;
|
class Track;
|
||||||
|
|
||||||
FILE *mFile;
|
FILE *mFile;
|
||||||
|
bool mPaused;
|
||||||
|
bool mStarted;
|
||||||
off_t mOffset;
|
off_t mOffset;
|
||||||
off_t mMdatOffset;
|
off_t mMdatOffset;
|
||||||
uint8_t *mMoovBoxBuffer;
|
uint8_t *mMoovBoxBuffer;
|
||||||
@@ -77,6 +80,7 @@ private:
|
|||||||
|
|
||||||
void setStartTimestamp(int64_t timeUs);
|
void setStartTimestamp(int64_t timeUs);
|
||||||
int64_t getStartTimestamp(); // Not const
|
int64_t getStartTimestamp(); // Not const
|
||||||
|
status_t startTracks();
|
||||||
|
|
||||||
void lock();
|
void lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ struct MediaWriter : public RefBase {
|
|||||||
virtual bool reachedEOS() = 0;
|
virtual bool reachedEOS() = 0;
|
||||||
virtual status_t start() = 0;
|
virtual status_t start() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
virtual void pause() = 0;
|
||||||
virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; }
|
virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; }
|
||||||
virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; }
|
virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; }
|
||||||
virtual void setListener(const sp<IMediaPlayerClient>& listener) {
|
virtual void setListener(const sp<IMediaPlayerClient>& listener) {
|
||||||
|
|||||||
@@ -692,6 +692,14 @@ status_t StagefrightRecorder::startMPEG4Recording() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t StagefrightRecorder::pause() {
|
||||||
|
if (mWriter == NULL) {
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
mWriter->pause();
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
status_t StagefrightRecorder::stop() {
|
status_t StagefrightRecorder::stop() {
|
||||||
if (mWriter == NULL) {
|
if (mWriter == NULL) {
|
||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ struct StagefrightRecorder : public MediaRecorderBase {
|
|||||||
virtual status_t setListener(const sp<IMediaPlayerClient>& listener);
|
virtual status_t setListener(const sp<IMediaPlayerClient>& listener);
|
||||||
virtual status_t prepare();
|
virtual status_t prepare();
|
||||||
virtual status_t start();
|
virtual status_t start();
|
||||||
|
virtual status_t pause();
|
||||||
virtual status_t stop();
|
virtual status_t stop();
|
||||||
virtual status_t close();
|
virtual status_t close();
|
||||||
virtual status_t reset();
|
virtual status_t reset();
|
||||||
|
|||||||
@@ -29,13 +29,17 @@ namespace android {
|
|||||||
AMRWriter::AMRWriter(const char *filename)
|
AMRWriter::AMRWriter(const char *filename)
|
||||||
: mFile(fopen(filename, "wb")),
|
: mFile(fopen(filename, "wb")),
|
||||||
mInitCheck(mFile != NULL ? OK : NO_INIT),
|
mInitCheck(mFile != NULL ? OK : NO_INIT),
|
||||||
mStarted(false) {
|
mStarted(false),
|
||||||
|
mPaused(false),
|
||||||
|
mResumed(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AMRWriter::AMRWriter(int fd)
|
AMRWriter::AMRWriter(int fd)
|
||||||
: mFile(fdopen(fd, "wb")),
|
: mFile(fdopen(fd, "wb")),
|
||||||
mInitCheck(mFile != NULL ? OK : NO_INIT),
|
mInitCheck(mFile != NULL ? OK : NO_INIT),
|
||||||
mStarted(false) {
|
mStarted(false),
|
||||||
|
mPaused(false),
|
||||||
|
mResumed(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AMRWriter::~AMRWriter() {
|
AMRWriter::~AMRWriter() {
|
||||||
@@ -98,10 +102,19 @@ status_t AMRWriter::start() {
|
|||||||
return mInitCheck;
|
return mInitCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mStarted || mSource == NULL) {
|
if (mSource == NULL) {
|
||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStarted && mPaused) {
|
||||||
|
mPaused = false;
|
||||||
|
mResumed = true;
|
||||||
|
return OK;
|
||||||
|
} else if (mStarted) {
|
||||||
|
// Already started, does nothing
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
status_t err = mSource->start();
|
status_t err = mSource->start();
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
@@ -123,6 +136,13 @@ status_t AMRWriter::start() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AMRWriter::pause() {
|
||||||
|
if (!mStarted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mPaused = true;
|
||||||
|
}
|
||||||
|
|
||||||
void AMRWriter::stop() {
|
void AMRWriter::stop() {
|
||||||
if (!mStarted) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
@@ -163,6 +183,9 @@ void AMRWriter::threadFunc() {
|
|||||||
mEstimatedDurationUs = 0;
|
mEstimatedDurationUs = 0;
|
||||||
mEstimatedSizeBytes = 0;
|
mEstimatedSizeBytes = 0;
|
||||||
bool stoppedPrematurely = true;
|
bool stoppedPrematurely = true;
|
||||||
|
int64_t previousPausedDurationUs = 0;
|
||||||
|
int64_t maxTimestampUs = 0;
|
||||||
|
|
||||||
while (!mDone) {
|
while (!mDone) {
|
||||||
MediaBuffer *buffer;
|
MediaBuffer *buffer;
|
||||||
status_t err = mSource->read(&buffer);
|
status_t err = mSource->read(&buffer);
|
||||||
@@ -171,6 +194,12 @@ void AMRWriter::threadFunc() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mPaused) {
|
||||||
|
buffer->release();
|
||||||
|
buffer = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mEstimatedSizeBytes += buffer->range_length();
|
mEstimatedSizeBytes += buffer->range_length();
|
||||||
if (exceedsFileSizeLimit()) {
|
if (exceedsFileSizeLimit()) {
|
||||||
buffer->release();
|
buffer->release();
|
||||||
@@ -184,6 +213,17 @@ void AMRWriter::threadFunc() {
|
|||||||
if (timestampUs > mEstimatedDurationUs) {
|
if (timestampUs > mEstimatedDurationUs) {
|
||||||
mEstimatedDurationUs = timestampUs;
|
mEstimatedDurationUs = timestampUs;
|
||||||
}
|
}
|
||||||
|
if (mResumed) {
|
||||||
|
previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000);
|
||||||
|
mResumed = false;
|
||||||
|
}
|
||||||
|
timestampUs -= previousPausedDurationUs;
|
||||||
|
LOGV("time stamp: %lld, previous paused duration: %lld",
|
||||||
|
timestampUs, previousPausedDurationUs);
|
||||||
|
if (timestampUs > maxTimestampUs) {
|
||||||
|
maxTimestampUs = timestampUs;
|
||||||
|
}
|
||||||
|
|
||||||
if (exceedsFileDurationLimit()) {
|
if (exceedsFileDurationLimit()) {
|
||||||
buffer->release();
|
buffer->release();
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|||||||
@@ -121,11 +121,13 @@ status_t AudioSource::read(
|
|||||||
|
|
||||||
uint32_t numFramesRecorded;
|
uint32_t numFramesRecorded;
|
||||||
mRecord->getPosition(&numFramesRecorded);
|
mRecord->getPosition(&numFramesRecorded);
|
||||||
|
int64_t latency = mRecord->latency() * 1000;
|
||||||
|
uint32_t sampleRate = mRecord->getSampleRate();
|
||||||
|
int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate - latency;
|
||||||
|
LOGV("latency: %lld, sample rate: %d, timestamp: %lld",
|
||||||
|
latency, sampleRate, timestampUs);
|
||||||
|
|
||||||
buffer->meta_data()->setInt64(
|
buffer->meta_data()->setInt64(kKeyTime, timestampUs);
|
||||||
kKeyTime,
|
|
||||||
(1000000ll * numFramesRecorded) / mRecord->getSampleRate()
|
|
||||||
- mRecord->latency() * 1000);
|
|
||||||
|
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
if (mCollectStats) {
|
if (mCollectStats) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public:
|
|||||||
|
|
||||||
status_t start();
|
status_t start();
|
||||||
void stop();
|
void stop();
|
||||||
|
void pause();
|
||||||
bool reachedEOS();
|
bool reachedEOS();
|
||||||
|
|
||||||
int64_t getDurationUs() const;
|
int64_t getDurationUs() const;
|
||||||
@@ -54,6 +55,8 @@ private:
|
|||||||
sp<MetaData> mMeta;
|
sp<MetaData> mMeta;
|
||||||
sp<MediaSource> mSource;
|
sp<MediaSource> mSource;
|
||||||
volatile bool mDone;
|
volatile bool mDone;
|
||||||
|
volatile bool mPaused;
|
||||||
|
volatile bool mResumed;
|
||||||
int64_t mMaxTimeStampUs;
|
int64_t mMaxTimeStampUs;
|
||||||
int64_t mEstimatedTrackSizeBytes;
|
int64_t mEstimatedTrackSizeBytes;
|
||||||
|
|
||||||
@@ -120,6 +123,8 @@ private:
|
|||||||
|
|
||||||
MPEG4Writer::MPEG4Writer(const char *filename)
|
MPEG4Writer::MPEG4Writer(const char *filename)
|
||||||
: mFile(fopen(filename, "wb")),
|
: mFile(fopen(filename, "wb")),
|
||||||
|
mPaused(false),
|
||||||
|
mStarted(false),
|
||||||
mOffset(0),
|
mOffset(0),
|
||||||
mMdatOffset(0),
|
mMdatOffset(0),
|
||||||
mEstimatedMoovBoxSize(0),
|
mEstimatedMoovBoxSize(0),
|
||||||
@@ -129,6 +134,8 @@ MPEG4Writer::MPEG4Writer(const char *filename)
|
|||||||
|
|
||||||
MPEG4Writer::MPEG4Writer(int fd)
|
MPEG4Writer::MPEG4Writer(int fd)
|
||||||
: mFile(fdopen(fd, "wb")),
|
: mFile(fdopen(fd, "wb")),
|
||||||
|
mPaused(false),
|
||||||
|
mStarted(false),
|
||||||
mOffset(0),
|
mOffset(0),
|
||||||
mMdatOffset(0),
|
mMdatOffset(0),
|
||||||
mEstimatedMoovBoxSize(0),
|
mEstimatedMoovBoxSize(0),
|
||||||
@@ -153,11 +160,36 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t MPEG4Writer::startTracks() {
|
||||||
|
for (List<Track *>::iterator it = mTracks.begin();
|
||||||
|
it != mTracks.end(); ++it) {
|
||||||
|
status_t err = (*it)->start();
|
||||||
|
|
||||||
|
if (err != OK) {
|
||||||
|
for (List<Track *>::iterator it2 = mTracks.begin();
|
||||||
|
it2 != it; ++it2) {
|
||||||
|
(*it2)->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
status_t MPEG4Writer::start() {
|
status_t MPEG4Writer::start() {
|
||||||
if (mFile == NULL) {
|
if (mFile == NULL) {
|
||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStarted) {
|
||||||
|
if (mPaused) {
|
||||||
|
mPaused = false;
|
||||||
|
return startTracks();
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
mStartTimestampUs = 0;
|
mStartTimestampUs = 0;
|
||||||
mStreamableFile = true;
|
mStreamableFile = true;
|
||||||
mWriteMoovBoxToMemory = false;
|
mWriteMoovBoxToMemory = false;
|
||||||
@@ -186,23 +218,26 @@ status_t MPEG4Writer::start() {
|
|||||||
mOffset = mMdatOffset;
|
mOffset = mMdatOffset;
|
||||||
fseeko(mFile, mMdatOffset, SEEK_SET);
|
fseeko(mFile, mMdatOffset, SEEK_SET);
|
||||||
write("\x00\x00\x00\x01mdat????????", 16);
|
write("\x00\x00\x00\x01mdat????????", 16);
|
||||||
for (List<Track *>::iterator it = mTracks.begin();
|
|
||||||
it != mTracks.end(); ++it) {
|
|
||||||
status_t err = (*it)->start();
|
|
||||||
|
|
||||||
|
status_t err = startTracks();
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
for (List<Track *>::iterator it2 = mTracks.begin();
|
|
||||||
it2 != it; ++it2) {
|
|
||||||
(*it2)->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
mStarted = true;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::pause() {
|
||||||
|
if (mFile == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mPaused = true;
|
||||||
|
for (List<Track *>::iterator it = mTracks.begin();
|
||||||
|
it != mTracks.end(); ++it) {
|
||||||
|
(*it)->pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MPEG4Writer::stop() {
|
void MPEG4Writer::stop() {
|
||||||
if (mFile == NULL) {
|
if (mFile == NULL) {
|
||||||
return;
|
return;
|
||||||
@@ -298,6 +333,7 @@ void MPEG4Writer::stop() {
|
|||||||
fflush(mFile);
|
fflush(mFile);
|
||||||
fclose(mFile);
|
fclose(mFile);
|
||||||
mFile = NULL;
|
mFile = NULL;
|
||||||
|
mStarted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
|
status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
|
||||||
@@ -528,6 +564,8 @@ MPEG4Writer::Track::Track(
|
|||||||
mMeta(source->getFormat()),
|
mMeta(source->getFormat()),
|
||||||
mSource(source),
|
mSource(source),
|
||||||
mDone(false),
|
mDone(false),
|
||||||
|
mPaused(false),
|
||||||
|
mResumed(false),
|
||||||
mMaxTimeStampUs(0),
|
mMaxTimeStampUs(0),
|
||||||
mEstimatedTrackSizeBytes(0),
|
mEstimatedTrackSizeBytes(0),
|
||||||
mSamplesHaveSameSize(true),
|
mSamplesHaveSameSize(true),
|
||||||
@@ -547,6 +585,11 @@ MPEG4Writer::Track::~Track() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t MPEG4Writer::Track::start() {
|
status_t MPEG4Writer::Track::start() {
|
||||||
|
if (!mDone && mPaused) {
|
||||||
|
mPaused = false;
|
||||||
|
mResumed = true;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
status_t err = mSource->start();
|
status_t err = mSource->start();
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
@@ -569,6 +612,10 @@ status_t MPEG4Writer::Track::start() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::Track::pause() {
|
||||||
|
mPaused = true;
|
||||||
|
}
|
||||||
|
|
||||||
void MPEG4Writer::Track::stop() {
|
void MPEG4Writer::Track::stop() {
|
||||||
if (mDone) {
|
if (mDone) {
|
||||||
return;
|
return;
|
||||||
@@ -710,6 +757,7 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
int64_t lastDuration = 0; // Time spacing between the previous two samples
|
int64_t lastDuration = 0; // Time spacing between the previous two samples
|
||||||
int32_t sampleCount = 1; // Sample count in the current stts table entry
|
int32_t sampleCount = 1; // Sample count in the current stts table entry
|
||||||
uint32_t previousSampleSize = 0; // Size of the previous sample
|
uint32_t previousSampleSize = 0; // Size of the previous sample
|
||||||
|
int64_t previousPausedDurationUs = 0;
|
||||||
sp<MetaData> meta_data;
|
sp<MetaData> meta_data;
|
||||||
|
|
||||||
MediaBuffer *buffer;
|
MediaBuffer *buffer;
|
||||||
@@ -721,6 +769,15 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the codec specific data has not been received yet, delay pause.
|
||||||
|
// After the codec specific data is received, discard what we received
|
||||||
|
// when the track is to be paused.
|
||||||
|
if (mPaused && !mResumed) {
|
||||||
|
buffer->release();
|
||||||
|
buffer = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
int32_t isCodecConfig;
|
int32_t isCodecConfig;
|
||||||
@@ -831,6 +888,10 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mGotAllCodecSpecificData) {
|
||||||
|
mGotAllCodecSpecificData = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Make a deep copy of the MediaBuffer and Metadata and release
|
// Make a deep copy of the MediaBuffer and Metadata and release
|
||||||
// the original as soon as we can
|
// the original as soon as we can
|
||||||
MediaBuffer *copy = new MediaBuffer(buffer->range_length());
|
MediaBuffer *copy = new MediaBuffer(buffer->range_length());
|
||||||
@@ -876,6 +937,14 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp());
|
mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mResumed) {
|
||||||
|
previousPausedDurationUs += (timestampUs - mMaxTimeStampUs - 1000 * lastDuration);
|
||||||
|
mResumed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
timestampUs -= previousPausedDurationUs;
|
||||||
|
LOGV("time stamp: %lld and previous paused duration %lld",
|
||||||
|
timestampUs, previousPausedDurationUs);
|
||||||
if (timestampUs > mMaxTimeStampUs) {
|
if (timestampUs > mMaxTimeStampUs) {
|
||||||
mMaxTimeStampUs = timestampUs;
|
mMaxTimeStampUs = timestampUs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,13 +205,15 @@ status_t AACEncoder::read(
|
|||||||
buffer->set_range(0, 2);
|
buffer->set_range(0, 2);
|
||||||
buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
|
buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
|
||||||
*out = buffer;
|
*out = buffer;
|
||||||
++mFrameCount;
|
|
||||||
mInputBuffer = NULL;
|
mInputBuffer = NULL;
|
||||||
|
++mFrameCount;
|
||||||
return OK;
|
return OK;
|
||||||
} else {
|
} else if (mFrameCount == 1) {
|
||||||
buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
|
buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: We assume that the input buffer contains at least
|
||||||
|
// (actually, exactly) 1024 PCM samples. This needs to be fixed.
|
||||||
if (mInputBuffer == NULL) {
|
if (mInputBuffer == NULL) {
|
||||||
if (mSource->read(&mInputBuffer, options) != OK) {
|
if (mSource->read(&mInputBuffer, options) != OK) {
|
||||||
LOGE("failed to read from input audio source");
|
LOGE("failed to read from input audio source");
|
||||||
@@ -252,9 +254,10 @@ status_t AACEncoder::read(
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer->set_range(0, outputLength);
|
buffer->set_range(0, outputLength);
|
||||||
++mFrameCount;
|
|
||||||
int64_t timestampUs = (mFrameCount * 1000000LL * 1024) / mSampleRate;
|
|
||||||
|
|
||||||
|
// Each output frame compresses 1024 input PCM samples.
|
||||||
|
int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * 1024) / mSampleRate;
|
||||||
|
++mFrameCount;
|
||||||
buffer->meta_data()->setInt64(kKeyTime, timestampUs);
|
buffer->meta_data()->setInt64(kKeyTime, timestampUs);
|
||||||
|
|
||||||
*out = buffer;
|
*out = buffer;
|
||||||
|
|||||||
Reference in New Issue
Block a user