am cbd038fe
: Merge "Make MediaWriter stop and pause return errors if necessary" into gingerbread
Merge commit 'cbd038fe207f183bc7e0a610973473f7c2e9d118' into gingerbread-plus-aosp * commit 'cbd038fe207f183bc7e0a610973473f7c2e9d118': Make MediaWriter stop and pause return errors if necessary
This commit is contained in:
@ -37,8 +37,8 @@ struct AMRWriter : public MediaWriter {
|
|||||||
virtual status_t addSource(const sp<MediaSource> &source);
|
virtual status_t addSource(const sp<MediaSource> &source);
|
||||||
virtual bool reachedEOS();
|
virtual bool reachedEOS();
|
||||||
virtual status_t start(MetaData *params = NULL);
|
virtual status_t start(MetaData *params = NULL);
|
||||||
virtual void stop();
|
virtual status_t stop();
|
||||||
virtual void pause();
|
virtual status_t pause();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~AMRWriter();
|
virtual ~AMRWriter();
|
||||||
@ -57,7 +57,7 @@ private:
|
|||||||
int64_t mEstimatedDurationUs;
|
int64_t mEstimatedDurationUs;
|
||||||
|
|
||||||
static void *ThreadWrapper(void *);
|
static void *ThreadWrapper(void *);
|
||||||
void threadFunc();
|
status_t threadFunc();
|
||||||
bool exceedsFileSizeLimit();
|
bool exceedsFileSizeLimit();
|
||||||
bool exceedsFileDurationLimit();
|
bool exceedsFileDurationLimit();
|
||||||
|
|
||||||
|
@ -37,9 +37,9 @@ public:
|
|||||||
|
|
||||||
virtual status_t addSource(const sp<MediaSource> &source);
|
virtual status_t addSource(const sp<MediaSource> &source);
|
||||||
virtual status_t start(MetaData *param = NULL);
|
virtual status_t start(MetaData *param = NULL);
|
||||||
|
virtual status_t stop();
|
||||||
|
virtual status_t pause();
|
||||||
virtual bool reachedEOS();
|
virtual bool reachedEOS();
|
||||||
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);
|
||||||
|
@ -35,8 +35,9 @@ struct MediaWriter : public RefBase {
|
|||||||
virtual status_t addSource(const sp<MediaSource> &source) = 0;
|
virtual status_t addSource(const sp<MediaSource> &source) = 0;
|
||||||
virtual bool reachedEOS() = 0;
|
virtual bool reachedEOS() = 0;
|
||||||
virtual status_t start(MetaData *params = NULL) = 0;
|
virtual status_t start(MetaData *params = NULL) = 0;
|
||||||
virtual void stop() = 0;
|
virtual status_t stop() = 0;
|
||||||
virtual void pause() = 0;
|
virtual status_t 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<IMediaRecorderClient>& listener) {
|
virtual void setListener(const sp<IMediaRecorderClient>& listener) {
|
||||||
|
@ -1067,8 +1067,9 @@ status_t StagefrightRecorder::pause() {
|
|||||||
|
|
||||||
status_t StagefrightRecorder::stop() {
|
status_t StagefrightRecorder::stop() {
|
||||||
LOGV("stop");
|
LOGV("stop");
|
||||||
|
status_t err = OK;
|
||||||
if (mWriter != NULL) {
|
if (mWriter != NULL) {
|
||||||
mWriter->stop();
|
err = mWriter->stop();
|
||||||
mWriter.clear();
|
mWriter.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,7 +1091,7 @@ status_t StagefrightRecorder::stop() {
|
|||||||
mOutputFd = -1;
|
mOutputFd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t StagefrightRecorder::close() {
|
status_t StagefrightRecorder::close() {
|
||||||
|
@ -136,16 +136,17 @@ status_t AMRWriter::start(MetaData *params) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMRWriter::pause() {
|
status_t AMRWriter::pause() {
|
||||||
if (!mStarted) {
|
if (!mStarted) {
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
mPaused = true;
|
mPaused = true;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMRWriter::stop() {
|
status_t AMRWriter::stop() {
|
||||||
if (!mStarted) {
|
if (!mStarted) {
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDone = true;
|
mDone = true;
|
||||||
@ -153,9 +154,17 @@ void AMRWriter::stop() {
|
|||||||
void *dummy;
|
void *dummy;
|
||||||
pthread_join(mThread, &dummy);
|
pthread_join(mThread, &dummy);
|
||||||
|
|
||||||
mSource->stop();
|
status_t err = (status_t) dummy;
|
||||||
|
{
|
||||||
|
status_t status = mSource->stop();
|
||||||
|
if (err == OK &&
|
||||||
|
(status != OK && status != ERROR_END_OF_STREAM)) {
|
||||||
|
err = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mStarted = false;
|
mStarted = false;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMRWriter::exceedsFileSizeLimit() {
|
bool AMRWriter::exceedsFileSizeLimit() {
|
||||||
@ -174,21 +183,20 @@ bool AMRWriter::exceedsFileDurationLimit() {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void *AMRWriter::ThreadWrapper(void *me) {
|
void *AMRWriter::ThreadWrapper(void *me) {
|
||||||
static_cast<AMRWriter *>(me)->threadFunc();
|
return (void *) static_cast<AMRWriter *>(me)->threadFunc();
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMRWriter::threadFunc() {
|
status_t AMRWriter::threadFunc() {
|
||||||
mEstimatedDurationUs = 0;
|
mEstimatedDurationUs = 0;
|
||||||
mEstimatedSizeBytes = 0;
|
mEstimatedSizeBytes = 0;
|
||||||
bool stoppedPrematurely = true;
|
bool stoppedPrematurely = true;
|
||||||
int64_t previousPausedDurationUs = 0;
|
int64_t previousPausedDurationUs = 0;
|
||||||
int64_t maxTimestampUs = 0;
|
int64_t maxTimestampUs = 0;
|
||||||
|
status_t err = OK;
|
||||||
|
|
||||||
while (!mDone) {
|
while (!mDone) {
|
||||||
MediaBuffer *buffer;
|
MediaBuffer *buffer;
|
||||||
status_t err = mSource->read(&buffer);
|
err = mSource->read(&buffer);
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
break;
|
break;
|
||||||
@ -260,6 +268,10 @@ void AMRWriter::threadFunc() {
|
|||||||
fclose(mFile);
|
fclose(mFile);
|
||||||
mFile = NULL;
|
mFile = NULL;
|
||||||
mReachedEOS = true;
|
mReachedEOS = true;
|
||||||
|
if (err == ERROR_END_OF_STREAM) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMRWriter::reachedEOS() {
|
bool AMRWriter::reachedEOS() {
|
||||||
|
@ -48,8 +48,8 @@ public:
|
|||||||
~Track();
|
~Track();
|
||||||
|
|
||||||
status_t start(MetaData *params);
|
status_t start(MetaData *params);
|
||||||
void stop();
|
status_t stop();
|
||||||
void pause();
|
status_t pause();
|
||||||
bool reachedEOS();
|
bool reachedEOS();
|
||||||
|
|
||||||
int64_t getDurationUs() const;
|
int64_t getDurationUs() const;
|
||||||
@ -144,7 +144,7 @@ private:
|
|||||||
int64_t mTrackEveryTimeDurationUs;
|
int64_t mTrackEveryTimeDurationUs;
|
||||||
|
|
||||||
static void *ThreadWrapper(void *me);
|
static void *ThreadWrapper(void *me);
|
||||||
void threadEntry();
|
status_t threadEntry();
|
||||||
|
|
||||||
const uint8_t *parseParamSet(
|
const uint8_t *parseParamSet(
|
||||||
const uint8_t *data, size_t length, int type, size_t *paramSetLen);
|
const uint8_t *data, size_t length, int type, size_t *paramSetLen);
|
||||||
@ -378,16 +378,21 @@ status_t MPEG4Writer::start(MetaData *param) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPEG4Writer::pause() {
|
status_t MPEG4Writer::pause() {
|
||||||
if (mFile == NULL) {
|
if (mFile == NULL) {
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
mPaused = true;
|
mPaused = true;
|
||||||
|
status_t err = OK;
|
||||||
for (List<Track *>::iterator it = mTracks.begin();
|
for (List<Track *>::iterator it = mTracks.begin();
|
||||||
it != mTracks.end(); ++it) {
|
it != mTracks.end(); ++it) {
|
||||||
(*it)->pause();
|
status_t status = (*it)->pause();
|
||||||
|
if (status != OK) {
|
||||||
|
err = status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void MPEG4Writer::stopWriterThread() {
|
void MPEG4Writer::stopWriterThread() {
|
||||||
LOGV("stopWriterThread");
|
LOGV("stopWriterThread");
|
||||||
@ -403,15 +408,19 @@ void MPEG4Writer::stopWriterThread() {
|
|||||||
pthread_join(mThread, &dummy);
|
pthread_join(mThread, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPEG4Writer::stop() {
|
status_t MPEG4Writer::stop() {
|
||||||
if (mFile == NULL) {
|
if (mFile == NULL) {
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t err = OK;
|
||||||
int64_t maxDurationUs = 0;
|
int64_t maxDurationUs = 0;
|
||||||
for (List<Track *>::iterator it = mTracks.begin();
|
for (List<Track *>::iterator it = mTracks.begin();
|
||||||
it != mTracks.end(); ++it) {
|
it != mTracks.end(); ++it) {
|
||||||
(*it)->stop();
|
status_t status = (*it)->stop();
|
||||||
|
if (err == OK && status != OK) {
|
||||||
|
err = status;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t durationUs = (*it)->getDurationUs();
|
int64_t durationUs = (*it)->getDurationUs();
|
||||||
if (durationUs > maxDurationUs) {
|
if (durationUs > maxDurationUs) {
|
||||||
@ -421,6 +430,15 @@ void MPEG4Writer::stop() {
|
|||||||
|
|
||||||
stopWriterThread();
|
stopWriterThread();
|
||||||
|
|
||||||
|
// Do not write out movie header on error.
|
||||||
|
if (err != OK) {
|
||||||
|
fflush(mFile);
|
||||||
|
fclose(mFile);
|
||||||
|
mFile = NULL;
|
||||||
|
mStarted = false;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
// Fix up the size of the 'mdat' chunk.
|
// Fix up the size of the 'mdat' chunk.
|
||||||
if (mUse32BitOffset) {
|
if (mUse32BitOffset) {
|
||||||
fseeko(mFile, mMdatOffset, SEEK_SET);
|
fseeko(mFile, mMdatOffset, SEEK_SET);
|
||||||
@ -508,6 +526,7 @@ void MPEG4Writer::stop() {
|
|||||||
fclose(mFile);
|
fclose(mFile);
|
||||||
mFile = NULL;
|
mFile = NULL;
|
||||||
mStarted = false;
|
mStarted = false;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
|
status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
|
||||||
@ -1030,13 +1049,14 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPEG4Writer::Track::pause() {
|
status_t MPEG4Writer::Track::pause() {
|
||||||
mPaused = true;
|
mPaused = true;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPEG4Writer::Track::stop() {
|
status_t MPEG4Writer::Track::stop() {
|
||||||
if (mDone) {
|
if (mDone) {
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDone = true;
|
mDone = true;
|
||||||
@ -1044,7 +1064,16 @@ void MPEG4Writer::Track::stop() {
|
|||||||
void *dummy;
|
void *dummy;
|
||||||
pthread_join(mThread, &dummy);
|
pthread_join(mThread, &dummy);
|
||||||
|
|
||||||
mSource->stop();
|
status_t err = (status_t) dummy;
|
||||||
|
|
||||||
|
{
|
||||||
|
status_t status = mSource->stop();
|
||||||
|
if (err == OK && status != OK && status != ERROR_END_OF_STREAM) {
|
||||||
|
err = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MPEG4Writer::Track::reachedEOS() {
|
bool MPEG4Writer::Track::reachedEOS() {
|
||||||
@ -1055,9 +1084,8 @@ bool MPEG4Writer::Track::reachedEOS() {
|
|||||||
void *MPEG4Writer::Track::ThreadWrapper(void *me) {
|
void *MPEG4Writer::Track::ThreadWrapper(void *me) {
|
||||||
Track *track = static_cast<Track *>(me);
|
Track *track = static_cast<Track *>(me);
|
||||||
|
|
||||||
track->threadEntry();
|
status_t err = track->threadEntry();
|
||||||
|
return (void *) err;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1352,7 +1380,7 @@ static bool collectStatisticalData() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPEG4Writer::Track::threadEntry() {
|
status_t MPEG4Writer::Track::threadEntry() {
|
||||||
int32_t count = 0;
|
int32_t count = 0;
|
||||||
const int64_t interleaveDurationUs = mOwner->interleaveDuration();
|
const int64_t interleaveDurationUs = mOwner->interleaveDuration();
|
||||||
int64_t chunkTimestampUs = 0;
|
int64_t chunkTimestampUs = 0;
|
||||||
@ -1595,7 +1623,7 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mSampleSizes.empty()) {
|
if (mSampleSizes.empty()) {
|
||||||
err = UNKNOWN_ERROR;
|
err = ERROR_MALFORMED;
|
||||||
}
|
}
|
||||||
mOwner->trackProgressStatus(this, -1, err);
|
mOwner->trackProgressStatus(this, -1, err);
|
||||||
|
|
||||||
@ -1626,6 +1654,10 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
count, nZeroLengthFrames, mNumSamples, mMaxWriteTimeUs, mIsAudio? "audio": "video");
|
count, nZeroLengthFrames, mNumSamples, mMaxWriteTimeUs, mIsAudio? "audio": "video");
|
||||||
|
|
||||||
logStatisticalData(mIsAudio);
|
logStatisticalData(mIsAudio);
|
||||||
|
if (err == ERROR_END_OF_STREAM) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
|
void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
|
||||||
@ -1973,7 +2005,6 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
int32_t samplerate;
|
int32_t samplerate;
|
||||||
bool success = mMeta->findInt32(kKeySampleRate, &samplerate);
|
bool success = mMeta->findInt32(kKeySampleRate, &samplerate);
|
||||||
CHECK(success);
|
CHECK(success);
|
||||||
|
|
||||||
mOwner->writeInt32(samplerate << 16);
|
mOwner->writeInt32(samplerate << 16);
|
||||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
|
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
|
||||||
mOwner->beginBox("esds");
|
mOwner->beginBox("esds");
|
||||||
|
@ -134,10 +134,10 @@ status_t ARTPWriter::start(MetaData *params) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARTPWriter::stop() {
|
status_t ARTPWriter::stop() {
|
||||||
Mutex::Autolock autoLock(mLock);
|
Mutex::Autolock autoLock(mLock);
|
||||||
if (!(mFlags & kFlagStarted)) {
|
if (!(mFlags & kFlagStarted)) {
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
(new AMessage(kWhatStop, mReflector->id()))->post();
|
(new AMessage(kWhatStop, mReflector->id()))->post();
|
||||||
@ -145,9 +145,11 @@ void ARTPWriter::stop() {
|
|||||||
while (mFlags & kFlagStarted) {
|
while (mFlags & kFlagStarted) {
|
||||||
mCondition.wait(mLock);
|
mCondition.wait(mLock);
|
||||||
}
|
}
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARTPWriter::pause() {
|
status_t ARTPWriter::pause() {
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StripStartcode(MediaBuffer *buffer) {
|
static void StripStartcode(MediaBuffer *buffer) {
|
||||||
|
@ -40,8 +40,8 @@ struct ARTPWriter : public MediaWriter {
|
|||||||
virtual status_t addSource(const sp<MediaSource> &source);
|
virtual status_t addSource(const sp<MediaSource> &source);
|
||||||
virtual bool reachedEOS();
|
virtual bool reachedEOS();
|
||||||
virtual status_t start(MetaData *params);
|
virtual status_t start(MetaData *params);
|
||||||
virtual void stop();
|
virtual status_t stop();
|
||||||
virtual void pause();
|
virtual status_t pause();
|
||||||
|
|
||||||
virtual void onMessageReceived(const sp<AMessage> &msg);
|
virtual void onMessageReceived(const sp<AMessage> &msg);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user