summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-08-18 19:10:39 -0700
committerJames Dong <jdong@google.com>2010-08-19 13:33:13 -0700
commitd036662470ceb6b20b0591b7d4123f2db911536d (patch)
tree6b751779eb0cc241a42034bf4e3ef74ec1691371 /media/libstagefright
parent54d41379357d1d800d0a7bd7c5dc56111710482a (diff)
downloadframeworks_base-d036662470ceb6b20b0591b7d4123f2db911536d.zip
frameworks_base-d036662470ceb6b20b0591b7d4123f2db911536d.tar.gz
frameworks_base-d036662470ceb6b20b0591b7d4123f2db911536d.tar.bz2
Make MediaWriter stop and pause return errors if necessary
o Make the API consistent with SF framework, which the MediaSource provides a return status for stop o Also, helps to convey errors that occurred right when a premature stop() is called, leading to a potentially mal-formed output file. Change-Id: I52a932345f38570fdf8ea04d67d73dd94ccd30ef
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/AMRWriter.cpp32
-rw-r--r--media/libstagefright/MPEG4Writer.cpp69
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.cpp8
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.h4
4 files changed, 79 insertions, 34 deletions
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index c71743e..71d48b3 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -136,16 +136,17 @@ status_t AMRWriter::start(MetaData *params) {
return OK;
}
-void AMRWriter::pause() {
+status_t AMRWriter::pause() {
if (!mStarted) {
- return;
+ return OK;
}
mPaused = true;
+ return OK;
}
-void AMRWriter::stop() {
+status_t AMRWriter::stop() {
if (!mStarted) {
- return;
+ return OK;
}
mDone = true;
@@ -153,9 +154,17 @@ void AMRWriter::stop() {
void *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;
+ return err;
}
bool AMRWriter::exceedsFileSizeLimit() {
@@ -174,21 +183,20 @@ bool AMRWriter::exceedsFileDurationLimit() {
// static
void *AMRWriter::ThreadWrapper(void *me) {
- static_cast<AMRWriter *>(me)->threadFunc();
-
- return NULL;
+ return (void *) static_cast<AMRWriter *>(me)->threadFunc();
}
-void AMRWriter::threadFunc() {
+status_t AMRWriter::threadFunc() {
mEstimatedDurationUs = 0;
mEstimatedSizeBytes = 0;
bool stoppedPrematurely = true;
int64_t previousPausedDurationUs = 0;
int64_t maxTimestampUs = 0;
+ status_t err = OK;
while (!mDone) {
MediaBuffer *buffer;
- status_t err = mSource->read(&buffer);
+ err = mSource->read(&buffer);
if (err != OK) {
break;
@@ -260,6 +268,10 @@ void AMRWriter::threadFunc() {
fclose(mFile);
mFile = NULL;
mReachedEOS = true;
+ if (err == ERROR_END_OF_STREAM) {
+ return OK;
+ }
+ return err;
}
bool AMRWriter::reachedEOS() {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index f52ec1a..6bb54bd 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -48,8 +48,8 @@ public:
~Track();
status_t start(MetaData *params);
- void stop();
- void pause();
+ status_t stop();
+ status_t pause();
bool reachedEOS();
int64_t getDurationUs() const;
@@ -144,7 +144,7 @@ private:
int64_t mTrackEveryTimeDurationUs;
static void *ThreadWrapper(void *me);
- void threadEntry();
+ status_t threadEntry();
const uint8_t *parseParamSet(
const uint8_t *data, size_t length, int type, size_t *paramSetLen);
@@ -378,15 +378,20 @@ status_t MPEG4Writer::start(MetaData *param) {
return OK;
}
-void MPEG4Writer::pause() {
+status_t MPEG4Writer::pause() {
if (mFile == NULL) {
- return;
+ return OK;
}
mPaused = true;
+ status_t err = OK;
for (List<Track *>::iterator it = mTracks.begin();
it != mTracks.end(); ++it) {
- (*it)->pause();
+ status_t status = (*it)->pause();
+ if (status != OK) {
+ err = status;
+ }
}
+ return err;
}
void MPEG4Writer::stopWriterThread() {
@@ -403,15 +408,19 @@ void MPEG4Writer::stopWriterThread() {
pthread_join(mThread, &dummy);
}
-void MPEG4Writer::stop() {
+status_t MPEG4Writer::stop() {
if (mFile == NULL) {
- return;
+ return OK;
}
+ status_t err = OK;
int64_t maxDurationUs = 0;
for (List<Track *>::iterator it = mTracks.begin();
it != mTracks.end(); ++it) {
- (*it)->stop();
+ status_t status = (*it)->stop();
+ if (err == OK && status != OK) {
+ err = status;
+ }
int64_t durationUs = (*it)->getDurationUs();
if (durationUs > maxDurationUs) {
@@ -421,6 +430,15 @@ void MPEG4Writer::stop() {
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.
if (mUse32BitOffset) {
fseeko(mFile, mMdatOffset, SEEK_SET);
@@ -508,6 +526,7 @@ void MPEG4Writer::stop() {
fclose(mFile);
mFile = NULL;
mStarted = false;
+ return err;
}
status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
@@ -1030,13 +1049,14 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
return OK;
}
-void MPEG4Writer::Track::pause() {
+status_t MPEG4Writer::Track::pause() {
mPaused = true;
+ return OK;
}
-void MPEG4Writer::Track::stop() {
+status_t MPEG4Writer::Track::stop() {
if (mDone) {
- return;
+ return OK;
}
mDone = true;
@@ -1044,7 +1064,16 @@ void MPEG4Writer::Track::stop() {
void *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() {
@@ -1055,9 +1084,8 @@ bool MPEG4Writer::Track::reachedEOS() {
void *MPEG4Writer::Track::ThreadWrapper(void *me) {
Track *track = static_cast<Track *>(me);
- track->threadEntry();
-
- return NULL;
+ status_t err = track->threadEntry();
+ return (void *) err;
}
#include <ctype.h>
@@ -1352,7 +1380,7 @@ static bool collectStatisticalData() {
return false;
}
-void MPEG4Writer::Track::threadEntry() {
+status_t MPEG4Writer::Track::threadEntry() {
int32_t count = 0;
const int64_t interleaveDurationUs = mOwner->interleaveDuration();
int64_t chunkTimestampUs = 0;
@@ -1595,7 +1623,7 @@ void MPEG4Writer::Track::threadEntry() {
}
if (mSampleSizes.empty()) {
- err = UNKNOWN_ERROR;
+ err = ERROR_MALFORMED;
}
mOwner->trackProgressStatus(this, -1, err);
@@ -1626,6 +1654,10 @@ void MPEG4Writer::Track::threadEntry() {
count, nZeroLengthFrames, mNumSamples, mMaxWriteTimeUs, mIsAudio? "audio": "video");
logStatisticalData(mIsAudio);
+ if (err == ERROR_END_OF_STREAM) {
+ return OK;
+ }
+ return err;
}
void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
@@ -1973,7 +2005,6 @@ void MPEG4Writer::Track::writeTrackHeader(
int32_t samplerate;
bool success = mMeta->findInt32(kKeySampleRate, &samplerate);
CHECK(success);
-
mOwner->writeInt32(samplerate << 16);
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
mOwner->beginBox("esds");
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index d6dd597..d4eed7c 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -134,10 +134,10 @@ status_t ARTPWriter::start(MetaData *params) {
return OK;
}
-void ARTPWriter::stop() {
+status_t ARTPWriter::stop() {
Mutex::Autolock autoLock(mLock);
if (!(mFlags & kFlagStarted)) {
- return;
+ return OK;
}
(new AMessage(kWhatStop, mReflector->id()))->post();
@@ -145,9 +145,11 @@ void ARTPWriter::stop() {
while (mFlags & kFlagStarted) {
mCondition.wait(mLock);
}
+ return OK;
}
-void ARTPWriter::pause() {
+status_t ARTPWriter::pause() {
+ return OK;
}
static void StripStartcode(MediaBuffer *buffer) {
diff --git a/media/libstagefright/rtsp/ARTPWriter.h b/media/libstagefright/rtsp/ARTPWriter.h
index b1b8b45..fdc8d23 100644
--- a/media/libstagefright/rtsp/ARTPWriter.h
+++ b/media/libstagefright/rtsp/ARTPWriter.h
@@ -40,8 +40,8 @@ struct ARTPWriter : public MediaWriter {
virtual status_t addSource(const sp<MediaSource> &source);
virtual bool reachedEOS();
virtual status_t start(MetaData *params);
- virtual void stop();
- virtual void pause();
+ virtual status_t stop();
+ virtual status_t pause();
virtual void onMessageReceived(const sp<AMessage> &msg);